* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#include "gtkbox.h"
ARG_HOMOGENEOUS
};
+enum {
+ CHILD_ARG_0,
+ CHILD_ARG_EXPAND,
+ CHILD_ARG_FILL,
+ CHILD_ARG_PADDING,
+ CHILD_ARG_PACK_TYPE,
+ CHILD_ARG_POSITION
+};
+
static void gtk_box_class_init (GtkBoxClass *klass);
static void gtk_box_init (GtkBox *box);
static void gtk_box_get_arg (GtkBox *box,
static void gtk_box_set_arg (GtkBox *box,
GtkArg *arg,
guint arg_id);
-static void gtk_box_destroy (GtkObject *object);
static void gtk_box_map (GtkWidget *widget);
static void gtk_box_unmap (GtkWidget *widget);
static void gtk_box_draw (GtkWidget *widget,
static void gtk_box_foreach (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
-
+static void gtk_box_set_child_arg (GtkContainer *container,
+ GtkWidget *child,
+ GtkArg *arg,
+ guint arg_id);
+static void gtk_box_get_child_arg (GtkContainer *container,
+ GtkWidget *child,
+ GtkArg *arg,
+ guint arg_id);
+static GtkType gtk_box_child_type (GtkContainer *container);
+
static GtkContainerClass *parent_class = NULL;
-guint
-gtk_box_get_type ()
+GtkType
+gtk_box_get_type (void)
{
- static guint box_type = 0;
+ static GtkType box_type = 0;
if (!box_type)
{
(GtkArgGetFunc) gtk_box_get_arg,
};
- box_type = gtk_type_unique (gtk_container_get_type (), &box_info);
+ box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &box_info);
}
return box_type;
widget_class = (GtkWidgetClass*) class;
container_class = (GtkContainerClass*) class;
- parent_class = gtk_type_class (gtk_container_get_type ());
+ parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
- gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, ARG_SPACING);
- gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, ARG_HOMOGENEOUS);
-
- object_class->destroy = gtk_box_destroy;
+ gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_SPACING);
+ gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
+ gtk_container_add_child_arg_type ("GtkBox::expand", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_EXPAND);
+ gtk_container_add_child_arg_type ("GtkBox::fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_FILL);
+ gtk_container_add_child_arg_type ("GtkBox::padding", GTK_TYPE_ULONG, GTK_ARG_READWRITE, CHILD_ARG_PADDING);
+ gtk_container_add_child_arg_type ("GtkBox::pack_type", GTK_TYPE_PACK_TYPE, GTK_ARG_READWRITE, CHILD_ARG_PACK_TYPE);
+ gtk_container_add_child_arg_type ("GtkBox::position", GTK_TYPE_LONG, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
widget_class->map = gtk_box_map;
widget_class->unmap = gtk_box_unmap;
container_class->add = gtk_box_add;
container_class->remove = gtk_box_remove;
container_class->foreach = gtk_box_foreach;
+ container_class->child_type = gtk_box_child_type;
+ container_class->set_child_arg = gtk_box_set_child_arg;
+ container_class->get_child_arg = gtk_box_get_child_arg;
}
static void
case ARG_HOMOGENEOUS:
gtk_box_set_homogeneous (box, GTK_VALUE_BOOL (*arg));
break;
+ default:
+ break;
}
}
}
}
+static GtkType
+gtk_box_child_type (GtkContainer *container)
+{
+ return GTK_TYPE_WIDGET;
+}
+
+static void
+gtk_box_set_child_arg (GtkContainer *container,
+ GtkWidget *child,
+ GtkArg *arg,
+ guint arg_id)
+{
+ gboolean expand = 0;
+ gboolean fill = 0;
+ guint padding = 0;
+ GtkPackType pack_type = 0;
+
+ if (arg_id != CHILD_ARG_POSITION)
+ gtk_box_query_child_packing (GTK_BOX (container),
+ child,
+ &expand,
+ &fill,
+ &padding,
+ &pack_type);
+
+ switch (arg_id)
+ {
+ case CHILD_ARG_EXPAND:
+ gtk_box_set_child_packing (GTK_BOX (container),
+ child,
+ GTK_VALUE_BOOL (*arg),
+ fill,
+ padding,
+ pack_type);
+ break;
+ case CHILD_ARG_FILL:
+ gtk_box_set_child_packing (GTK_BOX (container),
+ child,
+ expand,
+ GTK_VALUE_BOOL (*arg),
+ padding,
+ pack_type);
+ break;
+ case CHILD_ARG_PADDING:
+ gtk_box_set_child_packing (GTK_BOX (container),
+ child,
+ expand,
+ fill,
+ GTK_VALUE_ULONG (*arg),
+ pack_type);
+ break;
+ case CHILD_ARG_PACK_TYPE:
+ gtk_box_set_child_packing (GTK_BOX (container),
+ child,
+ expand,
+ fill,
+ padding,
+ GTK_VALUE_ENUM (*arg));
+ break;
+ case CHILD_ARG_POSITION:
+ gtk_box_reorder_child (GTK_BOX (container),
+ child,
+ GTK_VALUE_LONG (*arg));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gtk_box_get_child_arg (GtkContainer *container,
+ GtkWidget *child,
+ GtkArg *arg,
+ guint arg_id)
+{
+ gboolean expand = 0;
+ gboolean fill = 0;
+ guint padding = 0;
+ GtkPackType pack_type = 0;
+ GList *list;
+
+ if (arg_id != CHILD_ARG_POSITION)
+ gtk_box_query_child_packing (GTK_BOX (container),
+ child,
+ &expand,
+ &fill,
+ &padding,
+ &pack_type);
+
+ switch (arg_id)
+ {
+ case CHILD_ARG_EXPAND:
+ GTK_VALUE_BOOL (*arg) = expand;
+ break;
+ case CHILD_ARG_FILL:
+ GTK_VALUE_BOOL (*arg) = fill;
+ break;
+ case CHILD_ARG_PADDING:
+ GTK_VALUE_ULONG (*arg) = padding;
+ break;
+ case CHILD_ARG_PACK_TYPE:
+ GTK_VALUE_ENUM (*arg) = pack_type;
+ break;
+ case CHILD_ARG_POSITION:
+ GTK_VALUE_LONG (*arg) = 0;
+ for (list = GTK_BOX (container)->children; list; list = list->next)
+ {
+ GtkBoxChild *child_entry;
+
+ child_entry = list->data;
+ if (child_entry->widget == child)
+ break;
+ GTK_VALUE_LONG (*arg)++;
+ }
+ if (!list)
+ GTK_VALUE_LONG (*arg) = -1;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
void
gtk_box_pack_start (GtkBox *box,
GtkWidget *child,
- gint expand,
- gint fill,
- gint padding)
+ gboolean expand,
+ gboolean fill,
+ guint padding)
{
GtkBoxChild *child_info;
g_return_if_fail (box != NULL);
g_return_if_fail (GTK_IS_BOX (box));
g_return_if_fail (child != NULL);
+ g_return_if_fail (child->parent == NULL);
child_info = g_new (GtkBoxChild, 1);
child_info->widget = child;
void
gtk_box_pack_end (GtkBox *box,
GtkWidget *child,
- gint expand,
- gint fill,
- gint padding)
+ gboolean expand,
+ gboolean fill,
+ guint padding)
{
GtkBoxChild *child_info;
g_return_if_fail (box != NULL);
g_return_if_fail (GTK_IS_BOX (box));
g_return_if_fail (child != NULL);
+ g_return_if_fail (child->parent == NULL);
child_info = g_new (GtkBoxChild, 1);
child_info->widget = child;
}
void
-gtk_box_set_homogeneous (GtkBox *box,
- gint homogeneous)
+gtk_box_set_homogeneous (GtkBox *box,
+ gboolean homogeneous)
{
g_return_if_fail (box != NULL);
g_return_if_fail (GTK_IS_BOX (box));
}
}
-
-static void
-gtk_box_destroy (GtkObject *object)
+void
+gtk_box_reorder_child (GtkBox *box,
+ GtkWidget *child,
+ gint position)
{
- GtkBox *box;
- GtkBoxChild *child;
- GList *children;
+ GList *list;
- g_return_if_fail (object != NULL);
- g_return_if_fail (GTK_IS_BOX (object));
+ g_return_if_fail (box != NULL);
+ g_return_if_fail (GTK_IS_BOX (box));
+ g_return_if_fail (child != NULL);
- box = GTK_BOX (object);
+ list = box->children;
+ while (list)
+ {
+ GtkBoxChild *child_info;
- children = box->children;
- while (children)
+ child_info = list->data;
+ if (child_info->widget == child)
+ break;
+
+ list = list->next;
+ }
+
+ if (list && box->children->next)
{
- child = children->data;
- children = children->next;
+ GList *tmp_list;
+
+ if (list->next)
+ list->next->prev = list->prev;
+ if (list->prev)
+ list->prev->next = list->next;
+ else
+ box->children = list->next;
+
+ tmp_list = box->children;
+ while (position && tmp_list->next)
+ {
+ position--;
+ tmp_list = tmp_list->next;
+ }
+
+ if (position)
+ {
+ tmp_list->next = list;
+ list->prev = tmp_list;
+ list->next = NULL;
+ }
+ else
+ {
+ if (tmp_list->prev)
+ tmp_list->prev->next = list;
+ else
+ box->children = list;
+ list->prev = tmp_list->prev;
+ tmp_list->prev = list;
+ list->next = tmp_list;
+ }
+
+ if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
+ gtk_widget_queue_resize (child);
+ }
+}
+
+void
+gtk_box_query_child_packing (GtkBox *box,
+ GtkWidget *child,
+ gboolean *expand,
+ gboolean *fill,
+ guint *padding,
+ GtkPackType *pack_type)
+{
+ GList *list;
+ GtkBoxChild *child_info;
+
+ g_return_if_fail (box != NULL);
+ g_return_if_fail (GTK_IS_BOX (box));
+ g_return_if_fail (child != NULL);
+
+ list = box->children;
+ while (list)
+ {
+ child_info = list->data;
+ if (child_info->widget == child)
+ break;
- child->widget->parent = NULL;
- gtk_object_unref (GTK_OBJECT (child->widget));
- gtk_widget_destroy (child->widget);
- g_free (child);
+ list = list->next;
}
- g_list_free (box->children);
+ if (list)
+ {
+ if (expand)
+ *expand = child_info->expand;
+ if (fill)
+ *fill = child_info->fill;
+ if (padding)
+ *padding = child_info->padding;
+ if (pack_type)
+ *pack_type = child_info->pack;
+ }
+}
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+void
+gtk_box_set_child_packing (GtkBox *box,
+ GtkWidget *child,
+ gboolean expand,
+ gboolean fill,
+ guint padding,
+ GtkPackType pack_type)
+{
+ GList *list;
+ GtkBoxChild *child_info;
+
+ g_return_if_fail (box != NULL);
+ g_return_if_fail (GTK_IS_BOX (box));
+ g_return_if_fail (child != NULL);
+
+ list = box->children;
+ while (list)
+ {
+ child_info = list->data;
+ if (child_info->widget == child)
+ break;
+
+ list = list->next;
+ }
+
+ if (list)
+ {
+ child_info->expand = expand != FALSE;
+ child_info->fill = fill != FALSE;
+ child_info->padding = padding;
+ if (pack_type == GTK_PACK_END)
+ child_info->pack = GTK_PACK_END;
+ else
+ child_info->pack = GTK_PACK_START;
+
+ if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
+ gtk_widget_queue_resize (child);
+ }
}
static void
if (child->widget == widget)
{
+ gboolean was_visible;
+
+ was_visible = GTK_WIDGET_VISIBLE (widget);
gtk_widget_unparent (widget);
box->children = g_list_remove_link (box->children, children);
g_list_free (children);
g_free (child);
- if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+ /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
+ * since that's what is needed by toplevels.
+ */
+ if (was_visible)
gtk_widget_queue_resize (GTK_WIDGET (container));
break;