[Xfce4-commits] <xfce4-panel:devel> Simplify the itembar code and add support for wrapping.
Nick Schermer
noreply at xfce.org
Fri Sep 25 20:02:08 CEST 2009
Updating branch refs/heads/devel
to b9234db5f54c11d2ed75d272544f8050744eb603 (commit)
from cc210e1ae7187b660c4576bfbf37545cce7ea633 (commit)
commit b9234db5f54c11d2ed75d272544f8050744eb603
Author: Nick Schermer <nick at xfce.org>
Date: Fri Sep 25 19:53:52 2009 +0200
Simplify the itembar code and add support for wrapping.
Use the panel window for dnd support on the panel, this removed
a bunch of code from the itembar and makes things easier to
understand.
Also add support for wrap items in the itembar code, this
will be available in the next commit through the separator plugin.
The dnd visualisaion is also improved and works better then the
3px black line we used in previous versions of the panel; can
still be improved to moving existing items on a panel, but that
will come later.
Furthermore some related code cleanups and implement child
properties in the itembar so it is a real container.
libxfce4panel/xfce-panel-plugin-provider.h | 2 +
panel/panel-application.c | 117 ++--
panel/panel-item-dialog.c | 12 +-
panel/panel-itembar.c | 1081 ++++++++++++----------------
panel/panel-itembar.h | 51 +-
panel/panel-preferences-dialog.c | 4 +-
panel/panel-window.c | 15 +-
7 files changed, 578 insertions(+), 704 deletions(-)
diff --git a/libxfce4panel/xfce-panel-plugin-provider.h b/libxfce4panel/xfce-panel-plugin-provider.h
index b4a923a..097a4da 100644
--- a/libxfce4panel/xfce-panel-plugin-provider.h
+++ b/libxfce4panel/xfce-panel-plugin-provider.h
@@ -76,6 +76,8 @@ enum _XfcePanelPluginProviderSignal
PROVIDER_SIGNAL_MOVE_PLUGIN = 0,
PROVIDER_SIGNAL_EXPAND_PLUGIN,
PROVIDER_SIGNAL_COLLAPSE_PLUGIN,
+ PROVIDER_SIGNAL_WRAP_PLUGIN,
+ PROVIDER_SIGNAL_UNWRAP_PLUGIN,
PROVIDER_SIGNAL_LOCK_PANEL,
PROVIDER_SIGNAL_UNLOCK_PANEL,
PROVIDER_SIGNAL_REMOVE_PLUGIN,
diff --git a/panel/panel-application.c b/panel/panel-application.c
index 7bd8361..9fbc0d7 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -66,14 +66,14 @@ static void panel_application_window_destroyed (GtkWidget *w
PanelApplication *application);
static void panel_application_dialog_destroyed (GtkWindow *dialog,
PanelApplication *application);
-static void panel_application_drag_data_received (GtkWidget *itembar,
+static void panel_application_drag_data_received (PanelWindow *window,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint drag_time,
- PanelWindow *window);
+ GtkWidget *itembar);
static gboolean panel_application_drag_motion (GtkWidget *itembar,
GdkDragContext *context,
gint x,
@@ -154,7 +154,7 @@ static const GtkTargetEntry drop_targets[] =
-G_DEFINE_TYPE (PanelApplication, panel_application, G_TYPE_OBJECT);
+G_DEFINE_TYPE (PanelApplication, panel_application, G_TYPE_OBJECT)
@@ -327,8 +327,8 @@ panel_application_load (PanelApplication *application)
xfconf_channel_reset_property (application->xfconf, buf, TRUE);
/* show warnings */
- g_critical (_("Plugin \"%s-%d\" was not found and has been "
- "removed from the configuration"), name, unique_id);
+ g_message (_("Plugin \"%s-%d\" was not found and has been "
+ "removed from the configuration"), name, unique_id);
}
g_free (name);
@@ -380,14 +380,16 @@ panel_application_plugin_move (GtkWidget *item,
/* set the drag context icon name */
module = panel_module_get_from_plugin_provider (XFCE_PANEL_PLUGIN_PROVIDER (item));
icon_name = panel_module_get_icon_name (module);
- gtk_drag_set_icon_name (context, icon_name ? icon_name : GTK_STOCK_DND, 0, 0);
+ if (G_UNLIKELY (icon_name == NULL))
+ icon_name = GTK_STOCK_DND;
+ gtk_drag_set_icon_name (context, icon_name, 0, 0);
/* release the drag list */
gtk_target_list_unref (target_list);
/* signal to make the window sensitive again on a drag end */
g_signal_connect (G_OBJECT (item), "drag-end",
- G_CALLBACK (panel_application_plugin_move_drag_end), application);
+ G_CALLBACK (panel_application_plugin_move_drag_end), application);
}
@@ -432,7 +434,6 @@ panel_application_plugin_provider_signal (XfcePanelPluginProvider *provide
PanelWindow *window;
gint unique_id;
gchar *name;
- gboolean expand;
gint nth;
panel_return_if_fail (PANEL_IS_APPLICATION (application));
@@ -452,14 +453,16 @@ panel_application_plugin_provider_signal (XfcePanelPluginProvider *provide
case PROVIDER_SIGNAL_EXPAND_PLUGIN:
case PROVIDER_SIGNAL_COLLAPSE_PLUGIN:
- /* get the itembar */
itembar = gtk_bin_get_child (GTK_BIN (window));
+ gtk_container_child_set (GTK_CONTAINER (itembar), GTK_WIDGET (provider),
+ "expand", provider_signal == PROVIDER_SIGNAL_EXPAND_PLUGIN, NULL);
+ break;
- /* set new expand mode */
- expand = !!(provider_signal == PROVIDER_SIGNAL_EXPAND_PLUGIN);
- panel_itembar_set_child_expand (PANEL_ITEMBAR (itembar),
- GTK_WIDGET (provider),
- expand);
+ case PROVIDER_SIGNAL_WRAP_PLUGIN:
+ case PROVIDER_SIGNAL_UNWRAP_PLUGIN:
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ gtk_container_child_set (GTK_CONTAINER (itembar), GTK_WIDGET (provider),
+ "wrap", provider_signal == PROVIDER_SIGNAL_WRAP_PLUGIN, NULL);
break;
case PROVIDER_SIGNAL_LOCK_PANEL:
@@ -684,14 +687,14 @@ panel_application_dialog_destroyed (GtkWindow *dialog,
static void
-panel_application_drag_data_received (GtkWidget *itembar,
+panel_application_drag_data_received (PanelWindow *window,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint drag_time,
- PanelWindow *window)
+ GtkWidget *itembar)
{
guint position;
PanelApplication *application;
@@ -704,9 +707,9 @@ panel_application_drag_data_received (GtkWidget *itembar,
GSList *uris, *li;
guint i;
- panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
panel_return_if_fail (PANEL_IS_WINDOW (window));
+ panel_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
/* get the application */
application = panel_application_get ();
@@ -760,17 +763,15 @@ panel_application_drag_data_received (GtkWidget *itembar,
position = panel_itembar_get_drop_index (PANEL_ITEMBAR (itembar), x, y);
/* get the widget screen */
- screen = gtk_widget_get_screen (itembar);
+ screen = gtk_window_get_screen (GTK_WINDOW (window));
switch (info)
{
case TARGET_PLUGIN_NAME:
if (G_LIKELY (selection_data->length > 0))
{
- /* get the name from the selection data */
- name = (const gchar *) selection_data->data;
-
/* create a new item with a unique id */
+ name = (const gchar *) selection_data->data;
succeed = panel_application_plugin_insert (application, window,
screen, name,
-1, NULL, position);
@@ -847,30 +848,31 @@ bailout:
static gboolean
-panel_application_drag_motion (GtkWidget *itembar,
+panel_application_drag_motion (GtkWidget *window,
GdkDragContext *context,
gint x,
gint y,
guint drag_time,
PanelApplication *application)
{
- GdkAtom target;
- GdkDragAction action;
+ GdkAtom target;
+ GtkWidget *itembar;
- panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), FALSE);
+ panel_return_val_if_fail (PANEL_IS_WINDOW (window), FALSE);
panel_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
panel_return_val_if_fail (PANEL_IS_APPLICATION (application), FALSE);
panel_return_val_if_fail (application->drop_occurred == FALSE, FALSE);
/* determine the drag target */
- target = gtk_drag_dest_find_target (itembar, context, NULL);
+ target = gtk_drag_dest_find_target (window, context, NULL);
+
if (target == gdk_atom_intern_static_string ("text/uri-list"))
{
/* request the drop data on-demand (if we don't have it already) */
if (!application->drop_data_ready)
{
/* request the drop data from the source */
- gtk_drag_get_data (itembar, context, target, drag_time);
+ gtk_drag_get_data (window, context, target, drag_time);
/* we cannot drop here (yet!) */
return TRUE;
@@ -885,15 +887,25 @@ panel_application_drag_motion (GtkWidget *itembar,
goto invalid_drop;
}
}
- else if (target != GDK_NONE)
+ else if (target == gdk_atom_intern_static_string ("xfce-panel/plugin-name"))
{
- if (target == gdk_atom_intern_static_string ("xfce-panel/plugin-name"))
- action = GDK_ACTION_COPY;
- else
- action = GDK_ACTION_MOVE;
+ /* highlight the drop zone */
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ panel_itembar_set_drop_highlight_item (PANEL_ITEMBAR (itembar),
+ panel_itembar_get_drop_index (PANEL_ITEMBAR (itembar), x, y));
+
+ /* insert a new plugin */
+ gdk_drag_status (context, GDK_ACTION_COPY, drag_time);
+ }
+ else if (target == gdk_atom_intern_static_string ("xfce-panel/plugin-widget"))
+ {
+ /* highlight the drop zone */
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ panel_itembar_set_drop_highlight_item (PANEL_ITEMBAR (itembar),
+ panel_itembar_get_drop_index (PANEL_ITEMBAR (itembar), x, y));
- /* plugin-widget or -name */
- gdk_drag_status (context, action, drag_time);
+ /* move an existing plugin */
+ gdk_drag_status (context, GDK_ACTION_MOVE, drag_time);
}
else
{
@@ -911,7 +923,7 @@ panel_application_drag_motion (GtkWidget *itembar,
static gboolean
-panel_application_drag_drop (GtkWidget *itembar,
+panel_application_drag_drop (GtkWidget *window,
GdkDragContext *context,
gint x,
gint y,
@@ -920,11 +932,11 @@ panel_application_drag_drop (GtkWidget *itembar,
{
GdkAtom target;
- panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), FALSE);
+ panel_return_val_if_fail (PANEL_IS_WINDOW (window), FALSE);
panel_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
panel_return_val_if_fail (PANEL_IS_APPLICATION (application), FALSE);
- target = gtk_drag_dest_find_target (itembar, context, NULL);
+ target = gtk_drag_dest_find_target (window, context, NULL);
/* we cannot handle the drag data */
if (G_UNLIKELY (target == GDK_NONE))
@@ -935,7 +947,7 @@ panel_application_drag_drop (GtkWidget *itembar,
application->drop_occurred = TRUE;
/* request the drag data from the source. */
- gtk_drag_get_data (itembar, context, target, drag_time);
+ gtk_drag_get_data (window, context, target, drag_time);
/* we call gtk_drag_finish() later */
return TRUE;
@@ -944,12 +956,14 @@ panel_application_drag_drop (GtkWidget *itembar,
static void
-panel_application_drag_leave (GtkWidget *itembar,
+panel_application_drag_leave (GtkWidget *window,
GdkDragContext *context,
guint drag_time,
PanelApplication *application)
{
- panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
+ GtkWidget *itembar;
+
+ panel_return_if_fail (PANEL_IS_WINDOW (window));
panel_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
panel_return_if_fail (PANEL_IS_APPLICATION (application));
@@ -962,6 +976,10 @@ panel_application_drag_leave (GtkWidget *itembar,
/* reset the state */
application->drop_data_ready = FALSE;
+
+ /* unset the highlight position */
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ panel_itembar_set_drop_highlight_item (PANEL_ITEMBAR (itembar), -1);
}
@@ -1067,7 +1085,7 @@ panel_application_take_dialog (PanelApplication *application,
/* monitor window destruction */
g_signal_connect (G_OBJECT (dialog), "destroy",
- G_CALLBACK (panel_application_dialog_destroyed), application);
+ G_CALLBACK (panel_application_dialog_destroyed), application);
/* add the window to internal list */
application->dialogs = g_slist_prepend (application->dialogs, dialog);
@@ -1192,22 +1210,23 @@ panel_application_new_window (PanelApplication *application,
/* add the itembar */
itembar = panel_itembar_new ();
exo_binding_new (G_OBJECT (window), "horizontal", G_OBJECT (itembar), "horizontal");
+ exo_binding_new (G_OBJECT (window), "size", G_OBJECT (itembar), "size");
gtk_container_add (GTK_CONTAINER (window), itembar);
gtk_widget_show (itembar);
/* set the itembar drag destination targets */
- gtk_drag_dest_set (GTK_WIDGET (itembar), 0,
+ gtk_drag_dest_set (GTK_WIDGET (window), 0,
drop_targets, G_N_ELEMENTS (drop_targets),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
/* signals for drag and drop */
- g_signal_connect (G_OBJECT (itembar), "drag-data-received",
- G_CALLBACK (panel_application_drag_data_received), window);
- g_signal_connect (G_OBJECT (itembar), "drag-motion",
+ g_signal_connect (G_OBJECT (window), "drag-data-received",
+ G_CALLBACK (panel_application_drag_data_received), itembar);
+ g_signal_connect (G_OBJECT (window), "drag-motion",
G_CALLBACK (panel_application_drag_motion), application);
- g_signal_connect (G_OBJECT (itembar), "drag-drop",
+ g_signal_connect (G_OBJECT (window), "drag-drop",
G_CALLBACK (panel_application_drag_drop), application);
- g_signal_connect (G_OBJECT (itembar), "drag-leave",
+ g_signal_connect (G_OBJECT (window), "drag-leave",
G_CALLBACK (panel_application_drag_leave), application);
/* add the xfconf bindings */
@@ -1288,7 +1307,7 @@ panel_application_windows_sensitive (PanelApplication *application,
itembar = gtk_bin_get_child (GTK_BIN (li->data));
/* set sensitivity of the itembar (and the plugins) */
- panel_itembar_set_sensitive (PANEL_ITEMBAR (itembar), sensitive);
+ gtk_widget_set_sensitive (itembar, sensitive);
/* block autohide for all windows */
if (sensitive)
diff --git a/panel/panel-item-dialog.c b/panel/panel-item-dialog.c
index 4960ba4..4c5145f 100644
--- a/panel/panel-item-dialog.c
+++ b/panel/panel-item-dialog.c
@@ -221,8 +221,8 @@ panel_item_dialog_init (PanelItemDialog *dialog)
/* signals for treeview dnd */
gtk_drag_source_set (treeview, GDK_BUTTON1_MASK, drag_targets, G_N_ELEMENTS (drag_targets), GDK_ACTION_COPY);
- g_signal_connect_after (G_OBJECT (treeview), "drag-begin", G_CALLBACK (panel_item_dialog_drag_begin), dialog);
- g_signal_connect_after (G_OBJECT (treeview), "drag-data-get", G_CALLBACK (panel_item_dialog_drag_data_get), dialog);
+ g_signal_connect (G_OBJECT (treeview), "drag-begin", G_CALLBACK (panel_item_dialog_drag_begin), dialog);
+ g_signal_connect (G_OBJECT (treeview), "drag-data-get", G_CALLBACK (panel_item_dialog_drag_data_get), dialog);
/* icon renderer */
renderer = gtk_cell_renderer_pixbuf_new ();
@@ -457,7 +457,7 @@ panel_item_dialog_drag_begin (GtkWidget *treeview,
icon_name = panel_module_get_icon_name (module);
/* set the drag icon */
- if (G_LIKELY (icon_name))
+ if (G_LIKELY (icon_name != NULL))
gtk_drag_set_icon_name (context, icon_name, 0, 0);
else
gtk_drag_set_icon_default (context);
@@ -494,14 +494,10 @@ panel_item_dialog_drag_data_get (GtkWidget *treeview,
module = panel_item_dialog_get_selected_module (GTK_TREE_VIEW (treeview));
if (G_LIKELY (module != NULL))
{
- /* get the internal module name */
+ /* set the internal module name as selection data */
internal_name = panel_module_get_name (module);
-
- /* set the selection data */
gtk_selection_data_set (selection_data, selection_data->target, 8,
(guchar *) internal_name, strlen (internal_name));
-
- /* release module */
g_object_unref (G_OBJECT (module));
}
}
diff --git a/panel/panel-itembar.c b/panel/panel-itembar.c
index 2195c73..e9eb9b8 100644
--- a/panel/panel-itembar.c
+++ b/panel/panel-itembar.c
@@ -29,47 +29,46 @@
-#define OFFSCREEN (-9999)
-#define HIGHLIGHT_THINKNESS (2)
-
-
-
-static void panel_itembar_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void panel_itembar_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void panel_itembar_finalize (GObject *object);
-static void panel_itembar_realize (GtkWidget *widget);
-static void panel_itembar_unrealize (GtkWidget *widget);
-static void panel_itembar_map (GtkWidget *widget);
-static void panel_itembar_unmap (GtkWidget *widget);
-static gboolean panel_itembar_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
-static void panel_itembar_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void panel_itembar_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gboolean panel_itembar_drag_motion (GtkWidget *widget,
- GdkDragContext *drag_context,
- gint drag_x,
- gint drag_y,
- guint drag_time);
-static void panel_itembar_drag_leave (GtkWidget *widget,
- GdkDragContext *drag_context,
- guint drag_time);
-static void panel_itembar_add (GtkContainer *container,
- GtkWidget *child);
-static void panel_itembar_remove (GtkContainer *container,
- GtkWidget *child);
-static void panel_itembar_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static GType panel_itembar_child_type (GtkContainer *container);
+typedef struct _PanelItembarChild PanelItembarChild;
+
+
+
+static void panel_itembar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void panel_itembar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void panel_itembar_finalize (GObject *object);
+static void panel_itembar_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void panel_itembar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean panel_itembar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void panel_itembar_add (GtkContainer *container,
+ GtkWidget *child);
+static void panel_itembar_remove (GtkContainer *container,
+ GtkWidget *child);
+static void panel_itembar_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static GType panel_itembar_child_type (GtkContainer *container);
+static void panel_itembar_set_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void panel_itembar_get_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static PanelItembarChild *panel_itembar_get_child (PanelItembar *itembar,
+ GtkWidget *widget);
@@ -82,38 +81,51 @@ struct _PanelItembar
{
GtkContainer __parent__;
- /* window to send all events to the itembar */
- GdkWindow *event_window;
-
- /* dnd highlight line */
- GdkWindow *highlight_window;
+ GSList *children;
- /* whether the itembar is horizontal */
+ /* some properties we clone from the panel window */
guint horizontal : 1;
+ guint size;
- /* internal list of children */
- GSList *children;
-
- /* current sensitivity state */
- guint sensitive : 1;
+ /* dnd support */
+ gint highlight_index;
+ gint highlight_x, highlight_y;
};
struct _PanelItembarChild
{
GtkWidget *widget;
guint expand : 1;
+ guint wrap : 1;
};
enum
{
PROP_0,
PROP_HORIZONTAL,
- PROP_CHANGED
+ PROP_SIZE
+};
+
+enum
+{
+ CHILD_PROP_0,
+ CHILD_PROP_EXPAND,
+ CHILD_PROP_WRAP
+};
+
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
};
-G_DEFINE_TYPE (PanelItembar, panel_itembar, GTK_TYPE_CONTAINER);
+static guint itembar_signals[LAST_SIGNAL];
+
+
+
+G_DEFINE_TYPE (PanelItembar, panel_itembar, GTK_TYPE_CONTAINER)
@@ -130,23 +142,25 @@ panel_itembar_class_init (PanelItembarClass *klass)
gobject_class->finalize = panel_itembar_finalize;
gtkwidget_class = GTK_WIDGET_CLASS (klass);
- gtkwidget_class->realize = panel_itembar_realize;
- gtkwidget_class->unrealize = panel_itembar_unrealize;
- gtkwidget_class->map = panel_itembar_map;
- gtkwidget_class->unmap = panel_itembar_unmap;
- gtkwidget_class->expose_event = panel_itembar_expose_event;
gtkwidget_class->size_request = panel_itembar_size_request;
gtkwidget_class->size_allocate = panel_itembar_size_allocate;
- gtkwidget_class->drag_motion = panel_itembar_drag_motion;
- gtkwidget_class->drag_leave = panel_itembar_drag_leave;
+ gtkwidget_class->expose_event = panel_itembar_expose_event;
gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
gtkcontainer_class->add = panel_itembar_add;
gtkcontainer_class->remove = panel_itembar_remove;
gtkcontainer_class->forall = panel_itembar_forall;
gtkcontainer_class->child_type = panel_itembar_child_type;
- gtkcontainer_class->get_child_property = NULL;
- gtkcontainer_class->set_child_property = NULL;
+ gtkcontainer_class->get_child_property = panel_itembar_get_child_property;
+ gtkcontainer_class->set_child_property = panel_itembar_set_child_property;
+
+ itembar_signals[CHANGED] =
+ g_signal_new (I_("changed"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
g_object_class_install_property (gobject_class,
PROP_HORIZONTAL,
@@ -155,10 +169,22 @@ panel_itembar_class_init (PanelItembarClass *klass)
EXO_PARAM_WRITABLE));
g_object_class_install_property (gobject_class,
- PROP_CHANGED,
- g_param_spec_boolean ("changed", NULL, NULL,
- FALSE,
- EXO_PARAM_READABLE));
+ PROP_SIZE,
+ g_param_spec_uint ("size", NULL, NULL,
+ 16, 128, 48,
+ EXO_PARAM_WRITABLE));
+
+ gtk_container_class_install_child_property (gtkcontainer_class,
+ CHILD_PROP_EXPAND,
+ g_param_spec_boolean ("expand", NULL, NULL,
+ FALSE,
+ EXO_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (gtkcontainer_class,
+ CHILD_PROP_WRAP,
+ g_param_spec_boolean ("wrap", NULL, NULL,
+ FALSE,
+ EXO_PARAM_READWRITE));
}
@@ -168,10 +194,9 @@ panel_itembar_init (PanelItembar *itembar)
{
/* initialize */
itembar->children = NULL;
- itembar->event_window = NULL;
- itembar->highlight_window = NULL;
- itembar->sensitive = TRUE;
itembar->horizontal = TRUE;
+ itembar->size = 30;
+ itembar->highlight_index = -1;
/* setup */
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (itembar), GTK_NO_WINDOW);
@@ -194,13 +219,18 @@ panel_itembar_set_property (GObject *object,
{
case PROP_HORIZONTAL:
itembar->horizontal = g_value_get_boolean (value);
- gtk_widget_queue_resize (GTK_WIDGET (itembar));
+ break;
+
+ case PROP_SIZE:
+ itembar->size = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+
+ gtk_widget_queue_resize (GTK_WIDGET (itembar));
}
@@ -213,10 +243,6 @@ panel_itembar_get_property (GObject *object,
{
switch (prop_id)
{
- case PROP_CHANGED:
- g_value_set_boolean (value, TRUE);
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -236,100 +262,6 @@ panel_itembar_finalize (GObject *object)
static void
-panel_itembar_realize (GtkWidget *widget)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
- GdkWindowAttr attributes;
-
- /* let gtk handle it's own realation first */
- (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->realize) (widget);
-
- /* setup the window attributes */
- attributes.x = widget->allocation.x;
- attributes.y = widget->allocation.y;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
- attributes.wclass = GDK_INPUT_ONLY;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.event_mask = gtk_widget_get_events (widget);
-
- /* allocate the event window */
- itembar->event_window = gdk_window_new (GDK_WINDOW (widget->window), &attributes, GDK_WA_X | GDK_WA_Y);
-
- /* set the window user data */
- gdk_window_set_user_data (GDK_WINDOW (itembar->event_window), widget);
-}
-
-
-
-static void
-panel_itembar_unrealize (GtkWidget *widget)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
-
- /* destroy the event window */
- if (G_LIKELY (itembar->event_window))
- {
- gdk_window_set_user_data (itembar->event_window, NULL);
- gdk_window_destroy (itembar->event_window);
- itembar->event_window = NULL;
- }
-
- (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->unrealize) (widget);
-}
-
-
-
-static void
-panel_itembar_map (GtkWidget *widget)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
-
- /* show the event window */
- if (G_LIKELY (itembar->event_window))
- gdk_window_show (itembar->event_window);
-
- (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->map) (widget);
-
- /* raise the window if we're in insensitive mode */
- if (G_UNLIKELY (!itembar->sensitive && itembar->event_window))
- gdk_window_raise (itembar->event_window);
-}
-
-
-
-static void
-panel_itembar_unmap (GtkWidget *widget)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
-
- /* hide the event window */
- if (G_LIKELY (itembar->event_window))
- gdk_window_hide (itembar->event_window);
-
- (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->unmap) (widget);
-}
-
-
-
-static gboolean
-panel_itembar_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
-
- (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->expose_event) (widget, event);
-
- /* keep our event window on top */
- if (itembar->sensitive == FALSE && itembar->event_window)
- gdk_window_raise (itembar->event_window);
-
- return TRUE;
-}
-
-
-
-static void
panel_itembar_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
@@ -337,34 +269,74 @@ panel_itembar_size_request (GtkWidget *widget,
GSList *li;
PanelItembarChild *child;
GtkRequisition child_requisition;
+ gint border_width;
+ gint row_length = 0;
- /* initialize */
- requisition->width = GTK_CONTAINER (widget)->border_width * 2;
- requisition->height = requisition->width;
+ /* intialize the requisition, we always set the panel height */
+ if (itembar->horizontal)
+ {
+ requisition->height = itembar->size;
+ requisition->width = 0;
+ }
+ else
+ {
+ requisition->height = 0;
+ requisition->width = itembar->size;
+ }
- /* walk the childeren */
- for (li = itembar->children; li != NULL; li = li->next)
+ /* get the size requests of the children and use the longest row for
+ * the requested width/height when we have wrap items */
+ for (li = itembar->children; li != NULL; li = g_slist_next (li))
{
child = li->data;
-
- if (G_LIKELY (GTK_WIDGET_VISIBLE (child->widget)))
+ if (G_LIKELY (child != NULL))
{
- /* get the child size request */
+ if (!GTK_WIDGET_VISIBLE (child->widget))
+ continue;
+
gtk_widget_size_request (child->widget, &child_requisition);
- /* update the itembar requisition */
- if (itembar->horizontal)
+ if (G_LIKELY (!child->wrap))
{
- requisition->width += child_requisition.width;
- requisition->height = MAX (requisition->height, child_requisition.height);
+ if (itembar->horizontal)
+ row_length += child_requisition.width;
+ else
+ row_length += child_requisition.height;
}
else
{
- requisition->height += child_requisition.height;
- requisition->width = MAX (requisition->width, child_requisition.width);
+ if (itembar->horizontal)
+ {
+ requisition->height += itembar->size;
+ requisition->width = MAX (requisition->width, row_length);
+ }
+ else
+ {
+ requisition->width += itembar->size;
+ requisition->height = MAX (requisition->height, row_length);
+ }
+
+ /* reset length for new row */
+ row_length = 0;
}
}
+ else
+ {
+ /* this noop item is the dnd position */
+ row_length += itembar->size;
+ }
}
+
+ /* use the last row length */
+ if (itembar->horizontal)
+ requisition->width = MAX (requisition->width, row_length);
+ else
+ requisition->height = MAX (requisition->height, row_length);
+
+ /* add border width */
+ border_width = GTK_CONTAINER (widget)->border_width * 2;
+ requisition->height += border_width;
+ requisition->width += border_width;
}
@@ -374,265 +346,208 @@ panel_itembar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
PanelItembar *itembar = PANEL_ITEMBAR (widget);
- GSList *li;
+ GSList *li, *lp;
PanelItembarChild *child;
- GtkRequisition child_requisition;
- GtkAllocation child_allocation;
- guint n_expand_children = 0;
- gint alloc_expandable_size;
- gint req_expandable_size = 0;
+ GtkRequisition child_req;
+ GtkAllocation child_alloc;
+ guint n_expand_children;
+ guint row;
+ gint expand_length, border_width;
+ gint expand_length_avail;
+ gint expand_length_req;
+ gint length_req, length;
+ gint alloc_length;
gint x, y;
- gint border_width;
- gint alloc_size, req_size;
- gboolean expandable_children_fit;
+ gboolean expand_children_fit;
/* set widget allocation */
widget->allocation = *allocation;
- /* allocate the event window */
- if (G_LIKELY (itembar->event_window))
- gdk_window_move_resize (GDK_WINDOW (itembar->event_window), allocation->x,
- allocation->y, allocation->width, allocation->height);
-
- /* get the border width */
border_width = GTK_CONTAINER (widget)->border_width;
- /* get the itembar size */
if (itembar->horizontal)
- alloc_expandable_size = allocation->width - 2 * border_width;
+ expand_length = allocation->width - 2 * border_width;
else
- alloc_expandable_size = allocation->height - 2 * border_width;
+ expand_length = allocation->height - 2 * border_width;
- /* walk the children to get the (remaining) expandable length */
- for (li = itembar->children; li != NULL; li = li->next)
+ /* traverse the children to handle the wrap items */
+ for (row = 0, li = itembar->children; li != NULL; li = g_slist_next (li), row++)
{
- child = li->data;
+ expand_length_avail = expand_length;
+ expand_length_req = 0;
+ n_expand_children = 0;
- /* skip hidden widgets */
- if (GTK_WIDGET_VISIBLE (child->widget) == FALSE)
- continue;
-
- /* get the child size request */
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
-
- if (G_UNLIKELY (child->expand))
+ /* get information about the expandable lengths */
+ for (lp = li; lp != NULL; lp = g_slist_next (lp))
{
- /* increase counter */
- n_expand_children++;
-
- /* update the size requested by the expanding children */
- if (itembar->horizontal)
- req_expandable_size += child_requisition.width;
+ child = lp->data;
+ if (G_LIKELY (child != NULL))
+ {
+ if (!GTK_WIDGET_VISIBLE (child->widget))
+ continue;
+
+ /* continue allocating if we hit a wrap child */
+ if (G_UNLIKELY (child->wrap))
+ break;
+
+ gtk_widget_get_child_requisition (child->widget, &child_req);
+ length = itembar->horizontal ? child_req.width : child_req.height;
+
+ if (G_UNLIKELY (child->expand))
+ {
+ n_expand_children++;
+ expand_length_req += length;
+ }
+ else
+ {
+ expand_length_avail -= length;
+ }
+ }
else
- req_expandable_size += child_requisition.height;
+ {
+ expand_length_avail -= itembar->size;
+ }
}
+
+ /* set start coordinates for the items in the row*/
+ x = allocation->x + border_width;
+ y = allocation->y + border_width;
+ if (itembar->horizontal)
+ y += row * itembar->size;
else
+ x += row * itembar->size;
+
+ /* whether the expandable items fit on this row; we use this
+ * as a fast-path when there are expanding items on a panel with
+ * not really enough length to expand (ie. items make the panel grow,
+ * not the length set by the user) */
+ expand_children_fit = expand_length_req == expand_length_avail;
+ if (expand_length_avail < 0)
+ expand_length_avail = 0;
+
+ /* allocate the children on this row */
+ for (; li != NULL; li = g_slist_next (li))
{
- /* update the size avaible for allocation */
- if (itembar->horizontal)
- alloc_expandable_size -= child_requisition.width;
- else
- alloc_expandable_size -= child_requisition.height;
- }
- }
+ child = li->data;
- /* set coordinates */
- x = allocation->x + border_width;
- y = allocation->y + border_width;
-
- /* check if the expandable childs fit in the available expandable size */
- expandable_children_fit = !!(req_expandable_size == alloc_expandable_size);
-
- /* make sure the allocated expandable size is not below zero */
- alloc_expandable_size = MAX (0, alloc_expandable_size);
-
- /* allocate the children */
- for (li = itembar->children; li != NULL; li = li->next)
- {
- child = li->data;
+ /* the highlight item for which we keep some spare space */
+ if (G_UNLIKELY (child == NULL))
+ {
+ itembar->highlight_x = x;
+ itembar->highlight_y = y;
+ expand_length_avail -= itembar->size;
- /* still skip hidden widgets */
- if (GTK_WIDGET_VISIBLE (child->widget) == FALSE)
- continue;
+ if (itembar->horizontal)
+ x += itembar->size;
+ else
+ y += itembar->size;
- /* get the child size request */
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
+ continue;
+ }
- /* set coordinates for the child allocation */
- child_allocation.x = x;
- child_allocation.y = y;
+ if (!GTK_WIDGET_VISIBLE (child->widget))
+ continue;
- /* set the width or height of the child */
- if (G_UNLIKELY (child->expand && !expandable_children_fit))
- {
- /* get requested size */
- req_size = itembar->horizontal ? child_requisition.width : child_requisition.height;
+ gtk_widget_get_child_requisition (child->widget, &child_req);
- /* calculate allocated size */
- if (G_LIKELY (req_expandable_size > 0 || req_size > 0))
- alloc_size = alloc_expandable_size * req_size / req_expandable_size;
- else
- alloc_size = alloc_expandable_size / n_expand_children;
+ child_alloc.x = x;
+ child_alloc.y = y;
- /* decrease counter */
- n_expand_children--;
+ if (child->wrap)
+ {
+ /* if there is any expanding length available use it for the
+ * wrapping plugin to improve accessibility */
+ if (expand_length_avail > 0)
+ {
+ if (itembar->horizontal)
+ {
+ child_alloc.height = itembar->size;
+ child_alloc.width = expand_length_avail;
+ }
+ else
+ {
+ child_alloc.width = itembar->size;
+ child_alloc.height = expand_length_avail;
+ }
+ }
+ else
+ {
+ /* hide it */
+ child_alloc.width = child_alloc.height = 0;
+ }
+
+ gtk_widget_size_allocate (child->widget, &child_alloc);
+
+ /* stop and continue to the next row */
+ break;
+ }
- /* set the calculated expanding size */
- if (itembar->horizontal)
- child_allocation.width = alloc_size;
+ if (G_UNLIKELY (!expand_children_fit && child->expand))
+ {
+ /* try to equally distribute the length between the expanding plugins */
+ length_req = itembar->horizontal ? child_req.width : child_req.height;
+ panel_assert (n_expand_children > 0);
+ if (G_LIKELY (expand_length_req > 0 || length_req > 0))
+ alloc_length = expand_length_avail * length_req / expand_length_req;
+ else
+ alloc_length = expand_length_avail / n_expand_children;
+
+ if (itembar->horizontal)
+ child_alloc.width = alloc_length;
+ else
+ child_alloc.height = alloc_length;
+
+ n_expand_children--;
+ expand_length_req -= alloc_length;
+ expand_length_avail -= alloc_length;
+ }
else
- child_allocation.height = alloc_size;
+ {
+ if (itembar->horizontal)
+ child_alloc.width = child_req.width;
+ else
+ child_alloc.height = child_req.height;
+ }
- /* update total sizes */
- alloc_expandable_size -= alloc_size;
- req_expandable_size -= req_size;
- }
- else
- {
- /* set the requested size in the allocation */
if (itembar->horizontal)
- child_allocation.width = child_requisition.width;
- else
- child_allocation.height = child_requisition.height;
- }
-
- /* update the coordinates and set the allocated (user defined) panel size */
- if (itembar->horizontal)
- {
- x += child_allocation.width;
- child_allocation.height = allocation->height;
-
- /* check if everything fits in the allocated size */
- if (G_UNLIKELY (x > allocation->width + allocation->x))
{
- /* draw the next plugin offscreen */
- x = OFFSCREEN;
-
- /* make this plugin fit exactly on the panel */
- child_allocation.width = MAX (0, allocation->width + allocation->x - child_allocation.x);
+ child_alloc.height = itembar->size;
+ x += child_alloc.width;
}
- }
- else
- {
- y += child_allocation.height;
- child_allocation.width = allocation->width;
-
- /* check if everything fits in the allocated size */
- if (G_UNLIKELY (y > allocation->height + allocation->y))
+ else
{
- /* draw the next plugin offscreen */
- y = OFFSCREEN;
-
- /* make this plugin fit exactly on the panel */
- child_allocation.height = MAX (0, allocation->height + allocation->y - child_allocation.y);
+ child_alloc.width = itembar->size;
+ y += child_alloc.height;
}
- }
- /* allocate the child */
- gtk_widget_size_allocate (child->widget, &child_allocation);
+ gtk_widget_size_allocate (child->widget, &child_alloc);
+ }
}
}
static gboolean
-panel_itembar_drag_motion (GtkWidget *widget,
- GdkDragContext *drag_context,
- gint drag_x,
- gint drag_y,
- guint drag_time)
+panel_itembar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
- GdkWindowAttr attributes;
- gint drop_index;
- GtkWidget *child = NULL;
- gint x = 0, y = 0;
- gint width, height;
-
- if (G_UNLIKELY (itembar->highlight_window == NULL))
- {
- /* setup window attributes */
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
- attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
- attributes.width = HIGHLIGHT_THINKNESS;
- attributes.height = HIGHLIGHT_THINKNESS;
-
- /* allocate window */
- itembar->highlight_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
- GDK_WA_VISUAL | GDK_WA_COLORMAP);
-
- /* set user data */
- gdk_window_set_user_data (itembar->highlight_window, widget);
-
- /* set window background */
- gdk_window_set_background (itembar->highlight_window, &widget->style->fg[widget->state]);
- }
+ gboolean result;
+ PanelItembar *itembar = PANEL_ITEMBAR (widget);
- /* get the drop index */
- drop_index = panel_itembar_get_drop_index (itembar, drag_x, drag_y);
+ result = (*GTK_WIDGET_CLASS (panel_itembar_parent_class)->expose_event) (widget, event);
- /* get the nth child */
- child = panel_itembar_get_nth_child (itembar, drop_index);
- if (G_LIKELY (child))
+ if (itembar->highlight_index != -1)
{
- /* get child start coordinate */
- if (itembar->horizontal)
- x = child->allocation.x;
- else
- y = child->allocation.y;
- }
- else if (itembar->children)
- {
- /* get the last child */
- child = panel_itembar_get_nth_child (itembar, g_slist_length (itembar->children) - 1);
-
- /* get coordinate at end of the child */
- if (itembar->horizontal)
- x = child->allocation.x + child->allocation.width;
- else
- y = child->allocation.y + child->allocation.height;
+ gtk_paint_box (widget->style, widget->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ &event->area, widget, "panel-dnd",
+ itembar->highlight_x + 1,
+ itembar->highlight_y + 1,
+ itembar->size - 2,
+ itembar->size - 2);
}
- /* get size of the hightlight */
- width = itembar->horizontal ? HIGHLIGHT_THINKNESS : widget->allocation.width;
- height = itembar->horizontal ? widget->allocation.height : HIGHLIGHT_THINKNESS;
-
- /* show line between the two children */
- x += HIGHLIGHT_THINKNESS / 2;
- y += HIGHLIGHT_THINKNESS / 2;
-
- /* keep the heightlight window inside the itembar */
- x = CLAMP (x, widget->allocation.x, widget->allocation.x + widget->allocation.width - HIGHLIGHT_THINKNESS);
- y = CLAMP (y, widget->allocation.y, widget->allocation.y + widget->allocation.height - HIGHLIGHT_THINKNESS);
-
- /* move the hightlight window */
- gdk_window_move_resize (itembar->highlight_window, x, y, width, height);
-
- /* show the window */
- gdk_window_show (itembar->highlight_window);
-
- return TRUE;
-}
-
-
-
-static void
-panel_itembar_drag_leave (GtkWidget *widget,
- GdkDragContext *drag_context,
- guint drag_time)
-{
- PanelItembar *itembar = PANEL_ITEMBAR (widget);
-
- /* destroy the drag highlight window */
- if (G_LIKELY (itembar->highlight_window))
- {
- gdk_window_set_user_data (itembar->highlight_window, NULL);
- gdk_window_destroy (itembar->highlight_window);
- itembar->highlight_window = NULL;
- }
+ return result;
}
@@ -641,8 +556,7 @@ static void
panel_itembar_add (GtkContainer *container,
GtkWidget *child)
{
- /* append the item */
- panel_itembar_append (PANEL_ITEMBAR (container), child);
+ panel_itembar_insert (PANEL_ITEMBAR (container), child, -1);
}
@@ -651,45 +565,26 @@ static void
panel_itembar_remove (GtkContainer *container,
GtkWidget *widget)
{
- PanelItembar *itembar = PANEL_ITEMBAR (container);
- GSList *li;
PanelItembarChild *child;
- gboolean was_visible;
+ PanelItembar *itembar = PANEL_ITEMBAR (container);
panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_if_fail (GTK_IS_CONTAINER (container));
panel_return_if_fail (GTK_IS_WIDGET (widget));
- panel_return_if_fail (widget->parent == GTK_WIDGET (itembar));
+ panel_return_if_fail (widget->parent == GTK_WIDGET (container));
panel_return_if_fail (itembar->children != NULL);
- for (li = itembar->children; li != NULL; li = li->next)
+ child = panel_itembar_get_child (itembar, widget);
+ if (G_LIKELY (child != NULL))
{
- child = li->data;
-
- if (child->widget == widget)
- {
- /* remove the child from the list */
- itembar->children = g_slist_delete_link (itembar->children, li);
+ itembar->children = g_slist_remove (itembar->children, child);
- /* whether the widget is currently visible */
- was_visible = GTK_WIDGET_VISIBLE (widget);
+ gtk_widget_unparent (widget);
- /* remove from the itembar */
- gtk_widget_unparent (child->widget);
+ g_slice_free (PanelItembarChild, child);
- /* cleanup the slice */
- g_slice_free (PanelItembarChild, child);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
- /* queue a resize if needed */
- if (G_LIKELY (was_visible))
- gtk_widget_queue_resize (GTK_WIDGET (container));
-
- /* tell the consumers that we have changed the items */
- g_object_notify (G_OBJECT (itembar), "changed");
-
- /* done */
- break;
- }
+ g_signal_emit (G_OBJECT (itembar), itembar_signals[CHANGED], 0);
}
}
@@ -710,9 +605,10 @@ panel_itembar_forall (GtkContainer *container,
while (children != NULL)
{
child = children->data;
- children = children->next;
+ children = g_slist_next (children);
- (* callback) (child->widget, callback_data);
+ if (G_LIKELY (child != NULL))
+ (* callback) (child->widget, callback_data);
}
}
@@ -726,182 +622,154 @@ panel_itembar_child_type (GtkContainer *container)
-GtkWidget *
-panel_itembar_new (void)
-{
- return g_object_new (PANEL_TYPE_ITEMBAR, NULL);
-}
-
-
-
-void
-panel_itembar_set_sensitive (PanelItembar *itembar,
- gboolean sensitive)
+static void
+panel_itembar_set_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
PanelItembarChild *child;
- GSList *li;
-
- panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_if_fail (itembar->event_window == NULL || GDK_IS_WINDOW (itembar->event_window));
+ gboolean boolean;
- /* set internal value */
- itembar->sensitive = !!sensitive;
+ child = panel_itembar_get_child (PANEL_ITEMBAR (container), widget);
+ if (G_UNLIKELY (child == NULL))
+ return;
- /* raise or lower the event window */
- if (G_LIKELY (itembar->event_window))
+ switch (prop_id)
{
- if (sensitive)
- gdk_window_lower (itembar->event_window);
- else
- gdk_window_raise (itembar->event_window);
- }
+ case CHILD_PROP_EXPAND:
+ boolean = g_value_get_boolean (value);
+ if (child->expand == boolean)
+ return;
+ child->expand = boolean;
+ break;
- /* walk the children */
- for (li = itembar->children; li != NULL; li = li->next)
- {
- /* get child */
- child = li->data;
+ case CHILD_PROP_WRAP:
+ boolean = g_value_get_boolean (value);
+ if (child->wrap == boolean)
+ return;
+ child->wrap = boolean;
+ break;
- /* set widget sensitivity */
- gtk_widget_set_sensitive (child->widget, sensitive);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (container, prop_id, pspec);
+ break;
}
+
+ gtk_widget_queue_resize (GTK_WIDGET (container));
}
-void
-panel_itembar_insert (PanelItembar *itembar,
- GtkWidget *widget,
- gint position)
+static void
+panel_itembar_get_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
PanelItembarChild *child;
- panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_if_fail (GTK_IS_WIDGET (widget));
- panel_return_if_fail (widget->parent == NULL);
-
- /* allocate new child */
- child = g_slice_new (PanelItembarChild);
-
- /* set properties */
- child->widget = widget;
- child->expand = FALSE;
-
- /* insert in the internal list */
- itembar->children = g_slist_insert (itembar->children, child, position);
-
- /* set the parent */
- gtk_widget_set_parent (widget, GTK_WIDGET (itembar));
+ child = panel_itembar_get_child (PANEL_ITEMBAR (container), widget);
+ if (G_UNLIKELY (child == NULL))
+ return;
- /* sensitivity of the new item */
- gtk_widget_set_sensitive (widget, itembar->sensitive);
+ switch (prop_id)
+ {
+ case CHILD_PROP_EXPAND:
+ g_value_set_boolean (value, child->expand);
+ break;
- /* resize the itembar */
- gtk_widget_queue_resize (GTK_WIDGET (itembar));
+ case CHILD_PROP_WRAP:
+ g_value_set_boolean (value, child->wrap);
+ break;
- /* tell the consumers that we have changed the items */
- g_object_notify (G_OBJECT (itembar), "changed");
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (container, prop_id, pspec);
+ break;
+ }
}
-void
-panel_itembar_reorder_child (PanelItembar *itembar,
- GtkWidget *widget,
- gint position)
+static PanelItembarChild *
+panel_itembar_get_child (PanelItembar *itembar,
+ GtkWidget *widget)
{
GSList *li;
PanelItembarChild *child;
- panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_if_fail (GTK_IS_WIDGET (widget));
- panel_return_if_fail (widget->parent == GTK_WIDGET (itembar));
+ panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), NULL);
+ panel_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ panel_return_val_if_fail (widget->parent == GTK_WIDGET (itembar), NULL);
- for (li = itembar->children; li != NULL; li = li->next)
+ for (li = itembar->children; li != NULL; li = g_slist_next (li))
{
child = li->data;
+ if (child != NULL
+ && child->widget == widget)
+ return child;
+ }
- /* find the widget */
- if (child->widget == widget)
- {
- /* remove the link from the list */
- itembar->children = g_slist_delete_link (itembar->children, li);
-
- /* insert the child in the new position */
- itembar->children = g_slist_insert (itembar->children, child, position);
+ return NULL;
+}
- /* reallocate the itembar */
- gtk_widget_queue_resize (GTK_WIDGET (itembar));
- /* tell the consumers that we have changed the items */
- g_object_notify (G_OBJECT (itembar), "changed");
- /* we're done */
- break;
- }
- }
+GtkWidget *
+panel_itembar_new (void)
+{
+ return g_object_new (PANEL_TYPE_ITEMBAR, NULL);
}
-gboolean
-panel_itembar_get_child_expand (PanelItembar *itembar,
- GtkWidget *widget)
+void
+panel_itembar_insert (PanelItembar *itembar,
+ GtkWidget *widget,
+ gint position)
{
- GSList *li;
PanelItembarChild *child;
- panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), FALSE);
- panel_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- panel_return_val_if_fail (widget->parent == GTK_WIDGET (itembar), FALSE);
+ panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
+ panel_return_if_fail (GTK_IS_WIDGET (widget));
+ panel_return_if_fail (widget->parent == NULL);
- for (li = itembar->children; li != NULL; li = li->next)
- {
- child = li->data;
+ child = g_slice_new0 (PanelItembarChild);
+ child->widget = widget;
+ child->expand = FALSE;
+ child->wrap = FALSE;
- /* find the widget and return the expand mode */
- if (child->widget == widget)
- return child->expand;
- }
+ itembar->children = g_slist_insert (itembar->children, child, position);
+ gtk_widget_set_parent (widget, GTK_WIDGET (itembar));
- return FALSE;
+ gtk_widget_queue_resize (GTK_WIDGET (itembar));
+ g_signal_emit (G_OBJECT (itembar), itembar_signals[CHANGED], 0);
}
void
-panel_itembar_set_child_expand (PanelItembar *itembar,
- GtkWidget *widget,
- gboolean expand)
+panel_itembar_reorder_child (PanelItembar *itembar,
+ GtkWidget *widget,
+ gint position)
{
- GSList *li;
PanelItembarChild *child;
panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
panel_return_if_fail (GTK_IS_WIDGET (widget));
panel_return_if_fail (widget->parent == GTK_WIDGET (itembar));
- /* find child and set new expand mode */
- for (li = itembar->children; li != NULL; li = li->next)
+ child = panel_itembar_get_child (itembar, widget);
+ if (G_LIKELY (child != NULL))
{
- child = li->data;
-
- /* find the widget */
- if (child->widget == widget)
- {
- /* only update if the expand mode changed */
- if (G_LIKELY (child->expand != expand))
- {
- /* store new mode */
- child->expand = expand;
-
- /* resize the itembar */
- gtk_widget_queue_resize (GTK_WIDGET (itembar));
- }
+ /* move in the internal list */
+ itembar->children = g_slist_remove (itembar->children, child);
+ itembar->children = g_slist_insert (itembar->children, child, position);
- /* stop searching */
- break;
- }
+ gtk_widget_queue_resize (GTK_WIDGET (itembar));
+ g_signal_emit (G_OBJECT (itembar), itembar_signals[CHANGED], 0);
}
}
@@ -919,76 +787,93 @@ panel_itembar_get_child_index (PanelItembar *itembar,
panel_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
panel_return_val_if_fail (widget->parent == GTK_WIDGET (itembar), -1);
- /* walk the children to find the child widget */
- for (idx = 0, li = itembar->children; li != NULL; li = li->next, idx++)
+ for (idx = 0, li = itembar->children; li != NULL; li = g_slist_next (li), idx++)
{
child = li->data;
+ if (G_UNLIKELY (child == NULL))
+ continue;
- /* check if this is the widget */
if (child->widget == widget)
return idx;
}
- /* nothing found */
return -1;
}
-GtkWidget *
-panel_itembar_get_nth_child (PanelItembar *itembar,
- guint idx)
-{
- PanelItembarChild *child;
-
- panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), NULL);
-
- /* get the nth item */
- child = g_slist_nth_data (itembar->children, idx);
-
- /* return the widget */
- return (child != NULL ? child->widget : NULL);
-}
-
-
-
guint
panel_itembar_get_n_children (PanelItembar *itembar)
{
+ guint n;
+
panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), 0);
- return g_slist_length (itembar->children);
+ n = g_slist_length (itembar->children);
+ if (G_UNLIKELY (itembar->highlight_index != -1))
+ n--;
+
+ return n;
}
guint
-panel_itembar_get_drop_index (PanelItembar *itembar,
- gint x,
- gint y)
+panel_itembar_get_drop_index (PanelItembar *itembar,
+ gint x,
+ gint y)
{
PanelItembarChild *child;
GSList *li;
- GtkAllocation *allocation;
+ GtkAllocation *alloc;
guint idx;
+ gint row = 0;
panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), 0);
/* add the itembar position */
- x += GTK_WIDGET (itembar)->allocation.x;
- y += GTK_WIDGET (itembar)->allocation.y;
+ alloc = >K_WIDGET (itembar)->allocation;
+ x += alloc->x;
+ y += alloc->y;
- for (li = itembar->children, idx = 0; li != NULL; li = li->next, idx++)
+ /* return -1 if point is outside the widget allocation */
+ if (x > alloc->width || y > alloc->height)
+ return -1;
+
+ for (li = itembar->children, idx = 0; li != NULL; li = g_slist_next (li))
{
child = li->data;
+ if (G_UNLIKELY (child == NULL))
+ continue;
- /* get the child allocation */
- allocation = &(child->widget->allocation);
+ if (child->wrap)
+ {
+ row += itembar->size;
- /* check if the drop index is before the half of the allocation */
- if ((itembar->horizontal && x < (allocation->x + allocation->width / 2))
- || (!itembar->horizontal && y < (allocation->y + allocation->height / 2)))
- break;
+ /* always make sure the item is on the row */
+ if ((itembar->horizontal && y < row)
+ || (!itembar->horizontal && x < row))
+ break;
+ }
+
+ alloc = &child->widget->allocation;
+
+ if (itembar->horizontal)
+ {
+ if (x < (alloc->x + (alloc->width / 2))
+ && y >= alloc->y
+ && y <= alloc->y + alloc->height)
+ break;
+ }
+ else
+ {
+ if (y < (alloc->y + (alloc->height / 2))
+ && x >= alloc->x
+ && x <= alloc->x + alloc->width)
+ break;
+ }
+
+ idx++;
}
return idx;
@@ -996,29 +881,21 @@ panel_itembar_get_drop_index (PanelItembar *itembar,
-GtkWidget *
-panel_itembar_get_child_at_position (PanelItembar *itembar,
- gint x,
- gint y)
+void
+panel_itembar_set_drop_highlight_item (PanelItembar *itembar,
+ gint idx)
{
- PanelItembarChild *child;
- GSList *li;
- GtkAllocation *allocation;
+ panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
- panel_return_val_if_fail (PANEL_IS_ITEMBAR (itembar), NULL);
+ if (idx == itembar->highlight_index)
+ return;
- for (li = itembar->children; li != NULL; li = li->next)
- {
- child = li->data;
+ if (itembar->highlight_index != -1)
+ itembar->children = g_slist_remove_all (itembar->children, NULL);
+ if (idx != -1)
+ itembar->children = g_slist_insert (itembar->children, NULL, idx);
- /* get the child allocation */
- allocation = &(child->widget->allocation);
+ itembar->highlight_index = idx;
- /* check if the coordinate is inside the allocation */
- if (x >= allocation->x && x <= (allocation->x + allocation->width)
- && y >= allocation->y && y <= (allocation->y + allocation->height))
- return child->widget;
- }
-
- return NULL;
+ gtk_widget_queue_resize (GTK_WIDGET (itembar));
}
diff --git a/panel/panel-itembar.h b/panel/panel-itembar.h
index cc4b6a6..c158b9b 100644
--- a/panel/panel-itembar.h
+++ b/panel/panel-itembar.h
@@ -26,7 +26,6 @@ G_BEGIN_DECLS
typedef struct _PanelItembarClass PanelItembarClass;
typedef struct _PanelItembar PanelItembar;
-typedef struct _PanelItembarChild PanelItembarChild;
#define PANEL_TYPE_ITEMBAR (panel_itembar_get_type ())
#define PANEL_ITEMBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_ITEMBAR, PanelItembar))
@@ -35,48 +34,30 @@ typedef struct _PanelItembarChild PanelItembarChild;
#define PANEL_IS_ITEMBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_ITEMBAR))
#define PANEL_ITEMBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_ITEMBAR, PanelItembarClass))
-#define panel_itembar_append(itembar,widget) panel_itembar_insert ((itembar), (widget), -1)
-#define panel_itembar_prepend(itembar,widget) panel_itembar_insert ((itembar), (widget), 0)
+GType panel_itembar_get_type (void) G_GNUC_CONST;
-GType panel_itembar_get_type (void) G_GNUC_CONST;
+GtkWidget *panel_itembar_new (void) G_GNUC_MALLOC;
-GtkWidget *panel_itembar_new (void) G_GNUC_MALLOC;
+void panel_itembar_insert (PanelItembar *itembar,
+ GtkWidget *widget,
+ gint position);
-void panel_itembar_set_sensitive (PanelItembar *itembar,
- gboolean sensitive);
+void panel_itembar_reorder_child (PanelItembar *itembar,
+ GtkWidget *widget,
+ gint position);
-void panel_itembar_insert (PanelItembar *itembar,
- GtkWidget *widget,
- gint position);
+gint panel_itembar_get_child_index (PanelItembar *itembar,
+ GtkWidget *widget);
-void panel_itembar_reorder_child (PanelItembar *itembar,
- GtkWidget *widget,
- gint position);
+guint panel_itembar_get_n_children (PanelItembar *itembar);
-gboolean panel_itembar_get_child_expand (PanelItembar *itembar,
- GtkWidget *widget);
+guint panel_itembar_get_drop_index (PanelItembar *itembar,
+ gint x,
+ gint y);
-void panel_itembar_set_child_expand (PanelItembar *itembar,
- GtkWidget *widget,
- gboolean expand);
-
-gint panel_itembar_get_child_index (PanelItembar *itembar,
- GtkWidget *widget);
-
-GtkWidget *panel_itembar_get_nth_child (PanelItembar *itembar,
- guint idx);
-
-guint panel_itembar_get_n_children (PanelItembar *itembar);
-
-guint panel_itembar_get_drop_index (PanelItembar *itembar,
- gint x,
- gint y);
-
-GtkWidget *panel_itembar_get_child_at_position (PanelItembar *itembar,
- gint x,
- gint y);
+void panel_itembar_set_drop_highlight_item (PanelItembar *itembar,
+ gint idx);
G_END_DECLS
#endif /* !__PANEL_ITEMBAR_H__ */
-
diff --git a/panel/panel-preferences-dialog.c b/panel/panel-preferences-dialog.c
index 48a8216..959fe23 100644
--- a/panel/panel-preferences-dialog.c
+++ b/panel/panel-preferences-dialog.c
@@ -99,7 +99,7 @@ struct _PanelPreferencesDialog
-G_DEFINE_TYPE (PanelPreferencesDialog, panel_preferences_dialog, GTK_TYPE_BUILDER);
+G_DEFINE_TYPE (PanelPreferencesDialog, panel_preferences_dialog, GTK_TYPE_BUILDER)
@@ -355,7 +355,7 @@ panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobo
{
itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
dialog->changed_handler_id =
- g_signal_connect_swapped (G_OBJECT (itembar), "notify::changed",
+ g_signal_connect_swapped (G_OBJECT (itembar), "changed",
G_CALLBACK (panel_preferences_dialog_item_store_rebuild),
dialog);
diff --git a/panel/panel-window.c b/panel/panel-window.c
index 0cd86f3..ed36c65 100644
--- a/panel/panel-window.c
+++ b/panel/panel-window.c
@@ -946,7 +946,7 @@ panel_window_size_request (GtkWidget *widget,
{
PanelWindow *window = PANEL_WINDOW (widget);
GtkRequisition child_requisition = { 0, 0 };
- gint value, length;
+ gint length;
gint extra_width = 0, extra_height = 0;
PanelBorders borders;
@@ -974,20 +974,19 @@ panel_window_size_request (GtkWidget *widget,
if (PANEL_HAS_FLAG (borders, PANEL_BORDER_BOTTOM))
extra_height++;
- /* set the window requisition */
+ requisition->height = child_requisition.height + extra_height;
+ requisition->width = child_requisition.width + extra_width;
+
+ /* respect the length and monitor/screen size */
if (window->horizontal)
{
- requisition->height = window->size + extra_height;
length = window->area.width * window->length;
- value = child_requisition.width + extra_width;
- requisition->width = CLAMP (value, length, window->area.width);
+ requisition->width = CLAMP (requisition->width, length, window->area.width);
}
else
{
- requisition->width = window->size + extra_width;
length = window->area.height * window->length;
- value = child_requisition.height + extra_height;
- requisition->height = CLAMP (value, length, window->area.height);
+ requisition->height = CLAMP (requisition->height, length, window->area.height);
}
}
More information about the Xfce4-commits
mailing list