Allowed GTK+ windows to be resized smaller than the size request of the controls within.
This commit is contained in:
parent
05905e3add
commit
e429b8d6b8
|
@ -66,16 +66,30 @@ func gtk_window_get_size(window *gtkWidget) (int, int) {
|
||||||
return int(width), int(height)
|
return int(width), int(height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gtk_fixed_new() *gtkWidget {
|
// this should allow us to resize the window arbitrarily
|
||||||
return fromgtkwidget(C.gtk_fixed_new())
|
// thanks to Company in irc.gimp.net/#gtk+
|
||||||
|
func gtkNewWindowLayout() *gtkWidget {
|
||||||
|
layout := C.gtk_layout_new(nil, nil)
|
||||||
|
scrollarea := C.gtk_scrolled_window_new((*C.GtkAdjustment)(nil), (*C.GtkAdjustment)(nil))
|
||||||
|
C.gtk_container_add((*C.GtkContainer)(unsafe.Pointer(scrollarea)), layout)
|
||||||
|
// never show scrollbars; we're just doing this to allow arbitrary resizes
|
||||||
|
C.gtk_scrolled_window_set_policy((*C.GtkScrolledWindow)(unsafe.Pointer(scrollarea)),
|
||||||
|
C.GTK_POLICY_NEVER, C.GTK_POLICY_NEVER)
|
||||||
|
return fromgtkwidget(scrollarea)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gtk_container_add(container *gtkWidget, widget *gtkWidget) {
|
func gtk_container_add(container *gtkWidget, widget *gtkWidget) {
|
||||||
C.gtk_container_add(togtkcontainer(container), togtkwidget(widget))
|
C.gtk_container_add(togtkcontainer(container), togtkwidget(widget))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gtk_fixed_move(container *gtkWidget, widget *gtkWidget, x int, y int) {
|
func gtkAddWidgetToLayout(container *gtkWidget, widget *gtkWidget) {
|
||||||
C.gtk_fixed_move(togtkfixed(container), togtkwidget(widget),
|
layout := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(container)))
|
||||||
|
C.gtk_container_add((*C.GtkContainer)(unsafe.Pointer(layout)), togtkwidget(widget))
|
||||||
|
}
|
||||||
|
|
||||||
|
func gtkMoveWidgetInLayout(container *gtkWidget, widget *gtkWidget, x int, y int) {
|
||||||
|
layout := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(container)))
|
||||||
|
C.gtk_layout_move((*C.GtkLayout)(unsafe.Pointer(layout)), togtkwidget(widget),
|
||||||
C.gint(x), C.gint(y))
|
C.gint(x), C.gint(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,12 +61,12 @@ func togtkcontainer(what *gtkWidget) *C.GtkContainer {
|
||||||
return (*C.GtkContainer)(unsafe.Pointer(what))
|
return (*C.GtkContainer)(unsafe.Pointer(what))
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromgtkfixed(x *C.GtkFixed) *gtkWidget {
|
func fromgtklayout(x *C.GtkLayout) *gtkWidget {
|
||||||
return (*gtkWidget)(unsafe.Pointer(x))
|
return (*gtkWidget)(unsafe.Pointer(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
func togtkfixed(what *gtkWidget) *C.GtkFixed {
|
func togtklayout(what *gtkWidget) *C.GtkLayout {
|
||||||
return (*C.GtkFixed)(unsafe.Pointer(what))
|
return (*C.GtkLayout)(unsafe.Pointer(what))
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromgtkbutton(x *C.GtkButton) *gtkWidget {
|
func fromgtkbutton(x *C.GtkButton) *gtkWidget {
|
||||||
|
|
|
@ -47,7 +47,7 @@ GTK+ is strange: there are constructor functions that return `GtkWidget *`, but
|
||||||
|
|
||||||
As the GTK+ main loop system does not quite run in a sane way (it allows recursion, and the `gtk_main_loop_iteration_do` function only onperates on the innermost call), we cannot use the `for`/`select` template for `ui()`. Fortunately, GDK provides gdk_threads_add_idle(), which allows us to run, and optionally (and importantly) run only once, a function on the `gtk_main()` thread when not processing events. We use this, combined with a goroutine for dispatching, to handle `uitask` requests. See `our_idle_callback` in callbacks_unix.go for details.
|
As the GTK+ main loop system does not quite run in a sane way (it allows recursion, and the `gtk_main_loop_iteration_do` function only onperates on the innermost call), we cannot use the `for`/`select` template for `ui()`. Fortunately, GDK provides gdk_threads_add_idle(), which allows us to run, and optionally (and importantly) run only once, a function on the `gtk_main()` thread when not processing events. We use this, combined with a goroutine for dispatching, to handle `uitask` requests. See `our_idle_callback` in callbacks_unix.go for details.
|
||||||
|
|
||||||
GTK+ layout managers are not used since the UI library's layout managers are coded in a portable way. (`GtkFixed` is used instead.) This isn't ideal, but it works for now.
|
GTK+ layout managers are not used since the UI library's layout managers are coded in a portable way. (A `GtkLayout` in a `GtkScrolledWindow` is used instead. This is done instead of just a `GtkFixed` so that a window can be resized smaller than the size requests of its contents.) This isn't ideal, but it works for now.
|
||||||
|
|
||||||
All event handlers take the `sysData` as their user data parameter; this means all the event-handling code is stored in static functions in callbacks_unix.go. (Early versions of the package generated signal handlers for each control on the fly, but this needed to be changed to accommodoate Area, which not only needs the `sysData` but also needs to connect to a subwidget of a subwidget (specifically the subwidget of the `GtkViewport` of a `GtkScrolledWindow`); the current setup also avoids creating closures for each and every Window and Button created, and also means we can stop having to shove those callbacks in an ever-growing slice to prevent them from being garbage collected.) Should the widget actually be a child widget of a `GtkScrolledWindow`, the `child` function and `childsigs` signal list are used to assign signals as well.
|
All event handlers take the `sysData` as their user data parameter; this means all the event-handling code is stored in static functions in callbacks_unix.go. (Early versions of the package generated signal handlers for each control on the fly, but this needed to be changed to accommodoate Area, which not only needs the `sysData` but also needs to connect to a subwidget of a subwidget (specifically the subwidget of the `GtkViewport` of a `GtkScrolledWindow`); the current setup also avoids creating closures for each and every Window and Button created, and also means we can stop having to shove those callbacks in an ever-growing slice to prevent them from being garbage collected.) Should the widget actually be a child widget of a `GtkScrolledWindow`, the `child` function and `childsigs` signal list are used to assign signals as well.
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (s *sysData) make(initText string, window *sysData) error {
|
||||||
s.widget = <-ret
|
s.widget = <-ret
|
||||||
if window == nil {
|
if window == nil {
|
||||||
uitask <- func() {
|
uitask <- func() {
|
||||||
fixed := gtk_fixed_new()
|
fixed := gtkNewWindowLayout()
|
||||||
gtk_container_add(s.widget, fixed)
|
gtk_container_add(s.widget, fixed)
|
||||||
// TODO return the container before assigning the signals?
|
// TODO return the container before assigning the signals?
|
||||||
for signame, sigfunc := range ct.signals {
|
for signame, sigfunc := range ct.signals {
|
||||||
|
@ -129,7 +129,7 @@ func (s *sysData) make(initText string, window *sysData) error {
|
||||||
} else {
|
} else {
|
||||||
s.container = window.container
|
s.container = window.container
|
||||||
uitask <- func() {
|
uitask <- func() {
|
||||||
gtk_container_add(s.container, s.widget)
|
gtkAddWidgetToLayout(s.container, s.widget)
|
||||||
for signame, sigfunc := range ct.signals {
|
for signame, sigfunc := range ct.signals {
|
||||||
g_signal_connect(s.widget, signame, sigfunc, s)
|
g_signal_connect(s.widget, signame, sigfunc, s)
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ func (s *sysData) setText(text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error {
|
func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error {
|
||||||
gtk_fixed_move(s.container, s.widget, x, y)
|
gtkMoveWidgetInLayout(s.container, s.widget, x, y)
|
||||||
gtk_widget_set_size_request(s.widget, width, height)
|
gtk_widget_set_size_request(s.widget, width, height)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
2
todo.md
2
todo.md
|
@ -45,7 +45,6 @@ important things:
|
||||||
- make gcc (Unix)/clang (Mac OS X) pedantic about warnings/errors; also -Werror
|
- make gcc (Unix)/clang (Mac OS X) pedantic about warnings/errors; also -Werror
|
||||||
- make sure scrollbars in Listbox work identically on all platforms (specifically the existence and autohiding of both horizontal and vertical scrollbars)
|
- make sure scrollbars in Listbox work identically on all platforms (specifically the existence and autohiding of both horizontal and vertical scrollbars)
|
||||||
- pin down this behavior; also note non-editability
|
- pin down this behavior; also note non-editability
|
||||||
- GTK+ windows cannot be resized smaller than their controls's current sizes in their current positions; find out how to overrule that so they can be freely resized
|
|
||||||
- the size of Listboxes on Windows does not fill the requested space completely (wait, wasn't there a style that governed this?)
|
- the size of Listboxes on Windows does not fill the requested space completely (wait, wasn't there a style that governed this?)
|
||||||
|
|
||||||
super ultra important things:
|
super ultra important things:
|
||||||
|
@ -74,6 +73,7 @@ super ultra important things:
|
||||||
- frame sizes are a bit of a hack: the preferred size of a NSScrollView is the preferred size of its document view; the frameSize method described on the above link might be better but a real solution is optimal
|
- frame sizes are a bit of a hack: the preferred size of a NSScrollView is the preferred size of its document view; the frameSize method described on the above link might be better but a real solution is optimal
|
||||||
- make sure the image drawn on an Area looks correct on all platforms (is not cropped incorrectly or blurred)
|
- make sure the image drawn on an Area looks correct on all platforms (is not cropped incorrectly or blurred)
|
||||||
- GTK+: requested clip rect seems to be larger than the size of the Area (also larger than the visible portion? TODO)
|
- GTK+: requested clip rect seems to be larger than the size of the Area (also larger than the visible portion? TODO)
|
||||||
|
- when resizing a GTK+ window smaller than a certain size, the controls inside will start clipping in bizarre ways (progress bars/entry lines will just cut off; editable comboboxes will stretch slightly longer than noneditable ones; the horizontal scrollbar in Area will disappear smoothly; etc.)
|
||||||
|
|
||||||
important things:
|
important things:
|
||||||
- make specific wording in documentation consistent (make/create, etc.)
|
- make specific wording in documentation consistent (make/create, etc.)
|
||||||
|
|
Loading…
Reference in New Issue