Skip to content

Commit

Permalink
Migrated the GTK+ backend to the new new container system in which co…
Browse files Browse the repository at this point in the history
…ntainers are no longer full controls but are still used to hold more than one control and handle the resizing entirely on their own.
  • Loading branch information
andlabs committed Oct 27, 2014
1 parent f9699ff commit bd44815
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 71 deletions.
1 change: 1 addition & 0 deletions container_unix.c
Expand Up @@ -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 {
Expand Down
34 changes: 15 additions & 19 deletions container_unix.go
Expand Up @@ -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 {
Expand All @@ -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
}
Expand All @@ -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 (
Expand All @@ -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
Expand Down
23 changes: 5 additions & 18 deletions group_unix.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand All @@ -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
18 changes: 3 additions & 15 deletions tab_unix.go
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
24 changes: 5 additions & 19 deletions window_unix.go
Expand Up @@ -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 {
Expand All @@ -25,8 +24,6 @@ type window struct {

child Control
container *container

margined bool
}

func newWindow(title string, width int, height int, control Control) *window {
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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

0 comments on commit bd44815

Please sign in to comment.