added gas bottle shape
[dia.git] / app / gtkwrapbox.c
blob90da770addcddc52c6b4b79d2079df33c1043899
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 <math.h>
24 #include "gtkwrapbox.h"
27 /* --- arguments --- */
28 enum {
29 ARG_0,
30 ARG_HOMOGENEOUS,
31 ARG_JUSTIFY,
32 ARG_HSPACING,
33 ARG_VSPACING,
34 ARG_LINE_JUSTIFY,
35 ARG_ASPECT_RATIO,
36 ARG_CURRENT_RATIO,
37 ARG_CHILD_LIMIT
39 enum {
40 CHILD_ARG_0,
41 CHILD_ARG_POSITION,
42 CHILD_ARG_HEXPAND,
43 CHILD_ARG_HFILL,
44 CHILD_ARG_VEXPAND,
45 CHILD_ARG_VFILL,
46 CHILD_ARG_FORCED_BREAK
50 /* --- prototypes --- */
51 static void gtk_wrap_box_class_init (GtkWrapBoxClass *klass);
52 static void gtk_wrap_box_init (GtkWrapBox *wbox);
53 static void gtk_wrap_box_get_arg (GtkObject *object,
54 GtkArg *arg,
55 guint arg_id);
56 static void gtk_wrap_box_set_arg (GtkObject *object,
57 GtkArg *arg,
58 guint arg_id);
59 static void gtk_wrap_box_set_child_arg (GtkContainer *container,
60 GtkWidget *child,
61 GtkArg *arg,
62 guint arg_id);
63 static void gtk_wrap_box_get_child_arg (GtkContainer *container,
64 GtkWidget *child,
65 GtkArg *arg,
66 guint arg_id);
67 static void gtk_wrap_box_map (GtkWidget *widget);
68 static void gtk_wrap_box_unmap (GtkWidget *widget);
69 static void gtk_wrap_box_draw (GtkWidget *widget,
70 GdkRectangle *area);
71 static gint gtk_wrap_box_expose (GtkWidget *widget,
72 GdkEventExpose *event);
73 static void gtk_wrap_box_add (GtkContainer *container,
74 GtkWidget *widget);
75 static void gtk_wrap_box_remove (GtkContainer *container,
76 GtkWidget *widget);
77 static void gtk_wrap_box_forall (GtkContainer *container,
78 gboolean include_internals,
79 GtkCallback callback,
80 gpointer callback_data);
81 static GtkType gtk_wrap_box_child_type (GtkContainer *container);
84 /* --- variables --- */
85 static gpointer parent_class = NULL;
88 /* --- functions --- */
89 GtkType
90 gtk_wrap_box_get_type (void)
92 static GtkType wrap_box_type = 0;
94 if (!wrap_box_type)
96 static const GtkTypeInfo wrap_box_info =
98 "GtkWrapBox",
99 sizeof (GtkWrapBox),
100 sizeof (GtkWrapBoxClass),
101 (GtkClassInitFunc) gtk_wrap_box_class_init,
102 (GtkObjectInitFunc) gtk_wrap_box_init,
103 /* reserved_1 */ NULL,
104 /* reserved_2 */ NULL,
105 (GtkClassInitFunc) NULL,
108 wrap_box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &wrap_box_info);
111 return wrap_box_type;
114 static void
115 gtk_wrap_box_class_init (GtkWrapBoxClass *class)
117 GtkObjectClass *object_class;
118 GtkWidgetClass *widget_class;
119 GtkContainerClass *container_class;
121 object_class = GTK_OBJECT_CLASS (class);
122 widget_class = GTK_WIDGET_CLASS (class);
123 container_class = GTK_CONTAINER_CLASS (class);
125 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
127 object_class->set_arg = gtk_wrap_box_set_arg;
128 object_class->get_arg = gtk_wrap_box_get_arg;
130 widget_class->map = gtk_wrap_box_map;
131 widget_class->unmap = gtk_wrap_box_unmap;
132 widget_class->draw = gtk_wrap_box_draw;
133 widget_class->expose_event = gtk_wrap_box_expose;
135 container_class->add = gtk_wrap_box_add;
136 container_class->remove = gtk_wrap_box_remove;
137 container_class->forall = gtk_wrap_box_forall;
138 container_class->child_type = gtk_wrap_box_child_type;
139 container_class->set_child_arg = gtk_wrap_box_set_child_arg;
140 container_class->get_child_arg = gtk_wrap_box_get_child_arg;
142 class->rlist_line_children = NULL;
144 gtk_object_add_arg_type ("GtkWrapBox::homogeneous",
145 GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
146 gtk_object_add_arg_type ("GtkWrapBox::justify",
147 GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_JUSTIFY);
148 gtk_object_add_arg_type ("GtkWrapBox::hspacing",
149 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_HSPACING);
150 gtk_object_add_arg_type ("GtkWrapBox::vspacing",
151 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_VSPACING);
152 gtk_object_add_arg_type ("GtkWrapBox::line_justify",
153 GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_LINE_JUSTIFY);
154 gtk_object_add_arg_type ("GtkWrapBox::aspect_ratio",
155 GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_ASPECT_RATIO);
156 gtk_object_add_arg_type ("GtkWrapBox::current_ratio",
157 GTK_TYPE_FLOAT, GTK_ARG_READABLE, ARG_CURRENT_RATIO);
158 gtk_object_add_arg_type ("GtkWrapBox::max_children_per_line",
159 GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_CHILD_LIMIT);
160 gtk_container_add_child_arg_type ("GtkWrapBox::position",
161 GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
162 gtk_container_add_child_arg_type ("GtkWrapBox::hexpand",
163 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_HEXPAND);
164 gtk_container_add_child_arg_type ("GtkWrapBox::hfill",
165 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_HFILL);
166 gtk_container_add_child_arg_type ("GtkWrapBox::vexpand",
167 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_VEXPAND);
168 gtk_container_add_child_arg_type ("GtkWrapBox::vfill",
169 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_VFILL);
170 gtk_container_add_child_arg_type ("GtkWrapBox::forcebreak",
171 GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_FORCED_BREAK);
174 static void
175 gtk_wrap_box_init (GtkWrapBox *wbox)
177 GTK_WIDGET_SET_FLAGS (wbox, GTK_NO_WINDOW);
179 wbox->homogeneous = FALSE;
180 wbox->hspacing = 0;
181 wbox->vspacing = 0;
182 wbox->justify = GTK_JUSTIFY_LEFT;
183 wbox->line_justify = GTK_JUSTIFY_BOTTOM;
184 wbox->n_children = 0;
185 wbox->children = NULL;
186 wbox->aspect_ratio = 1;
187 wbox->child_limit = 32767;
190 static void
191 gtk_wrap_box_set_arg (GtkObject *object,
192 GtkArg *arg,
193 guint arg_id)
195 GtkWrapBox *wbox = GTK_WRAP_BOX (object);
197 switch (arg_id)
199 case ARG_HOMOGENEOUS:
200 gtk_wrap_box_set_homogeneous (wbox, GTK_VALUE_BOOL (*arg));
201 break;
202 case ARG_JUSTIFY:
203 gtk_wrap_box_set_justify (wbox, GTK_VALUE_ENUM (*arg));
204 break;
205 case ARG_LINE_JUSTIFY:
206 gtk_wrap_box_set_line_justify (wbox, GTK_VALUE_ENUM (*arg));
207 break;
208 case ARG_HSPACING:
209 gtk_wrap_box_set_hspacing (wbox, GTK_VALUE_UINT (*arg));
210 break;
211 case ARG_VSPACING:
212 gtk_wrap_box_set_vspacing (wbox, GTK_VALUE_UINT (*arg));
213 break;
214 case ARG_ASPECT_RATIO:
215 gtk_wrap_box_set_aspect_ratio (wbox, GTK_VALUE_FLOAT (*arg));
216 break;
217 case ARG_CHILD_LIMIT:
218 if (wbox->child_limit != GTK_VALUE_UINT (*arg))
220 wbox->child_limit = CLAMP (GTK_VALUE_UINT (*arg), 1, 32767);
221 gtk_widget_queue_resize (GTK_WIDGET (wbox));
223 break;
227 static void
228 gtk_wrap_box_get_arg (GtkObject *object,
229 GtkArg *arg,
230 guint arg_id)
232 GtkWrapBox *wbox = GTK_WRAP_BOX (object);
233 GtkWidget *widget = GTK_WIDGET (object);
235 switch (arg_id)
237 case ARG_HOMOGENEOUS:
238 GTK_VALUE_BOOL (*arg) = wbox->homogeneous;
239 break;
240 case ARG_JUSTIFY:
241 GTK_VALUE_ENUM (*arg) = wbox->justify;
242 break;
243 case ARG_LINE_JUSTIFY:
244 GTK_VALUE_ENUM (*arg) = wbox->line_justify;
245 break;
246 case ARG_HSPACING:
247 GTK_VALUE_UINT (*arg) = wbox->hspacing;
248 break;
249 case ARG_VSPACING:
250 GTK_VALUE_UINT (*arg) = wbox->vspacing;
251 break;
252 case ARG_ASPECT_RATIO:
253 GTK_VALUE_FLOAT (*arg) = wbox->aspect_ratio;
254 break;
255 case ARG_CURRENT_RATIO:
256 GTK_VALUE_FLOAT (*arg) = (((gfloat) widget->allocation.width) /
257 ((gfloat) widget->allocation.height));
258 break;
259 case ARG_CHILD_LIMIT:
260 GTK_VALUE_UINT (*arg) = wbox->child_limit;
261 break;
262 default:
263 arg->type = GTK_TYPE_INVALID;
264 break;
268 static void
269 gtk_wrap_box_set_child_arg (GtkContainer *container,
270 GtkWidget *child,
271 GtkArg *arg,
272 guint arg_id)
274 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
275 gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
277 if (arg_id != CHILD_ARG_POSITION)
278 gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
280 switch (arg_id)
282 case CHILD_ARG_POSITION:
283 gtk_wrap_box_reorder_child (wbox, child, GTK_VALUE_INT (*arg));
284 break;
285 case CHILD_ARG_HEXPAND:
286 gtk_wrap_box_set_child_packing (wbox, child,
287 GTK_VALUE_BOOL (*arg), hfill,
288 vexpand, vfill);
289 break;
290 case CHILD_ARG_HFILL:
291 gtk_wrap_box_set_child_packing (wbox, child,
292 hexpand, GTK_VALUE_BOOL (*arg),
293 vexpand, vfill);
294 break;
295 case CHILD_ARG_VEXPAND:
296 gtk_wrap_box_set_child_packing (wbox, child,
297 hexpand, hfill,
298 GTK_VALUE_BOOL (*arg), vfill);
299 break;
300 case CHILD_ARG_VFILL:
301 gtk_wrap_box_set_child_packing (wbox, child,
302 hexpand, hfill,
303 vexpand, GTK_VALUE_BOOL (*arg));
304 break;
305 case CHILD_ARG_FORCED_BREAK:
306 gtk_wrap_box_set_child_forced_break (wbox, child,
307 GTK_VALUE_BOOL (*arg));
308 break;
309 default:
310 break;
314 static void
315 gtk_wrap_box_get_child_arg (GtkContainer *container,
316 GtkWidget *child,
317 GtkArg *arg,
318 guint arg_id)
320 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
321 gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
323 if (arg_id != CHILD_ARG_POSITION)
324 gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
326 switch (arg_id)
328 GtkWrapBoxChild *child_info;
329 case CHILD_ARG_POSITION:
330 GTK_VALUE_INT (*arg) = 0;
331 for (child_info = wbox->children; child_info; child_info = child_info->next)
333 if (child_info->widget == child)
334 break;
335 GTK_VALUE_INT (*arg)++;
337 if (!child_info)
338 GTK_VALUE_INT (*arg) = -1;
339 break;
340 case CHILD_ARG_HEXPAND:
341 GTK_VALUE_BOOL (*arg) = hexpand;
342 break;
343 case CHILD_ARG_HFILL:
344 GTK_VALUE_BOOL (*arg) = hfill;
345 break;
346 case CHILD_ARG_VEXPAND:
347 GTK_VALUE_BOOL (*arg) = vexpand;
348 break;
349 case CHILD_ARG_VFILL:
350 GTK_VALUE_BOOL (*arg) = vfill;
351 break;
352 default:
353 arg->type = GTK_TYPE_INVALID;
354 break;
358 static GtkType
359 gtk_wrap_box_child_type (GtkContainer *container)
361 return GTK_TYPE_WIDGET;
364 void
365 gtk_wrap_box_set_homogeneous (GtkWrapBox *wbox,
366 gboolean homogeneous)
368 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
370 homogeneous = homogeneous != FALSE;
371 if (wbox->homogeneous != homogeneous)
373 wbox->homogeneous = homogeneous;
374 gtk_widget_queue_resize (GTK_WIDGET (wbox));
378 void
379 gtk_wrap_box_set_hspacing (GtkWrapBox *wbox,
380 guint hspacing)
382 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
384 if (wbox->hspacing != hspacing)
386 wbox->hspacing = hspacing;
387 gtk_widget_queue_resize (GTK_WIDGET (wbox));
391 void
392 gtk_wrap_box_set_vspacing (GtkWrapBox *wbox,
393 guint vspacing)
395 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
397 if (wbox->vspacing != vspacing)
399 wbox->vspacing = vspacing;
400 gtk_widget_queue_resize (GTK_WIDGET (wbox));
404 void
405 gtk_wrap_box_set_justify (GtkWrapBox *wbox,
406 GtkJustification justify)
408 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
409 g_return_if_fail (justify <= GTK_JUSTIFY_FILL);
411 if (wbox->justify != justify)
413 wbox->justify = justify;
414 gtk_widget_queue_resize (GTK_WIDGET (wbox));
418 void
419 gtk_wrap_box_set_line_justify (GtkWrapBox *wbox,
420 GtkJustification line_justify)
422 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
423 g_return_if_fail (line_justify <= GTK_JUSTIFY_FILL);
425 if (wbox->line_justify != line_justify)
427 wbox->line_justify = line_justify;
428 gtk_widget_queue_resize (GTK_WIDGET (wbox));
432 void
433 gtk_wrap_box_set_aspect_ratio (GtkWrapBox *wbox,
434 gfloat aspect_ratio)
436 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
438 aspect_ratio = CLAMP (aspect_ratio, 1.0 / 256.0, 256.0);
440 if (wbox->aspect_ratio != aspect_ratio)
442 wbox->aspect_ratio = aspect_ratio;
443 gtk_widget_queue_resize (GTK_WIDGET (wbox));
447 void
448 gtk_wrap_box_pack (GtkWrapBox *wbox,
449 GtkWidget *child,
450 gboolean hexpand,
451 gboolean hfill,
452 gboolean vexpand,
453 gboolean vfill)
455 GtkWrapBoxChild *child_info;
457 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
458 g_return_if_fail (GTK_IS_WIDGET (child));
459 g_return_if_fail (child->parent == NULL);
461 child_info = g_new (GtkWrapBoxChild, 1);
462 child_info->widget = child;
463 child_info->hexpand = hexpand ? TRUE : FALSE;
464 child_info->hfill = hfill ? TRUE : FALSE;
465 child_info->vexpand = vexpand ? TRUE : FALSE;
466 child_info->vfill = vfill ? TRUE : FALSE;
467 child_info->forced_break = FALSE;
468 child_info->next = NULL;
469 if (wbox->children)
471 GtkWrapBoxChild *last = wbox->children;
473 while (last->next)
474 last = last->next;
475 last->next = child_info;
477 else
478 wbox->children = child_info;
479 wbox->n_children++;
481 gtk_widget_set_parent (child, GTK_WIDGET (wbox));
483 if (GTK_WIDGET_REALIZED (wbox))
484 gtk_widget_realize (child);
486 if (GTK_WIDGET_VISIBLE (wbox) && GTK_WIDGET_VISIBLE (child))
488 if (GTK_WIDGET_MAPPED (wbox))
489 gtk_widget_map (child);
491 gtk_widget_queue_resize (child);
495 void
496 gtk_wrap_box_reorder_child (GtkWrapBox *wbox,
497 GtkWidget *child,
498 gint position)
500 GtkWrapBoxChild *child_info, *last = NULL;
502 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
503 g_return_if_fail (GTK_IS_WIDGET (child));
505 for (child_info = wbox->children; child_info; last = child_info, child_info = last->next)
506 if (child_info->widget == child)
507 break;
509 if (child_info && wbox->children->next)
511 GtkWrapBoxChild *tmp;
513 if (last)
514 last->next = child_info->next;
515 else
516 wbox->children = child_info->next;
518 last = NULL;
519 tmp = wbox->children;
520 while (position && tmp->next)
522 position--;
523 last = tmp;
524 tmp = last->next;
527 if (position)
529 tmp->next = child_info;
530 child_info->next = NULL;
532 else
534 child_info->next = tmp;
535 if (last)
536 last->next = child_info;
537 else
538 wbox->children = child_info;
541 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
542 gtk_widget_queue_resize (child);
546 void
547 gtk_wrap_box_query_child_packing (GtkWrapBox *wbox,
548 GtkWidget *child,
549 gboolean *hexpand,
550 gboolean *hfill,
551 gboolean *vexpand,
552 gboolean *vfill)
554 GtkWrapBoxChild *child_info;
556 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
557 g_return_if_fail (GTK_IS_WIDGET (child));
559 for (child_info = wbox->children; child_info; child_info = child_info->next)
560 if (child_info->widget == child)
561 break;
563 if (child_info)
565 if (hexpand)
566 *hexpand = child_info->hexpand;
567 if (hfill)
568 *hfill = child_info->hfill;
569 if (vexpand)
570 *vexpand = child_info->vexpand;
571 if (vfill)
572 *vfill = child_info->vfill;
576 void
577 gtk_wrap_box_query_child_forced_break (GtkWrapBox *wbox,
578 GtkWidget *child,
579 gboolean *forced_break)
581 GtkWrapBoxChild *child_info;
583 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
584 g_return_if_fail (GTK_IS_WIDGET (child));
586 for (child_info = wbox->children; child_info; child_info = child_info->next)
587 if (child_info->widget == child)
588 break;
590 if (child_info)
592 if (forced_break)
593 *forced_break = child_info->forced_break;
597 void
598 gtk_wrap_box_set_child_packing (GtkWrapBox *wbox,
599 GtkWidget *child,
600 gboolean hexpand,
601 gboolean hfill,
602 gboolean vexpand,
603 gboolean vfill)
605 GtkWrapBoxChild *child_info;
607 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
608 g_return_if_fail (GTK_IS_WIDGET (child));
610 hexpand = hexpand != FALSE;
611 hfill = hfill != FALSE;
612 vexpand = vexpand != FALSE;
613 vfill = vfill != FALSE;
615 for (child_info = wbox->children; child_info; child_info = child_info->next)
616 if (child_info->widget == child)
617 break;
619 if (child_info &&
620 (child_info->hexpand != hexpand || child_info->vexpand != vexpand ||
621 child_info->hfill != hfill || child_info->vfill != vfill))
623 child_info->hexpand = hexpand;
624 child_info->hfill = hfill;
625 child_info->vexpand = vexpand;
626 child_info->vfill = vfill;
628 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
629 gtk_widget_queue_resize (child);
633 void
634 gtk_wrap_box_set_child_forced_break (GtkWrapBox *wbox,
635 GtkWidget *child,
636 gboolean forced_break)
638 GtkWrapBoxChild *child_info;
640 g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
641 g_return_if_fail (GTK_IS_WIDGET (child));
643 forced_break = forced_break != FALSE;
645 for (child_info = wbox->children; child_info; child_info = child_info->next)
646 if (child_info->widget == child)
647 break;
649 if (child_info &&
650 (child_info->forced_break != forced_break))
652 child_info->forced_break = forced_break;
654 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
655 gtk_widget_queue_resize (child);
659 guint*
660 gtk_wrap_box_query_line_lengths (GtkWrapBox *wbox,
661 guint *_n_lines)
663 GtkWrapBoxChild *next_child = NULL;
664 GtkAllocation area, *allocation;
665 gboolean expand_line;
666 GSList *slist;
667 guint max_child_size, border, n_lines = 0, *lines = NULL;
669 if (_n_lines)
670 *_n_lines = 0;
671 g_return_val_if_fail (GTK_IS_WRAP_BOX (wbox), NULL);
673 allocation = &GTK_WIDGET (wbox)->allocation;
674 border = GTK_CONTAINER (wbox)->border_width;
675 area.x = allocation->x + border;
676 area.y = allocation->y + border;
677 area.width = MAX (1, (gint) allocation->width - border * 2);
678 area.height = MAX (1, (gint) allocation->height - border * 2);
680 next_child = wbox->children;
681 slist = GTK_WRAP_BOX_GET_CLASS (wbox)->rlist_line_children (wbox,
682 &next_child,
683 &area,
684 &max_child_size,
685 &expand_line);
686 while (slist)
688 guint l = n_lines++;
690 lines = g_renew (guint, lines, n_lines);
691 lines[l] = g_slist_length (slist);
692 g_slist_free (slist);
694 slist = GTK_WRAP_BOX_GET_CLASS (wbox)->rlist_line_children (wbox,
695 &next_child,
696 &area,
697 &max_child_size,
698 &expand_line);
701 if (_n_lines)
702 *_n_lines = n_lines;
704 return lines;
707 static void
708 gtk_wrap_box_map (GtkWidget *widget)
710 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
711 GtkWrapBoxChild *child;
713 GTK_WIDGET_SET_FLAGS (wbox, GTK_MAPPED);
715 for (child = wbox->children; child; child = child->next)
716 if (GTK_WIDGET_VISIBLE (child->widget) &&
717 !GTK_WIDGET_MAPPED (child->widget))
718 gtk_widget_map (child->widget);
721 static void
722 gtk_wrap_box_unmap (GtkWidget *widget)
724 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
725 GtkWrapBoxChild *child;
727 GTK_WIDGET_UNSET_FLAGS (wbox, GTK_MAPPED);
729 for (child = wbox->children; child; child = child->next)
730 if (GTK_WIDGET_VISIBLE (child->widget) &&
731 GTK_WIDGET_MAPPED (child->widget))
732 gtk_widget_unmap (child->widget);
735 static void
736 gtk_wrap_box_draw (GtkWidget *widget,
737 GdkRectangle *area)
739 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
740 GtkWrapBoxChild *child;
741 GdkRectangle child_area;
743 if (GTK_WIDGET_DRAWABLE (widget))
744 for (child = wbox->children; child; child = child->next)
745 if (GTK_WIDGET_DRAWABLE (child->widget) &&
746 gtk_widget_intersect (child->widget, area, &child_area))
747 gtk_widget_draw (child->widget, &child_area);
750 static gint
751 gtk_wrap_box_expose (GtkWidget *widget,
752 GdkEventExpose *event)
754 GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
755 GtkWrapBoxChild *child;
756 GdkEventExpose child_event = *event;
758 g_return_val_if_fail (event != NULL, FALSE);
760 if (GTK_WIDGET_DRAWABLE (widget))
761 for (child = wbox->children; child; child = child->next)
762 if (GTK_WIDGET_DRAWABLE (child->widget) &&
763 GTK_WIDGET_NO_WINDOW (child->widget) &&
764 gtk_widget_intersect (child->widget, &event->area, &child_event.area))
765 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
767 return TRUE;
770 static void
771 gtk_wrap_box_add (GtkContainer *container,
772 GtkWidget *widget)
774 gtk_wrap_box_pack (GTK_WRAP_BOX (container), widget, FALSE, TRUE, FALSE, TRUE);
777 static void
778 gtk_wrap_box_remove (GtkContainer *container,
779 GtkWidget *widget)
781 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
782 GtkWrapBoxChild *child, *last = NULL;
784 child = wbox->children;
785 while (child)
787 if (child->widget == widget)
789 gboolean was_visible;
791 was_visible = GTK_WIDGET_VISIBLE (widget);
792 gtk_widget_unparent (widget);
794 if (last)
795 last->next = child->next;
796 else
797 wbox->children = child->next;
798 g_free (child);
799 wbox->n_children--;
801 if (was_visible)
802 gtk_widget_queue_resize (GTK_WIDGET (container));
804 break;
807 last = child;
808 child = last->next;
812 static void
813 gtk_wrap_box_forall (GtkContainer *container,
814 gboolean include_internals,
815 GtkCallback callback,
816 gpointer callback_data)
818 GtkWrapBox *wbox = GTK_WRAP_BOX (container);
819 GtkWrapBoxChild *child;
821 child = wbox->children;
822 while (child)
824 GtkWidget *widget = child->widget;
826 child = child->next;
828 callback (widget, callback_data);