Allowed GTK+ windows to be resized smaller than the size request of the controls within.

This commit is contained in:
Pietro Gagliardi 2014-03-15 14:27:18 -04:00
parent 05905e3add
commit e429b8d6b8
5 changed files with 26 additions and 12 deletions

View File

@ -66,16 +66,30 @@ func gtk_window_get_size(window *gtkWidget) (int, int) {
return int(width), int(height)
}
func gtk_fixed_new() *gtkWidget {
return fromgtkwidget(C.gtk_fixed_new())
// this should allow us to resize the window arbitrarily
// 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) {
C.gtk_container_add(togtkcontainer(container), togtkwidget(widget))
}
func gtk_fixed_move(container *gtkWidget, widget *gtkWidget, x int, y int) {
C.gtk_fixed_move(togtkfixed(container), togtkwidget(widget),
func gtkAddWidgetToLayout(container *gtkWidget, widget *gtkWidget) {
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))
}

View File

@ -61,12 +61,12 @@ func togtkcontainer(what *gtkWidget) *C.GtkContainer {
return (*C.GtkContainer)(unsafe.Pointer(what))
}
func fromgtkfixed(x *C.GtkFixed) *gtkWidget {
func fromgtklayout(x *C.GtkLayout) *gtkWidget {
return (*gtkWidget)(unsafe.Pointer(x))
}
func togtkfixed(what *gtkWidget) *C.GtkFixed {
return (*C.GtkFixed)(unsafe.Pointer(what))
func togtklayout(what *gtkWidget) *C.GtkLayout {
return (*C.GtkLayout)(unsafe.Pointer(what))
}
func fromgtkbutton(x *C.GtkButton) *gtkWidget {

View File

@ -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.
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.

View File

@ -117,7 +117,7 @@ func (s *sysData) make(initText string, window *sysData) error {
s.widget = <-ret
if window == nil {
uitask <- func() {
fixed := gtk_fixed_new()
fixed := gtkNewWindowLayout()
gtk_container_add(s.widget, fixed)
// TODO return the container before assigning the signals?
for signame, sigfunc := range ct.signals {
@ -129,7 +129,7 @@ func (s *sysData) make(initText string, window *sysData) error {
} else {
s.container = window.container
uitask <- func() {
gtk_container_add(s.container, s.widget)
gtkAddWidgetToLayout(s.container, s.widget)
for signame, sigfunc := range ct.signals {
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 {
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)
return nil
}

View File

@ -45,7 +45,6 @@ important things:
- 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)
- 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?)
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
- 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)
- 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:
- make specific wording in documentation consistent (make/create, etc.)