Added Checkbox on the GTK+ backend, added a checkbox to the test program, and fixed a small error in the GTK+ widgetbase.parent() that kept the new widget hidden.

This commit is contained in:
Pietro Gagliardi 2014-07-21 21:07:14 -04:00
parent 54c999bc42
commit d57d2aa2de
4 changed files with 67 additions and 10 deletions

View File

@ -32,6 +32,17 @@ func freegstr(s *C.gchar) {
C.free(unsafe.Pointer(s)) C.free(unsafe.Pointer(s))
} }
func fromgbool(b C.gboolean) bool {
return b != C.FALSE
}
func togbool(b bool) C.gboolean {
if b == true {
return C.TRUE
}
return C.FALSE
}
func g_signal_connect(object C.gpointer, name string, to C.GCallback, data C.gpointer) { func g_signal_connect(object C.gpointer, name string, to C.GCallback, data C.gpointer) {
cname := togstr(name) cname := togstr(name)
defer freegstr(cname) defer freegstr(cname)

View File

@ -34,7 +34,7 @@ type Checkbox interface {
Control Control
// OnClicked sets the event handler for when the Checkbox is clicked (to change its toggle state). // OnClicked sets the event handler for when the Checkbox is clicked (to change its toggle state).
// TODO change to OnCheckChanged or OnToggled? // TODO change to OnToggled() or OnChecked()?
OnClicked(func()) OnClicked(func())
// Text and SetText are Requests that get and set the Checkbox's label text. // Text and SetText are Requests that get and set the Checkbox's label text.
@ -49,7 +49,5 @@ type Checkbox interface {
// NewCheckbox creates a new Checkbox with the given label text. // NewCheckbox creates a new Checkbox with the given label text.
// The Checkbox will be initially unchecked. // The Checkbox will be initially unchecked.
func NewCheckbox(text string) Checkbox { func NewCheckbox(text string) Checkbox {
// return newCheckbox(text) return newCheckbox(text)
return nil
//TODO add checkbox after resolving other TODOs
} }

View File

@ -10,6 +10,7 @@ import (
// #include "gtk_unix.h" // #include "gtk_unix.h"
// extern void buttonClicked(GtkButton *, gpointer); // extern void buttonClicked(GtkButton *, gpointer);
// extern void checkboxToggled(GtkToggleButton *, gpointer);
import "C" import "C"
type widgetbase struct { type widgetbase struct {
@ -45,6 +46,8 @@ func (w *widgetbase) parent(win *window) {
C.g_object_unref(C.gpointer(unsafe.Pointer(w.widget))) C.g_object_unref(C.gpointer(unsafe.Pointer(w.widget)))
w.floating = false w.floating = false
} }
// make sure the new widget is shown
C.gtk_widget_show_all(w.widget)
} }
type button struct { type button struct {
@ -53,10 +56,8 @@ type button struct {
clicked *event clicked *event
} }
func newButton(text string) *button { // shared code for setting up buttons, check boxes, etc.
ctext := togstr(text) func finishNewButton(widget *C.GtkWidget, event string, handler unsafe.Pointer) *button {
defer freegstr(ctext)
widget := C.gtk_button_new_with_label(ctext)
b := &button{ b := &button{
widgetbase: newWidget(widget), widgetbase: newWidget(widget),
button: (*C.GtkButton)(unsafe.Pointer(widget)), button: (*C.GtkButton)(unsafe.Pointer(widget)),
@ -64,12 +65,19 @@ func newButton(text string) *button {
} }
g_signal_connect( g_signal_connect(
C.gpointer(unsafe.Pointer(b.button)), C.gpointer(unsafe.Pointer(b.button)),
"clicked", event,
C.GCallback(C.buttonClicked), C.GCallback(handler),
C.gpointer(unsafe.Pointer(b))) C.gpointer(unsafe.Pointer(b)))
return b return b
} }
func newButton(text string) *button {
ctext := togstr(text)
defer freegstr(ctext)
widget := C.gtk_button_new_with_label(ctext)
return finishNewButton(widget, "clicked", C.buttonClicked)
}
func (b *button) OnClicked(e func()) { func (b *button) OnClicked(e func()) {
b.clicked.set(e) b.clicked.set(e)
} }
@ -90,3 +98,36 @@ func (b *button) SetText(text string) {
defer freegstr(ctext) defer freegstr(ctext)
C.gtk_button_set_label(b.button, ctext) C.gtk_button_set_label(b.button, ctext)
} }
type checkbox struct {
// embed button so its methods and events carry over
*button
toggle *C.GtkToggleButton
checkbox *C.GtkCheckButton
}
func newCheckbox(text string) *checkbox {
ctext := togstr(text)
defer freegstr(ctext)
widget := C.gtk_check_button_new_with_label(ctext)
return &checkbox{
button: finishNewButton(widget, "toggled", C.checkboxToggled),
toggle: (*C.GtkToggleButton)(unsafe.Pointer(widget)),
checkbox: (*C.GtkCheckButton)(unsafe.Pointer(widget)),
}
}
//export checkboxToggled
func checkboxToggled(bwid *C.GtkToggleButton, data C.gpointer) {
// note that the finishNewButton() call uses the embedded *button as data
// this is fine because we're only deferring to buttonClicked() anyway
buttonClicked(nil, data)
}
func (c *checkbox) Checked() bool {
return fromgbool(C.gtk_toggle_button_get_active(c.toggle))
}
func (c *checkbox) SetChecked(checked bool) {
C.gtk_toggle_button_set_active(c.toggle, togbool(checked))
}

View File

@ -5,6 +5,7 @@ package ui
// This file is called zz_test.go to keep it separate from the other files in this package (and because go test won't accept just test.go) // This file is called zz_test.go to keep it separate from the other files in this package (and because go test won't accept just test.go)
import ( import (
"fmt"
"flag" "flag"
"testing" "testing"
) )
@ -39,6 +40,12 @@ func init() {
w.Close() w.Close()
Stop() Stop()
done <- struct{}{} done <- struct{}{}
} else {
c := NewCheckbox("You Should Now See Me Instead")
w.SetControl(c)
c.OnClicked(func() {
w.SetTitle(fmt.Sprint(c.Checked()))
})
} }
}) })
w.Show() w.Show()