qulogic/libgnt

Improve resizing a box.

2010-03-24, Sadrul Habib Chowdhury
11f5e4943b5b
Parents 199b6ca25405
Children e2e041e8e37d
Improve resizing a box.

libgnt used to always change the size of the first widget. So in a lot of
dialogs (e.g. the log viewer, the add-buddy dialogs etc.) only the labels
would be resized, and the entry/comboboxes, resizing which would be more
useful, would never be resized. So change that behaviour to cycle through
all the widgets in the box for resize.

Fixes #11580, #7843.
  • +55 -59
    gntbox.c
  • --- a/gntbox.c Sun Feb 21 00:11:56 2010 +0000
    +++ b/gntbox.c Wed Mar 24 02:38:56 2010 +0000
    @@ -27,6 +27,9 @@
    #include <string.h>
    +#define PROP_LAST_RESIZE_S "last-resize"
    +#define PROP_SIZE_QUEUED_S "size-queued"
    +
    enum
    {
    PROP_0,
    @@ -194,7 +197,7 @@
    GntBox *box = GNT_BOX(widget);
    GList *iter;
    int maxw = 0, maxh = 0;
    -
    +
    g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
    for (iter = box->list; iter; iter = iter->next)
    @@ -398,6 +401,7 @@
    GList *iter;
    GntBox *box = GNT_BOX(widget);
    int wchange, hchange;
    + GntWidget *child, *last;
    if (!box->list)
    return TRUE;
    @@ -406,67 +410,59 @@
    hchange = widget->priv.height - height;
    if (wchange == 0 && hchange == 0)
    - return TRUE; /* Quit playing games */
    + return TRUE; /* Quit playing games with my size */
    - /* XXX: Right now, I am trying to just apply all the changes to
    - * just one widget. It should be possible to distribute the
    - * changes to all the widgets in the box. */
    - for (iter = box->list; iter; iter = iter->next)
    - {
    + child = NULL;
    + last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S);
    +
    + /* First, make sure all the widgets will fit into the box after resizing. */
    + for (iter = box->list; iter; iter = iter->next) {
    GntWidget *wid = iter->data;
    int w, h;
    gnt_widget_get_size(wid, &w, &h);
    - if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
    - {
    - GList *i;
    -
    - for (i = box->list; i; i = i->next)
    - {
    - int tw, th;
    - if (i == iter) continue;
    - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
    - if (box->vertical)
    - {
    - if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) {
    - /* If we are decreasing the size and the widget is going
    - * to be too large to fit into the box, then do not allow
    - * resizing. */
    - if (wchange > 0 && tw >= widget->priv.width)
    - return FALSE;
    - }
    - }
    - else
    - {
    - if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) {
    - if (hchange > 0 && th >= widget->priv.height)
    - return FALSE;
    - return FALSE;
    - }
    - }
    - }
    -#if 0
    - gnt_widget_set_size(wid, w - wchange, h - hchange);
    - if (box->vertical)
    - hchange = 0;
    - else
    - wchange = 0;
    -
    - for (i = box->list; i; i = i->next)
    - {
    - int tw, th;
    - if (i == iter) continue;
    - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
    - gnt_widget_set_size(i->data, tw - wchange, th - hchange);
    - }
    -#endif
    - g_object_set_data(G_OBJECT(box), "size-queued", wid);
    - return TRUE;
    + if (wid != last && !child && gnt_widget_confirm_size(wid, w - wchange, h - hchange)) {
    + child = wid;
    + break;
    }
    }
    - return FALSE;
    + if (!child && (child = last)) {
    + int w, h;
    + gnt_widget_get_size(child, &w, &h);
    + if (!gnt_widget_confirm_size(child, w - wchange, h - hchange))
    + child = NULL;
    + }
    +
    + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child);
    +
    + if (child) {
    + for (iter = box->list; iter; iter = iter->next) {
    + GntWidget *wid = iter->data;
    + int w, h;
    +
    + gnt_widget_get_size(wid, &w, &h);
    + if (box->vertical) {
    + /* For a vertical box, if we are changing the width, make sure the widgets
    + * in the box will fit after resizing the width. */
    + if (wchange > 0 &&
    + w >= child->priv.width &&
    + !gnt_widget_confirm_size(wid, w - wchange, h))
    + return FALSE;
    + } else {
    + /* If we are changing the height, make sure the widgets in the box fit after
    + * the resize. */
    + if (hchange > 0 &&
    + h >= child->priv.height &&
    + !gnt_widget_confirm_size(wid, w, h - hchange))
    + return FALSE;
    + }
    +
    + }
    + }
    +
    + return (child != NULL);
    }
    static void
    @@ -477,16 +473,16 @@
    GntBox *box = GNT_BOX(widget);
    GntWidget *wid;
    int tw, th;
    -
    +
    wchange = widget->priv.width - oldw;
    hchange = widget->priv.height - oldh;
    -
    - wid = g_object_get_data(G_OBJECT(box), "size-queued");
    - if (wid)
    - {
    +
    + wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S);
    + if (wid) {
    gnt_widget_get_size(wid, &tw, &th);
    gnt_widget_set_size(wid, tw + wchange, th + hchange);
    - g_object_set_data(G_OBJECT(box), "size-queued", NULL);
    + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL);
    + g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid);
    }
    if (box->vertical)