Mercurial > pidgin
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 |