Added Spinbox.OnChanged() and implemented it on GTK+ and Mac OS X. Implementing it on Windows is going to be a pain...

This commit is contained in:
Pietro Gagliardi 2014-10-31 19:57:48 -04:00
parent 68af61435e
commit 7c96841392
5 changed files with 44 additions and 10 deletions

View File

@ -146,7 +146,6 @@ func NewTextbox() Textbox {
// - TODO set increment? (work on windows) // - TODO set increment? (work on windows)
// - TODO set page step? // - TODO set page step?
// - TODO wrapping // - TODO wrapping
// - TODO set/get integer value
// - TODO negative values // - TODO negative values
// - TODO ensuring values entered in text box stay within bounds // - TODO ensuring values entered in text box stay within bounds
type Spinbox interface { type Spinbox interface {
@ -156,6 +155,10 @@ type Spinbox interface {
// For SetValue, if the new value is outside the current range of the Spinbox, it is set to the nearest extremity. // For SetValue, if the new value is outside the current range of the Spinbox, it is set to the nearest extremity.
Value() int Value() int
SetValue(value int) SetValue(value int)
// OnChanged sets the event handler for when the Spinbox's value is changed.
// Under what conditions this event is raised when the user types into the Spinbox's edit field is platform-defined.
OnChanged(func())
} }
// NewSpinbox creates a new Spinbox with the given minimum and maximum. // NewSpinbox creates a new Spinbox with the given minimum and maximum.

View File

@ -21,12 +21,14 @@ import "C"
// - proper spacing between edit and spinner: Interface Builder isn't clear; NSDatePicker doesn't spill the beans // - proper spacing between edit and spinner: Interface Builder isn't clear; NSDatePicker doesn't spill the beans
type spinbox struct { type spinbox struct {
id C.id id C.id
changed *event
} }
func newSpinbox(min int, max int) Spinbox { func newSpinbox(min int, max int) Spinbox {
s := new(spinbox) s := new(spinbox)
s.id = C.newSpinbox(unsafe.Pointer(s), C.intmax_t(min), C.intmax_t(max)) s.id = C.newSpinbox(unsafe.Pointer(s), C.intmax_t(min), C.intmax_t(max))
s.changed = newEvent()
return s return s
} }
@ -38,6 +40,16 @@ func (s *spinbox) SetValue(value int) {
C.spinboxSetValue(s.id, C.intmax_t(value)) C.spinboxSetValue(s.id, C.intmax_t(value))
} }
func (s *spinbox) OnChanged(e func()) {
s.changed.set(e)
}
//export spinboxChanged
func spinboxChanged(data unsafe.Pointer) {
s := (*spinbox)(data)
s.changed.fire()
}
func (s *spinbox) textfield() C.id { func (s *spinbox) textfield() C.id {
return C.spinboxTextField(s.id) return C.spinboxTextField(s.id)
} }

View File

@ -84,11 +84,13 @@
- (IBAction)stepperClicked:(id)sender - (IBAction)stepperClicked:(id)sender
{ {
[self setValue:[self->stepper integerValue]]; [self setValue:[self->stepper integerValue]];
spinboxChanged(self->gospinbox);
} }
- (void)controlTextDidChange:(NSNotification *)note - (void)controlTextDidChange:(NSNotification *)note
{ {
[self setValue:[self->textfield integerValue]]; [self setValue:[self->textfield integerValue]];
spinboxChanged(self->gospinbox);
} }
@end @end

View File

@ -9,6 +9,7 @@ import (
) )
// #include "gtk_unix.h" // #include "gtk_unix.h"
// extern void spinboxChanged(GtkSpinButton *, gpointer);
import "C" import "C"
// TODO preferred width may be too wide // TODO preferred width may be too wide
@ -16,6 +17,7 @@ import "C"
type spinbox struct { type spinbox struct {
*controlSingleWidget *controlSingleWidget
spinbutton *C.GtkSpinButton spinbutton *C.GtkSpinButton
changed *event
} }
func newSpinbox(min int, max int) Spinbox { func newSpinbox(min int, max int) Spinbox {
@ -24,9 +26,18 @@ func newSpinbox(min int, max int) Spinbox {
s := &spinbox{ s := &spinbox{
controlSingleWidget: newControlSingleWidget(widget), controlSingleWidget: newControlSingleWidget(widget),
spinbutton: (*C.GtkSpinButton)(unsafe.Pointer(widget)), spinbutton: (*C.GtkSpinButton)(unsafe.Pointer(widget)),
changed: newEvent(),
} }
C.gtk_spin_button_set_digits(s.spinbutton, 0) // integers C.gtk_spin_button_set_digits(s.spinbutton, 0) // integers
C.gtk_spin_button_set_numeric(s.spinbutton, C.TRUE) // digits only C.gtk_spin_button_set_numeric(s.spinbutton, C.TRUE) // digits only
// this isn't specifically documented as the signal to connect to until 3.14
// it has existed as far back as 3.4, though, if not earlier
// there's also ::change-value which is for keyboard changing
g_signal_connect(
C.gpointer(unsafe.Pointer(s.spinbutton)),
"value-changed",
C.GCallback(C.spinboxChanged),
C.gpointer(unsafe.Pointer(s)))
return s return s
} }
@ -46,3 +57,13 @@ func (s *spinbox) SetValue(value int) {
} }
C.gtk_spin_button_set_value(s.spinbutton, C.gdouble(value)) C.gtk_spin_button_set_value(s.spinbutton, C.gdouble(value))
} }
func (s *spinbox) OnChanged(e func()) {
s.changed.set(e)
}
//export spinboxChanged
func spinboxChanged(swid *C.GtkSpinButton, data C.gpointer) {
s := (*spinbox)(unsafe.Pointer(data))
s.changed.fire()
}

View File

@ -150,15 +150,11 @@ func (tw *testwin) addfe() {
tw.festack.SetStretchy(4) tw.festack.SetStretchy(4)
tw.festack.SetStretchy(6) tw.festack.SetStretchy(6)
sb := NewSpinbox(0, 100) sb := NewSpinbox(0, 100)
cbutton := NewButton("Set to Invalid Low") sl := NewLabel("")
cbutton.OnClicked(func() { sb.OnChanged(func() {
sb.SetValue(-500) sl.SetText(fmt.Sprintf("%d", sb.Value()))
}) })
dbutton := NewButton("Set to Invalid High") tw.festack2 = newVerticalStack(sb, sl, Space(), Space(), NewTextbox())
dbutton.OnClicked(func() {
sb.SetValue(500)
})
tw.festack2 = newVerticalStack(sb, cbutton, dbutton, Space(), NewTextbox())
tw.festack2.SetStretchy(3) tw.festack2.SetStretchy(3)
tw.festack2.SetStretchy(4) tw.festack2.SetStretchy(4)
tw.festack = newHorizontalStack(tw.festack, tw.festack2) tw.festack = newHorizontalStack(tw.festack, tw.festack2)