Prefer dealing with GdkEvent pointers and using accessor functions like gdk_event_get_button(). This is complicated by the fact that some GtkWidget method declarations still use GdkEventButton pointers, and synthesizing button events pretty much requires direct GdkEventButton access. But GDK seems to be nudging itself toward sealing the GdkEvent union. Likely to happen in GDK4. Mainly clean up signal handlers and leave method overrides alone for now.
793 lines
19 KiB
C
793 lines
19 KiB
C
/*
|
|
* e-shell-switcher.c
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with the program; if not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
*
|
|
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* SECTION: e-shell-switcher
|
|
* @short_description: buttons for switching views
|
|
* @include: shell/e-shell-switcher.h
|
|
**/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include "e-shell-switcher.h"
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <libebackend/libebackend.h>
|
|
|
|
#define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE \
|
|
((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
|
|
|
|
#define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE \
|
|
((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
|
|
|
|
#define H_PADDING 6
|
|
#define V_PADDING 6
|
|
|
|
struct _EShellSwitcherPrivate {
|
|
GList *proxies;
|
|
gboolean style_set;
|
|
GtkToolbarStyle style;
|
|
GtkSettings *settings;
|
|
gulong settings_handler_id;
|
|
gboolean toolbar_visible;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_TOOLBAR_STYLE,
|
|
PROP_TOOLBAR_VISIBLE
|
|
};
|
|
|
|
enum {
|
|
STYLE_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint signals[LAST_SIGNAL];
|
|
|
|
/* Forward Declarations */
|
|
static void shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface);
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (
|
|
EShellSwitcher,
|
|
e_shell_switcher,
|
|
GTK_TYPE_BIN,
|
|
G_IMPLEMENT_INTERFACE (
|
|
E_TYPE_EXTENSIBLE, NULL)
|
|
G_IMPLEMENT_INTERFACE (
|
|
GTK_TYPE_TOOL_SHELL,
|
|
shell_switcher_tool_shell_iface_init))
|
|
|
|
static gint
|
|
shell_switcher_layout_actions (EShellSwitcher *switcher)
|
|
{
|
|
GtkAllocation allocation;
|
|
gint num_btns = g_list_length (switcher->priv->proxies), btns_per_row;
|
|
GList **rows, *p;
|
|
gboolean icons_only;
|
|
gint row_number;
|
|
gint max_width = 0;
|
|
gint max_height = 0;
|
|
gint row_last;
|
|
gint x, y;
|
|
gint i;
|
|
|
|
gtk_widget_get_allocation (GTK_WIDGET (switcher), &allocation);
|
|
|
|
y = allocation.y + allocation.height;
|
|
|
|
if (num_btns == 0)
|
|
return allocation.height;
|
|
|
|
icons_only = (switcher->priv->style == GTK_TOOLBAR_ICONS);
|
|
|
|
/* Figure out the max width and height. */
|
|
for (p = switcher->priv->proxies; p != NULL; p = p->next) {
|
|
GtkWidget *widget = p->data;
|
|
GtkRequisition requisition;
|
|
|
|
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
|
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 = 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
|
|
* the odd row to have just a single button. */
|
|
while (btns_per_row > 0 && num_btns % btns_per_row > 1)
|
|
btns_per_row--;
|
|
}
|
|
|
|
/* Assign buttons to rows. */
|
|
rows = g_new0 (GList *, num_btns / btns_per_row + 1);
|
|
|
|
if (!icons_only && num_btns % btns_per_row != 0) {
|
|
rows[0] = g_list_append (rows[0], switcher->priv->proxies->data);
|
|
|
|
p = switcher->priv->proxies->next;
|
|
row_number = p ? 1 : 0;
|
|
} else {
|
|
p = switcher->priv->proxies;
|
|
row_number = 0;
|
|
}
|
|
|
|
for (; p != NULL; p = p->next) {
|
|
GtkWidget *widget = p->data;
|
|
|
|
if (g_list_length (rows[row_number]) == btns_per_row)
|
|
row_number++;
|
|
|
|
rows[row_number] = g_list_append (rows[row_number], widget);
|
|
}
|
|
|
|
row_last = row_number;
|
|
|
|
/* Layout the buttons. */
|
|
for (i = row_last; i >= 0; i--) {
|
|
gint len, extra_width;
|
|
|
|
x = H_PADDING + allocation.x;
|
|
y -= max_height;
|
|
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) {
|
|
GtkAllocation child_allocation;
|
|
|
|
child_allocation.x = x;
|
|
child_allocation.y = y;
|
|
child_allocation.width = max_width + extra_width;
|
|
child_allocation.height = max_height;
|
|
|
|
gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
|
|
|
|
x += child_allocation.width + H_PADDING;
|
|
}
|
|
|
|
y -= V_PADDING;
|
|
}
|
|
|
|
for (i = 0; i <= row_last; i++)
|
|
g_list_free (rows[i]);
|
|
g_free (rows);
|
|
|
|
return y - allocation.y;
|
|
}
|
|
|
|
static void
|
|
shell_switcher_toolbar_style_changed_cb (EShellSwitcher *switcher)
|
|
{
|
|
if (!switcher->priv->style_set) {
|
|
switcher->priv->style_set = TRUE;
|
|
e_shell_switcher_unset_style (switcher);
|
|
}
|
|
}
|
|
|
|
static void
|
|
shell_switcher_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_TOOLBAR_STYLE:
|
|
e_shell_switcher_set_style (
|
|
E_SHELL_SWITCHER (object),
|
|
g_value_get_enum (value));
|
|
return;
|
|
|
|
case PROP_TOOLBAR_VISIBLE:
|
|
e_shell_switcher_set_visible (
|
|
E_SHELL_SWITCHER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_TOOLBAR_STYLE:
|
|
g_value_set_enum (
|
|
value, e_shell_switcher_get_style (
|
|
E_SHELL_SWITCHER (object)));
|
|
return;
|
|
|
|
case PROP_TOOLBAR_VISIBLE:
|
|
g_value_set_boolean (
|
|
value, e_shell_switcher_get_visible (
|
|
E_SHELL_SWITCHER (object)));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_dispose (GObject *object)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (object);
|
|
|
|
while (priv->proxies != NULL) {
|
|
GtkWidget *widget = priv->proxies->data;
|
|
gtk_container_remove (GTK_CONTAINER (object), widget);
|
|
}
|
|
|
|
/* Chain up to parent's dispose() method. */
|
|
G_OBJECT_CLASS (e_shell_switcher_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_get_preferred_width (GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
GtkWidget *child;
|
|
GList *iter;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
|
|
|
|
*minimum = *natural = 0;
|
|
|
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
if (child != NULL)
|
|
gtk_widget_get_preferred_width (child, minimum, natural);
|
|
|
|
if (!priv->toolbar_visible)
|
|
return;
|
|
|
|
for (iter = priv->proxies; iter != NULL; iter = iter->next) {
|
|
GtkWidget *widget_proxy = iter->data;
|
|
gint child_min, child_nat;
|
|
|
|
gtk_widget_get_preferred_width (
|
|
widget_proxy, &child_min, &child_nat);
|
|
|
|
child_min += H_PADDING;
|
|
child_nat += H_PADDING;
|
|
|
|
*minimum = MAX (*minimum, child_min);
|
|
*natural = MAX (*natural, child_nat);
|
|
}
|
|
}
|
|
|
|
static void
|
|
shell_switcher_get_preferred_height (GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
GtkWidget *child;
|
|
GList *iter;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
|
|
|
|
*minimum = *natural = 0;
|
|
|
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
if (child != NULL)
|
|
gtk_widget_get_preferred_height (child, minimum, natural);
|
|
|
|
if (!priv->toolbar_visible)
|
|
return;
|
|
|
|
for (iter = priv->proxies; iter != NULL; iter = iter->next) {
|
|
GtkWidget *widget = iter->data;
|
|
gint child_min, child_nat;
|
|
|
|
gtk_widget_get_preferred_height (
|
|
widget, &child_min, &child_nat);
|
|
|
|
child_min += V_PADDING;
|
|
child_nat += V_PADDING;
|
|
|
|
*minimum += child_min;
|
|
*natural += child_nat;
|
|
}
|
|
}
|
|
|
|
static void
|
|
shell_switcher_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation)
|
|
{
|
|
EShellSwitcher *switcher;
|
|
GtkAllocation child_allocation;
|
|
GtkWidget *child;
|
|
gint height;
|
|
|
|
switcher = E_SHELL_SWITCHER (widget);
|
|
|
|
gtk_widget_set_allocation (widget, allocation);
|
|
|
|
if (switcher->priv->toolbar_visible)
|
|
height = shell_switcher_layout_actions (switcher);
|
|
else
|
|
height = allocation->height;
|
|
|
|
child_allocation.x = allocation->x;
|
|
child_allocation.y = allocation->y;
|
|
child_allocation.width = allocation->width;
|
|
child_allocation.height = height;
|
|
|
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
if (child != NULL)
|
|
gtk_widget_size_allocate (child, &child_allocation);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_screen_changed (GtkWidget *widget,
|
|
GdkScreen *previous_screen)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
GtkSettings *settings;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
|
|
|
|
if (gtk_widget_has_screen (widget))
|
|
settings = gtk_widget_get_settings (widget);
|
|
else
|
|
settings = NULL;
|
|
|
|
if (settings == priv->settings)
|
|
return;
|
|
|
|
if (priv->settings != NULL) {
|
|
g_signal_handler_disconnect (
|
|
priv->settings, priv->settings_handler_id);
|
|
g_object_unref (priv->settings);
|
|
}
|
|
|
|
if (settings != NULL) {
|
|
priv->settings = g_object_ref (settings);
|
|
priv->settings_handler_id = g_signal_connect_swapped (
|
|
settings, "notify::gtk-toolbar-style",
|
|
G_CALLBACK (shell_switcher_toolbar_style_changed_cb),
|
|
widget);
|
|
} else
|
|
priv->settings = NULL;
|
|
|
|
shell_switcher_toolbar_style_changed_cb (E_SHELL_SWITCHER (widget));
|
|
}
|
|
|
|
static void
|
|
shell_switcher_remove (GtkContainer *container,
|
|
GtkWidget *widget)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
GList *link;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
|
|
|
|
/* Look in the internal widgets first. */
|
|
|
|
link = g_list_find (priv->proxies, widget);
|
|
if (link != NULL) {
|
|
GtkWidget *widget = link->data;
|
|
|
|
gtk_widget_unparent (widget);
|
|
priv->proxies = g_list_delete_link (priv->proxies, link);
|
|
gtk_widget_queue_resize (GTK_WIDGET (container));
|
|
return;
|
|
}
|
|
|
|
/* Chain up to parent's remove() method. */
|
|
GTK_CONTAINER_CLASS (e_shell_switcher_parent_class)->remove (
|
|
container, widget);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_forall (GtkContainer *container,
|
|
gboolean include_internals,
|
|
GtkCallback callback,
|
|
gpointer callback_data)
|
|
{
|
|
EShellSwitcherPrivate *priv;
|
|
|
|
priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
|
|
|
|
if (include_internals)
|
|
g_list_foreach (
|
|
priv->proxies, (GFunc) callback, callback_data);
|
|
|
|
/* Chain up to parent's forall() method. */
|
|
GTK_CONTAINER_CLASS (e_shell_switcher_parent_class)->forall (
|
|
container, include_internals, callback, callback_data);
|
|
}
|
|
|
|
static void
|
|
shell_switcher_style_changed (EShellSwitcher *switcher,
|
|
GtkToolbarStyle style)
|
|
{
|
|
if (switcher->priv->style == style)
|
|
return;
|
|
|
|
switcher->priv->style = style;
|
|
|
|
g_list_foreach (
|
|
switcher->priv->proxies,
|
|
(GFunc) gtk_tool_item_toolbar_reconfigured, NULL);
|
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (switcher));
|
|
g_object_notify (G_OBJECT (switcher), "toolbar-style");
|
|
}
|
|
|
|
static GtkIconSize
|
|
shell_switcher_get_icon_size (GtkToolShell *shell)
|
|
{
|
|
return GTK_ICON_SIZE_LARGE_TOOLBAR;
|
|
}
|
|
|
|
static GtkOrientation
|
|
shell_switcher_get_orientation (GtkToolShell *shell)
|
|
{
|
|
return GTK_ORIENTATION_HORIZONTAL;
|
|
}
|
|
|
|
static GtkToolbarStyle
|
|
shell_switcher_get_style (GtkToolShell *shell)
|
|
{
|
|
return e_shell_switcher_get_style (E_SHELL_SWITCHER (shell));
|
|
}
|
|
|
|
static GtkReliefStyle
|
|
shell_switcher_get_relief_style (GtkToolShell *shell)
|
|
{
|
|
return GTK_RELIEF_NORMAL;
|
|
}
|
|
|
|
static gfloat
|
|
shell_switcher_get_text_alignment (GtkToolShell *shell)
|
|
{
|
|
return 0.0;
|
|
}
|
|
|
|
static void
|
|
e_shell_switcher_class_init (EShellSwitcherClass *class)
|
|
{
|
|
GObjectClass *object_class;
|
|
GtkWidgetClass *widget_class;
|
|
GtkContainerClass *container_class;
|
|
|
|
g_type_class_add_private (class, sizeof (EShellSwitcherPrivate));
|
|
|
|
object_class = G_OBJECT_CLASS (class);
|
|
object_class->set_property = shell_switcher_set_property;
|
|
object_class->get_property = shell_switcher_get_property;
|
|
object_class->dispose = shell_switcher_dispose;
|
|
|
|
widget_class = GTK_WIDGET_CLASS (class);
|
|
widget_class->get_preferred_width = shell_switcher_get_preferred_width;
|
|
widget_class->get_preferred_height = shell_switcher_get_preferred_height;
|
|
widget_class->size_allocate = shell_switcher_size_allocate;
|
|
widget_class->screen_changed = shell_switcher_screen_changed;
|
|
|
|
container_class = GTK_CONTAINER_CLASS (class);
|
|
container_class->remove = shell_switcher_remove;
|
|
container_class->forall = shell_switcher_forall;
|
|
|
|
class->style_changed = shell_switcher_style_changed;
|
|
|
|
/**
|
|
* EShellSwitcher:toolbar-style
|
|
*
|
|
* The switcher's toolbar style.
|
|
**/
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_TOOLBAR_STYLE,
|
|
g_param_spec_enum (
|
|
"toolbar-style",
|
|
"Toolbar Style",
|
|
"The switcher's toolbar style",
|
|
GTK_TYPE_TOOLBAR_STYLE,
|
|
E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT));
|
|
|
|
/**
|
|
* EShellSwitcher:toolbar-visible
|
|
*
|
|
* Whether the switcher is visible.
|
|
**/
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_TOOLBAR_VISIBLE,
|
|
g_param_spec_boolean (
|
|
"toolbar-visible",
|
|
"Toolbar Visible",
|
|
"Whether the switcher is visible",
|
|
TRUE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT));
|
|
|
|
/**
|
|
* EShellSwitcher::style-changed
|
|
* @switcher: the #EShellSwitcher which emitted the signal
|
|
* @style: the new #GtkToolbarStyle of the switcher
|
|
*
|
|
* Emitted when the style of the switcher changes.
|
|
**/
|
|
signals[STYLE_CHANGED] = g_signal_new (
|
|
"style-changed",
|
|
G_OBJECT_CLASS_TYPE (class),
|
|
G_SIGNAL_RUN_FIRST,
|
|
G_STRUCT_OFFSET (EShellSwitcherClass, style_changed),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__ENUM,
|
|
G_TYPE_NONE, 1,
|
|
GTK_TYPE_TOOLBAR_STYLE);
|
|
}
|
|
|
|
static void
|
|
e_shell_switcher_init (EShellSwitcher *switcher)
|
|
{
|
|
switcher->priv = E_SHELL_SWITCHER_GET_PRIVATE (switcher);
|
|
|
|
gtk_widget_set_has_window (GTK_WIDGET (switcher), FALSE);
|
|
|
|
e_extensible_load_extensions (E_EXTENSIBLE (switcher));
|
|
}
|
|
|
|
static void
|
|
shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface)
|
|
{
|
|
iface->get_icon_size = shell_switcher_get_icon_size;
|
|
iface->get_orientation = shell_switcher_get_orientation;
|
|
iface->get_style = shell_switcher_get_style;
|
|
iface->get_relief_style = shell_switcher_get_relief_style;
|
|
iface->get_text_alignment = shell_switcher_get_text_alignment;
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_new:
|
|
*
|
|
* Creates a new #EShellSwitcher instance.
|
|
*
|
|
* Returns: a new #EShellSwitcher instance
|
|
**/
|
|
GtkWidget *
|
|
e_shell_switcher_new (void)
|
|
{
|
|
return g_object_new (E_TYPE_SHELL_SWITCHER, NULL);
|
|
}
|
|
|
|
/*
|
|
* gtk+ doesn't give us what we want - a middle click,
|
|
* option on toolbar items, so we have to get it by force.
|
|
*/
|
|
static GtkButton *
|
|
tool_item_get_button (GtkWidget *widget)
|
|
{
|
|
GtkWidget *child;
|
|
|
|
g_return_val_if_fail (GTK_IS_TOOL_ITEM (widget), NULL);
|
|
|
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
if (child != NULL && GTK_IS_BUTTON (child))
|
|
return GTK_BUTTON (child);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
static gboolean
|
|
tool_item_button_cb (GtkWidget *internal_widget,
|
|
GdkEvent *button_event,
|
|
GtkAction *action)
|
|
{
|
|
guint event_button = 0;
|
|
|
|
g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
|
|
|
|
gdk_event_get_button (button_event, &event_button);
|
|
|
|
if (event_button == 2) {
|
|
gtk_action_activate (action);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_add_action:
|
|
* @switcher: an #EShellSwitcher
|
|
* @switch_action: a #GtkAction
|
|
* @new_window_action: a #GtkAction
|
|
*
|
|
* Adds a button to @switcher that proxies for @switcher_action.
|
|
* Switcher buttons appear in the order they were added. A middle
|
|
* click opens a new window of this type.
|
|
*
|
|
* #EShellWindow adds switcher actions in the order given by the
|
|
* <structfield>sort_order</structfield> field in #EShellBackendClass.
|
|
**/
|
|
void
|
|
e_shell_switcher_add_action (EShellSwitcher *switcher,
|
|
GtkAction *switch_action,
|
|
GtkAction *new_window_action)
|
|
{
|
|
GtkWidget *widget;
|
|
GtkButton *button;
|
|
|
|
g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
|
|
g_return_if_fail (GTK_IS_ACTION (switch_action));
|
|
g_return_if_fail (GTK_IS_ACTION (new_window_action));
|
|
|
|
g_object_ref (switch_action);
|
|
widget = gtk_action_create_tool_item (switch_action);
|
|
gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), TRUE);
|
|
gtk_widget_show (widget);
|
|
|
|
button = tool_item_get_button (widget);
|
|
if (button != NULL)
|
|
g_signal_connect (
|
|
button, "button-release-event",
|
|
G_CALLBACK (tool_item_button_cb),
|
|
new_window_action);
|
|
|
|
switcher->priv->proxies = g_list_append (
|
|
switcher->priv->proxies, widget);
|
|
|
|
gtk_widget_set_parent (widget, GTK_WIDGET (switcher));
|
|
gtk_widget_queue_resize (GTK_WIDGET (switcher));
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_get_style:
|
|
* @switcher: an #EShellSwitcher
|
|
*
|
|
* Returns whether @switcher has text, icons or both.
|
|
*
|
|
* Returns: the current style of @shell
|
|
**/
|
|
GtkToolbarStyle
|
|
e_shell_switcher_get_style (EShellSwitcher *switcher)
|
|
{
|
|
g_return_val_if_fail (
|
|
E_IS_SHELL_SWITCHER (switcher),
|
|
E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE);
|
|
|
|
return switcher->priv->style;
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_set_style:
|
|
* @switcher: an #EShellSwitcher
|
|
* @style: the new style for @switcher
|
|
*
|
|
* Alters the view of @switcher to display either icons only, text only,
|
|
* or both.
|
|
**/
|
|
void
|
|
e_shell_switcher_set_style (EShellSwitcher *switcher,
|
|
GtkToolbarStyle style)
|
|
{
|
|
g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
|
|
|
|
switcher->priv->style_set = TRUE;
|
|
g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_unset_style:
|
|
* @switcher: an #EShellSwitcher
|
|
*
|
|
* Unsets a switcher style set with e_shell_switcher_set_style(), so
|
|
* that user preferences will be used to determine the switcher style.
|
|
**/
|
|
void
|
|
e_shell_switcher_unset_style (EShellSwitcher *switcher)
|
|
{
|
|
GtkSettings *settings;
|
|
GtkToolbarStyle style;
|
|
|
|
g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
|
|
|
|
if (!switcher->priv->style_set)
|
|
return;
|
|
|
|
settings = switcher->priv->settings;
|
|
if (settings != NULL)
|
|
g_object_get (settings, "gtk-toolbar-style", &style, NULL);
|
|
else
|
|
style = E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE;
|
|
|
|
if (style == GTK_TOOLBAR_BOTH)
|
|
style = GTK_TOOLBAR_BOTH_HORIZ;
|
|
|
|
if (style != switcher->priv->style)
|
|
g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
|
|
|
|
switcher->priv->style_set = FALSE;
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_get_visible:
|
|
* @switcher: an #EShellSwitcher
|
|
*
|
|
* Returns %TRUE if the switcher buttons are visible.
|
|
*
|
|
* Note that switcher button visibility is different than
|
|
* @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
|
|
* is actually a container widget for #EShellSidebar.
|
|
*
|
|
* Returns: %TRUE if the switcher buttons are visible
|
|
**/
|
|
gboolean
|
|
e_shell_switcher_get_visible (EShellSwitcher *switcher)
|
|
{
|
|
g_return_val_if_fail (E_IS_SHELL_SWITCHER (switcher), FALSE);
|
|
|
|
return switcher->priv->toolbar_visible;
|
|
}
|
|
|
|
/**
|
|
* e_shell_switcher_set_visible:
|
|
* @switcher: an #EShellSwitcher
|
|
* @visible: whether the switcher buttons should be visible
|
|
*
|
|
* Sets the switcher button visiblity to @visible.
|
|
*
|
|
* Note that switcher button visibility is different than
|
|
* @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
|
|
* is actually a container widget for #EShellSidebar.
|
|
**/
|
|
void
|
|
e_shell_switcher_set_visible (EShellSwitcher *switcher,
|
|
gboolean visible)
|
|
{
|
|
GList *iter;
|
|
|
|
g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
|
|
|
|
if (switcher->priv->toolbar_visible == visible)
|
|
return;
|
|
|
|
switcher->priv->toolbar_visible = visible;
|
|
|
|
for (iter = switcher->priv->proxies; iter != NULL; iter = iter->next)
|
|
g_object_set (iter->data, "visible", visible, NULL);
|
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (switcher));
|
|
|
|
g_object_notify (G_OBJECT (switcher), "toolbar-visible");
|
|
}
|