diff options
Diffstat (limited to 'shell/e-sidebar.c')
-rw-r--r-- | shell/e-sidebar.c | 887 |
1 files changed, 305 insertions, 582 deletions
diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c index d3404b5813..aa63f00ed4 100644 --- a/shell/e-sidebar.c +++ b/shell/e-sidebar.c @@ -16,234 +16,66 @@ * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include "e-sidebar.h" -#include "e-shell-marshal.h" +#define E_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SIDEBAR, ESidebarPrivate)) -#include <gconf/gconf-client.h> -#include <libgnome/gnome-gconf.h> +#define H_PADDING 6 +#define V_PADDING 6 -typedef struct { - GtkWidget *button_widget; - GtkWidget *label; - GtkWidget *icon; - GtkWidget *hbox; - GdkPixbuf *default_icon; - int id; -} Button; +#define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH_HORIZ struct _ESidebarPrivate { - ESidebarMode mode; - ESidebarMode toolbar_mode; - - gboolean show; - - GtkWidget *selection_widget; - GSList *buttons; - - guint style_changed_id; - - gboolean in_toggle; + GList *proxies; + gboolean actions_visible; + GtkToolbarStyle toolbar_style; }; - enum { - BUTTON_SELECTED, - BUTTON_PRESSED, - NUM_SIGNALS + PROP_0, + PROP_ACTIONS_VISIBLE, + PROP_TOOLBAR_STYLE }; -static unsigned int signals[NUM_SIGNALS] = { 0 }; - -G_DEFINE_TYPE (ESidebar, e_sidebar, GTK_TYPE_CONTAINER) - -#define INTERNAL_MODE(sidebar) (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR ? sidebar->priv->toolbar_mode : sidebar->priv->mode) -#define H_PADDING 6 -#define V_PADDING 6 - -/* Utility functions. */ - -static Button * -button_new (GtkWidget *button_widget, - GtkWidget *label, - GtkWidget *icon, - GtkWidget *hbox, - int id) -{ - Button *button = g_new (Button, 1); - - button->button_widget = button_widget; - button->label = label; - button->icon = icon; - button->hbox = hbox; - button->id = id; - button->default_icon = NULL; - - g_object_ref (button_widget); - g_object_ref (label); - g_object_ref (icon); - g_object_ref (hbox); - - return button; -} - -static void -button_free (Button *button) -{ - g_object_unref (button->button_widget); - g_object_unref (button->label); - g_object_unref (button->icon); - g_object_unref (button->hbox); - if (button->default_icon) - g_object_unref (button->default_icon); - g_free (button); -} - -static void -update_buttons (ESidebar *sidebar, int new_selected_id) -{ - GSList *p; - - sidebar->priv->in_toggle = TRUE; - - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - - if (button->id == new_selected_id) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE); - } - - sidebar->priv->in_toggle = FALSE; -} - - -/* Callbacks. */ - -static void -button_toggled_callback (GtkToggleButton *toggle_button, - ESidebar *sidebar) -{ - int id = 0; - gboolean is_active = FALSE; - GSList *p; - - if (sidebar->priv->in_toggle) - return; - - sidebar->priv->in_toggle = TRUE; - - if (gtk_toggle_button_get_active (toggle_button)) - is_active = TRUE; - - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - - if (button->button_widget != GTK_WIDGET (toggle_button)) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE); - } else { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE); - id = button->id; - } - } - - sidebar->priv->in_toggle = FALSE; - - if (is_active) - g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id); -} - -static gboolean -button_pressed_callback (GtkToggleButton *toggle_button, - GdkEventButton *event, - ESidebar *sidebar) -{ - gboolean return_val = FALSE; - GSList *p; - - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - - if (button->button_widget == GTK_WIDGET (toggle_button)) - g_signal_emit (sidebar, signals [BUTTON_PRESSED], - 0, event, button->id, &return_val); - } - - return return_val; -} - -static gboolean -button_query_tooltip (GtkWidget *widget, - gint x, - gint y, - gboolean keyboard_mode, - GtkTooltip *tooltip, - ESidebar *sidebar) -{ - /* Show the tooltip only if the label is hidden */ - if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) { - char *tip; - - tip = g_object_get_data (G_OBJECT (widget), - "ESidebar:button-tooltip"); - if (tip) { - gtk_tooltip_set_text (tooltip, tip); - - return TRUE; - } - } - - return FALSE; -} - - -/* Layout. */ +static gpointer parent_class; static int -layout_buttons (ESidebar *sidebar) +sidebar_layout_actions (ESidebar *sidebar) { GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation; - ESidebarMode mode; gboolean icons_only; - int num_btns = g_slist_length (sidebar->priv->buttons), btns_per_row; - GSList **rows, *p; - Button *button; + int num_btns = g_list_length (sidebar->priv->proxies), btns_per_row; + GList **rows, *p; int row_number; - int max_btn_width = 0, max_btn_height = 0; + int max_width = 0, max_height = 0; int row_last; int x, y; int i; - y = allocation->y + allocation->height - V_PADDING - 1; + /*y = allocation->y + allocation->height - V_PADDING - 1;*/ + y = allocation->y + allocation->height - 1; if (num_btns == 0) return y; - mode = INTERNAL_MODE (sidebar); - icons_only = (mode == E_SIDEBAR_MODE_ICON); + icons_only = (sidebar->priv->toolbar_style == GTK_TOOLBAR_ICONS); /* Figure out the max width and height */ - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { + for (p = sidebar->priv->proxies; p != NULL; p = p->next) { + GtkWidget *widget = p->data; GtkRequisition requisition; - button = p->data; - gtk_widget_size_request (GTK_WIDGET (button->button_widget), &requisition); - - max_btn_height = MAX (max_btn_height, requisition.height); - max_btn_width = MAX (max_btn_width, requisition.width); + gtk_widget_size_request (widget, &requisition); + max_height = MAX (max_height, requisition.height); + max_width = MAX (max_width, requisition.width); } /* Figure out how many rows and columns we'll use. */ - btns_per_row = allocation->width / (max_btn_width + H_PADDING); + btns_per_row = MAX (1, allocation->width / (max_width + H_PADDING)); if (!icons_only) { /* If using text buttons, we want to try to have a * completely filled-in grid, but if we can't, we want @@ -254,26 +86,25 @@ layout_buttons (ESidebar *sidebar) } /* Assign buttons to rows */ - rows = g_new0 (GSList *, num_btns / btns_per_row + 1); + rows = g_new0 (GList *, num_btns / btns_per_row + 1); if (!icons_only && num_btns % btns_per_row != 0) { - button = sidebar->priv->buttons->data; - rows [0] = g_slist_append (rows [0], button->button_widget); + rows [0] = g_list_append (rows [0], sidebar->priv->proxies->data); - p = sidebar->priv->buttons->next; + p = sidebar->priv->proxies->next; row_number = p ? 1 : 0; } else { - p = sidebar->priv->buttons; + p = sidebar->priv->proxies; row_number = 0; } for (; p != NULL; p = p->next) { - button = p->data; + GtkWidget *widget = p->data; - if (g_slist_length (rows [row_number]) == btns_per_row) + if (g_list_length (rows [row_number]) == btns_per_row) row_number ++; - rows [row_number] = g_slist_append (rows [row_number], button->button_widget); + rows [row_number] = g_list_append (rows [row_number], widget); } row_last = row_number; @@ -282,11 +113,11 @@ layout_buttons (ESidebar *sidebar) for (i = row_last; i >= 0; i --) { int len, extra_width; - y -= max_btn_height; + y -= max_height; x = H_PADDING + allocation->x; - len = g_slist_length (rows[i]); - if (mode == E_SIDEBAR_MODE_TEXT || mode == E_SIDEBAR_MODE_BOTH) - extra_width = (allocation->width - (len * max_btn_width ) - (len * H_PADDING)) / len; + len = g_list_length (rows[i]); + if (!icons_only) + extra_width = (allocation->width - (len * max_width ) - (len * H_PADDING)) / len; else extra_width = 0; for (p = rows [i]; p != NULL; p = p->next) { @@ -294,8 +125,8 @@ layout_buttons (ESidebar *sidebar) child_allocation.x = x; child_allocation.y = y; - child_allocation.width = max_btn_width + extra_width; - child_allocation.height = max_btn_height; + child_allocation.width = max_width + extra_width; + child_allocation.height = max_height; gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation); @@ -306,493 +137,385 @@ layout_buttons (ESidebar *sidebar) } for (i = 0; i <= row_last; i ++) - g_slist_free (rows [i]); + g_list_free (rows [i]); g_free (rows); return y; } +/* GtkWidget methods. */ + static void -do_layout (ESidebar *sidebar) +sidebar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation; - GtkAllocation child_allocation; - int y; - - if (sidebar->priv->show) - y = layout_buttons (sidebar); - else - y = allocation->y + allocation->height; - - /* Place the selection widget. */ - child_allocation.x = allocation->x; - child_allocation.y = allocation->y; - child_allocation.width = allocation->width; - child_allocation.height = y - allocation->y; + switch (property_id) { + case PROP_ACTIONS_VISIBLE: + e_sidebar_set_actions_visible ( + E_SIDEBAR (object), + g_value_get_boolean (value)); + return; + + case PROP_TOOLBAR_STYLE: + e_sidebar_set_toolbar_style ( + E_SIDEBAR (object), + g_value_get_enum (value)); + return; + } - gtk_widget_size_allocate (sidebar->priv->selection_widget, & child_allocation); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } - -/* GtkContainer methods. */ - static void -impl_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - void *callback_data) +sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - ESidebar *sidebar = E_SIDEBAR (container); - GSList *p; - - if (sidebar->priv->selection_widget != NULL) - (* callback) (sidebar->priv->selection_widget, callback_data); - - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - GtkWidget *widget = ((Button *) p->data)->button_widget; - (* callback) (widget, callback_data); + switch (property_id) { + case PROP_ACTIONS_VISIBLE: + g_value_set_boolean ( + value, e_sidebar_get_actions_visible ( + E_SIDEBAR (object))); + return; + + case PROP_TOOLBAR_STYLE: + g_value_set_enum ( + value, e_sidebar_get_toolbar_style ( + E_SIDEBAR (object))); + return; } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -impl_remove (GtkContainer *container, - GtkWidget *widget) +sidebar_dispose (GObject *object) { - ESidebar *sidebar = E_SIDEBAR (container); - GSList *p; + ESidebarPrivate *priv = E_SIDEBAR (object)->priv; - if (widget == sidebar->priv->selection_widget) { - e_sidebar_set_selection_widget (sidebar, NULL); - return; + while (priv->proxies != NULL) { + GtkWidget *widget = priv->proxies->data; + gtk_container_remove (GTK_CONTAINER (object), widget); } - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - GtkWidget *button_widget = ((Button *) p->data)->button_widget; - - if (button_widget == widget) { - gtk_widget_unparent (button_widget); - sidebar->priv->buttons = g_slist_remove_link (sidebar->priv->buttons, p); - gtk_widget_queue_resize (GTK_WIDGET (sidebar)); - break; - } - } + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } - -/* GtkWidget methods. */ - static void -impl_size_request (GtkWidget *widget, - GtkRequisition *requisition) +sidebar_size_request (GtkWidget *widget, + GtkRequisition *requisition) { - ESidebar *sidebar = E_SIDEBAR (widget); - GSList *p; + ESidebarPrivate *priv; + GtkWidget *child; + GList *iter; - if (sidebar->priv->selection_widget == NULL) { + priv = E_SIDEBAR_GET_PRIVATE (widget); + child = gtk_bin_get_child (GTK_BIN (widget)); + + if (child == NULL) { requisition->width = 2 * H_PADDING; - requisition->height = 2 * V_PADDING; + requisition->height = V_PADDING; } else { - gtk_widget_size_request (sidebar->priv->selection_widget, requisition); + gtk_widget_size_request (child, requisition); } - if (!sidebar->priv->show) + if (!priv->actions_visible) return; - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - GtkRequisition button_requisition; + for (iter = priv->proxies; iter != NULL; iter = iter->next) { + GtkWidget *widget = iter->data; + GtkRequisition child_requisition; + + gtk_widget_size_request (widget, &child_requisition); - gtk_widget_size_request (button->button_widget, &button_requisition); + child_requisition.width += H_PADDING; + child_requisition.height += V_PADDING; - requisition->width = MAX (requisition->width, button_requisition.width + 2 * H_PADDING); - requisition->height += button_requisition.height + V_PADDING; + requisition->width = MAX ( + requisition->width, child_requisition.width); + requisition->height += child_requisition.height; } } static void -impl_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +sidebar_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { + ESidebarPrivate *priv; + GtkWidget *child; + gint y; + + priv = E_SIDEBAR_GET_PRIVATE (widget); + widget->allocation = *allocation; - do_layout (E_SIDEBAR (widget)); -} + if (priv->actions_visible) + y = sidebar_layout_actions (E_SIDEBAR (widget)); + else + y = allocation->y + allocation->height; + child = gtk_bin_get_child (GTK_BIN (widget)); -/* GObject methods. */ + if (child != NULL) { + GtkAllocation child_allocation; + + child_allocation.x = allocation->x; + child_allocation.y = allocation->y; + child_allocation.width = allocation->width; + child_allocation.height = y - allocation->y; + + gtk_widget_size_allocate (child, &child_allocation); + } +} static void -impl_dispose (GObject *object) +sidebar_remove (GtkContainer *container, + GtkWidget *widget) { - ESidebarPrivate *priv = E_SIDEBAR (object)->priv; - GConfClient *gconf_client = gconf_client_get_default (); + ESidebarPrivate *priv; + GList *link; - g_slist_foreach (priv->buttons, (GFunc) button_free, NULL); - g_slist_free (priv->buttons); - priv->buttons = NULL; + priv = E_SIDEBAR_GET_PRIVATE (container); - if (priv->style_changed_id) { - gconf_client_notify_remove (gconf_client, priv->style_changed_id); - priv->style_changed_id = 0; - } + /* Look in the internal widgets first. */ + link = g_list_find (priv->proxies, widget); + if (link != NULL) { + GtkWidget *widget = link->data; - g_object_unref (gconf_client); + gtk_widget_unparent (widget); + priv->proxies = g_list_delete_link (priv->proxies, link); + gtk_widget_queue_resize (GTK_WIDGET (container)); + return; + } - (* G_OBJECT_CLASS (e_sidebar_parent_class)->dispose) (object); + /* Chain up to parent's remove() method. */ + GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); } -static gboolean -boolean_handled_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) +static void +sidebar_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { - gboolean handled; + ESidebarPrivate *priv; + + priv = E_SIDEBAR_GET_PRIVATE (container); - handled = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, handled); + if (include_internals) + g_list_foreach ( + priv->proxies, (GFunc) callback, callback_data); - return !handled; + /* Chain up to parent's forall() method. */ + GTK_CONTAINER_CLASS (parent_class)->forall ( + container, include_internals, callback, callback_data); } -static void -impl_finalize (GObject *object) +static GtkIconSize +sidebar_get_icon_size (GtkToolShell *shell) { - ESidebarPrivate *priv = E_SIDEBAR (object)->priv; - - g_free (priv); + return GTK_ICON_SIZE_LARGE_TOOLBAR; +} - (* G_OBJECT_CLASS (e_sidebar_parent_class)->finalize) (object); +static GtkOrientation +sidebar_get_orientation (GtkToolShell *shell) +{ + return GTK_ORIENTATION_HORIZONTAL; } +static GtkToolbarStyle +sidebar_get_style (GtkToolShell *shell) +{ + return e_sidebar_get_toolbar_style (E_SIDEBAR (shell)); +} -/* Initialization. */ +static GtkReliefStyle +sidebar_get_relief_style (GtkToolShell *shell) +{ + g_debug ("%s", G_STRFUNC); + return GTK_RELIEF_NORMAL; +} static void -e_sidebar_class_init (ESidebarClass *klass) +sidebar_class_init (ESidebarClass *class) { - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - container_class->forall = impl_forall; - container_class->remove = impl_remove; - - widget_class->size_request = impl_size_request; - widget_class->size_allocate = impl_size_allocate; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; - - signals[BUTTON_SELECTED] - = g_signal_new ("button_selected", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ESidebarClass, button_selected), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - signals[BUTTON_PRESSED] - = g_signal_new ("button_pressed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESidebarClass, button_pressed), - boolean_handled_accumulator, NULL, - e_shell_marshal_NONE__POINTER_INT, - G_TYPE_BOOLEAN, 2, - G_TYPE_POINTER, G_TYPE_INT); + GObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkContainerClass *container_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = sidebar_set_property; + object_class->get_property = sidebar_get_property; + object_class->dispose = sidebar_dispose; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->size_request = sidebar_size_request; + widget_class->size_allocate = sidebar_size_allocate; + + container_class = GTK_CONTAINER_CLASS (class); + container_class->remove = sidebar_remove; + container_class->forall = sidebar_forall; + + g_object_class_install_property ( + object_class, + PROP_ACTIONS_VISIBLE, + g_param_spec_boolean ( + "actions-visible", + NULL, + NULL, + TRUE, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_TOOLBAR_STYLE, + g_param_spec_enum ( + "toolbar-style", + NULL, + NULL, + GTK_TYPE_TOOLBAR_STYLE, + DEFAULT_TOOLBAR_STYLE, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE)); } static void -e_sidebar_init (ESidebar *sidebar) +sidebar_init (ESidebar *sidebar) { - ESidebarPrivate *priv; + sidebar->priv = E_SIDEBAR_GET_PRIVATE (sidebar); GTK_WIDGET_SET_FLAGS (sidebar, GTK_NO_WINDOW); - - priv = g_new0 (ESidebarPrivate, 1); - sidebar->priv = priv; - - priv->mode = E_SIDEBAR_MODE_TEXT; } -GtkWidget * -e_sidebar_new (void) +static void +sidebar_tool_shell_iface_init (GtkToolShellIface *iface) { - ESidebar *sidebar = g_object_new (e_sidebar_get_type (), NULL); - - return GTK_WIDGET (sidebar); + iface->get_icon_size = sidebar_get_icon_size; + iface->get_orientation = sidebar_get_orientation; + iface->get_style = sidebar_get_style; + iface->get_relief_style = sidebar_get_relief_style; } - -void -e_sidebar_set_selection_widget (ESidebar *sidebar, GtkWidget *widget) +GType +e_sidebar_get_type (void) { - if (sidebar->priv->selection_widget != NULL) - gtk_widget_unparent (sidebar->priv->selection_widget); - - sidebar->priv->selection_widget = widget; - - if (widget != NULL) - gtk_widget_set_parent (widget, GTK_WIDGET (sidebar)); + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) sidebar_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo tool_shell_info = { + (GInterfaceInitFunc) sidebar_tool_shell_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + type = g_type_register_static ( + GTK_TYPE_BIN, "ESidebar", &type_info, 0); + + g_type_add_interface_static ( + type, GTK_TYPE_TOOL_SHELL, &tool_shell_info); + } - gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + return type; } - -void -e_sidebar_add_button (ESidebar *sidebar, - const char *label, - const char *tooltips, - GdkPixbuf *icon, - int id) +GtkWidget * +e_sidebar_new (void) { - GtkWidget *button_widget; - GtkWidget *hbox; - GtkWidget *icon_widget; - GtkWidget *label_widget; - - button_widget = gtk_toggle_button_new (); - if (sidebar->priv->show) - gtk_widget_show (button_widget); - g_signal_connect (button_widget, "toggled", G_CALLBACK (button_toggled_callback), sidebar); - g_signal_connect (button_widget, "button_press_event", - G_CALLBACK (button_pressed_callback), sidebar); - - hbox = gtk_hbox_new (FALSE, 3); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 2); - gtk_widget_show (hbox); - - icon_widget = gtk_image_new_from_pixbuf (icon); - gtk_widget_show (icon_widget); - - label_widget = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); - gtk_widget_show (label_widget); - - g_object_set_data_full (G_OBJECT (button_widget), - "ESidebar:button-tooltip", - g_strdup (tooltips), - g_free); - gtk_widget_set_has_tooltip (button_widget, TRUE); - g_signal_connect (button_widget, "query-tooltip", - G_CALLBACK (button_query_tooltip), sidebar); - - switch (INTERNAL_MODE (sidebar)) { - case E_SIDEBAR_MODE_TEXT: - gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0); - break; - case E_SIDEBAR_MODE_ICON: - gtk_box_pack_start (GTK_BOX (hbox), icon_widget, TRUE, TRUE, 0); - break; - case E_SIDEBAR_MODE_BOTH: - default: - gtk_box_pack_start (GTK_BOX (hbox), icon_widget, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0); - break; - } - - gtk_container_add (GTK_CONTAINER (button_widget), hbox); - - sidebar->priv->buttons = g_slist_append (sidebar->priv->buttons, button_new (button_widget, label_widget, icon_widget, hbox, id)); - gtk_widget_set_parent (button_widget, GTK_WIDGET (sidebar)); - - gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + return g_object_new (E_TYPE_SIDEBAR, NULL); } -/** - * e_sidebar_change_button_icon - * This will change icon in icon_widget of the button of known component. - * You cannot change icon as in a stack, only one default icon will be stored. - * @param sidebar ESidebar instance. - * @param icon Pointer to buffer with icon. Can by NULL, in this case the icon will be - * put back to default one for the component. - * @param button_id Component's button ID, for which change the icon. - **/ - void -e_sidebar_change_button_icon (ESidebar *sidebar, GdkPixbuf *icon, int button_id) +e_sidebar_add_action (ESidebar *sidebar, + GtkAction *action) { - GSList *p; - - g_return_if_fail (sidebar != NULL); + GtkWidget *widget; - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; + g_return_if_fail (E_IS_SIDEBAR (sidebar)); + g_return_if_fail (GTK_IS_ACTION (action)); - if (button->id == button_id) { - if (!button->icon) - break; + g_object_ref (action); + widget = gtk_action_create_tool_item (action); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), TRUE); + gtk_widget_show (widget); - if (icon) { - if (!button->default_icon) - button->default_icon = gdk_pixbuf_copy (gtk_image_get_pixbuf (GTK_IMAGE (button->icon))); + sidebar->priv->proxies = g_list_append (sidebar->priv->proxies, widget); - gtk_image_set_from_pixbuf (GTK_IMAGE (button->icon), icon); - } else if (button->default_icon) { - gtk_image_set_from_pixbuf (GTK_IMAGE (button->icon), button->default_icon); - g_object_unref (button->default_icon); - button->default_icon = NULL; - } + gtk_widget_set_parent (widget, GTK_WIDGET (sidebar)); + gtk_widget_queue_resize (GTK_WIDGET (sidebar)); - break; - } - } + g_debug ("Relief Style: %d", gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (widget))); } -void -e_sidebar_select_button (ESidebar *sidebar, int id) +gboolean +e_sidebar_get_actions_visible (ESidebar *sidebar) { - update_buttons (sidebar, id); + g_return_val_if_fail (E_IS_SIDEBAR (sidebar), FALSE); - g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id); + return sidebar->priv->actions_visible; } -ESidebarMode -e_sidebar_get_mode (ESidebar *sidebar) -{ - return sidebar->priv->mode; -} - - -static GConfEnumStringPair toolbar_styles[] = { - { E_SIDEBAR_MODE_TEXT, "text" }, - { E_SIDEBAR_MODE_ICON, "icons" }, - { E_SIDEBAR_MODE_BOTH, "both" }, - { E_SIDEBAR_MODE_BOTH, "both-horiz" }, - { E_SIDEBAR_MODE_BOTH, "both_horiz" }, - { -1, NULL } -}; - -static void -set_mode_internal (ESidebar *sidebar, ESidebarMode mode ) +void +e_sidebar_set_actions_visible (ESidebar *sidebar, + gboolean visible) { - GSList *p; + GList *iter; - if (mode == INTERNAL_MODE (sidebar)) + if (sidebar->priv->actions_visible == visible) return; - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - - switch (mode) { - case E_SIDEBAR_MODE_TEXT: - gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon); - if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0); - gtk_widget_show (button->label); - } - break; - case E_SIDEBAR_MODE_ICON: - gtk_container_remove(GTK_CONTAINER (button->hbox), button->label); - if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, TRUE, TRUE, 0); - gtk_widget_show (button->icon); - } else - gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon, - "expand", TRUE, - NULL); - break; - case E_SIDEBAR_MODE_BOTH: - if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) { - gtk_container_remove (GTK_CONTAINER (button->hbox), button->label); - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, FALSE, TRUE, 0); - gtk_widget_show (button->icon); - } else { - gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon, - "expand", FALSE, - NULL); - } - - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0); - gtk_widget_show (button->label); - break; - default: - break; - } - } -} + sidebar->priv->actions_visible = visible; -static void -style_changed_notify (GConfClient *gconf, guint id, GConfEntry *entry, void *data) -{ - ESidebar *sidebar = data; - char *val; - int mode; - - val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL); - if (val == NULL || !gconf_string_to_enum (toolbar_styles, val, &mode)) - mode = E_SIDEBAR_MODE_BOTH; - g_free(val); - - set_mode_internal (E_SIDEBAR (sidebar), mode); - sidebar->priv->toolbar_mode = mode; + for (iter = sidebar->priv->proxies; iter != NULL; iter = iter->next) + g_object_set (iter->data, "visible", visible, NULL); gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + + g_object_notify (G_OBJECT (sidebar), "actions-visible"); } -void -e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode) +GtkToolbarStyle +e_sidebar_get_toolbar_style (ESidebar *sidebar) { - GConfClient *gconf_client = gconf_client_get_default (); - - if (sidebar->priv->mode == mode) - return; - - if (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR) { - if (sidebar->priv->style_changed_id) { - gconf_client_notify_remove (gconf_client, sidebar->priv->style_changed_id); - sidebar->priv->style_changed_id = 0; - } - } - - if (mode != E_SIDEBAR_MODE_TOOLBAR) { - set_mode_internal (sidebar, mode); - - gtk_widget_queue_resize (GTK_WIDGET (sidebar)); - } else { - /* This is a little bit tricky, toolbar mode is more - * of a meta-mode where the actual mode is dictated by - * the gnome toolbar setting, so that is why we have - * the is_toolbar_mode bool - it tracks the toolbar - * mode while the mode member is the actual look and - * feel */ - sidebar->priv->style_changed_id = gconf_client_notify_add (gconf_client, - "/desktop/gnome/interface/toolbar_style", - style_changed_notify, sidebar, NULL, NULL); - style_changed_notify (gconf_client, 0, NULL, sidebar); - } - - g_object_unref (gconf_client); + g_return_val_if_fail (E_IS_SIDEBAR (sidebar), DEFAULT_TOOLBAR_STYLE); - sidebar->priv->mode = mode; + return sidebar->priv->toolbar_style; } void -e_sidebar_set_show_buttons (ESidebar *sidebar, gboolean show) +e_sidebar_set_toolbar_style (ESidebar *sidebar, + GtkToolbarStyle style) { - GSList *p; + g_return_if_fail (E_IS_SIDEBAR (sidebar)); - if (sidebar->priv->show == show) + if (sidebar->priv->toolbar_style == style) return; - for (p = sidebar->priv->buttons; p != NULL; p = p->next) { - Button *button = p->data; - - if (show) - gtk_widget_show (button->button_widget); - else - gtk_widget_hide (button->button_widget); - } + sidebar->priv->toolbar_style = style; - sidebar->priv->show = show; + g_list_foreach ( + sidebar->priv->proxies, + (GFunc) gtk_tool_item_toolbar_reconfigured, NULL); - gtk_widget_queue_resize (GTK_WIDGET (sidebar)); -} - -gboolean -e_sidebar_get_show_buttons (ESidebar *sidebar) -{ - return sidebar->priv->show; + g_object_notify (G_OBJECT (sidebar), "toolbar-style"); } |