Made the sizing recursive chain idempotent and added a -spaced option to the test program to test spacing.
This commit is contained in:
parent
22989c13da
commit
d34ffa326c
|
@ -28,23 +28,17 @@ type controlSizing interface {
|
||||||
// on Windows, this is only embedded by window, as all other containers cannot have their own children; beginResize() points to an instance method literal (TODO get correct term) from window
|
// on Windows, this is only embedded by window, as all other containers cannot have their own children; beginResize() points to an instance method literal (TODO get correct term) from window
|
||||||
// on GTK+ and Mac OS X, one is embedded by window and all containers; beginResize() points to a global function (TODO NOT GOOD; ideally the sizing data should be passed across size-allocate requests)
|
// on GTK+ and Mac OS X, one is embedded by window and all containers; beginResize() points to a global function (TODO NOT GOOD; ideally the sizing data should be passed across size-allocate requests)
|
||||||
type container struct {
|
type container struct {
|
||||||
child Control
|
child Control
|
||||||
spaced bool
|
spaced bool
|
||||||
beginResize func() (d *sizing) // for the initial call
|
d *sizing
|
||||||
d *sizing // for recursive calls
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) resize(width, height int) {
|
func (c *container) resize(width, height int) {
|
||||||
if c.child == nil { // no children; nothing to do
|
if c.child == nil { // no children; nothing to do
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.d == nil { // initial call
|
if c.d == nil { // not ready (called early or out of the proper recursive call chain (such as by the underlying system when marking an unparented Tab as shown))
|
||||||
if c.beginResize == nil {
|
return
|
||||||
// should be a recursive call, but is not
|
|
||||||
// TODO get rid of this
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.d = c.beginResize()
|
|
||||||
}
|
}
|
||||||
d := c.d
|
d := c.d
|
||||||
allocations := c.child.allocate(0, 0, width, height, d)
|
allocations := c.child.allocate(0, 0, width, height, d)
|
||||||
|
@ -54,6 +48,5 @@ func (c *container) resize(width, height int) {
|
||||||
allocations[i].this.commitResize(allocations[i], d)
|
allocations[i].this.commitResize(allocations[i], d)
|
||||||
}
|
}
|
||||||
// always set c.d to nil so it can be garbage-collected
|
// always set c.d to nil so it can be garbage-collected
|
||||||
// the c.endResize() above won't matter since the c.d there is evaluated then, not when c.endResize() is called
|
|
||||||
c.d = nil
|
c.d = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ func newWindow(title string, width int, height int, control Control) *window {
|
||||||
closing: newEvent(),
|
closing: newEvent(),
|
||||||
container: new(container),
|
container: new(container),
|
||||||
}
|
}
|
||||||
w.container.beginResize = w.beginResize
|
|
||||||
C.windowSetDelegate(id, unsafe.Pointer(w))
|
C.windowSetDelegate(id, unsafe.Pointer(w))
|
||||||
w.child = control
|
w.child = control
|
||||||
w.child.setParent(C.windowContentView(w.id))
|
w.child.setParent(C.windowContentView(w.id))
|
||||||
|
@ -78,6 +77,7 @@ func windowClosing(xw unsafe.Pointer) C.BOOL {
|
||||||
//export windowResized
|
//export windowResized
|
||||||
func windowResized(xw unsafe.Pointer, width C.uintptr_t, height C.uintptr_t) {
|
func windowResized(xw unsafe.Pointer, width C.uintptr_t, height C.uintptr_t) {
|
||||||
w := (*window)(unsafe.Pointer(xw))
|
w := (*window)(unsafe.Pointer(xw))
|
||||||
|
w.container.d = w.beginResize()
|
||||||
w.resize(int(width), int(height))
|
w.resize(int(width), int(height))
|
||||||
fmt.Printf("new size %d x %d\n", width, height)
|
fmt.Printf("new size %d x %d\n", width, height)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ func newWindow(title string, width int, height int, control Control) *window {
|
||||||
closing: newEvent(),
|
closing: newEvent(),
|
||||||
container: new(container),
|
container: new(container),
|
||||||
}
|
}
|
||||||
w.container.beginResize = w.beginResize
|
|
||||||
C.gtk_window_set_title(w.window, ctitle)
|
C.gtk_window_set_title(w.window, ctitle)
|
||||||
g_signal_connect(
|
g_signal_connect(
|
||||||
C.gpointer(unsafe.Pointer(w.window)),
|
C.gpointer(unsafe.Pointer(w.window)),
|
||||||
|
@ -111,6 +110,7 @@ func windowClosing(wid *C.GtkWidget, e *C.GdkEvent, data C.gpointer) C.gboolean
|
||||||
//export windowResizing
|
//export windowResizing
|
||||||
func windowResizing(wid *C.GtkWidget, r *C.GdkRectangle, data C.gpointer) {
|
func windowResizing(wid *C.GtkWidget, r *C.GdkRectangle, data C.gpointer) {
|
||||||
w := (*window)(unsafe.Pointer(data))
|
w := (*window)(unsafe.Pointer(data))
|
||||||
|
w.container.d = w.beginResize()
|
||||||
w.resize(int(r.width), int(r.height))
|
w.resize(int(r.width), int(r.height))
|
||||||
fmt.Printf("new size %d x %d\n", r.width, r.height)
|
fmt.Printf("new size %d x %d\n", r.width, r.height)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ func newWindow(title string, width int, height int, control Control) *window {
|
||||||
closing: newEvent(),
|
closing: newEvent(),
|
||||||
container: new(container),
|
container: new(container),
|
||||||
}
|
}
|
||||||
w.container.beginResize = w.beginResize
|
|
||||||
hwnd := C.newWindow(toUTF16(title), C.int(width), C.int(height), unsafe.Pointer(w))
|
hwnd := C.newWindow(toUTF16(title), C.int(width), C.int(height), unsafe.Pointer(w))
|
||||||
if hwnd != w.hwnd {
|
if hwnd != w.hwnd {
|
||||||
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in window (%p) differ", hwnd, w.hwnd))
|
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in window (%p) differ", hwnd, w.hwnd))
|
||||||
|
@ -97,6 +96,7 @@ func storeWindowHWND(data unsafe.Pointer, hwnd C.HWND) {
|
||||||
//export windowResize
|
//export windowResize
|
||||||
func windowResize(data unsafe.Pointer, r *C.RECT) {
|
func windowResize(data unsafe.Pointer, r *C.RECT) {
|
||||||
w := (*window)(data)
|
w := (*window)(data)
|
||||||
|
w.container.d = w.beginResize()
|
||||||
w.resize(int(r.right - r.left), int(r.bottom - r.top))
|
w.resize(int(r.right - r.left), int(r.bottom - r.top))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var closeOnClick = flag.Bool("close", false, "close on click")
|
var closeOnClick = flag.Bool("close", false, "close on click")
|
||||||
|
var spaced = flag.Bool("spaced", false, "enable spacing")
|
||||||
|
|
||||||
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
|
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -20,6 +21,8 @@ func init() {
|
||||||
Do(func() {
|
Do(func() {
|
||||||
t := NewTab()
|
t := NewTab()
|
||||||
w := NewWindow("Hello", 320, 240, t)
|
w := NewWindow("Hello", 320, 240, t)
|
||||||
|
// TODO use a method here
|
||||||
|
w.(*window).spaced = *spaced
|
||||||
w.OnClosing(func() bool {
|
w.OnClosing(func() bool {
|
||||||
if *closeOnClick {
|
if *closeOnClick {
|
||||||
panic("window closed normally in close on click mode (should not happen)")
|
panic("window closed normally in close on click mode (should not happen)")
|
||||||
|
|
Loading…
Reference in New Issue