From 62048303a34f6cac733798651adb53b640e2114a Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 18 Oct 2014 17:03:07 -0400 Subject: Merged new container/sizing stuff. --- control_unix.go | 121 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 60 deletions(-) (limited to 'control_unix.go') diff --git a/control_unix.go b/control_unix.go index e8200c4..6aa2278 100644 --- a/control_unix.go +++ b/control_unix.go @@ -11,24 +11,34 @@ import ( // #include "gtk_unix.h" import "C" -// all Controls that call base methods must be this -type controlPrivate interface { - widget() *C.GtkWidget - Control -} - type controlParent struct { c *C.GtkContainer } -func basesetParent(c controlPrivate, p *controlParent) { - widget := c.widget() // avoid multiple interface lookups - C.gtk_container_add(p.c, widget) +type controlSingleWidget struct { + *controlbase + widget *C.GtkWidget +} + +func newControlSingleWidget(widget *C.GtkWidget) *controlSingleWidget { + c := new(controlSingleWidget) + c.controlbase = &controlbase{ + fsetParent: c.xsetParent, + fpreferredSize: c.xpreferredSize, + fresize: c.xresize, + } + c.widget = widget + return c +} + +func (c *controlSingleWidget) xsetParent(p *controlParent) { + C.gtk_container_add(p.c, c.widget) // make sure the new widget is shown if not explicitly hidden - C.gtk_widget_show_all(widget) + // TODO why did I have this again? + C.gtk_widget_show_all(c.widget) } -func basepreferredSize(c controlPrivate, d *sizing) (int, int) { +func (c *controlSingleWidget) xpreferredSize(d *sizing) (int, int) { // GTK+ 3 makes this easy: controls can tell us what their preferred size is! // ...actually, it tells us two things: the "minimum size" and the "natural size". // The "minimum size" is the smallest size we /can/ display /anything/. The "natural size" is the smallest size we would /prefer/ to display. @@ -37,15 +47,11 @@ func basepreferredSize(c controlPrivate, d *sizing) (int, int) { // There is a warning about height-for-width controls, but in my tests this isn't an issue. 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) } -func basecommitResize(c controlPrivate, a *allocation, d *sizing) { - dobasecommitResize(c.widget(), a, d) -} - -func dobasecommitResize(w *C.GtkWidget, c *allocation, d *sizing) { +func (c *controlSingleWidget) xresize(x int, y int, width int, height int, 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 @@ -53,68 +59,63 @@ func dobasecommitResize(w *C.GtkWidget, c *allocation, d *sizing) { 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(c Control, 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 + r.x = C.int(x) + r.y = C.int(y) + r.width = C.int(width) + r.height = C.int(height) + C.gtk_widget_size_allocate(c.widget, &r) } type scroller struct { + *controlSingleWidget + + scroller *controlSingleWidget scrollwidget *C.GtkWidget scrollcontainer *C.GtkContainer scrollwindow *C.GtkScrolledWindow + overlay *controlSingleWidget overlaywidget *C.GtkWidget overlaycontainer *C.GtkContainer - overlay *C.GtkOverlay - - addShowWhich *C.GtkWidget + overlayoverlay *C.GtkOverlay } func newScroller(widget *C.GtkWidget, native bool, bordered bool, overlay bool) *scroller { - var o *C.GtkWidget - - scrollwidget := C.gtk_scrolled_window_new(nil, nil) - if overlay { - o = C.gtk_overlay_new() - } - s := &scroller{ - scrollwidget: scrollwidget, - scrollcontainer: (*C.GtkContainer)(unsafe.Pointer(scrollwidget)), - scrollwindow: (*C.GtkScrolledWindow)(unsafe.Pointer(scrollwidget)), - overlaywidget: o, - overlaycontainer: (*C.GtkContainer)(unsafe.Pointer(o)), - overlay: (*C.GtkOverlay)(unsafe.Pointer(o)), + s := new(scroller) + s.controlSingleWidget = newControlSingleWidget(widget) + s.scrollwidget = C.gtk_scrolled_window_new(nil, nil) + s.scrollcontainer = (*C.GtkContainer)(unsafe.Pointer(s.scrollwidget)) + s.scrollwindow = (*C.GtkScrolledWindow)(unsafe.Pointer(s.scrollwidget)) + + // any actual changing operations need to be done to the GtkScrolledWindow + // that is, everything /except/ preferredSize() are done to the GtkScrolledWindow + s.scroller = newControlSingleWidget(s.scrollwidget) + s.fsetParent = s.scroller.fsetParent + s.fresize = s.scroller.fresize + + // in GTK+ 3.4 we still technically need to use the separate gtk_scrolled_window_add_with_viewpoint()/gtk_container_add() spiel for adding the widget to the scrolled window + if native { + C.gtk_container_add(s.scrollcontainer, s.widget) + } else { + C.gtk_scrolled_window_add_with_viewport(s.scrollwindow, s.widget) } + // give the scrolled window a border (thanks to jlindgren in irc.gimp.net/#gtk+) if bordered { C.gtk_scrolled_window_set_shadow_type(s.scrollwindow, C.GTK_SHADOW_IN) } - if native { - C.gtk_container_add(s.scrollcontainer, widget) - } else { - C.gtk_scrolled_window_add_with_viewport(s.scrollwindow, widget) - } - s.addShowWhich = s.scrollwidget + if overlay { + // ok things get REALLY fun now + // we now have to do all of the above again + s.overlaywidget = C.gtk_overlay_new() + s.overlaycontainer = (*C.GtkContainer)(unsafe.Pointer(s.overlaywidget)) + s.overlayoverlay = (*C.GtkOverlay)(unsafe.Pointer(s.overlaywidget)) + s.overlay = newControlSingleWidget(s.overlaywidget) + s.fsetParent = s.overlay.fsetParent + s.fresize = s.overlay.fresize C.gtk_container_add(s.overlaycontainer, s.scrollwidget) - s.addShowWhich = s.overlaywidget } - return s -} -func (s *scroller) setParent(p *controlParent) { - C.gtk_container_add(p.c, s.addShowWhich) - // see basesetParent() above for why we call gtk_widget_show_all() - C.gtk_widget_show_all(s.addShowWhich) -} - -func (s *scroller) commitResize(c *allocation, d *sizing) { - dobasecommitResize(s.addShowWhich, c, d) + return s } -- cgit v1.2.3