15818
|
1 #include "gntbox.h"
|
|
2 #include "gntutils.h"
|
|
3
|
|
4 #include <string.h>
|
|
5
|
|
6 enum
|
|
7 {
|
|
8 SIGS = 1,
|
|
9 };
|
|
10
|
|
11 static GntWidgetClass *parent_class = NULL;
|
|
12
|
|
13 static GntWidget * find_focusable_widget(GntBox *box);
|
|
14
|
|
15 static void
|
|
16 add_to_focus(gpointer value, gpointer data)
|
|
17 {
|
|
18 GntBox *box = GNT_BOX(data);
|
|
19 GntWidget *w = GNT_WIDGET(value);
|
|
20
|
|
21 if (GNT_IS_BOX(w))
|
|
22 g_list_foreach(GNT_BOX(w)->list, add_to_focus, box);
|
|
23 else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS))
|
|
24 box->focus = g_list_append(box->focus, w);
|
|
25 }
|
|
26
|
|
27 static void
|
|
28 get_title_thingies(GntBox *box, char *title, int *p, int *r)
|
|
29 {
|
|
30 GntWidget *widget = GNT_WIDGET(box);
|
|
31 int len;
|
|
32 char *end = (char*)gnt_util_onscreen_width_to_pointer(title, widget->priv.width - 4, &len);
|
|
33
|
|
34 if (p)
|
|
35 *p = (widget->priv.width - len) / 2;
|
|
36 if (r)
|
|
37 *r = (widget->priv.width + len) / 2;
|
|
38 *end = '\0';
|
|
39 }
|
|
40
|
|
41 static void
|
|
42 gnt_box_draw(GntWidget *widget)
|
|
43 {
|
|
44 GntBox *box = GNT_BOX(widget);
|
|
45
|
|
46 if (box->focus == NULL && widget->parent == NULL)
|
|
47 g_list_foreach(box->list, add_to_focus, box);
|
|
48
|
|
49 g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL);
|
|
50
|
|
51 gnt_box_sync_children(box);
|
|
52
|
|
53 if (box->title && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
|
|
54 {
|
|
55 int pos, right;
|
|
56 char *title = g_strdup(box->title);
|
|
57
|
|
58 get_title_thingies(box, title, &pos, &right);
|
|
59
|
|
60 if (gnt_widget_has_focus(widget))
|
|
61 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));
|
|
62 else
|
|
63 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D));
|
|
64 mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
|
|
65 mvwaddstr(widget->window, 0, pos, title);
|
|
66 mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
|
|
67 g_free(title);
|
|
68 }
|
|
69
|
|
70 GNTDEBUG;
|
|
71 }
|
|
72
|
|
73 static void
|
|
74 reposition_children(GntWidget *widget)
|
|
75 {
|
|
76 GList *iter;
|
|
77 GntBox *box = GNT_BOX(widget);
|
|
78 int w, h, curx, cury, max;
|
|
79 gboolean has_border = FALSE;
|
|
80
|
|
81 w = h = 0;
|
|
82 max = 0;
|
|
83 curx = widget->priv.x;
|
|
84 cury = widget->priv.y;
|
|
85 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
|
|
86 {
|
|
87 has_border = TRUE;
|
|
88 curx += 1;
|
|
89 cury += 1;
|
|
90 }
|
|
91
|
|
92 for (iter = box->list; iter; iter = iter->next)
|
|
93 {
|
|
94 if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE))
|
|
95 continue;
|
|
96 gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);
|
|
97 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
|
|
98 if (box->vertical)
|
|
99 {
|
|
100 if (h)
|
|
101 {
|
|
102 cury += h + box->pad;
|
|
103 if (max < w)
|
|
104 max = w;
|
|
105 }
|
|
106 }
|
|
107 else
|
|
108 {
|
|
109 if (w)
|
|
110 {
|
|
111 curx += w + box->pad;
|
|
112 if (max < h)
|
|
113 max = h;
|
|
114 }
|
|
115 }
|
|
116 }
|
|
117
|
|
118 if (has_border)
|
|
119 {
|
|
120 curx += 1;
|
|
121 cury += 1;
|
|
122 max += 2;
|
|
123 }
|
|
124
|
|
125 if (box->list)
|
|
126 {
|
|
127 if (box->vertical)
|
|
128 cury -= box->pad;
|
|
129 else
|
|
130 curx -= box->pad;
|
|
131 }
|
|
132
|
|
133 if (box->vertical)
|
|
134 {
|
|
135 widget->priv.width = max;
|
|
136 widget->priv.height = cury - widget->priv.y;
|
|
137 }
|
|
138 else
|
|
139 {
|
|
140 widget->priv.width = curx - widget->priv.x;
|
|
141 widget->priv.height = max;
|
|
142 }
|
|
143 }
|
|
144
|
|
145 static void
|
|
146 gnt_box_set_position(GntWidget *widget, int x, int y)
|
|
147 {
|
|
148 GList *iter;
|
|
149 int changex, changey;
|
|
150
|
|
151 changex = widget->priv.x - x;
|
|
152 changey = widget->priv.y - y;
|
|
153
|
|
154 for (iter = GNT_BOX(widget)->list; iter; iter = iter->next)
|
|
155 {
|
|
156 GntWidget *w = GNT_WIDGET(iter->data);
|
|
157 gnt_widget_set_position(w, w->priv.x - changex,
|
|
158 w->priv.y - changey);
|
|
159 }
|
|
160 }
|
|
161
|
|
162 static void
|
|
163 gnt_box_size_request(GntWidget *widget)
|
|
164 {
|
|
165 GntBox *box = GNT_BOX(widget);
|
|
166 GList *iter;
|
|
167 int maxw = 0, maxh = 0;
|
|
168
|
|
169 g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
|
|
170
|
|
171 for (iter = box->list; iter; iter = iter->next)
|
|
172 {
|
|
173 int w, h;
|
|
174 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
|
|
175 if (maxh < h)
|
|
176 maxh = h;
|
|
177 if (maxw < w)
|
|
178 maxw = w;
|
|
179 }
|
|
180
|
|
181 for (iter = box->list; iter; iter = iter->next)
|
|
182 {
|
|
183 int w, h;
|
|
184 GntWidget *wid = GNT_WIDGET(iter->data);
|
|
185
|
|
186 gnt_widget_get_size(wid, &w, &h);
|
|
187
|
|
188 if (box->homogeneous)
|
|
189 {
|
|
190 if (box->vertical)
|
|
191 h = maxh;
|
|
192 else
|
|
193 w = maxw;
|
|
194 }
|
|
195 if (box->fill)
|
|
196 {
|
|
197 if (box->vertical)
|
|
198 w = maxw;
|
|
199 else
|
|
200 h = maxh;
|
|
201 }
|
|
202
|
|
203 gnt_widget_set_size(wid, w, h);
|
|
204 }
|
|
205
|
|
206 reposition_children(widget);
|
|
207 }
|
|
208
|
|
209 static void
|
|
210 gnt_box_map(GntWidget *widget)
|
|
211 {
|
|
212 if (widget->priv.width == 0 || widget->priv.height == 0)
|
|
213 {
|
|
214 gnt_widget_size_request(widget);
|
|
215 find_focusable_widget(GNT_BOX(widget));
|
|
216 }
|
|
217 GNTDEBUG;
|
|
218 }
|
|
219
|
|
220 /* Ensures that the current widget can take focus */
|
|
221 static GntWidget *
|
|
222 find_focusable_widget(GntBox *box)
|
|
223 {
|
|
224 /* XXX: Make sure the widget is visible? */
|
|
225 if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL)
|
|
226 g_list_foreach(box->list, add_to_focus, box);
|
|
227
|
|
228 if (box->active == NULL && box->focus)
|
|
229 box->active = box->focus->data;
|
|
230
|
|
231 return box->active;
|
|
232 }
|
|
233
|
|
234 static void
|
|
235 find_next_focus(GntBox *box)
|
|
236 {
|
|
237 gpointer last = box->active;
|
|
238 do
|
|
239 {
|
|
240 GList *iter = g_list_find(box->focus, box->active);
|
|
241 if (iter && iter->next)
|
|
242 box->active = iter->next->data;
|
|
243 else if (box->focus)
|
|
244 box->active = box->focus->data;
|
|
245 if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
|
|
246 break;
|
|
247 } while (box->active != last);
|
|
248 }
|
|
249
|
|
250 static void
|
|
251 find_prev_focus(GntBox *box)
|
|
252 {
|
|
253 gpointer last = box->active;
|
|
254
|
|
255 if (!box->focus)
|
|
256 return;
|
|
257
|
|
258 do
|
|
259 {
|
|
260 GList *iter = g_list_find(box->focus, box->active);
|
|
261 if (!iter)
|
|
262 box->active = box->focus->data;
|
|
263 else if (!iter->prev)
|
|
264 box->active = g_list_last(box->focus)->data;
|
|
265 else
|
|
266 box->active = iter->prev->data;
|
|
267 if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
|
|
268 break;
|
|
269 } while (box->active != last);
|
|
270 }
|
|
271
|
|
272 static gboolean
|
|
273 gnt_box_key_pressed(GntWidget *widget, const char *text)
|
|
274 {
|
|
275 GntBox *box = GNT_BOX(widget);
|
|
276 GntWidget *now;
|
|
277
|
|
278 if (box->active == NULL && !find_focusable_widget(box))
|
|
279 return FALSE;
|
|
280
|
|
281 if (gnt_widget_key_pressed(box->active, text))
|
|
282 return TRUE;
|
|
283
|
|
284 now = box->active;
|
|
285
|
|
286 if (text[0] == 27)
|
|
287 {
|
|
288 if (strcmp(text, GNT_KEY_LEFT) == 0)
|
|
289 {
|
|
290 find_prev_focus(box);
|
|
291 }
|
|
292 else if (strcmp(text, GNT_KEY_RIGHT) == 0)
|
|
293 {
|
|
294 find_next_focus(box);
|
|
295 }
|
|
296 }
|
|
297 else if (text[0] == '\t')
|
|
298 {
|
|
299 find_next_focus(box);
|
|
300 }
|
|
301
|
|
302 if (now && now != box->active)
|
|
303 {
|
|
304 gnt_widget_set_focus(now, FALSE);
|
|
305 gnt_widget_set_focus(box->active, TRUE);
|
|
306 return TRUE;
|
|
307 }
|
|
308
|
|
309 return FALSE;
|
|
310 }
|
|
311
|
|
312 static void
|
|
313 gnt_box_lost_focus(GntWidget *widget)
|
|
314 {
|
|
315 GntWidget *w = GNT_BOX(widget)->active;
|
|
316 if (w)
|
|
317 gnt_widget_set_focus(w, FALSE);
|
|
318 gnt_widget_draw(widget);
|
|
319 }
|
|
320
|
|
321 static void
|
|
322 gnt_box_gained_focus(GntWidget *widget)
|
|
323 {
|
|
324 GntWidget *w = GNT_BOX(widget)->active;
|
|
325 if (w)
|
|
326 gnt_widget_set_focus(w, TRUE);
|
|
327 gnt_widget_draw(widget);
|
|
328 }
|
|
329
|
|
330 static void
|
|
331 gnt_box_destroy(GntWidget *w)
|
|
332 {
|
|
333 GntBox *box = GNT_BOX(w);
|
|
334
|
|
335 gnt_box_remove_all(box);
|
|
336 gnt_screen_release(w);
|
|
337 }
|
|
338
|
|
339 static void
|
|
340 gnt_box_expose(GntWidget *widget, int x, int y, int width, int height)
|
|
341 {
|
|
342 WINDOW *win = newwin(height, width, widget->priv.y + y, widget->priv.x + x);
|
|
343 copywin(widget->window, win, y, x, 0, 0, height - 1, width - 1, FALSE);
|
|
344 wrefresh(win);
|
|
345 delwin(win);
|
|
346 }
|
|
347
|
|
348 static gboolean
|
|
349 gnt_box_confirm_size(GntWidget *widget, int width, int height)
|
|
350 {
|
|
351 GList *iter;
|
|
352 GntBox *box = GNT_BOX(widget);
|
|
353 int wchange, hchange;
|
|
354
|
|
355 if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
|
|
356 return FALSE;
|
|
357 if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
|
|
358 return FALSE;
|
|
359
|
|
360 if (!box->list)
|
|
361 return TRUE;
|
|
362
|
|
363 wchange = widget->priv.width - width;
|
|
364 hchange = widget->priv.height - height;
|
|
365
|
|
366 if (wchange == 0 && hchange == 0)
|
|
367 return TRUE; /* Quit playing games */
|
|
368
|
|
369 /* XXX: Right now, I am trying to just apply all the changes to
|
|
370 * just one widget. It should be possible to distribute the
|
|
371 * changes to all the widgets in the box. */
|
|
372 for (iter = box->list; iter; iter = iter->next)
|
|
373 {
|
|
374 GntWidget *wid = iter->data;
|
|
375 int w, h;
|
|
376
|
|
377 gnt_widget_get_size(wid, &w, &h);
|
|
378
|
|
379 if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
|
|
380 {
|
|
381 GList *i;
|
|
382
|
|
383 for (i = box->list; i; i = i->next)
|
|
384 {
|
|
385 int tw, th;
|
|
386 if (i == iter) continue;
|
|
387 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
|
|
388 if (box->vertical)
|
|
389 {
|
|
390 if (!gnt_widget_confirm_size(i->data, tw - wchange, th))
|
|
391 return FALSE;
|
|
392 }
|
|
393 else
|
|
394 {
|
|
395 if (!gnt_widget_confirm_size(i->data, tw, th - hchange))
|
|
396 return FALSE;
|
|
397 }
|
|
398 }
|
|
399 #if 0
|
|
400 gnt_widget_set_size(wid, w - wchange, h - hchange);
|
|
401 if (box->vertical)
|
|
402 hchange = 0;
|
|
403 else
|
|
404 wchange = 0;
|
|
405
|
|
406 for (i = box->list; i; i = i->next)
|
|
407 {
|
|
408 int tw, th;
|
|
409 if (i == iter) continue;
|
|
410 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
|
|
411 gnt_widget_set_size(i->data, tw - wchange, th - hchange);
|
|
412 }
|
|
413 #endif
|
|
414 g_object_set_data(G_OBJECT(box), "size-queued", wid);
|
|
415 return TRUE;
|
|
416 }
|
|
417 }
|
|
418
|
|
419 return FALSE;
|
|
420 }
|
|
421
|
|
422 static void
|
|
423 gnt_box_size_changed(GntWidget *widget, int oldw, int oldh)
|
|
424 {
|
|
425 int wchange, hchange;
|
|
426 GList *i;
|
|
427 GntBox *box = GNT_BOX(widget);
|
|
428 GntWidget *wid;
|
|
429 int tw, th;
|
|
430
|
|
431 wchange = widget->priv.width - oldw;
|
|
432 hchange = widget->priv.height - oldh;
|
|
433
|
|
434 wid = g_object_get_data(G_OBJECT(box), "size-queued");
|
|
435 if (wid)
|
|
436 {
|
|
437 gnt_widget_get_size(wid, &tw, &th);
|
|
438 gnt_widget_set_size(wid, tw + wchange, th + hchange);
|
|
439 g_object_set_data(G_OBJECT(box), "size-queued", NULL);
|
|
440 }
|
|
441
|
|
442 if (box->vertical)
|
|
443 hchange = 0;
|
|
444 else
|
|
445 wchange = 0;
|
|
446
|
|
447 for (i = box->list; i; i = i->next)
|
|
448 {
|
|
449 if (wid != i->data)
|
|
450 {
|
|
451 gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
|
|
452 gnt_widget_set_size(i->data, tw + wchange, th + hchange);
|
|
453 }
|
|
454 }
|
|
455
|
|
456 reposition_children(widget);
|
|
457 }
|
|
458
|
|
459 static gboolean
|
|
460 gnt_box_clicked(GntWidget *widget, GntMouseEvent event, int cx, int cy)
|
|
461 {
|
|
462 GList *iter;
|
|
463 for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) {
|
|
464 int x, y, w, h;
|
|
465 GntWidget *wid = iter->data;
|
|
466
|
|
467 gnt_widget_get_position(wid, &x, &y);
|
|
468 gnt_widget_get_size(wid, &w, &h);
|
|
469
|
|
470 if (cx >= x && cx < x + w && cy >= y && cy < y + h) {
|
|
471 if (event <= GNT_MIDDLE_MOUSE_DOWN &&
|
|
472 GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_CAN_TAKE_FOCUS)) {
|
|
473 while (widget->parent)
|
|
474 widget = widget->parent;
|
|
475 gnt_box_give_focus_to_child(GNT_BOX(widget), wid);
|
|
476 }
|
|
477 return gnt_widget_clicked(wid, event, cx, cy);
|
|
478 }
|
|
479 }
|
|
480 return FALSE;
|
|
481 }
|
|
482
|
|
483 static void
|
|
484 gnt_box_class_init(GntBoxClass *klass)
|
|
485 {
|
|
486 parent_class = GNT_WIDGET_CLASS(klass);
|
|
487 parent_class->destroy = gnt_box_destroy;
|
|
488 parent_class->draw = gnt_box_draw;
|
|
489 parent_class->expose = gnt_box_expose;
|
|
490 parent_class->map = gnt_box_map;
|
|
491 parent_class->size_request = gnt_box_size_request;
|
|
492 parent_class->set_position = gnt_box_set_position;
|
|
493 parent_class->key_pressed = gnt_box_key_pressed;
|
|
494 parent_class->clicked = gnt_box_clicked;
|
|
495 parent_class->lost_focus = gnt_box_lost_focus;
|
|
496 parent_class->gained_focus = gnt_box_gained_focus;
|
|
497 parent_class->confirm_size = gnt_box_confirm_size;
|
|
498 parent_class->size_changed = gnt_box_size_changed;
|
|
499
|
|
500 GNTDEBUG;
|
|
501 }
|
|
502
|
|
503 static void
|
|
504 gnt_box_init(GTypeInstance *instance, gpointer class)
|
|
505 {
|
|
506 GntWidget *widget = GNT_WIDGET(instance);
|
|
507 GntBox *box = GNT_BOX(widget);
|
|
508 /* Initially make both the height and width resizable.
|
|
509 * Update the flags as necessary when widgets are added to it. */
|
|
510 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
|
|
511 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
|
|
512 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
|
|
513 box->pad = 1;
|
|
514 box->fill = TRUE;
|
|
515 GNTDEBUG;
|
|
516 }
|
|
517
|
|
518 /******************************************************************************
|
|
519 * GntBox API
|
|
520 *****************************************************************************/
|
|
521 GType
|
|
522 gnt_box_get_gtype(void)
|
|
523 {
|
|
524 static GType type = 0;
|
|
525
|
|
526 if(type == 0)
|
|
527 {
|
|
528 static const GTypeInfo info = {
|
|
529 sizeof(GntBoxClass),
|
|
530 NULL, /* base_init */
|
|
531 NULL, /* base_finalize */
|
|
532 (GClassInitFunc)gnt_box_class_init,
|
|
533 NULL, /* class_finalize */
|
|
534 NULL, /* class_data */
|
|
535 sizeof(GntBox),
|
|
536 0, /* n_preallocs */
|
|
537 gnt_box_init, /* instance_init */
|
|
538 NULL /* value_table */
|
|
539 };
|
|
540
|
|
541 type = g_type_register_static(GNT_TYPE_WIDGET,
|
|
542 "GntBox",
|
|
543 &info, 0);
|
|
544 }
|
|
545
|
|
546 return type;
|
|
547 }
|
|
548
|
|
549 GntWidget *gnt_box_new(gboolean homo, gboolean vert)
|
|
550 {
|
|
551 GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL);
|
|
552 GntBox *box = GNT_BOX(widget);
|
|
553
|
|
554 box->homogeneous = homo;
|
|
555 box->vertical = vert;
|
|
556 box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID;
|
|
557
|
|
558 return widget;
|
|
559 }
|
|
560
|
|
561 void gnt_box_add_widget(GntBox *b, GntWidget *widget)
|
|
562 {
|
|
563 b->list = g_list_append(b->list, widget);
|
|
564 widget->parent = GNT_WIDGET(b);
|
|
565
|
|
566 if (b->vertical)
|
|
567 {
|
|
568 if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
|
|
569 GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_X);
|
|
570 }
|
|
571 else
|
|
572 {
|
|
573 if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
|
|
574 GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_Y);
|
|
575 }
|
|
576 }
|
|
577
|
|
578 void gnt_box_set_title(GntBox *b, const char *title)
|
|
579 {
|
|
580 char *prev = b->title;
|
|
581 GntWidget *w = GNT_WIDGET(b);
|
|
582 b->title = g_strdup(title);
|
|
583 if (w->window && !GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_NO_BORDER)) {
|
|
584 /* Erase the old title */
|
|
585 int pos, right;
|
|
586 get_title_thingies(b, prev, &pos, &right);
|
|
587 mvwhline(w->window, 0, pos - 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
|
|
588 right - pos + 2);
|
|
589 g_free(prev);
|
|
590 }
|
|
591 }
|
|
592
|
|
593 void gnt_box_set_pad(GntBox *box, int pad)
|
|
594 {
|
|
595 box->pad = pad;
|
|
596 /* XXX: Perhaps redraw if already showing? */
|
|
597 }
|
|
598
|
|
599 void gnt_box_set_toplevel(GntBox *box, gboolean set)
|
|
600 {
|
|
601 GntWidget *widget = GNT_WIDGET(box);
|
|
602 if (set)
|
|
603 {
|
|
604 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
|
|
605 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
|
|
606 }
|
|
607 else
|
|
608 {
|
|
609 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
|
|
610 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
|
|
611 }
|
|
612 }
|
|
613
|
|
614 void gnt_box_sync_children(GntBox *box)
|
|
615 {
|
|
616 GList *iter;
|
|
617 GntWidget *widget = GNT_WIDGET(box);
|
|
618 int pos = 1;
|
|
619
|
|
620 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
|
|
621 pos = 0;
|
|
622
|
|
623 for (iter = box->list; iter; iter = iter->next)
|
|
624 {
|
|
625 GntWidget *w = GNT_WIDGET(iter->data);
|
|
626 int height, width;
|
|
627 int x, y;
|
|
628
|
|
629 if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_INVISIBLE))
|
|
630 continue;
|
|
631
|
|
632 if (GNT_IS_BOX(w))
|
|
633 gnt_box_sync_children(GNT_BOX(w));
|
|
634
|
|
635 gnt_widget_get_size(w, &width, &height);
|
|
636
|
|
637 x = w->priv.x - widget->priv.x;
|
|
638 y = w->priv.y - widget->priv.y;
|
|
639
|
|
640 if (box->vertical)
|
|
641 {
|
|
642 x = pos;
|
|
643 if (box->alignment == GNT_ALIGN_RIGHT)
|
|
644 x += widget->priv.width - width;
|
|
645 else if (box->alignment == GNT_ALIGN_MID)
|
|
646 x += (widget->priv.width - width)/2;
|
|
647 if (x + width > widget->priv.width - pos)
|
|
648 x -= x + width - (widget->priv.width - pos);
|
|
649 }
|
|
650 else
|
|
651 {
|
|
652 y = pos;
|
|
653 if (box->alignment == GNT_ALIGN_BOTTOM)
|
|
654 y += widget->priv.height - height;
|
|
655 else if (box->alignment == GNT_ALIGN_MID)
|
|
656 y += (widget->priv.height - height)/2;
|
|
657 if (y + height >= widget->priv.height - pos)
|
|
658 y = widget->priv.height - height - pos;
|
|
659 }
|
|
660
|
|
661 copywin(w->window, widget->window, 0, 0,
|
|
662 y, x, y + height - 1, x + width - 1, FALSE);
|
|
663 gnt_widget_set_position(w, x + widget->priv.x, y + widget->priv.y);
|
|
664 }
|
|
665 }
|
|
666
|
|
667 void gnt_box_set_alignment(GntBox *box, GntAlignment alignment)
|
|
668 {
|
|
669 box->alignment = alignment;
|
|
670 }
|
|
671
|
|
672 void gnt_box_remove(GntBox *box, GntWidget *widget)
|
|
673 {
|
|
674 box->list = g_list_remove(box->list, widget);
|
|
675 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)
|
|
676 && GNT_WIDGET(box)->parent == NULL && box->focus)
|
|
677 {
|
|
678 if (widget == box->active)
|
|
679 {
|
|
680 find_next_focus(box);
|
|
681 if (box->active == widget) /* There's only one widget */
|
|
682 box->active = NULL;
|
|
683 }
|
|
684 box->focus = g_list_remove(box->focus, widget);
|
|
685 }
|
|
686
|
|
687 if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(box), GNT_WIDGET_MAPPED))
|
|
688 gnt_widget_draw(GNT_WIDGET(box));
|
|
689 }
|
|
690
|
|
691 void gnt_box_remove_all(GntBox *box)
|
|
692 {
|
|
693 g_list_foreach(box->list, (GFunc)gnt_widget_destroy, NULL);
|
|
694 g_list_free(box->list);
|
|
695 g_list_free(box->focus);
|
|
696 box->list = NULL;
|
|
697 box->focus = NULL;
|
|
698 GNT_WIDGET(box)->priv.width = 0;
|
|
699 GNT_WIDGET(box)->priv.height = 0;
|
|
700 }
|
|
701
|
|
702 void gnt_box_readjust(GntBox *box)
|
|
703 {
|
|
704 GList *iter;
|
|
705 GntWidget *wid;
|
|
706 int width, height;
|
|
707
|
|
708 if (GNT_WIDGET(box)->parent != NULL)
|
|
709 return;
|
|
710
|
|
711 for (iter = box->list; iter; iter = iter->next)
|
|
712 {
|
|
713 GntWidget *w = iter->data;
|
|
714 if (GNT_IS_BOX(w))
|
|
715 gnt_box_readjust(GNT_BOX(w));
|
|
716 else
|
|
717 {
|
|
718 GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_MAPPED);
|
|
719 w->priv.width = 0;
|
|
720 w->priv.height = 0;
|
|
721 }
|
|
722 }
|
|
723
|
|
724 wid = GNT_WIDGET(box);
|
|
725 GNT_WIDGET_UNSET_FLAGS(wid, GNT_WIDGET_MAPPED);
|
|
726 wid->priv.width = 0;
|
|
727 wid->priv.height = 0;
|
|
728
|
|
729 if (wid->parent == NULL)
|
|
730 {
|
|
731 g_list_free(box->focus);
|
|
732 box->focus = NULL;
|
|
733 box->active = NULL;
|
|
734 gnt_widget_size_request(wid);
|
|
735 gnt_widget_get_size(wid, &width, &height);
|
|
736 gnt_screen_resize_widget(wid, width, height);
|
|
737 find_focusable_widget(box);
|
|
738 }
|
|
739 }
|
|
740
|
|
741 void gnt_box_set_fill(GntBox *box, gboolean fill)
|
|
742 {
|
|
743 box->fill = fill;
|
|
744 }
|
|
745
|
|
746 void gnt_box_move_focus(GntBox *box, int dir)
|
|
747 {
|
|
748 GntWidget *now;
|
|
749
|
|
750 if (box->active == NULL)
|
|
751 {
|
|
752 find_focusable_widget(box);
|
|
753 return;
|
|
754 }
|
|
755
|
|
756 now = box->active;
|
|
757
|
|
758 if (dir == 1)
|
|
759 find_next_focus(box);
|
|
760 else if (dir == -1)
|
|
761 find_prev_focus(box);
|
|
762
|
|
763 if (now && now != box->active)
|
|
764 {
|
|
765 gnt_widget_set_focus(now, FALSE);
|
|
766 gnt_widget_set_focus(box->active, TRUE);
|
|
767 }
|
|
768
|
|
769 if (GNT_WIDGET(box)->window)
|
|
770 gnt_widget_draw(GNT_WIDGET(box));
|
|
771 }
|
|
772
|
|
773 void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget)
|
|
774 {
|
|
775 GList *find = g_list_find(box->focus, widget);
|
|
776 gpointer now = box->active;
|
|
777 if (find)
|
|
778 box->active = widget;
|
|
779 if (now && now != box->active)
|
|
780 {
|
|
781 gnt_widget_set_focus(now, FALSE);
|
|
782 gnt_widget_set_focus(box->active, TRUE);
|
|
783 }
|
|
784
|
|
785 if (GNT_WIDGET(box)->window)
|
|
786 gnt_widget_draw(GNT_WIDGET(box));
|
|
787 }
|
|
788
|