svg text alignment
[dia.git] / app / gtkwrapbox.c
blob97c759b1523456a918a575682316803029567ba7
1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GtkWrapBox: Wrapping box widget
5 * Copyright (C) 1999 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
22 #include <config.h>
24 #include <math.h>
26 #include "gtkwrapbox.h"
29 /* --- arguments --- */
30 enum {
31 ARG_0,
32 ARG_HOMOGENEOUS,
33 ARG_JUSTIFY,
34 ARG_HSPACING,
35 ARG_VSPACING,
36 ARG_LINE_JUSTIFY,
37 ARG_ASPECT_RATIO,
38 ARG_CURRENT_RATIO,
39 ARG_CHILD_LIMIT
41 enum {
42 CHILD_ARG_0,
43 CHILD_ARG_POSITION,
44 CHILD_ARG_HEXPAND,
45 CHILD_ARG_HFILL,
46 CHILD_ARG_VEXPAND,
47 CHILD_ARG_VFILL,
48 CHILD_ARG_FORCED_BREAK
52 /* --- prototypes --- */
53 static void gtk_wrap_box_class_init (GtkWrapBoxClass *klass);
54 static void gtk_wrap_box_init (GtkWrapBox *wbox);
55 static void gtk_wrap_box_get_arg (GtkObject *object,
56 GtkArg *arg,
57 guint arg_id);
58 static void gtk_wrap_box_set_arg (GtkObject *object,
59 GtkArg *arg,
60 guint arg_id);
61 static void gtk_wrap_box_set_child_arg (GtkContainer *container,
62 GtkWidget *child,
63 GtkArg *arg,
64 guint arg_id);
65 static void gtk_wrap_box_get_child_arg (GtkContainer *container,
66 GtkWidget *child,
67 GtkArg *arg,
68 guint arg_id);
69 static void gtk_wrap_box_map (GtkWidget *widget);
70 static void gtk_wrap_box_unmap (GtkWidget *widget);
71 static void gtk_wrap_box_draw (GtkWidget *widget,
72 GdkRectangle *area);
73 static gint gtk_wrap_box_expose (GtkWidget *widget,
74 GdkEventExpose *event);
75 static void gtk_wrap_box_add (GtkContainer *container,
76 GtkWidget *widget);
77 static void gtk_wrap_box_remove (GtkContainer *container,
78 GtkWidget *widget);
79 static void gtk_wrap_box_forall (GtkContainer *container,
80 gboolean include_internals,
81 GtkCallback callback,
82 gpointer callback_data);
83 static GtkType gtk_wrap_box_child_type (GtkContainer *container);
86 /* --- variables --- */
87 static gpointer parent_class = NULL;
90 /* --- functions --- */
91 GtkType
92 gtk_wrap_box_get_type (void)
94 static GtkType wrap_box_type = 0;
96 if (!wrap_box_type)
98 static const GtkTypeInfo wrap_box_info =
100 "GtkWrapBox",
101 sizeof (GtkWrapBox),
102 sizeof (GtkWrapBoxClass),
103 (GtkClassInitFunc) gtk_wrap_box_class_init,
104 (GtkObjectInitFunc) gtk_wrap_box_init,
105 /* reserved_1 */ NULL,
106 /* reserved_2 */ NULL,
107 (GtkClassInitFunc) NULL,
110 wrap_box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &wrap_box_info);
113 return wrap_box_type;
116 static void
117 gtk_wrap_box_class_init (GtkWrapBoxClass *class)
119 GtkObjectClass *object_class;
120 GtkWidgetClass *widget_class;
121 GtkContainerClass *container_class;
123 object_class = GTK_OBJECT_CLASS (class);
124 widget_class = GTK_WIDGET_CLASS (class);
125 container_class = GTK_CONTAINER_CLASS (class);
127 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
129 object_class->set_arg = gtk_wrap_box_set_arg;
130 object_class->get_arg = gtk_wrap_box_get_arg;
132 widget_class->map = gtk_wrap_box_map;
133 widget_class->unmap = gtk_wrap_box_unmap;
134 widget_class->draw = gtk_wrap_box_draw;
135 widget_class->expose_event = gtk_wrap_box_expose;
137 container_class->add = gtk_wrap_box_add;
138 container_class->remove = gtk_wrap_box_remove;
139 container_class->forall = gtk_wrap_box_forall;
140 container_class->child_type = gtk_wrap_box_child_type;
141 container_class->set_child_arg = gtk_wrap_box_set_child_arg;
142 container_class->get_child_arg = gtk_wrap_box_get_child_arg;
144 class->rlist_line_children = NULL;
146 gtk_object_add_arg_type ("GtkWrapBox::homogeneous",
147 GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
148 gtk_object_add_arg_type ("GtkWrapBox::justify",
149 GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_JUSTIFY);
150 gtk_object_add_arg_type ("GtkWrapBox::hspacing",
151 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_HSPACING);
152 gtk_object_add_arg_type ("GtkWrapBox::vspacing",
153 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_VSPACING);
154 gtk_object_add_arg_type ("GtkWrapBox::line_justify",
155 GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_LINE_JUSTIFY);
156 gtk_object_add_arg_type ("GtkWrapBox::aspect_ratio",
157 GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_ASPECT_RATIO);
158 gtk_object_add_arg_type ("GtkWrapBox::current_ratio",
159 GTK_TYPE_FLOAT, GTK_ARG_READABLE, ARG_CURRENT_RATIO);
160 gtk_object_add_arg_type ("GtkWrapBox::max_children_per_line",
161 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_CHILD_LIMIT);
162 gtk_container_add_child_arg_type ("GtkWrapBox::position",
163 GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
164 gtk_container_add_child_arg_type ("GtkWrapBox::hexpand",
165 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_HEXPAND);
166 gtk_container_add_child_arg_type ("GtkWrapBox::hfill",
167 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_HFILL);
168 gtk_container_add_child_arg_type ("GtkWrapBox::vexpand",
169 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_VEXPAND);
170 gtk_container_add_child_arg_type ("GtkWrapBox::vfill",
171 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_VFILL);
172 gtk_container_add_child_arg_type ("GtkWrapBox::forcebreak",
173 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_FORCED_BREAK);
176 static void
177 gtk_wrap_box_init (GtkWrapBox *wbox)
179 GTK_WIDGET_SET_FLAGS (wbox, GTK_NO_WINDOW);
181 wbox->homogeneous = FALSE;
182 wbox->hspacing = 0;
183 wbox->vspacing = 0;
184 wbox->justify = GTK_JUSTIFY_LEFT;
185 wbox->line_justify = GTK_JUSTIFY_BOTTOM;
186 wbox->n_children = 0;
187 wbox->children = NULL;
188 wbox->aspect_ratio = 1;
189 wbox->child_limit = 32767;
192 static void
193 gtk_wrap_box_set_arg (GtkObject *object,
194 GtkArg *arg,
195 guint arg_id)
197 GtkWrapBox *wbox = GTK_WRAP_BOX (object);
199 switch (arg_id)
201 case ARG_HOMOGENEOUS:
202 gtk_wrap_box_set_homogeneous (wbox, GTK_VALUE_BOOL (*arg));
203 break;
204 case ARG_JUSTIFY:
205 gtk_wrap_box_set_justify (wbox, GTK_VALUE_ENUM (*arg));
206 break;
207 case ARG_LINE_JUSTIFY:
208 gtk_wrap_box_set_line_justify (wbox, GTK_VALUE_ENUM (*arg));
209 break;
210 case ARG_HSPACING:
211 gtk_wrap_box_set_hspacing (wbox, GTK_VALUE_UINT (*arg));
212 break;
213 case ARG_VSPACING:
214 gtk_wrap_box_set_vspacing (wbox, GTK_VALUE_UINT (*arg));
215 break;
216 case ARG_ASPECT_RATIO:
217 gtk_wrap_box_set_aspect_ratio (wbox, GTK_VALUE_FLOAT (*arg));
218 break;
219 case ARG_CHILD_LIMIT:
220 if (wbox->child_limit != GTK_VALUE_UINT (*arg))
222 wbox->child_limit = CLAMP (GTK_VALUE_UINT (*arg), 1, 32767);
223 gtk_widget_queue_resize (GTK_WIDGET (wbox));
225 break;
229 static void
230 gtk_wrap_box_get_arg (GtkObject *object,
231 GtkArg *arg,
232 guint arg_id)
234 GtkWrapBox *wbox = GTK_WRAP_BOX (object);
235 GtkWidget *widget = GTK_WIDGET (object);
237 switch (arg_id)
239 case ARG_HOMOGENEOUS:
240 GTK_VALUE_BOOL (*arg) = wbox->homogeneous;
241 break;
242 case ARG_JUSTIFY:
243 GTK_VALUE_ENUM (*arg) = wbox->justify;
244 break;
245 case ARG_LINE_JUSTIFY:
246 GTK_VALUE_ENUM (*arg) = wbox->line_justify;
247 break;
248 case ARG_HSPACING:
249 GTK_VALUE_UINT (*arg) = wbox->hspacing;
250 break;
251 case ARG_VSPACING:
252 GTK_VALUE_UINT (*arg) = wbox->vspacing;
253 break;
254 case ARG_ASPECT_RATIO:
255 GTK_VALUE_FLOAT (*arg) = wbox->aspect_ratio;
256 break;
257 case ARG_CURRENT_RATIO:
258 GTK_VALUE_FLOAT (*arg) = (((gfloat) widget->allocation.width) /
259 ((gfloat) widget->allocation.height));
260 break;
261 case ARG_CHILD_LIMIT:
262 GTK_VALUE_UINT (*arg) = wbox->child_limit;
263 break;
264 default:
265 arg->type = GTK_TYPE_INVALID;
266 break;
270 static void
271 gtk_wrap_box_set_child_arg (GtkContainer *container,
272 GtkWidget *child,
273 GtkArg *arg,
274 guint arg_id)
276 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
277 gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
279 if (arg_id != CHILD_ARG_POSITION)
280 gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
282 switch (arg_id)
284 case CHILD_ARG_POSITION:
285 gtk_wrap_box_reorder_child (wbox, child, GTK_VALUE_INT (*arg));
286 break;
287 case CHILD_ARG_HEXPAND:
288 gtk_wrap_box_set_child_packing (wbox, child,
289 GTK_VALUE_BOOL (*arg), hfill,
290 vexpand, vfill);
291 break;
292 case CHILD_ARG_HFILL:
293 gtk_wrap_box_set_child_packing (wbox, child,
294 hexpand, GTK_VALUE_BOOL (*arg),
295 vexpand, vfill);
296 break;
297 case CHILD_ARG_VEXPAND:
298 gtk_wrap_box_set_child_packing (wbox, child,
299 hexpand, hfill,
300 GTK_VALUE_BOOL (*arg), vfill);
301 break;
302 case CHILD_ARG_VFILL:
303 gtk_wrap_box_set_child_packing (wbox, child,
304 hexpand, hfill,
305 vexpand, GTK_VALUE_BOOL (*arg));
306 break;
307 case CHILD_ARG_FORCED_BREAK:
308 gtk_wrap_box_set_child_forced_break (wbox, child,
309 GTK_VALUE_BOOL (*arg));
310 break;
311 default:
312 break;
316 static void
317 gtk_wrap_box_get_child_arg (GtkContainer *container,
318 GtkWidget *child,
319 GtkArg *arg,
320 guint arg_id)
322 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
323 gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
325 if (arg_id != CHILD_ARG_POSITION)
326 gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
328 switch (arg_id)
330 GtkWrapBoxChild *child_info;
331 case CHILD_ARG_POSITION:
332 GTK_VALUE_INT (*arg) = 0;
333 for (child_info = wbox->children; child_info; child_info = child_info->next)
335 if (child_info->widget == child)
336 break;
337 GTK_VALUE_INT (*arg)++;
339 if (!child_info)
340 GTK_VALUE_INT (*arg) = -1;
341 break;
342 case CHILD_ARG_HEXPAND:
343 GTK_VALUE_BOOL (*arg) = hexpand;
344 break;
345 case CHILD_ARG_HFILL:
346 GTK_VALUE_BOOL (*arg) = hfill;
347 break;
348 case CHILD_ARG_VEXPAND:
349 GTK_VALUE_BOOL (*arg) = vexpand;
350 break;
351 case CHILD_ARG_VFILL:
352 GTK_VALUE_BOOL (*arg) = vfill;
353 break;
354 default:
355 arg->type = GTK_TYPE_INVALID;
356 break;
360 static GtkType
361 gtk_wrap_box_child_type (GtkContainer *container)
363 return GTK_TYPE_WIDGET;
366 void
367 gtk_wrap_box_set_homogeneous (GtkWrapBox *wbox,
368 gboolean homogeneous)
370 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
372 homogeneous = homogeneous != FALSE;
373 if (wbox->homogeneous != homogeneous)
375 wbox->homogeneous = homogeneous;
376 gtk_widget_queue_resize (GTK_WIDGET (wbox));
380 void
381 gtk_wrap_box_set_hspacing (GtkWrapBox *wbox,
382 guint hspacing)
384 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
386 if (wbox->hspacing != hspacing)
388 wbox->hspacing = hspacing;
389 gtk_widget_queue_resize (GTK_WIDGET (wbox));
393 void
394 gtk_wrap_box_set_vspacing (GtkWrapBox *wbox,
395 guint vspacing)
397 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
399 if (wbox->vspacing != vspacing)
401 wbox->vspacing = vspacing;
402 gtk_widget_queue_resize (GTK_WIDGET (wbox));
406 void
407 gtk_wrap_box_set_justify (GtkWrapBox *wbox,
408 GtkJustification justify)
410 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
411 g_return_if_fail (justify <= GTK_JUSTIFY_FILL);
413 if (wbox->justify != justify)
415 wbox->justify = justify;
416 gtk_widget_queue_resize (GTK_WIDGET (wbox));
420 void
421 gtk_wrap_box_set_line_justify (GtkWrapBox *wbox,
422 GtkJustification line_justify)
424 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
425 g_return_if_fail (line_justify <= GTK_JUSTIFY_FILL);
427 if (wbox->line_justify != line_justify)
429 wbox->line_justify = line_justify;
430 gtk_widget_queue_resize (GTK_WIDGET (wbox));
434 void
435 gtk_wrap_box_set_aspect_ratio (GtkWrapBox *wbox,
436 gfloat aspect_ratio)
438 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
440 aspect_ratio = CLAMP (aspect_ratio, 1.0 / 256.0, 256.0);
442 if (wbox->aspect_ratio != aspect_ratio)
444 wbox->aspect_ratio = aspect_ratio;
445 gtk_widget_queue_resize (GTK_WIDGET (wbox));
449 void
450 gtk_wrap_box_pack (GtkWrapBox *wbox,
451 GtkWidget *child,
452 gboolean hexpand,
453 gboolean hfill,
454 gboolean vexpand,
455 gboolean vfill)
457 GtkWrapBoxChild *child_info;
459 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
460 g_return_if_fail (GTK_IS_WIDGET (child));
461 g_return_if_fail (child->parent == NULL);
463 child_info = g_new (GtkWrapBoxChild, 1);
464 child_info->widget = child;
465 child_info->hexpand = hexpand ? TRUE : FALSE;
466 child_info->hfill = hfill ? TRUE : FALSE;
467 child_info->vexpand = vexpand ? TRUE : FALSE;
468 child_info->vfill = vfill ? TRUE : FALSE;
469 child_info->forced_break = FALSE;
470 child_info->next = NULL;
471 if (wbox->children)
473 GtkWrapBoxChild *last = wbox->children;
475 while (last->next)
476 last = last->next;
477 last->next = child_info;
479 else
480 wbox->children = child_info;
481 wbox->n_children++;
483 gtk_widget_set_parent (child, GTK_WIDGET (wbox));
485 if (GTK_WIDGET_REALIZED (wbox))
486 gtk_widget_realize (child);
488 if (GTK_WIDGET_VISIBLE (wbox) && GTK_WIDGET_VISIBLE (child))
490 if (GTK_WIDGET_MAPPED (wbox))
491 gtk_widget_map (child);
493 gtk_widget_queue_resize (child);
497 void
498 gtk_wrap_box_reorder_child (GtkWrapBox *wbox,
499 GtkWidget *child,
500 gint position)
502 GtkWrapBoxChild *child_info, *last = NULL;
504 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
505 g_return_if_fail (GTK_IS_WIDGET (child));
507 for (child_info = wbox->children; child_info; last = child_info, child_info = last->next)
508 if (child_info->widget == child)
509 break;
511 if (child_info && wbox->children->next)
513 GtkWrapBoxChild *tmp;
515 if (last)
516 last->next = child_info->next;
517 else
518 wbox->children = child_info->next;
520 last = NULL;
521 tmp = wbox->children;
522 while (position && tmp->next)
524 position--;
525 last = tmp;
526 tmp = last->next;
529 if (position)
531 tmp->next = child_info;
532 child_info->next = NULL;
534 else
536 child_info->next = tmp;
537 if (last)
538 last->next = child_info;
539 else
540 wbox->children = child_info;
543 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
544 gtk_widget_queue_resize (child);
548 void
549 gtk_wrap_box_query_child_packing (GtkWrapBox *wbox,
550 GtkWidget *child,
551 gboolean *hexpand,
552 gboolean *hfill,
553 gboolean *vexpand,
554 gboolean *vfill)
556 GtkWrapBoxChild *child_info;
558 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
559 g_return_if_fail (GTK_IS_WIDGET (child));
561 for (child_info = wbox->children; child_info; child_info = child_info->next)
562 if (child_info->widget == child)
563 break;
565 if (child_info)
567 if (hexpand)
568 *hexpand = child_info->hexpand;
569 if (hfill)
570 *hfill = child_info->hfill;
571 if (vexpand)
572 *vexpand = child_info->vexpand;
573 if (vfill)
574 *vfill = child_info->vfill;
578 void
579 gtk_wrap_box_query_child_forced_break (GtkWrapBox *wbox,
580 GtkWidget *child,
581 gboolean *forced_break)
583 GtkWrapBoxChild *child_info;
585 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
586 g_return_if_fail (GTK_IS_WIDGET (child));
588 for (child_info = wbox->children; child_info; child_info = child_info->next)
589 if (child_info->widget == child)
590 break;
592 if (child_info)
594 if (forced_break)
595 *forced_break = child_info->forced_break;
599 void
600 gtk_wrap_box_set_child_packing (GtkWrapBox *wbox,
601 GtkWidget *child,
602 gboolean hexpand,
603 gboolean hfill,
604 gboolean vexpand,
605 gboolean vfill)
607 GtkWrapBoxChild *child_info;
609 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
610 g_return_if_fail (GTK_IS_WIDGET (child));
612 hexpand = hexpand != FALSE;
613 hfill = hfill != FALSE;
614 vexpand = vexpand != FALSE;
615 vfill = vfill != FALSE;
617 for (child_info = wbox->children; child_info; child_info = child_info->next)
618 if (child_info->widget == child)
619 break;
621 if (child_info &&
622 (child_info->hexpand != hexpand || child_info->vexpand != vexpand ||
623 child_info->hfill != hfill || child_info->vfill != vfill))
625 child_info->hexpand = hexpand;
626 child_info->hfill = hfill;
627 child_info->vexpand = vexpand;
628 child_info->vfill = vfill;
630 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
631 gtk_widget_queue_resize (child);
635 void
636 gtk_wrap_box_set_child_forced_break (GtkWrapBox *wbox,
637 GtkWidget *child,
638 gboolean forced_break)
640 GtkWrapBoxChild *child_info;
642 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
643 g_return_if_fail (GTK_IS_WIDGET (child));
645 forced_break = forced_break != FALSE;
647 for (child_info = wbox->children; child_info; child_info = child_info->next)
648 if (child_info->widget == child)
649 break;
651 if (child_info &&
652 (child_info->forced_break != forced_break))
654 child_info->forced_break = forced_break;
656 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
657 gtk_widget_queue_resize (child);
661 guint*
662 gtk_wrap_box_query_line_lengths (GtkWrapBox *wbox,
663 guint *_n_lines)
665 GtkWrapBoxChild *next_child = NULL;
666 GtkAllocation area, *allocation;
667 gboolean expand_line;
668 GSList *slist;
669 guint max_child_size, border, n_lines = 0, *lines = NULL;
671 if (_n_lines)
672 *_n_lines = 0;
673 g_return_val_if_fail (GTK_IS_WRAP_BOX (wbox), NULL);
675 allocation = &GTK_WIDGET (wbox)->allocation;
676 border = GTK_CONTAINER (wbox)->border_width;
677 area.x = allocation->x + border;
678 area.y = allocation->y + border;
679 area.width = MAX (1, (gint) allocation->width - border * 2);
680 area.height = MAX (1, (gint) allocation->height - border * 2);
682 next_child = wbox->children;
683 slist = GTK_WRAP_BOX_GET_CLASS (wbox)->rlist_line_children (wbox,
684 &next_child,
685 &area,
686 &max_child_size,
687 &expand_line);
688 while (slist)
690 guint l = n_lines++;
692 lines = g_renew (guint, lines, n_lines);
693 lines[l] = g_slist_length (slist);
694 g_slist_free (slist);
696 slist = GTK_WRAP_BOX_GET_CLASS (wbox)->rlist_line_children (wbox,
697 &next_child,
698 &area,
699 &max_child_size,
700 &expand_line);
703 if (_n_lines)
704 *_n_lines = n_lines;
706 return lines;
709 static void
710 gtk_wrap_box_map (GtkWidget *widget)
712 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
713 GtkWrapBoxChild *child;
715 GTK_WIDGET_SET_FLAGS (wbox, GTK_MAPPED);
717 for (child = wbox->children; child; child = child->next)
718 if (GTK_WIDGET_VISIBLE (child->widget) &&
719 !GTK_WIDGET_MAPPED (child->widget))
720 gtk_widget_map (child->widget);
723 static void
724 gtk_wrap_box_unmap (GtkWidget *widget)
726 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
727 GtkWrapBoxChild *child;
729 GTK_WIDGET_UNSET_FLAGS (wbox, GTK_MAPPED);
731 for (child = wbox->children; child; child = child->next)
732 if (GTK_WIDGET_VISIBLE (child->widget) &&
733 GTK_WIDGET_MAPPED (child->widget))
734 gtk_widget_unmap (child->widget);
737 static void
738 gtk_wrap_box_draw (GtkWidget *widget,
739 GdkRectangle *area)
741 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
742 GtkWrapBoxChild *child;
743 GdkRectangle child_area;
745 if (GTK_WIDGET_DRAWABLE (widget))
746 for (child = wbox->children; child; child = child->next)
747 if (GTK_WIDGET_DRAWABLE (child->widget) &&
748 gtk_widget_intersect (child->widget, area, &child_area))
749 gtk_widget_draw (child->widget, &child_area);
752 static gint
753 gtk_wrap_box_expose (GtkWidget *widget,
754 GdkEventExpose *event)
756 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
757 GtkWrapBoxChild *child;
758 GdkEventExpose child_event = *event;
760 g_return_val_if_fail (event != NULL, FALSE);
762 if (GTK_WIDGET_DRAWABLE (widget))
763 for (child = wbox->children; child; child = child->next)
764 if (GTK_WIDGET_DRAWABLE (child->widget) &&
765 GTK_WIDGET_NO_WINDOW (child->widget) &&
766 gtk_widget_intersect (child->widget, &event->area, &child_event.area))
767 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
769 return TRUE;
772 static void
773 gtk_wrap_box_add (GtkContainer *container,
774 GtkWidget *widget)
776 gtk_wrap_box_pack (GTK_WRAP_BOX (container), widget, FALSE, TRUE, FALSE, TRUE);
779 static void
780 gtk_wrap_box_remove (GtkContainer *container,
781 GtkWidget *widget)
783 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
784 GtkWrapBoxChild *child, *last = NULL;
786 child = wbox->children;
787 while (child)
789 if (child->widget == widget)
791 gboolean was_visible;
793 was_visible = GTK_WIDGET_VISIBLE (widget);
794 gtk_widget_unparent (widget);
796 if (last)
797 last->next = child->next;
798 else
799 wbox->children = child->next;
800 g_free (child);
801 wbox->n_children--;
803 if (was_visible)
804 gtk_widget_queue_resize (GTK_WIDGET (container));
806 break;
809 last = child;
810 child = last->next;
814 static void
815 gtk_wrap_box_forall (GtkContainer *container,
816 gboolean include_internals,
817 GtkCallback callback,
818 gpointer callback_data)
820 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
821 GtkWrapBoxChild *child;
823 child = wbox->children;
824 while (child)
826 GtkWidget *widget = child->widget;
828 child = child->next;
830 callback (widget, callback_data);