Migrated the GTK+ backend to the new Control system. Added controlParent to deal with interface issues; need to apply this to the Windows backend too.
This commit is contained in:
parent
fd48be68ee
commit
b6d07237b4
|
@ -10,48 +10,36 @@ 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 button struct {
|
type button struct {
|
||||||
*controlbase
|
_widget *C.GtkWidget
|
||||||
button *C.GtkButton
|
button *C.GtkButton
|
||||||
clicked *event
|
clicked *event
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared code for setting up buttons, check boxes, etc.
|
// shared code for setting up buttons, check boxes, etc.
|
||||||
func finishNewButton(widget *C.GtkWidget, event string, handler unsafe.Pointer) *button {
|
func newButton(text string) *button {
|
||||||
|
ctext := togstr(text)
|
||||||
|
defer freegstr(ctext)
|
||||||
|
widget := C.gtk_button_new_with_label(ctext)
|
||||||
b := &button{
|
b := &button{
|
||||||
controlbase: newControl(widget),
|
_widget: widget,
|
||||||
button: (*C.GtkButton)(unsafe.Pointer(widget)),
|
button: (*C.GtkButton)(unsafe.Pointer(widget)),
|
||||||
clicked: newEvent(),
|
clicked: newEvent(),
|
||||||
}
|
}
|
||||||
g_signal_connect(
|
g_signal_connect(
|
||||||
C.gpointer(unsafe.Pointer(b.button)),
|
C.gpointer(unsafe.Pointer(b.button)),
|
||||||
event,
|
"clicked",
|
||||||
C.GCallback(handler),
|
C.GCallback(C.buttonClicked),
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export buttonClicked
|
|
||||||
func buttonClicked(bwid *C.GtkButton, data C.gpointer) {
|
|
||||||
b := (*button)(unsafe.Pointer(data))
|
|
||||||
b.clicked.fire()
|
|
||||||
println("button clicked")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *button) Text() string {
|
func (b *button) Text() string {
|
||||||
return fromgstr(C.gtk_button_get_label(b.button))
|
return fromgstr(C.gtk_button_get_label(b.button))
|
||||||
}
|
}
|
||||||
|
@ -61,3 +49,42 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export buttonClicked
|
||||||
|
func buttonClicked(bwid *C.GtkButton, data C.gpointer) {
|
||||||
|
b := (*button)(unsafe.Pointer(data))
|
||||||
|
b.clicked.fire()
|
||||||
|
println("button clicked")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) widget() *C.GtkWidget {
|
||||||
|
return b._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) setParent(p *controlParent) {
|
||||||
|
basesetParent(b, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) containerShow() {
|
||||||
|
basecontainerShow(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) containerHide() {
|
||||||
|
basecontainerHide(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(b, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(b, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) commitResize(a *allocation, d *sizing) {
|
||||||
|
basecommitResize(b, a, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *button) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
|
}
|
||||||
|
|
|
@ -9,33 +9,48 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
// extern void buttonClicked(GtkButton *, gpointer);
|
|
||||||
// extern void checkboxToggled(GtkToggleButton *, gpointer);
|
// extern void checkboxToggled(GtkToggleButton *, gpointer);
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type checkbox struct {
|
type checkbox struct {
|
||||||
// embed button so its methods and events carry over
|
_widget *C.GtkWidget
|
||||||
*button
|
button *C.GtkButton
|
||||||
toggle *C.GtkToggleButton
|
toggle *C.GtkToggleButton
|
||||||
checkbox *C.GtkCheckButton
|
checkbox *C.GtkCheckButton
|
||||||
|
toggled *event
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCheckbox(text string) *checkbox {
|
func newCheckbox(text string) *checkbox {
|
||||||
ctext := togstr(text)
|
ctext := togstr(text)
|
||||||
defer freegstr(ctext)
|
defer freegstr(ctext)
|
||||||
widget := C.gtk_check_button_new_with_label(ctext)
|
widget := C.gtk_check_button_new_with_label(ctext)
|
||||||
return &checkbox{
|
c := &checkbox{
|
||||||
button: finishNewButton(widget, "toggled", C.checkboxToggled),
|
_widget: widget,
|
||||||
|
button: (*C.GtkButton)(unsafe.Pointer(widget)),
|
||||||
toggle: (*C.GtkToggleButton)(unsafe.Pointer(widget)),
|
toggle: (*C.GtkToggleButton)(unsafe.Pointer(widget)),
|
||||||
checkbox: (*C.GtkCheckButton)(unsafe.Pointer(widget)),
|
checkbox: (*C.GtkCheckButton)(unsafe.Pointer(widget)),
|
||||||
|
toggled: newEvent(),
|
||||||
}
|
}
|
||||||
|
g_signal_connect(
|
||||||
|
C.gpointer(unsafe.Pointer(c.checkbox)),
|
||||||
|
"toggled",
|
||||||
|
C.GCallback(C.checkboxToggled),
|
||||||
|
C.gpointer(unsafe.Pointer(c)))
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
//export checkboxToggled
|
func (c *checkbox) OnToggled(e func()) {
|
||||||
func checkboxToggled(bwid *C.GtkToggleButton, data C.gpointer) {
|
c.toggled.set(e)
|
||||||
// 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) Text() string {
|
||||||
|
return fromgstr(C.gtk_button_get_label(c.button))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) SetText(text string) {
|
||||||
|
ctext := togstr(text)
|
||||||
|
defer freegstr(ctext)
|
||||||
|
C.gtk_button_set_label(c.button, ctext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *checkbox) Checked() bool {
|
func (c *checkbox) Checked() bool {
|
||||||
|
@ -46,3 +61,40 @@ func (c *checkbox) SetChecked(checked bool) {
|
||||||
C.gtk_toggle_button_set_active(c.toggle, togbool(checked))
|
C.gtk_toggle_button_set_active(c.toggle, togbool(checked))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export checkboxToggled
|
||||||
|
func checkboxToggled(bwid *C.GtkToggleButton, data C.gpointer) {
|
||||||
|
c := (*checkbox)(unsafe.Pointer(data))
|
||||||
|
c.toggled.fire()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) widget() *C.GtkWidget {
|
||||||
|
return c._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) setParent(p *controlParent) {
|
||||||
|
basesetParent(c, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) containerShow() {
|
||||||
|
basecontainerShow(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) containerHide() {
|
||||||
|
basecontainerHide(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(c, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(c, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) commitResize(a *allocation, d *sizing) {
|
||||||
|
basecommitResize(c, a, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkbox) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
|
}
|
||||||
|
|
|
@ -11,92 +11,102 @@ import (
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type controlbase struct {
|
// all Controls that call base methods must be this
|
||||||
*controldefs
|
type controlPrivate interface {
|
||||||
widget *C.GtkWidget
|
widget() *C.GtkWidget
|
||||||
|
Control
|
||||||
}
|
}
|
||||||
|
|
||||||
type controlParent struct {
|
type controlParent struct {
|
||||||
c *C.GtkContainer
|
c *C.GtkContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newControl(widget *C.GtkWidget) *controlbase {
|
func basesetParent(c controlPrivate, p *controlParent) {
|
||||||
c := new(controlbase)
|
C.gtk_container_add(p.c, c.widget())
|
||||||
c.widget = widget
|
// make sure the new widget is shown if not explicitly hidden
|
||||||
c.controldefs = new(controldefs)
|
c.containerShow()
|
||||||
c.fsetParent = func(p *controlParent) {
|
}
|
||||||
C.gtk_container_add(p.c, c.widget)
|
|
||||||
// make sure the new widget is shown if not explicitly hidden
|
func basecontainerShow(c controlPrivate) {
|
||||||
c.containerShow()
|
C.gtk_widget_show_all(c.widget())
|
||||||
}
|
}
|
||||||
c.fcontainerShow = func() {
|
|
||||||
C.gtk_widget_show_all(c.widget)
|
func basecontainerHide(c controlPrivate) {
|
||||||
}
|
C.gtk_widget_hide(c.widget())
|
||||||
c.fcontainerHide = func() {
|
}
|
||||||
C.gtk_widget_hide(c.widget)
|
|
||||||
}
|
func basepreferredSize(c controlPrivate, d *sizing) (int, int) {
|
||||||
c.fallocate = baseallocate(c)
|
// GTK+ 3 makes this easy: controls can tell us what their preferred size is!
|
||||||
c.fpreferredSize = func(d *sizing) (int, int) {
|
// ...actually, it tells us two things: the "minimum size" and the "natural size".
|
||||||
// GTK+ 3 makes this easy: controls can tell us what their preferred size is!
|
// The "minimum size" is the smallest size we /can/ display /anything/. The "natural size" is the smallest size we would /prefer/ to display.
|
||||||
// ...actually, it tells us two things: the "minimum size" and the "natural size".
|
// The difference? Minimum size takes into account things like truncation with ellipses: the minimum size of a label can allot just the ellipses!
|
||||||
// The "minimum size" is the smallest size we /can/ display /anything/. The "natural size" is the smallest size we would /prefer/ to display.
|
// So we use the natural size instead.
|
||||||
// The difference? Minimum size takes into account things like truncation with ellipses: the minimum size of a label can allot just the ellipses!
|
// There is a warning about height-for-width controls, but in my tests this isn't an issue.
|
||||||
// So we use the natural size instead.
|
// For Areas, we manually save the Area size and use that, just to be safe.
|
||||||
// There is a warning about height-for-width controls, but in my tests this isn't an issue.
|
|
||||||
// For Areas, we manually save the Area size and use that, just to be safe.
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
/*
|
/*
|
||||||
if s.ctype == c_area {
|
if s.ctype == c_area {
|
||||||
return s.areawidth, s.areaheight
|
return s.areawidth, s.areaheight
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var r C.GtkRequisition
|
var r C.GtkRequisition
|
||||||
|
|
||||||
C.gtk_widget_get_preferred_size(c.widget, nil, &r)
|
C.gtk_widget_get_preferred_size(c.widget(), nil, &r)
|
||||||
return int(r.width), int(r.height)
|
return int(r.width), int(r.height)
|
||||||
}
|
|
||||||
c.fcommitResize = func(a *allocation, d *sizing) {
|
|
||||||
// as we resize on size-allocate, we have to also use size-allocate on our children
|
|
||||||
// this is fine anyway; in fact, this allows us to move without knowing what the container is!
|
|
||||||
// this is what GtkBox does anyway
|
|
||||||
// thanks to tristan in irc.gimp.net/#gtk+
|
|
||||||
|
|
||||||
var r C.GtkAllocation
|
|
||||||
|
|
||||||
r.x = C.int(a.x)
|
|
||||||
r.y = C.int(a.y)
|
|
||||||
r.width = C.int(a.width)
|
|
||||||
r.height = C.int(a.height)
|
|
||||||
C.gtk_widget_size_allocate(c.widget, &r)
|
|
||||||
}
|
|
||||||
c.fgetAuxResizeInfo = func(d *sizing) {
|
|
||||||
// controls set this to true if a Label to its left should be vertically aligned to the control's top
|
|
||||||
d.shouldVAlignTop = false
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type scrolledcontrol struct {
|
func basecommitResize(c controlPrivate, a *allocation, d *sizing) {
|
||||||
*controlbase
|
dobasecommitResize(c.widget(), a, d)
|
||||||
scroller *controlbase
|
}
|
||||||
|
|
||||||
|
func dobasecommitResize(w *C.GtkWidget, c *allocation, d *sizing) {
|
||||||
|
// as we resize on size-allocate, we have to also use size-allocate on our children
|
||||||
|
// this is fine anyway; in fact, this allows us to move without knowing what the container is!
|
||||||
|
// this is what GtkBox does anyway
|
||||||
|
// thanks to tristan in irc.gimp.net/#gtk+
|
||||||
|
|
||||||
|
var r C.GtkAllocation
|
||||||
|
|
||||||
|
r.x = C.int(c.x)
|
||||||
|
r.y = C.int(c.y)
|
||||||
|
r.width = C.int(c.width)
|
||||||
|
r.height = C.int(c.height)
|
||||||
|
C.gtk_widget_size_allocate(w, &r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func basegetAuxResizeInfo(d *sizing) {
|
||||||
|
// controls set this to true if a Label to its left should be vertically aligned to the control's top
|
||||||
|
d.shouldVAlignTop = false
|
||||||
|
}
|
||||||
|
|
||||||
|
type scroller struct {
|
||||||
|
scrollwidget *C.GtkWidget
|
||||||
scrollcontainer *C.GtkContainer
|
scrollcontainer *C.GtkContainer
|
||||||
scrollwindow *C.GtkScrolledWindow
|
scrollwindow *C.GtkScrolledWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
func newScrolledControl(widget *C.GtkWidget, native bool) *scrolledcontrol {
|
func newScroller(widget *C.GtkWidget, native bool) *scroller {
|
||||||
scroller := C.gtk_scrolled_window_new(nil, nil)
|
scrollwidget := C.gtk_scrolled_window_new(nil, nil)
|
||||||
s := &scrolledcontrol{
|
s := &scroller{
|
||||||
controlbase: newControl(widget),
|
scrollwidget: scrollwidget,
|
||||||
scroller: newControl(scroller),
|
scrollcontainer: (*C.GtkContainer)(unsafe.Pointer(scrollwidget)),
|
||||||
scrollcontainer: (*C.GtkContainer)(unsafe.Pointer(scroller)),
|
scrollwindow: (*C.GtkScrolledWindow)(unsafe.Pointer(scrollwidget)),
|
||||||
scrollwindow: (*C.GtkScrolledWindow)(unsafe.Pointer(scroller)),
|
|
||||||
}
|
}
|
||||||
// give the scrolled window a border (thanks to jlindgren in irc.gimp.net/#gtk+)
|
// give the scrolled window a border (thanks to jlindgren in irc.gimp.net/#gtk+)
|
||||||
C.gtk_scrolled_window_set_shadow_type(s.scrollwindow, C.GTK_SHADOW_IN)
|
C.gtk_scrolled_window_set_shadow_type(s.scrollwindow, C.GTK_SHADOW_IN)
|
||||||
C.gtk_container_add(s.scrollcontainer, s.widget)
|
// TODO use native here
|
||||||
s.fsetParent = s.scroller.fsetParent
|
C.gtk_container_add(s.scrollcontainer, widget)
|
||||||
s.fcommitResize = s.scroller.fcommitResize
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *scroller) setParent(p *controlParent) {
|
||||||
|
C.gtk_container_add(p.c, s.scrollwidget)
|
||||||
|
// TODO for when hiding/showing is implemented
|
||||||
|
C.gtk_widget_show_all(s.scrollwidget)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scroller) commitResize(c *allocation, d *sizing) {
|
||||||
|
dobasecommitResize(s.scrollwidget, c, d)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
sed "s/AAA/$1/g
|
||||||
|
s/BBB/$2/g
|
||||||
|
s/CCC/$3/g
|
||||||
|
s/DDD/$4/g" <<\END
|
||||||
|
func (AAA *BBB) CCC() DDD {
|
||||||
|
return AAA._CCC
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) setParent(p *controlParent) {
|
||||||
|
basesetParent(AAA, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) containerShow() {
|
||||||
|
basecontainerShow(AAA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) containerHide() {
|
||||||
|
basecontainerHide(AAA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(AAA, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(AAA, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) commitResize(a *allocation, d *sizing) {
|
||||||
|
basecommitResize(AAA, a, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AAA *BBB) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
|
}
|
||||||
|
END
|
|
@ -17,11 +17,10 @@ import "C"
|
||||||
// - standalone label on its own: should it be centered or not?
|
// - standalone label on its own: should it be centered or not?
|
||||||
|
|
||||||
type label struct {
|
type label struct {
|
||||||
*controlbase
|
_widget *C.GtkWidget
|
||||||
misc *C.GtkMisc
|
misc *C.GtkMisc
|
||||||
label *C.GtkLabel
|
label *C.GtkLabel
|
||||||
standalone bool
|
standalone bool
|
||||||
supercommitResize func(c *allocation, d *sizing)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func finishNewLabel(text string, standalone bool) *label {
|
func finishNewLabel(text string, standalone bool) *label {
|
||||||
|
@ -29,13 +28,11 @@ func finishNewLabel(text string, standalone bool) *label {
|
||||||
defer freegstr(ctext)
|
defer freegstr(ctext)
|
||||||
widget := C.gtk_label_new(ctext)
|
widget := C.gtk_label_new(ctext)
|
||||||
l := &label{
|
l := &label{
|
||||||
controlbase: newControl(widget),
|
_widget: widget,
|
||||||
misc: (*C.GtkMisc)(unsafe.Pointer(widget)),
|
misc: (*C.GtkMisc)(unsafe.Pointer(widget)),
|
||||||
label: (*C.GtkLabel)(unsafe.Pointer(widget)),
|
label: (*C.GtkLabel)(unsafe.Pointer(widget)),
|
||||||
standalone: standalone,
|
standalone: standalone,
|
||||||
}
|
}
|
||||||
l.supercommitResize = l.fcommitResize
|
|
||||||
l.fcommitResize = l.labelcommitResize
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +54,31 @@ func (l *label) SetText(text string) {
|
||||||
C.gtk_label_set_text(l.label, ctext)
|
C.gtk_label_set_text(l.label, ctext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *label) labelcommitResize(c *allocation, d *sizing) {
|
func (l *label) widget() *C.GtkWidget {
|
||||||
|
return l._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) setParent(p *controlParent) {
|
||||||
|
basesetParent(l, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) containerShow() {
|
||||||
|
basecontainerShow(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) containerHide() {
|
||||||
|
basecontainerHide(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(l, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(l, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) commitResize(c *allocation, d *sizing) {
|
||||||
if !l.standalone && c.neighbor != nil {
|
if !l.standalone && c.neighbor != nil {
|
||||||
c.neighbor.getAuxResizeInfo(d)
|
c.neighbor.getAuxResizeInfo(d)
|
||||||
if d.shouldVAlignTop {
|
if d.shouldVAlignTop {
|
||||||
|
@ -67,5 +88,9 @@ func (l *label) labelcommitResize(c *allocation, d *sizing) {
|
||||||
C.gtk_misc_set_alignment(l.misc, 0, 0.5)
|
C.gtk_misc_set_alignment(l.misc, 0, 0.5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l.supercommitResize(c, d)
|
basecommitResize(l, c, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *label) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type tab struct {
|
type tab struct {
|
||||||
*controlbase
|
_widget *C.GtkWidget
|
||||||
notebook *C.GtkNotebook
|
notebook *C.GtkNotebook
|
||||||
|
|
||||||
tabs []*layout
|
tabs []*layout
|
||||||
|
@ -21,7 +21,7 @@ type tab struct {
|
||||||
func newTab() Tab {
|
func newTab() Tab {
|
||||||
widget := C.gtk_notebook_new()
|
widget := C.gtk_notebook_new()
|
||||||
t := &tab{
|
t := &tab{
|
||||||
controlbase: newControl(widget),
|
_widget: widget,
|
||||||
notebook: (*C.GtkNotebook)(unsafe.Pointer(widget)),
|
notebook: (*C.GtkNotebook)(unsafe.Pointer(widget)),
|
||||||
}
|
}
|
||||||
// there are no scrolling arrows by default; add them in case there are too many tabs
|
// there are no scrolling arrows by default; add them in case there are too many tabs
|
||||||
|
@ -42,4 +42,35 @@ func (t *tab) Append(name string, control Control) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *tab) widget() *C.GtkWidget {
|
||||||
|
return t._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) setParent(p *controlParent) {
|
||||||
|
basesetParent(t, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) containerShow() {
|
||||||
|
basecontainerShow(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) containerHide() {
|
||||||
|
basecontainerHide(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(t, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(t, d)
|
||||||
|
}
|
||||||
|
|
||||||
// no need to override Control.commitResize() as only prepared the tabbed control; its children will be reallocated when that one is resized
|
// no need to override Control.commitResize() as only prepared the tabbed control; its children will be reallocated when that one is resized
|
||||||
|
func (t *tab) commitResize(a *allocation, d *sizing) {
|
||||||
|
basecommitResize(t, a, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tab) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
|
}
|
||||||
|
|
|
@ -14,10 +14,11 @@ import (
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type table struct {
|
type table struct {
|
||||||
*scrolledcontrol
|
|
||||||
*tablebase
|
*tablebase
|
||||||
|
|
||||||
|
_widget *C.GtkWidget
|
||||||
treeview *C.GtkTreeView
|
treeview *C.GtkTreeView
|
||||||
|
scroller *scroller
|
||||||
|
|
||||||
model *C.goTableModel
|
model *C.goTableModel
|
||||||
modelgtk *C.GtkTreeModel
|
modelgtk *C.GtkTreeModel
|
||||||
|
@ -30,15 +31,11 @@ type table struct {
|
||||||
func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
||||||
widget := C.gtk_tree_view_new()
|
widget := C.gtk_tree_view_new()
|
||||||
t := &table{
|
t := &table{
|
||||||
scrolledcontrol: newScrolledControl(widget, true),
|
scroller: newScroller(widget, true),
|
||||||
tablebase: b,
|
tablebase: b,
|
||||||
|
_widget: widget,
|
||||||
treeview: (*C.GtkTreeView)(unsafe.Pointer(widget)),
|
treeview: (*C.GtkTreeView)(unsafe.Pointer(widget)),
|
||||||
}
|
}
|
||||||
t.fgetAuxResizeInfo = func(d *sizing) {
|
|
||||||
// a Label to the left of a Table should be vertically aligned to the top
|
|
||||||
// TODO do the same with Area
|
|
||||||
d.shouldVAlignTop = true
|
|
||||||
}
|
|
||||||
model := C.newTableModel(unsafe.Pointer(t))
|
model := C.newTableModel(unsafe.Pointer(t))
|
||||||
t.model = model
|
t.model = model
|
||||||
t.modelgtk = (*C.GtkTreeModel)(unsafe.Pointer(model))
|
t.modelgtk = (*C.GtkTreeModel)(unsafe.Pointer(model))
|
||||||
|
@ -96,3 +93,37 @@ func goTableModel_getRowCount(data unsafe.Pointer) C.gint {
|
||||||
d := reflect.Indirect(reflect.ValueOf(t.data))
|
d := reflect.Indirect(reflect.ValueOf(t.data))
|
||||||
return C.gint(d.Len())
|
return C.gint(d.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *table) widget() *C.GtkWidget {
|
||||||
|
return t._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) setParent(p *controlParent) {
|
||||||
|
t.scroller.setParent(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) containerShow() {
|
||||||
|
basecontainerShow(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) containerHide() {
|
||||||
|
basecontainerHide(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(t, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(t, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) commitResize(c *allocation, d *sizing) {
|
||||||
|
t.scroller.commitResize(c, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *table) getAuxResizeInfo(d *sizing) {
|
||||||
|
// a Label to the left of a Table should be vertically aligned to the top
|
||||||
|
// TODO do the same with Area
|
||||||
|
d.shouldVAlignTop = true
|
||||||
|
}
|
||||||
|
|
|
@ -14,15 +14,15 @@ import (
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type textField struct {
|
type textField struct {
|
||||||
*controlbase
|
_widget *C.GtkWidget
|
||||||
entry *C.GtkEntry
|
entry *C.GtkEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
func startNewTextField() *textField {
|
func startNewTextField() *textField {
|
||||||
w := C.gtk_entry_new()
|
widget := C.gtk_entry_new()
|
||||||
return &textField{
|
return &textField{
|
||||||
controlbase: newControl(w),
|
_widget: widget,
|
||||||
entry: (*C.GtkEntry)(unsafe.Pointer(w)),
|
entry: (*C.GtkEntry)(unsafe.Pointer(widget)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,3 +45,35 @@ func (t *textField) SetText(text string) {
|
||||||
defer freegstr(ctext)
|
defer freegstr(ctext)
|
||||||
C.gtk_entry_set_text(t.entry, ctext)
|
C.gtk_entry_set_text(t.entry, ctext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *textField) widget() *C.GtkWidget {
|
||||||
|
return t._widget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) setParent(p *controlParent) {
|
||||||
|
basesetParent(t, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) containerShow() {
|
||||||
|
basecontainerShow(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) containerHide() {
|
||||||
|
basecontainerHide(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||||
|
return baseallocate(t, x, y, width, height, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) preferredSize(d *sizing) (width, height int) {
|
||||||
|
return basepreferredSize(t, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) commitResize(a *allocation, d *sizing) {
|
||||||
|
basecommitResize(t, a, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textField) getAuxResizeInfo(d *sizing) {
|
||||||
|
basegetAuxResizeInfo(d)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue