Update.
[gnt.git] / gntbox.c
blobc4320f48d65268a77265dfc4af9718b3b9493aa9
1 /**
2 * GNT - The GLib Ncurses Toolkit
4 * GNT is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 #include "gntbox.h"
24 #include "gntutils.h"
26 #include <string.h>
28 enum
30 PROP_0,
31 PROP_VERTICAL,
32 PROP_HOMO /* ... */
35 enum
37 SIGS = 1,
40 static GntWidgetClass *parent_class = NULL;
42 static GntWidget * find_focusable_widget(GntBox *box);
44 static void
45 add_to_focus(gpointer value, gpointer data)
47 GntBox *box = GNT_BOX(data);
48 GntWidget *w = GNT_WIDGET(value);
50 if (GNT_IS_BOX(w))
51 g_list_foreach(GNT_BOX(w)->list, add_to_focus, box);
52 else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS))
53 box->focus = g_list_append(box->focus, w);
56 static void
57 get_title_thingies(GntBox *box, char *title, int *p, int *r)
59 GntWidget *widget = GNT_WIDGET(box);
60 int len;
61 char *end = (char*)gnt_util_onscreen_width_to_pointer(title, widget->priv.width - 4, &len);
63 if (p)
64 *p = (widget->priv.width - len) / 2;
65 if (r)
66 *r = (widget->priv.width + len) / 2;
67 *end = '\0';
70 static void
71 gnt_box_draw(GntWidget *widget)
73 GntBox *box = GNT_BOX(widget);
75 if (box->focus == NULL && widget->parent == NULL)
76 g_list_foreach(box->list, add_to_focus, box);
78 g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL);
80 gnt_box_sync_children(box);
82 if (box->title && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
84 int pos, right;
85 char *title = g_strdup(box->title);
87 get_title_thingies(box, title, &pos, &right);
89 if (gnt_widget_has_focus(widget))
90 wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TITLE));
91 else
92 wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TITLE_D));
93 mvwaddch(widget->window, 0, pos-1, ACS_RTEE | gnt_color_pair(GNT_COLOR_NORMAL));
94 mvwaddstr(widget->window, 0, pos, title);
95 mvwaddch(widget->window, 0, right, ACS_LTEE | gnt_color_pair(GNT_COLOR_NORMAL));
96 g_free(title);
99 GNTDEBUG;
102 static void
103 reposition_children(GntWidget *widget)
105 GList *iter;
106 GntBox *box = GNT_BOX(widget);
107 int w, h, curx, cury, max;
108 gboolean has_border = FALSE;
110 w = h = 0;
111 max = 0;
112 curx = widget->priv.x;
113 cury = widget->priv.y;
114 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
116 has_border = TRUE;
117 curx += 1;
118 cury += 1;
121 for (iter = box->list; iter; iter = iter->next)
123 if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE))
124 continue;
125 gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);
126 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
127 if (box->vertical)
129 if (h)
131 cury += h + box->pad;
132 if (max < w)
133 max = w;
136 else
138 if (w)
140 curx += w + box->pad;
141 if (max < h)
142 max = h;
147 if (has_border)
149 curx += 1;
150 cury += 1;
151 max += 2;
154 if (box->list)
156 if (box->vertical)
157 cury -= box->pad;
158 else
159 curx -= box->pad;
162 if (box->vertical)
164 widget->priv.width = max;
165 widget->priv.height = cury - widget->priv.y;
167 else
169 widget->priv.width = curx - widget->priv.x;
170 widget->priv.height = max;
174 static void
175 gnt_box_set_position(GntWidget *widget, int x, int y)
177 GList *iter;
178 int changex, changey;
180 changex = widget->priv.x - x;
181 changey = widget->priv.y - y;
183 for (iter = GNT_BOX(widget)->list; iter; iter = iter->next)
185 GntWidget *w = GNT_WIDGET(iter->data);
186 gnt_widget_set_position(w, w->priv.x - changex,
187 w->priv.y - changey);
191 static void
192 gnt_box_size_request(GntWidget *widget)
194 GntBox *box = GNT_BOX(widget);
195 GList *iter;
196 int maxw = 0, maxh = 0;
198 g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
200 for (iter = box->list; iter; iter = iter->next)
202 int w, h;
203 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
204 if (maxh < h)
205 maxh = h;
206 if (maxw < w)
207 maxw = w;
210 for (iter = box->list; iter; iter = iter->next)
212 int w, h;
213 GntWidget *wid = GNT_WIDGET(iter->data);
215 gnt_widget_get_size(wid, &w, &h);
217 if (box->homogeneous)
219 if (box->vertical)
220 h = maxh;
221 else
222 w = maxw;
224 if (box->fill)
226 if (box->vertical)
227 w = maxw;
228 else
229 h = maxh;
232 gnt_widget_confirm_size(wid, w, h);
233 gnt_widget_set_size(wid, w, h);
236 reposition_children(widget);
239 static void
240 gnt_box_map(GntWidget *widget)
242 if (widget->priv.width == 0 || widget->priv.height == 0)
244 gnt_widget_size_request(widget);
245 find_focusable_widget(GNT_BOX(widget));
247 GNTDEBUG;
250 /* Ensures that the current widget can take focus */
251 static GntWidget *
252 find_focusable_widget(GntBox *box)
254 /* XXX: Make sure the widget is visible? */
255 if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL)
256 g_list_foreach(box->list, add_to_focus, box);
258 if (box->active == NULL && box->focus)
259 box->active = box->focus->data;
261 return box->active;
264 static void
265 find_next_focus(GntBox *box)
267 gpointer last = box->active;
270 GList *iter = g_list_find(box->focus, box->active);
271 if (iter && iter->next)
272 box->active = iter->next->data;
273 else if (box->focus)
274 box->active = box->focus->data;
275 if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
276 break;
277 } while (box->active != last);
280 static void
281 find_prev_focus(GntBox *box)
283 gpointer last = box->active;
285 if (!box->focus)
286 return;
290 GList *iter = g_list_find(box->focus, box->active);
291 if (!iter)
292 box->active = box->focus->data;
293 else if (!iter->prev)
294 box->active = g_list_last(box->focus)->data;
295 else
296 box->active = iter->prev->data;
297 if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
298 break;
299 } while (box->active != last);
302 static gboolean
303 gnt_box_key_pressed(GntWidget *widget, const char *text)
305 GntBox *box = GNT_BOX(widget);
306 GntWidget *now;
308 if (box->active == NULL && !find_focusable_widget(box))
309 return FALSE;
311 if (gnt_widget_key_pressed(box->active, text))
312 return TRUE;
314 now = box->active;
316 if (text[0] == 27)
318 if (strcmp(text, GNT_KEY_LEFT) == 0)
320 find_prev_focus(box);
322 else if (strcmp(text, GNT_KEY_RIGHT) == 0)
324 find_next_focus(box);
326 else if (strcmp(text, GNT_KEY_BACK_TAB) == 0)
328 find_prev_focus(box);
331 else if (text[0] == '\t')
333 find_next_focus(box);
336 if (now && now != box->active)
338 gnt_widget_set_focus(now, FALSE);
339 gnt_widget_set_focus(box->active, TRUE);
340 return TRUE;
343 return FALSE;
346 static void
347 gnt_box_lost_focus(GntWidget *widget)
349 GntWidget *w = GNT_BOX(widget)->active;
350 if (w)
351 gnt_widget_set_focus(w, FALSE);
352 gnt_widget_draw(widget);
355 static void
356 gnt_box_gained_focus(GntWidget *widget)
358 GntWidget *w = GNT_BOX(widget)->active;
359 if (w)
360 gnt_widget_set_focus(w, TRUE);
361 gnt_widget_draw(widget);
364 static void
365 gnt_box_destroy(GntWidget *w)
367 GntBox *box = GNT_BOX(w);
369 gnt_box_remove_all(box);
370 gnt_screen_release(w);
373 static void
374 gnt_box_expose(GntWidget *widget, int x, int y, int width, int height)
376 WINDOW *win = newwin(height, width, widget->priv.y + y, widget->priv.x + x);
377 copywin(widget->window, win, y, x, 0, 0, height - 1, width - 1, FALSE);
378 wrefresh(win);
379 delwin(win);
382 static gboolean
383 gnt_box_confirm_size(GntWidget *widget, int width, int height)
385 GList *iter;
386 GntBox *box = GNT_BOX(widget);
387 int wchange, hchange;
389 if (!box->list)
390 return TRUE;
392 wchange = widget->priv.width - width;
393 hchange = widget->priv.height - height;
395 if (wchange == 0 && hchange == 0)
396 return TRUE; /* Quit playing games */
398 /* XXX: Right now, I am trying to just apply all the changes to
399 * just one widget. It should be possible to distribute the
400 * changes to all the widgets in the box. */
401 for (iter = box->list; iter; iter = iter->next)
403 GntWidget *wid = iter->data;
404 int w, h;
406 gnt_widget_get_size(wid, &w, &h);
408 if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
410 GList *i;
412 for (i = box->list; i; i = i->next)
414 int tw, th;
415 if (i == iter) continue;
416 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
417 if (box->vertical)
419 if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) {
420 /* If we are decreasing the size and the widget is going
421 * to be too large to fit into the box, then do not allow
422 * resizing. */
423 if (wchange > 0 && tw >= widget->priv.width)
424 return FALSE;
427 else
429 if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) {
430 if (hchange > 0 && th >= widget->priv.height)
431 return FALSE;
432 return FALSE;
436 #if 0
437 gnt_widget_set_size(wid, w - wchange, h - hchange);
438 if (box->vertical)
439 hchange = 0;
440 else
441 wchange = 0;
443 for (i = box->list; i; i = i->next)
445 int tw, th;
446 if (i == iter) continue;
447 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
448 gnt_widget_set_size(i->data, tw - wchange, th - hchange);
450 #endif
451 g_object_set_data(G_OBJECT(box), "size-queued", wid);
452 return TRUE;
456 return FALSE;
459 static void
460 gnt_box_size_changed(GntWidget *widget, int oldw, int oldh)
462 int wchange, hchange;
463 GList *i;
464 GntBox *box = GNT_BOX(widget);
465 GntWidget *wid;
466 int tw, th;
468 wchange = widget->priv.width - oldw;
469 hchange = widget->priv.height - oldh;
471 wid = g_object_get_data(G_OBJECT(box), "size-queued");
472 if (wid)
474 gnt_widget_get_size(wid, &tw, &th);
475 gnt_widget_set_size(wid, tw + wchange, th + hchange);
476 g_object_set_data(G_OBJECT(box), "size-queued", NULL);
479 if (box->vertical)
480 hchange = 0;
481 else
482 wchange = 0;
484 for (i = box->list; i; i = i->next)
486 if (wid != i->data)
488 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
489 gnt_widget_set_size(i->data, tw + wchange, th + hchange);
493 reposition_children(widget);
496 static gboolean
497 gnt_box_clicked(GntWidget *widget, GntMouseEvent event, int cx, int cy)
499 GList *iter;
500 for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) {
501 int x, y, w, h;
502 GntWidget *wid = iter->data;
504 gnt_widget_get_position(wid, &x, &y);
505 gnt_widget_get_size(wid, &w, &h);
507 if (cx >= x && cx < x + w && cy >= y && cy < y + h) {
508 if (event <= GNT_MIDDLE_MOUSE_DOWN &&
509 GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_CAN_TAKE_FOCUS)) {
510 while (widget->parent)
511 widget = widget->parent;
512 gnt_box_give_focus_to_child(GNT_BOX(widget), wid);
514 return gnt_widget_clicked(wid, event, cx, cy);
517 return FALSE;
520 static void
521 gnt_box_set_property(GObject *obj, guint prop_id, const GValue *value,
522 GParamSpec *spec)
524 GntBox *box = GNT_BOX(obj);
525 switch (prop_id) {
526 case PROP_VERTICAL:
527 box->vertical = g_value_get_boolean(value);
528 break;
529 case PROP_HOMO:
530 box->homogeneous = g_value_get_boolean(value);
531 break;
532 default:
533 g_return_if_reached();
534 break;
538 static void
539 gnt_box_get_property(GObject *obj, guint prop_id, GValue *value,
540 GParamSpec *spec)
542 GntBox *box = GNT_BOX(obj);
543 switch (prop_id) {
544 case PROP_VERTICAL:
545 g_value_set_boolean(value, box->vertical);
546 break;
547 case PROP_HOMO:
548 g_value_set_boolean(value, box->homogeneous);
549 break;
550 default:
551 break;
555 static void
556 gnt_box_class_init(GntBoxClass *klass)
558 GObjectClass *gclass = G_OBJECT_CLASS(klass);
559 parent_class = GNT_WIDGET_CLASS(klass);
560 parent_class->destroy = gnt_box_destroy;
561 parent_class->draw = gnt_box_draw;
562 parent_class->expose = gnt_box_expose;
563 parent_class->map = gnt_box_map;
564 parent_class->size_request = gnt_box_size_request;
565 parent_class->set_position = gnt_box_set_position;
566 parent_class->key_pressed = gnt_box_key_pressed;
567 parent_class->clicked = gnt_box_clicked;
568 parent_class->lost_focus = gnt_box_lost_focus;
569 parent_class->gained_focus = gnt_box_gained_focus;
570 parent_class->confirm_size = gnt_box_confirm_size;
571 parent_class->size_changed = gnt_box_size_changed;
573 gclass->set_property = gnt_box_set_property;
574 gclass->get_property = gnt_box_get_property;
575 g_object_class_install_property(gclass,
576 PROP_VERTICAL,
577 g_param_spec_boolean("vertical", "Vertical",
578 "Whether the child widgets in the box should be stacked vertically.",
579 TRUE,
580 G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
583 g_object_class_install_property(gclass,
584 PROP_HOMO,
585 g_param_spec_boolean("homogeneous", "Homogeneous",
586 "Whether the child widgets in the box should have the same size.",
587 TRUE,
588 G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
593 static void
594 gnt_box_init(GTypeInstance *instance, gpointer class)
596 GntWidget *widget = GNT_WIDGET(instance);
597 GntBox *box = GNT_BOX(widget);
598 /* Initially make both the height and width resizable.
599 * Update the flags as necessary when widgets are added to it. */
600 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
601 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
602 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
603 box->pad = 1;
604 box->fill = TRUE;
605 GNTDEBUG;
608 /******************************************************************************
609 * GntBox API
610 *****************************************************************************/
611 GType
612 gnt_box_get_gtype(void)
614 static GType type = 0;
616 if(type == 0)
618 static const GTypeInfo info = {
619 sizeof(GntBoxClass),
620 NULL, /* base_init */
621 NULL, /* base_finalize */
622 (GClassInitFunc)gnt_box_class_init,
623 NULL, /* class_finalize */
624 NULL, /* class_data */
625 sizeof(GntBox),
626 0, /* n_preallocs */
627 gnt_box_init, /* instance_init */
628 NULL /* value_table */
631 type = g_type_register_static(GNT_TYPE_WIDGET,
632 "GntBox",
633 &info, 0);
636 return type;
639 GntWidget *gnt_box_new(gboolean homo, gboolean vert)
641 GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL);
642 GntBox *box = GNT_BOX(widget);
644 box->homogeneous = homo;
645 box->vertical = vert;
646 box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID;
648 return widget;
651 void gnt_box_add_widget(GntBox *b, GntWidget *widget)
653 b->list = g_list_append(b->list, widget);
654 widget->parent = GNT_WIDGET(b);
657 void gnt_box_set_title(GntBox *b, const char *title)
659 char *prev = b->title;
660 GntWidget *w = GNT_WIDGET(b);
661 b->title = g_strdup(title);
662 if (w->window && !GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_NO_BORDER)) {
663 /* Erase the old title */
664 int pos, right;
665 get_title_thingies(b, prev, &pos, &right);
666 mvwhline(w->window, 0, pos - 1, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL),
667 right - pos + 2);
668 g_free(prev);
672 void gnt_box_set_pad(GntBox *box, int pad)
674 box->pad = pad;
675 /* XXX: Perhaps redraw if already showing? */
678 void gnt_box_set_toplevel(GntBox *box, gboolean set)
680 GntWidget *widget = GNT_WIDGET(box);
681 if (set)
683 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
684 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
686 else
688 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
689 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
693 void gnt_box_sync_children(GntBox *box)
695 GList *iter;
696 GntWidget *widget = GNT_WIDGET(box);
697 int pos = 1;
699 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
700 pos = 0;
702 for (iter = box->list; iter; iter = iter->next)
704 GntWidget *w = GNT_WIDGET(iter->data);
705 int height, width;
706 int x, y;
708 if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_INVISIBLE))
709 continue;
711 if (GNT_IS_BOX(w))
712 gnt_box_sync_children(GNT_BOX(w));
714 gnt_widget_get_size(w, &width, &height);
716 x = w->priv.x - widget->priv.x;
717 y = w->priv.y - widget->priv.y;
719 if (box->vertical)
721 x = pos;
722 if (box->alignment == GNT_ALIGN_RIGHT)
723 x += widget->priv.width - width;
724 else if (box->alignment == GNT_ALIGN_MID)
725 x += (widget->priv.width - width)/2;
726 if (x + width > widget->priv.width - pos)
727 x -= x + width - (widget->priv.width - pos);
729 else
731 y = pos;
732 if (box->alignment == GNT_ALIGN_BOTTOM)
733 y += widget->priv.height - height;
734 else if (box->alignment == GNT_ALIGN_MID)
735 y += (widget->priv.height - height)/2;
736 if (y + height >= widget->priv.height - pos)
737 y = widget->priv.height - height - pos;
740 copywin(w->window, widget->window, 0, 0,
741 y, x, y + height - 1, x + width - 1, FALSE);
742 gnt_widget_set_position(w, x + widget->priv.x, y + widget->priv.y);
746 void gnt_box_set_alignment(GntBox *box, GntAlignment alignment)
748 box->alignment = alignment;
751 void gnt_box_remove(GntBox *box, GntWidget *widget)
753 box->list = g_list_remove(box->list, widget);
754 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)
755 && GNT_WIDGET(box)->parent == NULL && box->focus)
757 if (widget == box->active)
759 find_next_focus(box);
760 if (box->active == widget) /* There's only one widget */
761 box->active = NULL;
763 box->focus = g_list_remove(box->focus, widget);
766 if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(box), GNT_WIDGET_MAPPED))
767 gnt_widget_draw(GNT_WIDGET(box));
770 void gnt_box_remove_all(GntBox *box)
772 g_list_foreach(box->list, (GFunc)gnt_widget_destroy, NULL);
773 g_list_free(box->list);
774 g_list_free(box->focus);
775 box->list = NULL;
776 box->focus = NULL;
777 GNT_WIDGET(box)->priv.width = 0;
778 GNT_WIDGET(box)->priv.height = 0;
781 void gnt_box_readjust(GntBox *box)
783 GList *iter;
784 GntWidget *wid;
785 int width, height;
787 if (GNT_WIDGET(box)->parent != NULL)
788 return;
790 for (iter = box->list; iter; iter = iter->next)
792 GntWidget *w = iter->data;
793 if (GNT_IS_BOX(w))
794 gnt_box_readjust(GNT_BOX(w));
795 else
797 GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_MAPPED);
798 w->priv.width = 0;
799 w->priv.height = 0;
803 wid = GNT_WIDGET(box);
804 GNT_WIDGET_UNSET_FLAGS(wid, GNT_WIDGET_MAPPED);
805 wid->priv.width = 0;
806 wid->priv.height = 0;
808 if (wid->parent == NULL)
810 g_list_free(box->focus);
811 box->focus = NULL;
812 box->active = NULL;
813 gnt_widget_size_request(wid);
814 gnt_widget_get_size(wid, &width, &height);
815 gnt_screen_resize_widget(wid, width, height);
816 find_focusable_widget(box);
820 void gnt_box_set_fill(GntBox *box, gboolean fill)
822 box->fill = fill;
825 void gnt_box_move_focus(GntBox *box, int dir)
827 GntWidget *now;
829 if (box->active == NULL)
831 find_focusable_widget(box);
832 return;
835 now = box->active;
837 if (dir == 1)
838 find_next_focus(box);
839 else if (dir == -1)
840 find_prev_focus(box);
842 if (now && now != box->active)
844 gnt_widget_set_focus(now, FALSE);
845 gnt_widget_set_focus(box->active, TRUE);
848 if (GNT_WIDGET(box)->window)
849 gnt_widget_draw(GNT_WIDGET(box));
852 void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget)
854 GList *find = g_list_find(box->focus, widget);
855 gpointer now = box->active;
856 if (find)
857 box->active = widget;
858 if (now && now != box->active)
860 gnt_widget_set_focus(now, FALSE);
861 gnt_widget_set_focus(box->active, TRUE);
864 if (GNT_WIDGET(box)->window)
865 gnt_widget_draw(GNT_WIDGET(box));