comparison finch/libgnt/gntbox.c @ 29635:33a4d72232a7

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.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 24 Mar 2010 02:38:56 +0000
parents a18f421696dc
children 5d3f64f8e7b5
comparison
equal deleted inserted replaced
29634:f19ee75947c6 29635:33a4d72232a7
25 #include "gntstyle.h" 25 #include "gntstyle.h"
26 #include "gntutils.h" 26 #include "gntutils.h"
27 27
28 #include <string.h> 28 #include <string.h>
29 29
30 #define PROP_LAST_RESIZE_S "last-resize"
31 #define PROP_SIZE_QUEUED_S "size-queued"
32
30 enum 33 enum
31 { 34 {
32 PROP_0, 35 PROP_0,
33 PROP_VERTICAL, 36 PROP_VERTICAL,
34 PROP_HOMO /* ... */ 37 PROP_HOMO /* ... */
192 gnt_box_size_request(GntWidget *widget) 195 gnt_box_size_request(GntWidget *widget)
193 { 196 {
194 GntBox *box = GNT_BOX(widget); 197 GntBox *box = GNT_BOX(widget);
195 GList *iter; 198 GList *iter;
196 int maxw = 0, maxh = 0; 199 int maxw = 0, maxh = 0;
197 200
198 g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL); 201 g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
199 202
200 for (iter = box->list; iter; iter = iter->next) 203 for (iter = box->list; iter; iter = iter->next)
201 { 204 {
202 int w, h; 205 int w, h;
396 gnt_box_confirm_size(GntWidget *widget, int width, int height) 399 gnt_box_confirm_size(GntWidget *widget, int width, int height)
397 { 400 {
398 GList *iter; 401 GList *iter;
399 GntBox *box = GNT_BOX(widget); 402 GntBox *box = GNT_BOX(widget);
400 int wchange, hchange; 403 int wchange, hchange;
404 GntWidget *child, *last;
401 405
402 if (!box->list) 406 if (!box->list)
403 return TRUE; 407 return TRUE;
404 408
405 wchange = widget->priv.width - width; 409 wchange = widget->priv.width - width;
406 hchange = widget->priv.height - height; 410 hchange = widget->priv.height - height;
407 411
408 if (wchange == 0 && hchange == 0) 412 if (wchange == 0 && hchange == 0)
409 return TRUE; /* Quit playing games */ 413 return TRUE; /* Quit playing games with my size */
410 414
411 /* XXX: Right now, I am trying to just apply all the changes to 415 child = NULL;
412 * just one widget. It should be possible to distribute the 416 last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S);
413 * changes to all the widgets in the box. */ 417
414 for (iter = box->list; iter; iter = iter->next) 418 /* First, make sure all the widgets will fit into the box after resizing. */
415 { 419 for (iter = box->list; iter; iter = iter->next) {
416 GntWidget *wid = iter->data; 420 GntWidget *wid = iter->data;
417 int w, h; 421 int w, h;
418 422
419 gnt_widget_get_size(wid, &w, &h); 423 gnt_widget_get_size(wid, &w, &h);
420 424
421 if (gnt_widget_confirm_size(wid, w - wchange, h - hchange)) 425 if (wid != last && !child && gnt_widget_confirm_size(wid, w - wchange, h - hchange)) {
422 { 426 child = wid;
423 GList *i; 427 break;
424 428 }
425 for (i = box->list; i; i = i->next) 429 }
426 { 430
427 int tw, th; 431 if (!child && (child = last)) {
428 if (i == iter) continue; 432 int w, h;
429 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); 433 gnt_widget_get_size(child, &w, &h);
430 if (box->vertical) 434 if (!gnt_widget_confirm_size(child, w - wchange, h - hchange))
431 { 435 child = NULL;
432 if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) { 436 }
433 /* If we are decreasing the size and the widget is going 437
434 * to be too large to fit into the box, then do not allow 438 g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child);
435 * resizing. */ 439
436 if (wchange > 0 && tw >= widget->priv.width) 440 if (child) {
437 return FALSE; 441 for (iter = box->list; iter; iter = iter->next) {
438 } 442 GntWidget *wid = iter->data;
439 } 443 int w, h;
440 else 444
441 { 445 gnt_widget_get_size(wid, &w, &h);
442 if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) { 446 if (box->vertical) {
443 if (hchange > 0 && th >= widget->priv.height) 447 /* For a vertical box, if we are changing the width, make sure the widgets
444 return FALSE; 448 * in the box will fit after resizing the width. */
445 return FALSE; 449 if (wchange > 0 &&
446 } 450 w >= child->priv.width &&
447 } 451 !gnt_widget_confirm_size(wid, w - wchange, h))
452 return FALSE;
453 } else {
454 /* If we are changing the height, make sure the widgets in the box fit after
455 * the resize. */
456 if (hchange > 0 &&
457 h >= child->priv.height &&
458 !gnt_widget_confirm_size(wid, w, h - hchange))
459 return FALSE;
448 } 460 }
449 #if 0 461
450 gnt_widget_set_size(wid, w - wchange, h - hchange); 462 }
451 if (box->vertical) 463 }
452 hchange = 0; 464
453 else 465 return (child != NULL);
454 wchange = 0;
455
456 for (i = box->list; i; i = i->next)
457 {
458 int tw, th;
459 if (i == iter) continue;
460 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
461 gnt_widget_set_size(i->data, tw - wchange, th - hchange);
462 }
463 #endif
464 g_object_set_data(G_OBJECT(box), "size-queued", wid);
465 return TRUE;
466 }
467 }
468
469 return FALSE;
470 } 466 }
471 467
472 static void 468 static void
473 gnt_box_size_changed(GntWidget *widget, int oldw, int oldh) 469 gnt_box_size_changed(GntWidget *widget, int oldw, int oldh)
474 { 470 {
475 int wchange, hchange; 471 int wchange, hchange;
476 GList *i; 472 GList *i;
477 GntBox *box = GNT_BOX(widget); 473 GntBox *box = GNT_BOX(widget);
478 GntWidget *wid; 474 GntWidget *wid;
479 int tw, th; 475 int tw, th;
480 476
481 wchange = widget->priv.width - oldw; 477 wchange = widget->priv.width - oldw;
482 hchange = widget->priv.height - oldh; 478 hchange = widget->priv.height - oldh;
483 479
484 wid = g_object_get_data(G_OBJECT(box), "size-queued"); 480 wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S);
485 if (wid) 481 if (wid) {
486 {
487 gnt_widget_get_size(wid, &tw, &th); 482 gnt_widget_get_size(wid, &tw, &th);
488 gnt_widget_set_size(wid, tw + wchange, th + hchange); 483 gnt_widget_set_size(wid, tw + wchange, th + hchange);
489 g_object_set_data(G_OBJECT(box), "size-queued", NULL); 484 g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL);
485 g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid);
490 } 486 }
491 487
492 if (box->vertical) 488 if (box->vertical)
493 hchange = 0; 489 hchange = 0;
494 else 490 else