home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / gtkwrapbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-07  |  22.6 KB  |  831 lines

  1. /* GTK - The GIMP Toolkit
  2.  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  3.  *
  4.  * GtkWrapBox: Wrapping box widget
  5.  * Copyright (C) 1999 Tim Janik
  6.  *
  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.
  11.  *
  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.
  16.  *
  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.
  21.  */
  22. #include <math.h>
  23.  
  24. #include "gtkwrapbox.h"
  25.  
  26.  
  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
  38. };
  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
  47. };
  48.  
  49.  
  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);
  82.  
  83.  
  84. /* --- variables --- */
  85. static gpointer parent_class = NULL;
  86.  
  87.  
  88. /* --- functions --- */
  89. GtkType
  90. gtk_wrap_box_get_type (void)
  91. {
  92.   static GtkType wrap_box_type = 0;
  93.   
  94.   if (!wrap_box_type)
  95.     {
  96.       static const GtkTypeInfo wrap_box_info =
  97.       {
  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,
  106.       };
  107.       
  108.       wrap_box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &wrap_box_info);
  109.     }
  110.   
  111.   return wrap_box_type;
  112. }
  113.  
  114. static void
  115. gtk_wrap_box_class_init (GtkWrapBoxClass *class)
  116. {
  117.   GtkObjectClass *object_class;
  118.   GtkWidgetClass *widget_class;
  119.   GtkContainerClass *container_class;
  120.   
  121.   object_class = GTK_OBJECT_CLASS (class);
  122.   widget_class = GTK_WIDGET_CLASS (class);
  123.   container_class = GTK_CONTAINER_CLASS (class);
  124.   
  125.   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
  126.   
  127.   object_class->set_arg = gtk_wrap_box_set_arg;
  128.   object_class->get_arg = gtk_wrap_box_get_arg;
  129.   
  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;
  134.   
  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;
  141.  
  142.   class->rlist_line_children = NULL;
  143.   
  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);
  172. }
  173.  
  174. static void
  175. gtk_wrap_box_init (GtkWrapBox *wbox)
  176. {
  177.   GTK_WIDGET_SET_FLAGS (wbox, GTK_NO_WINDOW);
  178.   
  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;
  188. }
  189.  
  190. static void
  191. gtk_wrap_box_set_arg (GtkObject *object,
  192.               GtkArg    *arg,
  193.               guint      arg_id)
  194. {
  195.   GtkWrapBox *wbox = GTK_WRAP_BOX (object);
  196.   
  197.   switch (arg_id)
  198.     {
  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))
  219.     {
  220.       wbox->child_limit = CLAMP (GTK_VALUE_UINT (*arg), 1, 32767);
  221.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  222.     }
  223.       break;
  224.     }
  225. }
  226.  
  227. static void
  228. gtk_wrap_box_get_arg (GtkObject *object,
  229.               GtkArg    *arg,
  230.               guint      arg_id)
  231. {
  232.   GtkWrapBox *wbox = GTK_WRAP_BOX (object);
  233.   GtkWidget *widget = GTK_WIDGET (object);
  234.   
  235.   switch (arg_id)
  236.     {
  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;
  265.     }
  266. }
  267.  
  268. static void
  269. gtk_wrap_box_set_child_arg (GtkContainer *container,
  270.                 GtkWidget    *child,
  271.                 GtkArg       *arg,
  272.                 guint         arg_id)
  273. {
  274.   GtkWrapBox *wbox = GTK_WRAP_BOX (container);
  275.   gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
  276.   
  277.   if (arg_id != CHILD_ARG_POSITION)
  278.     gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
  279.   
  280.   switch (arg_id)
  281.     {
  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;
  311.     }
  312. }
  313.  
  314. static void
  315. gtk_wrap_box_get_child_arg (GtkContainer *container,
  316.                 GtkWidget    *child,
  317.                 GtkArg       *arg,
  318.                 guint         arg_id)
  319. {
  320.   GtkWrapBox *wbox = GTK_WRAP_BOX (container);
  321.   gboolean hexpand = FALSE, hfill = FALSE, vexpand = FALSE, vfill = FALSE;
  322.   
  323.   if (arg_id != CHILD_ARG_POSITION)
  324.     gtk_wrap_box_query_child_packing (wbox, child, &hexpand, &hfill, &vexpand, &vfill);
  325.   
  326.   switch (arg_id)
  327.     {
  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)
  332.     {
  333.       if (child_info->widget == child)
  334.         break;
  335.       GTK_VALUE_INT (*arg)++;
  336.     }
  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;
  355.     }
  356. }
  357.  
  358. static GtkType
  359. gtk_wrap_box_child_type    (GtkContainer *container)
  360. {
  361.   return GTK_TYPE_WIDGET;
  362. }
  363.  
  364. void
  365. gtk_wrap_box_set_homogeneous (GtkWrapBox *wbox,
  366.                   gboolean    homogeneous)
  367. {
  368.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  369.   
  370.   homogeneous = homogeneous != FALSE;
  371.   if (wbox->homogeneous != homogeneous)
  372.     {
  373.       wbox->homogeneous = homogeneous;
  374.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  375.     }
  376. }
  377.  
  378. void
  379. gtk_wrap_box_set_hspacing (GtkWrapBox *wbox,
  380.                guint       hspacing)
  381. {
  382.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  383.   
  384.   if (wbox->hspacing != hspacing)
  385.     {
  386.       wbox->hspacing = hspacing;
  387.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  388.     }
  389. }
  390.  
  391. void
  392. gtk_wrap_box_set_vspacing (GtkWrapBox *wbox,
  393.                guint       vspacing)
  394. {
  395.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  396.   
  397.   if (wbox->vspacing != vspacing)
  398.     {
  399.       wbox->vspacing = vspacing;
  400.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  401.     }
  402. }
  403.  
  404. void
  405. gtk_wrap_box_set_justify (GtkWrapBox      *wbox,
  406.               GtkJustification justify)
  407. {
  408.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  409.   g_return_if_fail (justify <= GTK_JUSTIFY_FILL);
  410.   
  411.   if (wbox->justify != justify)
  412.     {
  413.       wbox->justify = justify;
  414.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  415.     }
  416. }
  417.  
  418. void
  419. gtk_wrap_box_set_line_justify (GtkWrapBox      *wbox,
  420.                    GtkJustification line_justify)
  421. {
  422.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  423.   g_return_if_fail (line_justify <= GTK_JUSTIFY_FILL);
  424.   
  425.   if (wbox->line_justify != line_justify)
  426.     {
  427.       wbox->line_justify = line_justify;
  428.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  429.     }
  430. }
  431.  
  432. void
  433. gtk_wrap_box_set_aspect_ratio (GtkWrapBox *wbox,
  434.                    gfloat      aspect_ratio)
  435. {
  436.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  437.   
  438.   aspect_ratio = CLAMP (aspect_ratio, 1.0 / 256.0, 256.0);
  439.   
  440.   if (wbox->aspect_ratio != aspect_ratio)
  441.     {
  442.       wbox->aspect_ratio = aspect_ratio;
  443.       gtk_widget_queue_resize (GTK_WIDGET (wbox));
  444.     }
  445. }
  446.  
  447. void
  448. gtk_wrap_box_pack (GtkWrapBox *wbox,
  449.            GtkWidget  *child,
  450.            gboolean    hexpand,
  451.            gboolean    hfill,
  452.            gboolean    vexpand,
  453.            gboolean    vfill)
  454. {
  455.   GtkWrapBoxChild *child_info;
  456.   
  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);
  460.   
  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)
  470.     {
  471.       GtkWrapBoxChild *last = wbox->children;
  472.       
  473.       while (last->next)
  474.     last = last->next;
  475.       last->next = child_info;
  476.     }
  477.   else
  478.     wbox->children = child_info;
  479.   wbox->n_children++;
  480.   
  481.   gtk_widget_set_parent (child, GTK_WIDGET (wbox));
  482.   
  483.   if (GTK_WIDGET_REALIZED (wbox))
  484.     gtk_widget_realize (child);
  485.   
  486.   if (GTK_WIDGET_VISIBLE (wbox) && GTK_WIDGET_VISIBLE (child))
  487.     {
  488.       if (GTK_WIDGET_MAPPED (wbox))
  489.     gtk_widget_map (child);
  490.       
  491.       gtk_widget_queue_resize (child);
  492.     }
  493. }
  494.  
  495. void
  496. gtk_wrap_box_reorder_child (GtkWrapBox *wbox,
  497.                 GtkWidget  *child,
  498.                 gint        position)
  499. {
  500.   GtkWrapBoxChild *child_info, *last = NULL;
  501.   
  502.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  503.   g_return_if_fail (GTK_IS_WIDGET (child));
  504.   
  505.   for (child_info = wbox->children; child_info; last = child_info, child_info = last->next)
  506.     if (child_info->widget == child)
  507.       break;
  508.   
  509.   if (child_info && wbox->children->next)
  510.     {
  511.       GtkWrapBoxChild *tmp;
  512.       
  513.       if (last)
  514.     last->next = child_info->next;
  515.       else
  516.     wbox->children = child_info->next;
  517.       
  518.       last = NULL;
  519.       tmp = wbox->children;
  520.       while (position && tmp->next)
  521.     {
  522.       position--;
  523.       last = tmp;
  524.       tmp = last->next;
  525.     }
  526.       
  527.       if (position)
  528.     {
  529.       tmp->next = child_info;
  530.       child_info->next = NULL;
  531.     }
  532.       else
  533.     {
  534.       child_info->next = tmp;
  535.       if (last)
  536.         last->next = child_info;
  537.       else
  538.         wbox->children = child_info;
  539.     }
  540.       
  541.       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
  542.     gtk_widget_queue_resize (child);
  543.     }
  544. }
  545.  
  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)
  553. {
  554.   GtkWrapBoxChild *child_info;
  555.   
  556.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  557.   g_return_if_fail (GTK_IS_WIDGET (child));
  558.   
  559.   for (child_info = wbox->children; child_info; child_info = child_info->next)
  560.     if (child_info->widget == child)
  561.       break;
  562.   
  563.   if (child_info)
  564.     {
  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;
  573.     }
  574. }
  575.  
  576. void
  577. gtk_wrap_box_query_child_forced_break (GtkWrapBox *wbox,
  578.                        GtkWidget  *child,
  579.                        gboolean   *forced_break)
  580. {
  581.   GtkWrapBoxChild *child_info;
  582.   
  583.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  584.   g_return_if_fail (GTK_IS_WIDGET (child));
  585.   
  586.   for (child_info = wbox->children; child_info; child_info = child_info->next)
  587.     if (child_info->widget == child)
  588.       break;
  589.   
  590.   if (child_info)
  591.     {
  592.       if (forced_break)
  593.     *forced_break = child_info->forced_break;
  594.     }
  595. }
  596.  
  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)
  604. {
  605.   GtkWrapBoxChild *child_info;
  606.   
  607.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  608.   g_return_if_fail (GTK_IS_WIDGET (child));
  609.   
  610.   hexpand = hexpand != FALSE;
  611.   hfill = hfill != FALSE;
  612.   vexpand = vexpand != FALSE;
  613.   vfill = vfill != FALSE;
  614.   
  615.   for (child_info = wbox->children; child_info; child_info = child_info->next)
  616.     if (child_info->widget == child)
  617.       break;
  618.   
  619.   if (child_info &&
  620.       (child_info->hexpand != hexpand || child_info->vexpand != vexpand ||
  621.        child_info->hfill != hfill || child_info->vfill != vfill))
  622.     {
  623.       child_info->hexpand = hexpand;
  624.       child_info->hfill = hfill;
  625.       child_info->vexpand = vexpand;
  626.       child_info->vfill = vfill;
  627.       
  628.       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
  629.     gtk_widget_queue_resize (child);
  630.     }
  631. }
  632.  
  633. void
  634. gtk_wrap_box_set_child_forced_break (GtkWrapBox *wbox,
  635.                      GtkWidget  *child,
  636.                      gboolean    forced_break)
  637. {
  638.   GtkWrapBoxChild *child_info;
  639.   
  640.   g_return_if_fail (GTK_IS_WRAP_BOX (wbox));
  641.   g_return_if_fail (GTK_IS_WIDGET (child));
  642.   
  643.   forced_break = forced_break != FALSE;
  644.   
  645.   for (child_info = wbox->children; child_info; child_info = child_info->next)
  646.     if (child_info->widget == child)
  647.       break;
  648.   
  649.   if (child_info &&
  650.       (child_info->forced_break != forced_break))
  651.     {
  652.       child_info->forced_break = forced_break;
  653.       
  654.       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (wbox))
  655.     gtk_widget_queue_resize (child);
  656.     }
  657. }
  658.  
  659. guint*
  660. gtk_wrap_box_query_line_lengths (GtkWrapBox *wbox,
  661.                  guint      *_n_lines)
  662. {
  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;
  668.  
  669.   if (_n_lines)
  670.     *_n_lines = 0;
  671.   g_return_val_if_fail (GTK_IS_WRAP_BOX (wbox), NULL);
  672.  
  673.   allocation = >K_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);
  679.  
  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)
  687.     {
  688.       guint l = n_lines++;
  689.  
  690.       lines = g_renew (guint, lines, n_lines);
  691.       lines[l] = g_slist_length (slist);
  692.       g_slist_free (slist);
  693.  
  694.       slist = GTK_WRAP_BOX_GET_CLASS (wbox)->rlist_line_children (wbox,
  695.                                   &next_child,
  696.                                   &area,
  697.                                   &max_child_size,
  698.                                   &expand_line);
  699.     }
  700.  
  701.   if (_n_lines)
  702.     *_n_lines = n_lines;
  703.  
  704.   return lines;
  705. }
  706.  
  707. static void
  708. gtk_wrap_box_map (GtkWidget *widget)
  709. {
  710.   GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
  711.   GtkWrapBoxChild *child;
  712.   
  713.   GTK_WIDGET_SET_FLAGS (wbox, GTK_MAPPED);
  714.   
  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);
  719. }
  720.  
  721. static void
  722. gtk_wrap_box_unmap (GtkWidget *widget)
  723. {
  724.   GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
  725.   GtkWrapBoxChild *child;
  726.   
  727.   GTK_WIDGET_UNSET_FLAGS (wbox, GTK_MAPPED);
  728.   
  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);
  733. }
  734.  
  735. static void
  736. gtk_wrap_box_draw (GtkWidget    *widget,
  737.            GdkRectangle *area)
  738. {
  739.   GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
  740.   GtkWrapBoxChild *child;
  741.   GdkRectangle child_area;
  742.   
  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);
  748. }
  749.  
  750. static gint
  751. gtk_wrap_box_expose (GtkWidget      *widget,
  752.              GdkEventExpose *event)
  753. {
  754.   GtkWrapBox *wbox = GTK_WRAP_BOX (widget);
  755.   GtkWrapBoxChild *child;
  756.   GdkEventExpose child_event = *event;
  757.   
  758.   g_return_val_if_fail (event != NULL, FALSE);
  759.   
  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);
  766.   
  767.   return TRUE;
  768. }
  769.  
  770. static void
  771. gtk_wrap_box_add (GtkContainer *container,
  772.           GtkWidget    *widget)
  773. {
  774.   gtk_wrap_box_pack (GTK_WRAP_BOX (container), widget, FALSE, TRUE, FALSE, TRUE);
  775. }
  776.  
  777. static void
  778. gtk_wrap_box_remove (GtkContainer *container,
  779.              GtkWidget    *widget)
  780. {
  781.   GtkWrapBox *wbox = GTK_WRAP_BOX (container);
  782.   GtkWrapBoxChild *child, *last = NULL;
  783.   
  784.   child = wbox->children;
  785.   while (child)
  786.     {
  787.       if (child->widget == widget)
  788.     {
  789.       gboolean was_visible;
  790.       
  791.       was_visible = GTK_WIDGET_VISIBLE (widget);
  792.       gtk_widget_unparent (widget);
  793.       
  794.       if (last)
  795.         last->next = child->next;
  796.       else
  797.         wbox->children = child->next;
  798.       g_free (child);
  799.       wbox->n_children--;
  800.       
  801.       if (was_visible)
  802.         gtk_widget_queue_resize (GTK_WIDGET (container));
  803.       
  804.       break;
  805.     }
  806.       
  807.       last = child;
  808.       child = last->next;
  809.     }
  810. }
  811.  
  812. static void
  813. gtk_wrap_box_forall (GtkContainer *container,
  814.              gboolean      include_internals,
  815.              GtkCallback   callback,
  816.              gpointer      callback_data)
  817. {
  818.   GtkWrapBox *wbox = GTK_WRAP_BOX (container);
  819.   GtkWrapBoxChild *child;
  820.   
  821.   child = wbox->children;
  822.   while (child)
  823.     {
  824.       GtkWidget *widget = child->widget;
  825.       
  826.       child = child->next;
  827.       
  828.       callback (widget, callback_data);
  829.     }
  830. }
  831.