Migrated the GTK+ backend to the new new container system in which containers are no longer full controls but are still used to hold more than one control and handle the resizing entirely on their own.
This commit is contained in:
parent
f9699ff938
commit
bd44815a54
|
@ -59,6 +59,7 @@ static void goContainer_remove(GtkContainer *container, GtkWidget *widget)
|
||||||
static void goContainer_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
|
static void goContainer_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
gtk_widget_set_allocation(widget, allocation);
|
gtk_widget_set_allocation(widget, allocation);
|
||||||
|
containerResize(GOCONTAINER(widget)->gocontainer, allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct forall {
|
struct forall {
|
||||||
|
|
|
@ -11,9 +11,12 @@ import (
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
// TODO avoid direct access to contents?
|
||||||
type container struct {
|
type container struct {
|
||||||
*controlSingleWidget
|
widget *C.GtkWidget
|
||||||
container *C.GtkContainer
|
container *C.GtkContainer
|
||||||
|
resize func(x int, y int, width int, height int, d *sizing)
|
||||||
|
margined bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type sizing struct {
|
type sizing struct {
|
||||||
|
@ -28,7 +31,7 @@ type sizing struct {
|
||||||
|
|
||||||
func newContainer() *container {
|
func newContainer() *container {
|
||||||
c := new(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))
|
c.container = (*C.GtkContainer)(unsafe.Pointer(c.widget))
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -37,26 +40,19 @@ func (c *container) parent() *controlParent {
|
||||||
return &controlParent{c.container}
|
return &controlParent{c.container}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) allocation(margined bool) C.GtkAllocation {
|
//export containerResize
|
||||||
var a C.GtkAllocation
|
func containerResize(data unsafe.Pointer, aorig *C.GtkAllocation) {
|
||||||
|
c := (*container)(data)
|
||||||
C.gtk_widget_get_allocation(c.widget, &a)
|
d := beginResize()
|
||||||
if margined {
|
// copy aorig
|
||||||
|
a := *aorig
|
||||||
|
if c.margined {
|
||||||
a.x += C.int(gtkXMargin)
|
a.x += C.int(gtkXMargin)
|
||||||
a.y += C.int(gtkYMargin)
|
a.y += C.int(gtkYMargin)
|
||||||
a.width -= C.int(gtkXMargin) * 2
|
a.width -= C.int(gtkXMargin) * 2
|
||||||
a.height -= C.int(gtkYMargin) * 2
|
a.height -= C.int(gtkYMargin) * 2
|
||||||
}
|
}
|
||||||
return a
|
c.resize(int(a.x), int(a.y), int(a.width), int(a.height), d)
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -66,7 +62,7 @@ const (
|
||||||
gtkYPadding = 6
|
gtkYPadding = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *window) beginResize() (d *sizing) {
|
func beginResize() (d *sizing) {
|
||||||
d = new(sizing)
|
d = new(sizing)
|
||||||
d.xpadding = gtkXPadding
|
d.xpadding = gtkXPadding
|
||||||
d.ypadding = gtkYPadding
|
d.ypadding = gtkYPadding
|
||||||
|
|
|
@ -18,10 +18,6 @@ type group struct {
|
||||||
|
|
||||||
child Control
|
child Control
|
||||||
container *container
|
container *container
|
||||||
|
|
||||||
margined bool
|
|
||||||
|
|
||||||
chainresize func(x int, y int, width int, height int, d *sizing)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGroup(text string, control Control) Group {
|
func newGroup(text string, control Control) Group {
|
||||||
|
@ -54,10 +50,8 @@ func newGroup(text string, control Control) Group {
|
||||||
|
|
||||||
g.container = newContainer()
|
g.container = newContainer()
|
||||||
g.child.setParent(g.container.parent())
|
g.child.setParent(g.container.parent())
|
||||||
g.container.setParent(&controlParent{g.gcontainer})
|
g.container.resize = g.child.resize
|
||||||
|
C.gtk_container_add(g.gcontainer, g.container.widget)
|
||||||
g.chainresize = g.fresize
|
|
||||||
g.fresize = g.xresize
|
|
||||||
|
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
@ -73,18 +67,11 @@ func (g *group) SetText(text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *group) Margined() bool {
|
func (g *group) Margined() bool {
|
||||||
return g.margined
|
return g.container.margined
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *group) SetMargined(margined bool) {
|
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) {
|
// no need to override resize; the child container handles that for us
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
18
tab_unix.go
18
tab_unix.go
|
@ -18,8 +18,6 @@ type tab struct {
|
||||||
|
|
||||||
tabs []*container
|
tabs []*container
|
||||||
children []Control
|
children []Control
|
||||||
|
|
||||||
chainresize func(x int, y int, width int, height int, d *sizing)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTab() Tab {
|
func newTab() Tab {
|
||||||
|
@ -29,8 +27,6 @@ func newTab() Tab {
|
||||||
container: (*C.GtkContainer)(unsafe.Pointer(widget)),
|
container: (*C.GtkContainer)(unsafe.Pointer(widget)),
|
||||||
notebook: (*C.GtkNotebook)(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
|
// 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)
|
C.gtk_notebook_set_scrollable(t.notebook, C.TRUE)
|
||||||
return t
|
return t
|
||||||
|
@ -40,8 +36,9 @@ func (t *tab) Append(name string, control Control) {
|
||||||
c := newContainer()
|
c := newContainer()
|
||||||
t.tabs = append(t.tabs, c)
|
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()
|
// 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())
|
control.setParent(c.parent())
|
||||||
|
c.resize = control.resize
|
||||||
t.children = append(t.children, control)
|
t.children = append(t.children, control)
|
||||||
cname := togstr(name)
|
cname := togstr(name)
|
||||||
defer freegstr(cname)
|
defer freegstr(cname)
|
||||||
|
@ -51,13 +48,4 @@ func (t *tab) Append(name string, control Control) {
|
||||||
cname)
|
cname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tab) xresize(x int, y int, width int, height int, d *sizing) {
|
// no need to handle resize; the children containers handle that for us
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
// extern gboolean windowClosing(GtkWidget *, GdkEvent *, gpointer);
|
// extern gboolean windowClosing(GtkWidget *, GdkEvent *, gpointer);
|
||||||
// extern void windowResized(GtkWidget *, GdkRectangle *, gpointer);
|
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type window struct {
|
type window struct {
|
||||||
|
@ -25,8 +24,6 @@ type window struct {
|
||||||
|
|
||||||
child Control
|
child Control
|
||||||
container *container
|
container *container
|
||||||
|
|
||||||
margined bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWindow(title string, width int, height int, control Control) *window {
|
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))
|
C.gtk_window_resize(w.window, C.gint(width), C.gint(height))
|
||||||
w.container = newContainer()
|
w.container = newContainer()
|
||||||
w.child.setParent(w.container.parent())
|
w.child.setParent(w.container.parent())
|
||||||
w.container.setParent(&controlParent{w.wc})
|
w.container.resize = w.child.resize
|
||||||
// notice that we connect this to the container
|
C.gtk_container_add(w.wc, w.container.widget)
|
||||||
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)))
|
|
||||||
// for dialogs; otherwise, they will be modal to all windows, not just this one
|
// for dialogs; otherwise, they will be modal to all windows, not just this one
|
||||||
w.group = C.gtk_window_group_new()
|
w.group = C.gtk_window_group_new()
|
||||||
C.gtk_window_group_add_window(w.group, w.window)
|
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 {
|
func (w *window) Margined() bool {
|
||||||
return w.margined
|
return w.container.margined
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) SetMargined(margined bool) {
|
func (w *window) SetMargined(margined bool) {
|
||||||
w.margined = margined
|
w.container.margined = margined
|
||||||
}
|
}
|
||||||
|
|
||||||
//export windowClosing
|
//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
|
return C.GDK_EVENT_STOP // keeps window alive
|
||||||
}
|
}
|
||||||
|
|
||||||
//export windowResized
|
// no need for windowResized; the child container takes care of that
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue