diff --git a/container_unix.c b/container_unix.c index 8de3cb50..963984ba 100644 --- a/container_unix.c +++ b/container_unix.c @@ -59,6 +59,7 @@ static void goContainer_remove(GtkContainer *container, GtkWidget *widget) static void goContainer_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { gtk_widget_set_allocation(widget, allocation); + containerResize(GOCONTAINER(widget)->gocontainer, allocation); } struct forall { diff --git a/container_unix.go b/container_unix.go index 90bc84b2..c9ed89c5 100644 --- a/container_unix.go +++ b/container_unix.go @@ -11,9 +11,12 @@ import ( // #include "gtk_unix.h" import "C" +// TODO avoid direct access to contents? type container struct { - *controlSingleWidget - container *C.GtkContainer + widget *C.GtkWidget + container *C.GtkContainer + resize func(x int, y int, width int, height int, d *sizing) + margined bool } type sizing struct { @@ -28,7 +31,7 @@ type sizing struct { func newContainer() *container { c := new(container) - c.controlSingleWidget = newControlSingleWidget(C.newContainer(unsafe.Pointer(c))) + c.widget = C.newContainer(unsafe.Pointer(c)) c.container = (*C.GtkContainer)(unsafe.Pointer(c.widget)) return c } @@ -37,26 +40,19 @@ func (c *container) parent() *controlParent { return &controlParent{c.container} } -func (c *container) allocation(margined bool) C.GtkAllocation { - var a C.GtkAllocation - - C.gtk_widget_get_allocation(c.widget, &a) - if margined { +//export containerResize +func containerResize(data unsafe.Pointer, aorig *C.GtkAllocation) { + c := (*container)(data) + d := beginResize() + // copy aorig + a := *aorig + if c.margined { a.x += C.int(gtkXMargin) a.y += C.int(gtkYMargin) a.width -= C.int(gtkXMargin) * 2 a.height -= C.int(gtkYMargin) * 2 } - return a -} - -// we can just return these values as is -// note that allocations of a widget on GTK+ have their origin in the /window/ origin -func (c *container) bounds(d *sizing) (int, int, int, int) { - var a C.GtkAllocation - - C.gtk_widget_get_allocation(c.widget, &a) - return int(a.x), int(a.y), int(a.width), int(a.height) + c.resize(int(a.x), int(a.y), int(a.width), int(a.height), d) } const ( @@ -66,7 +62,7 @@ const ( gtkYPadding = 6 ) -func (w *window) beginResize() (d *sizing) { +func beginResize() (d *sizing) { d = new(sizing) d.xpadding = gtkXPadding d.ypadding = gtkYPadding diff --git a/group_unix.go b/group_unix.go index 681ec75a..054c170e 100644 --- a/group_unix.go +++ b/group_unix.go @@ -18,10 +18,6 @@ type group struct { child Control container *container - - margined bool - - chainresize func(x int, y int, width int, height int, d *sizing) } func newGroup(text string, control Control) Group { @@ -54,10 +50,8 @@ func newGroup(text string, control Control) Group { g.container = newContainer() g.child.setParent(g.container.parent()) - g.container.setParent(&controlParent{g.gcontainer}) - - g.chainresize = g.fresize - g.fresize = g.xresize + g.container.resize = g.child.resize + C.gtk_container_add(g.gcontainer, g.container.widget) return g } @@ -73,18 +67,11 @@ func (g *group) SetText(text string) { } func (g *group) Margined() bool { - return g.margined + return g.container.margined } func (g *group) SetMargined(margined bool) { - g.margined = margined + g.container.margined = margined } -func (g *group) xresize(x int, y int, width int, height int, d *sizing) { - // first, chain up to change the GtkFrame and its child container - g.chainresize(x, y, width, height, d) - - // now that the container has the correct size, we can resize the child - a := g.container.allocation(g.margined) - g.child.resize(int(a.x), int(a.y), int(a.width), int(a.height), d) -} +// no need to override resize; the child container handles that for us diff --git a/tab_unix.go b/tab_unix.go index 064f17f5..5e77b177 100644 --- a/tab_unix.go +++ b/tab_unix.go @@ -18,8 +18,6 @@ type tab struct { tabs []*container children []Control - - chainresize func(x int, y int, width int, height int, d *sizing) } func newTab() Tab { @@ -29,8 +27,6 @@ func newTab() Tab { container: (*C.GtkContainer)(unsafe.Pointer(widget)), notebook: (*C.GtkNotebook)(unsafe.Pointer(widget)), } - t.chainresize = t.fresize - t.fresize = t.xresize // there are no scrolling arrows by default; add them in case there are too many tabs C.gtk_notebook_set_scrollable(t.notebook, C.TRUE) return t @@ -40,8 +36,9 @@ func (t *tab) Append(name string, control Control) { c := newContainer() t.tabs = append(t.tabs, c) // this calls gtk_container_add(), which, according to gregier in irc.gimp.net/#gtk+, acts just like gtk_notebook_append_page() - c.setParent(&controlParent{t.container}) + C.gtk_container_add(t.container, c.widget) control.setParent(c.parent()) + c.resize = control.resize t.children = append(t.children, control) cname := togstr(name) defer freegstr(cname) @@ -51,13 +48,4 @@ func (t *tab) Append(name string, control Control) { cname) } -func (t *tab) xresize(x int, y int, width int, height int, d *sizing) { - // first, chain up to change the GtkFrame and its child container - t.chainresize(x, y, width, height, d) - - // now that the containers have the correct size, we can resize the children - for i, _ := range t.tabs { - a := t.tabs[i].allocation(false/*TODO*/) - t.children[i].resize(int(a.x), int(a.y), int(a.width), int(a.height), d) - } -} +// no need to handle resize; the children containers handle that for us diff --git a/window_unix.go b/window_unix.go index 6b15bc17..236cac72 100644 --- a/window_unix.go +++ b/window_unix.go @@ -10,7 +10,6 @@ import ( // #include "gtk_unix.h" // extern gboolean windowClosing(GtkWidget *, GdkEvent *, gpointer); -// extern void windowResized(GtkWidget *, GdkRectangle *, gpointer); import "C" type window struct { @@ -25,8 +24,6 @@ type window struct { child Control container *container - - margined bool } func newWindow(title string, width int, height int, control Control) *window { @@ -50,13 +47,8 @@ func newWindow(title string, width int, height int, control Control) *window { C.gtk_window_resize(w.window, C.gint(width), C.gint(height)) w.container = newContainer() w.child.setParent(w.container.parent()) - w.container.setParent(&controlParent{w.wc}) - // notice that we connect this to the container - g_signal_connect_after( // so we get it after the child container has been allocated - C.gpointer(unsafe.Pointer(w.container.widget)), - "size-allocate", - C.GCallback(C.windowResized), - C.gpointer(unsafe.Pointer(w))) + w.container.resize = w.child.resize + C.gtk_container_add(w.wc, w.container.widget) // for dialogs; otherwise, they will be modal to all windows, not just this one w.group = C.gtk_window_group_new() C.gtk_window_group_add_window(w.group, w.window) @@ -90,11 +82,11 @@ func (w *window) OnClosing(e func() bool) { } func (w *window) Margined() bool { - return w.margined + return w.container.margined } func (w *window) SetMargined(margined bool) { - w.margined = margined + w.container.margined = margined } //export windowClosing @@ -107,10 +99,4 @@ func windowClosing(wid *C.GtkWidget, e *C.GdkEvent, data C.gpointer) C.gboolean return C.GDK_EVENT_STOP // keeps window alive } -//export windowResized -func windowResized(wid *C.GtkWidget, r *C.GdkRectangle, data C.gpointer) { - w := (*window)(unsafe.Pointer(data)) - a := w.container.allocation(w.margined) - d := w.beginResize() - w.child.resize(int(a.x), int(a.y), int(a.width), int(a.height), d) -} +// no need for windowResized; the child container takes care of that