[evince] Use a GtkEntry with an arrow icon instead of a GtkComboBox for zoom selector
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] Use a GtkEntry with an arrow icon instead of a GtkComboBox for zoom selector
- Date: Fri, 26 Jul 2013 15:48:21 +0000 (UTC)
commit 1648495f1d82c4469b855907e61e446a134bf297
Author: Carlos Garcia Campos <carlosgc gnome org>
Date: Fri Jul 26 17:23:31 2013 +0200
Use a GtkEntry with an arrow icon instead of a GtkComboBox for zoom selector
This allows us to use our own custom menu with toggle and non-toggle
menu items. Fit-page and fit-width options are toggle menu items, so
that it's possible to know which mode is currently in use. The code is
simpler now too and zoom selector actions are handled like all other
chrome actions.
po/POTFILES.in | 1 -
shell/ev-window.c | 125 +++++++++++---
shell/ev-window.h | 41 +++---
shell/ev-zoom-action-widget.c | 377 +++++++++++++++++++++++------------------
shell/ev-zoom-action-widget.h | 14 +-
shell/ev-zoom-action.c | 43 +++---
shell/ev-zoom-action.h | 34 +++-
shell/evince-ui.xml | 7 +
8 files changed, 396 insertions(+), 246 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 87cc0c2..e02c4f1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -54,6 +54,5 @@ shell/ev-sidebar-thumbnails.c
shell/ev-utils.c
shell/ev-window.c
shell/ev-window-title.c
-shell/ev-zoom-action-widget.c
shell/main.c
[type: gettext/glade]shell/evince-appmenu.ui
diff --git a/shell/ev-window.c b/shell/ev-window.c
index db25972..06ce072 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -173,6 +173,7 @@ struct _EvWindowPrivate {
GtkActionGroup *action_group;
GtkActionGroup *view_popup_action_group;
GtkActionGroup *attachment_popup_action_group;
+ GtkActionGroup *zoom_selector_popup_action_group;
GtkRecentManager *recent_manager;
GtkActionGroup *recent_action_group;
guint recent_ui_id;
@@ -474,8 +475,6 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages);
ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages);
ev_window_set_action_sensitive (ev_window, "ViewDualOddLeft", has_pages);
- ev_window_set_action_sensitive (ev_window, "ViewFitPage", has_pages);
- ev_window_set_action_sensitive (ev_window, "ViewFitWidth", has_pages);
ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages);
ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages);
ev_window_set_action_sensitive (ev_window, "ViewInvertedColors", has_pages);
@@ -597,7 +596,7 @@ update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active)
static void
update_sizing_buttons (EvWindow *window)
{
- GtkActionGroup *action_group = window->priv->action_group;
+ GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
GtkAction *action;
gboolean fit_page, fit_width;
@@ -3852,6 +3851,26 @@ ev_window_cmd_fit_width (GtkAction *action, EvWindow *ev_window)
ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_WIDTH);
}
+static void
+ev_window_cmd_view_zoom_activate (GtkAction *action,
+ EvWindow *ev_window)
+{
+ const char *action_name = gtk_action_get_name (action);
+ gdouble zoom = 0;
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
+ if (strcmp (action_name, zoom_levels[i].name) == 0) {
+ zoom = zoom_levels[i].level;
+ break;
+ }
+ }
+ g_assert (zoom > 0);
+
+ ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
+ ev_document_model_set_scale (ev_window->priv->model,
+ zoom * get_screen_dpi (ev_window) / 72.0);
+}
static void
ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window)
@@ -4766,15 +4785,24 @@ ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *
}
static void
-ev_window_max_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *window)
+ev_window_setup_zoom_actions_visibility (EvWindow *window,
+ gdouble max_scale)
{
- GtkAction *action;
- gdouble max_scale;
+ GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
+ guint i;
- max_scale = ev_document_model_get_max_scale (model);
- action = gtk_action_group_get_action (window->priv->action_group,
- ZOOM_CONTROL_ACTION);
- ev_zoom_action_set_max_zoom_level (EV_ZOOM_ACTION (action), max_scale);
+ for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (action_group, zoom_levels[i].name);
+ gtk_action_set_visible (action, zoom_levels[i].level <= max_scale);
+ }
+}
+
+static void
+ev_window_max_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *window)
+{
+ ev_window_setup_zoom_actions_visibility (window, ev_document_model_get_max_scale (model));
}
static void
@@ -5612,6 +5640,8 @@ ev_window_dispose (GObject *object)
priv->attachment_popup_action_group = NULL;
}
+ g_clear_object (&priv->zoom_selector_popup_action_group);
+
if (priv->recent_action_group) {
g_object_unref (priv->recent_action_group);
priv->recent_action_group = NULL;
@@ -5982,12 +6012,6 @@ static const GtkToggleActionEntry toggle_entries[] = {
{ "ViewPresentation", EV_STOCK_RUN_PRESENTATION, N_("Pre_sentation"), "F5",
N_("Run document as a presentation"),
G_CALLBACK (ev_window_cmd_view_presentation) },
- { "ViewFitPage", EV_STOCK_ZOOM_PAGE, N_("Fit Pa_ge"), NULL,
- N_("Make the current document fill the window"),
- G_CALLBACK (ev_window_cmd_view_fit_page) },
- { "ViewFitWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit _Width"), NULL,
- N_("Make the current document fill the window width"),
- G_CALLBACK (ev_window_cmd_view_fit_width) },
{ "ViewInvertedColors", EV_STOCK_INVERTED_COLORS, N_("_Inverted Colors"), "<control>I",
N_("Show page contents with the colors inverted"),
G_CALLBACK (ev_window_cmd_view_inverted_colors) },
@@ -5995,7 +6019,6 @@ static const GtkToggleActionEntry toggle_entries[] = {
{ "EditFind", "edit-find-symbolic", N_("_Find…"), "<control>F",
N_("Find a word or phrase in the document"),
G_CALLBACK (ev_window_cmd_toggle_find) },
-
};
/* Popups specific items */
@@ -6024,6 +6047,15 @@ static const GtkActionEntry attachment_popup_entries [] = {
NULL, G_CALLBACK (ev_attachment_popup_cmd_save_attachment_as) },
};
+static const GtkToggleActionEntry zoom_selector_popup_actions[] = {
+ { "ViewFitPage", EV_STOCK_ZOOM_PAGE, N_("Fit Pa_ge"), NULL,
+ N_("Make the current document fill the window"),
+ G_CALLBACK (ev_window_cmd_view_fit_page) },
+ { "ViewFitWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit _Width"), NULL,
+ N_("Make the current document fill the window width"),
+ G_CALLBACK (ev_window_cmd_view_fit_width) }
+};
+
static void
sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
{
@@ -6091,6 +6123,36 @@ zoom_action_activated_cb (EvZoomAction *action,
}
static void
+ev_window_register_zoom_selector_popup_actions (EvWindow *window)
+{
+ GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
+ guint i, new_ui_id;
+
+ new_ui_id = gtk_ui_manager_new_merge_id (window->priv->ui_manager);
+
+ for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
+ GtkAction *action;
+
+ action = gtk_action_new (zoom_levels[i].name,
+ _(zoom_levels[i].name),
+ NULL, NULL);
+ g_signal_connect (action, "activate",
+ G_CALLBACK (ev_window_cmd_view_zoom_activate),
+ window);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (window->priv->ui_manager,
+ new_ui_id,
+ "/ZoomSelectorPopup/ViewZoomItems",
+ _(zoom_levels[i].name),
+ zoom_levels[i].name,
+ GTK_UI_MANAGER_MENUITEM,
+ FALSE);
+ }
+}
+
+static void
register_custom_actions (EvWindow *window, GtkActionGroup *group)
{
GtkAction *action;
@@ -6117,6 +6179,8 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group)
NULL);
ev_zoom_action_set_model (EV_ZOOM_ACTION (action),
window->priv->model);
+ ev_zoom_action_set_window (EV_ZOOM_ACTION (action),
+ window);
g_signal_connect (action, "activated",
G_CALLBACK (zoom_action_activated_cb), window);
gtk_action_group_add_action (group, action);
@@ -6178,14 +6242,6 @@ set_action_properties (GtkActionGroup *action_group)
/*translators: this is the label for toolbar button*/
g_object_set (action, "short_label", _("Zoom Out"), NULL);
- action = gtk_action_group_get_action (action_group, "ViewFitPage");
- /*translators: this is the label for toolbar button*/
- g_object_set (action, "short_label", _("Fit Page"), NULL);
-
- action = gtk_action_group_get_action (action_group, "ViewFitWidth");
- /*translators: this is the label for toolbar button*/
- g_object_set (action, "short_label", _("Fit Width"), NULL);
-
action = gtk_action_group_get_action (action_group, "LeaveFullscreen");
g_object_set (action, "is-important", TRUE, NULL);
}
@@ -7160,11 +7216,22 @@ ev_window_init (EvWindow *ev_window)
gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
action_group, 0);
+ action_group = gtk_action_group_new ("ZoomSelectorPopupActions");
+ ev_window->priv->zoom_selector_popup_action_group = action_group;
+ gtk_action_group_set_translation_domain (action_group, NULL);
+ gtk_action_group_add_toggle_actions (action_group, zoom_selector_popup_actions,
+ G_N_ELEMENTS (zoom_selector_popup_actions),
+ ev_window);
+ gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
+ action_group, 0);
+
gtk_ui_manager_add_ui_from_resource (ev_window->priv->ui_manager,
"/org/gnome/evince/shell/ui/evince.xml",
&error);
g_assert_no_error (error);
+ ev_window_register_zoom_selector_popup_actions (ev_window);
+
css_provider = gtk_css_provider_new ();
_gtk_css_provider_load_from_resource (css_provider,
"/org/gnome/evince/shell/ui/evince.css",
@@ -7547,3 +7614,11 @@ ev_window_get_main_action_group (EvWindow *ev_window)
return ev_window->priv->action_group;
}
+
+GtkActionGroup *
+ev_window_get_zoom_selector_action_group (EvWindow *ev_window)
+{
+ g_return_val_if_fail (EV_WINDOW (ev_window), NULL);
+
+ return ev_window->priv->zoom_selector_popup_action_group;
+}
diff --git a/shell/ev-window.h b/shell/ev-window.h
index 5c618e7..fd2d0b5 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -68,26 +68,27 @@ struct _EvWindowClass {
GtkApplicationWindowClass base_class;
};
-GType ev_window_get_type (void) G_GNUC_CONST;
-GtkWidget *ev_window_new (void);
-const char *ev_window_get_uri (EvWindow *ev_window);
-void ev_window_open_uri (EvWindow *ev_window,
- const char *uri,
- EvLinkDest *dest,
- EvWindowRunMode mode,
- const gchar *search_string);
-void ev_window_open_document (EvWindow *ev_window,
- EvDocument *document,
- EvLinkDest *dest,
- EvWindowRunMode mode,
- const gchar *search_string);
-gboolean ev_window_is_empty (const EvWindow *ev_window);
-void ev_window_print_range (EvWindow *ev_window,
- int first_page,
- int last_page);
-const gchar *ev_window_get_dbus_object_path (EvWindow *ev_window);
-GtkUIManager *ev_window_get_ui_manager (EvWindow *ev_window);
-GtkActionGroup *ev_window_get_main_action_group (EvWindow *ev_window);
+GType ev_window_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_window_new (void);
+const char *ev_window_get_uri (EvWindow *ev_window);
+void ev_window_open_uri (EvWindow *ev_window,
+ const char *uri,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string);
+void ev_window_open_document (EvWindow *ev_window,
+ EvDocument *document,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string);
+gboolean ev_window_is_empty (const EvWindow *ev_window);
+void ev_window_print_range (EvWindow *ev_window,
+ int first_page,
+ int last_page);
+const gchar *ev_window_get_dbus_object_path (EvWindow *ev_window);
+GtkUIManager *ev_window_get_ui_manager (EvWindow *ev_window);
+GtkActionGroup *ev_window_get_main_action_group (EvWindow *ev_window);
+GtkActionGroup *ev_window_get_zoom_selector_action_group (EvWindow *ev_window);
G_END_DECLS
diff --git a/shell/ev-zoom-action-widget.c b/shell/ev-zoom-action-widget.c
index 379e43d..95a7f3b 100644
--- a/shell/ev-zoom-action-widget.c
+++ b/shell/ev-zoom-action-widget.c
@@ -21,48 +21,22 @@
#include "config.h"
#include "ev-zoom-action-widget.h"
+#include "ev-zoom-action.h"
#include <glib/gi18n.h>
-struct _EvZoomActionWidgetPrivate {
- GtkWidget *combo;
-
- EvDocumentModel *model;
- gulong combo_changed_handler;
-};
-
-#define EV_ZOOM_FIT_PAGE (-3.0)
-#define EV_ZOOM_FIT_WIDTH (-4.0)
-#define EV_ZOOM_SEPARATOR (-5.0)
-
-static const struct {
- const gchar *name;
- float level;
-} zoom_levels[] = {
- { N_("Fit Page"), EV_ZOOM_FIT_PAGE },
- { N_("Fit Width"), EV_ZOOM_FIT_WIDTH },
- { NULL, EV_ZOOM_SEPARATOR },
- { N_("50%"), 0.5 },
- { N_("70%"), 0.7071067811 },
- { N_("85%"), 0.8408964152 },
- { N_("100%"), 1.0 },
- { N_("125%"), 1.1892071149 },
- { N_("150%"), 1.4142135623 },
- { N_("175%"), 1.6817928304 },
- { N_("200%"), 2.0 },
- { N_("300%"), 2.8284271247 },
- { N_("400%"), 4.0 },
- { N_("800%"), 8.0 },
- { N_("1600%"), 16.0 },
- { N_("3200%"), 32.0 },
- { N_("6400%"), 64.0 }
+enum {
+ PROP_0,
+ PROP_POPUP_SHOWN
};
-enum {
- TEXT_COLUMN,
- IS_SEPARATOR_COLUMN,
+struct _EvZoomActionWidgetPrivate {
+ GtkWidget *entry;
- N_COLUMNS
+ EvDocumentModel *model;
+ EvWindow *window;
+ GtkWidget *popup;
+ gboolean popup_shown;
};
G_DEFINE_TYPE (EvZoomActionWidget, ev_zoom_action_widget, GTK_TYPE_TOOL_ITEM)
@@ -73,14 +47,14 @@ static void
ev_zoom_action_widget_set_zoom_level (EvZoomActionWidget *control,
float zoom)
{
- GtkWidget *entry = gtk_bin_get_child (GTK_BIN (control->priv->combo));
- gchar *zoom_str;
- float zoom_perc;
- guint i;
+ gchar *zoom_str;
+ float zoom_perc;
+ guint i;
for (i = 3; i < G_N_ELEMENTS (zoom_levels); i++) {
if (ABS (zoom - zoom_levels[i].level) < EPSILON) {
- gtk_entry_set_text (GTK_ENTRY (entry), zoom_levels[i].name);
+ gtk_entry_set_text (GTK_ENTRY (control->priv->entry),
+ zoom_levels[i].name);
return;
}
}
@@ -90,7 +64,7 @@ ev_zoom_action_widget_set_zoom_level (EvZoomActionWidget *control,
zoom_str = g_strdup_printf ("%d%%", (gint)zoom_perc);
else
zoom_str = g_strdup_printf ("%.2f%%", zoom_perc);
- gtk_entry_set_text (GTK_ENTRY (entry), zoom_str);
+ gtk_entry_set_text (GTK_ENTRY (control->priv->entry), zoom_str);
g_free (zoom_str);
}
@@ -124,36 +98,7 @@ document_changed_cb (EvDocumentModel *model,
}
static void
-combo_changed_cb (GtkComboBox *combo,
- EvZoomActionWidget *control)
-{
- gint index;
- float zoom;
- EvSizingMode mode;
-
- index = gtk_combo_box_get_active (combo);
- if (index == -1)
- return;
-
- zoom = zoom_levels[index].level;
- if (zoom == EV_ZOOM_FIT_PAGE)
- mode = EV_SIZING_FIT_PAGE;
- else if (zoom == EV_ZOOM_FIT_WIDTH)
- mode = EV_SIZING_FIT_WIDTH;
- else
- mode = EV_SIZING_FREE;
-
- ev_document_model_set_sizing_mode (control->priv->model, mode);
- if (mode == EV_SIZING_FREE) {
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (control));
-
- ev_document_model_set_scale (control->priv->model,
- zoom * ev_document_misc_get_screen_dpi (screen) / 72.0);
- }
-}
-
-static void
-combo_activated_cb (GtkEntry *entry,
+entry_activated_cb (GtkEntry *entry,
EvZoomActionWidget *control)
{
GdkScreen *screen;
@@ -181,124 +126,233 @@ combo_activated_cb (GtkEntry *entry,
}
static gboolean
-combo_focus_out_cb (EvZoomActionWidget *control)
+focus_out_cb (EvZoomActionWidget *control)
{
ev_zoom_action_widget_update_zoom_level (control);
return FALSE;
}
-static gchar *
-combo_format_entry_text (GtkComboBox *combo,
- const gchar *path,
- EvZoomActionWidget *control)
+static gint
+get_max_zoom_level_label (EvZoomActionWidget *control)
{
- GtkWidget *entry = gtk_bin_get_child (GTK_BIN (combo));
+ GList *actions, *l;
+ gint width = 0;
- return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ actions = gtk_action_group_list_actions (ev_window_get_zoom_selector_action_group
(control->priv->window));
+
+ for (l = actions; l; l = g_list_next (l)) {
+ GtkAction *action = (GtkAction *)l->data;
+ int length;
+
+ length = g_utf8_strlen (gtk_action_get_label (action), -1);
+ if (length > width)
+ width = length;
+ }
+
+ g_list_free (actions);
+
+ /* Count the toggle size as one character more */
+ return width + 1;
}
-static gboolean
-row_is_separator (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data)
+static void
+popup_menu_show_cb (GtkWidget *widget,
+ EvZoomActionWidget *control)
{
- gboolean is_sep;
-
- gtk_tree_model_get (model, iter, IS_SEPARATOR_COLUMN, &is_sep, -1);
+ control->priv->popup_shown = TRUE;
+ g_object_notify (G_OBJECT (control), "popup-shown");
+}
- return is_sep;
+static void
+popup_menu_hide_cb (GtkWidget *widget,
+ EvZoomActionWidget *control)
+{
+ control->priv->popup_shown = FALSE;
+ g_object_notify (G_OBJECT (control), "popup-shown");
}
static void
-ev_zoom_action_widget_finalize (GObject *object)
+popup_menu_detached (EvZoomActionWidget *control,
+ GtkWidget *popup)
{
- EvZoomActionWidget *control = EV_ZOOM_ACTION_WIDGET (object);
+ GtkWidget *toplevel;
- ev_zoom_action_widget_set_model (control, NULL);
+ if (control->priv->popup != popup)
+ return;
+
+ toplevel = gtk_widget_get_toplevel (control->priv->popup);
+ g_signal_handlers_disconnect_by_func (toplevel,
+ popup_menu_show_cb,
+ control);
+ g_signal_handlers_disconnect_by_func (toplevel,
+ popup_menu_hide_cb,
+ control);
- G_OBJECT_CLASS (ev_zoom_action_widget_parent_class)->finalize (object);
+ control->priv->popup = NULL;
}
-static void
-fill_combo_model (GtkListStore *model,
- guint max_level)
+static GtkWidget *
+get_popup (EvZoomActionWidget *control)
{
- guint i;
+ GtkUIManager *ui_manager;
+ GtkWidget *toplevel;
+
+ if (control->priv->popup)
+ return control->priv->popup;
+
+ ui_manager = ev_window_get_ui_manager (control->priv->window);
+ control->priv->popup = gtk_ui_manager_get_widget (ui_manager, "/ZoomSelectorPopup");
+ gtk_menu_attach_to_widget (GTK_MENU (control->priv->popup), GTK_WIDGET (control),
+ (GtkMenuDetachFunc)popup_menu_detached);
+ toplevel = gtk_widget_get_toplevel (control->priv->popup);
+ g_signal_connect (toplevel, "show",
+ G_CALLBACK (popup_menu_show_cb),
+ control);
+ g_signal_connect (toplevel, "hide",
+ G_CALLBACK (popup_menu_hide_cb),
+ control);
- for (i = 0; i < max_level; i++) {
- GtkTreeIter iter;
+ return control->priv->popup;
+}
- gtk_list_store_append (model, &iter);
- gtk_list_store_set (model, &iter,
- TEXT_COLUMN, _(zoom_levels[i].name),
- IS_SEPARATOR_COLUMN, zoom_levels[i].name == NULL,
- -1);
+static void
+menu_position_below (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gint *push_in,
+ gpointer user_data)
+{
+ EvZoomActionWidget *control;
+ GtkWidget *widget;
+ GtkAllocation child_allocation;
+ GtkRequisition req;
+ GdkScreen *screen;
+ gint monitor_num;
+ GdkRectangle monitor;
+ gint sx = 0, sy = 0;
+
+ control = EV_ZOOM_ACTION_WIDGET (user_data);
+ widget = GTK_WIDGET (control);
+
+ gtk_widget_get_allocation (control->priv->entry, &child_allocation);
+
+ if (!gtk_widget_get_has_window (control->priv->entry)) {
+ sx += child_allocation.x;
+ sy += child_allocation.y;
}
+
+ gdk_window_get_root_coords (gtk_widget_get_window (control->priv->entry),
+ sx, sy, &sx, &sy);
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ *x = sx;
+ else
+ *x = sx + child_allocation.width - req.width;
+ *y = sy;
+
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen,
+ gtk_widget_get_window (widget));
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ if (*x < monitor.x)
+ *x = monitor.x;
+ else if (*x + req.width > monitor.x + monitor.width)
+ *x = monitor.x + monitor.width - req.width;
+
+ if (monitor.y + monitor.height - *y - child_allocation.height >= req.height)
+ *y += child_allocation.height;
+ else if (*y - monitor.y >= req.height)
+ *y -= req.height;
+ else if (monitor.y + monitor.height - *y - child_allocation.height > *y - monitor.y)
+ *y += child_allocation.height;
+ else
+ *y -= req.height;
+
+ *push_in = FALSE;
}
-static gint
-get_max_zoom_level_label (void)
+static void
+entry_icon_press_callback (GtkEntry *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEventButton *event,
+ EvZoomActionWidget *control)
{
- gint i;
- gint width = 0;
+ GtkWidget *menu;
- for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
- int length;
+ if (!control->priv->window || event->button != GDK_BUTTON_PRIMARY)
+ return;
- length = zoom_levels[i].name ? strlen (_(zoom_levels[i].name)) : 0;
- if (length > width)
- width = length;
- }
+ menu = get_popup (control);
+ gtk_widget_set_size_request (menu,
+ gtk_widget_get_allocated_width (GTK_WIDGET (control)),
+ -1);
- return width;
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+ menu_position_below, control,
+ event->button, event->time);
+}
+
+static gboolean
+setup_initial_entry_size (EvZoomActionWidget *control)
+{
+ gtk_entry_set_width_chars (GTK_ENTRY (control->priv->entry),
+ get_max_zoom_level_label (control));
+ return FALSE;
}
static void
ev_zoom_action_widget_init (EvZoomActionWidget *control)
{
EvZoomActionWidgetPrivate *priv;
- GtkWidget *entry;
GtkWidget *vbox;
- GtkListStore *store;
control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, EV_TYPE_ZOOM_ACTION_WIDGET,
EvZoomActionWidgetPrivate);
priv = control->priv;
- store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN);
- fill_combo_model (store, G_N_ELEMENTS (zoom_levels));
-
- priv->combo = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL (store));
- gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (priv->combo), FALSE);
- gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->combo), TEXT_COLUMN);
- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (priv->combo),
- (GtkTreeViewRowSeparatorFunc)row_is_separator,
- NULL, NULL);
- g_object_unref (store);
-
- entry = gtk_bin_get_child (GTK_BIN (priv->combo));
- gtk_entry_set_width_chars (GTK_ENTRY (entry), get_max_zoom_level_label ());
-
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_pack_start (GTK_BOX (vbox), priv->combo, TRUE, FALSE, 0);
- gtk_widget_show (priv->combo);
+
+ priv->entry = gtk_entry_new ();
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ "go-down-symbolic");
+ gtk_box_pack_start (GTK_BOX (vbox), priv->entry, TRUE, FALSE, 0);
+ gtk_widget_show (priv->entry);
gtk_container_add (GTK_CONTAINER (control), vbox);
gtk_widget_show (vbox);
- priv->combo_changed_handler =
- g_signal_connect (priv->combo, "changed",
- G_CALLBACK (combo_changed_cb),
- control);
- g_signal_connect (priv->combo, "format-entry-text",
- G_CALLBACK (combo_format_entry_text),
+ g_signal_connect (priv->entry, "icon-press",
+ G_CALLBACK (entry_icon_press_callback),
control);
- g_signal_connect (entry, "activate",
- G_CALLBACK (combo_activated_cb),
+ g_signal_connect (priv->entry, "activate",
+ G_CALLBACK (entry_activated_cb),
control);
- g_signal_connect_swapped (entry, "focus-out-event",
- G_CALLBACK (combo_focus_out_cb),
+ g_signal_connect_swapped (priv->entry, "focus-out-event",
+ G_CALLBACK (focus_out_cb),
control);
+
+ g_idle_add ((GSourceFunc)setup_initial_entry_size, control);
+}
+
+static void
+ev_zoom_action_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvZoomActionWidget *control = EV_ZOOM_ACTION_WIDGET (object);
+
+ switch (prop_id) {
+ case PROP_POPUP_SHOWN:
+ g_value_set_boolean (value, control->priv->popup_shown);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
@@ -306,7 +360,15 @@ ev_zoom_action_widget_class_init (EvZoomActionWidgetClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = ev_zoom_action_widget_finalize;
+ object_class->get_property = ev_zoom_action_widget_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_POPUP_SHOWN,
+ g_param_spec_boolean ("popup-shown",
+ "Popup shown",
+ "Whether the zoom control's dropdown is
shown",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_type_class_add_private (object_class, sizeof (EvZoomActionWidgetPrivate));
}
@@ -349,36 +411,19 @@ ev_zoom_action_widget_set_model (EvZoomActionWidget *control,
}
void
-ev_zoom_action_widget_set_max_zoom_level (EvZoomActionWidget *control,
- float max_zoom)
+ev_zoom_action_widget_set_window (EvZoomActionWidget *control,
+ EvWindow *window)
{
- EvZoomActionWidgetPrivate *priv;
- GtkListStore *model;
- guint max_level_index = 3;
- guint i;
-
- g_return_if_fail (EV_IS_ZOOM_ACTION_WIDGET (control));
-
- priv = control->priv;
-
- for (i = 3; i < G_N_ELEMENTS (zoom_levels); i++, max_level_index++) {
- if (zoom_levels[i].level > max_zoom)
- break;
- }
-
- g_signal_handler_block (priv->combo, priv->combo_changed_handler);
-
- model = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo)));
- gtk_list_store_clear (model);
- fill_combo_model (model, max_level_index);
+ if (control->priv->window == window)
+ return;
- g_signal_handler_unblock (priv->combo, priv->combo_changed_handler);
+ control->priv->window = window;
}
GtkWidget *
-ev_zoom_action_widget_get_combo_box (EvZoomActionWidget *control)
+ev_zoom_action_widget_get_entry (EvZoomActionWidget *control)
{
g_return_val_if_fail (EV_IS_ZOOM_ACTION_WIDGET (control), NULL);
- return control->priv->combo;
+ return control->priv->entry;
}
diff --git a/shell/ev-zoom-action-widget.h b/shell/ev-zoom-action-widget.h
index c42c7d3..a2dc293 100644
--- a/shell/ev-zoom-action-widget.h
+++ b/shell/ev-zoom-action-widget.h
@@ -25,6 +25,8 @@
#include <evince-document.h>
#include <evince-view.h>
+#include "ev-window.h"
+
G_BEGIN_DECLS
#define EV_TYPE_ZOOM_ACTION_WIDGET (ev_zoom_action_widget_get_type())
@@ -48,13 +50,13 @@ struct _EvZoomActionWidgetClass {
GtkToolItemClass parent_class;
};
-GType ev_zoom_action_widget_get_type (void);
+GType ev_zoom_action_widget_get_type (void);
-void ev_zoom_action_widget_set_model (EvZoomActionWidget *control,
- EvDocumentModel *model);
-GtkWidget *ev_zoom_action_widget_get_combo_box (EvZoomActionWidget *control);
-void ev_zoom_action_widget_set_max_zoom_level (EvZoomActionWidget *control,
- float max_zoom);
+void ev_zoom_action_widget_set_model (EvZoomActionWidget *control,
+ EvDocumentModel *model);
+GtkWidget *ev_zoom_action_widget_get_entry (EvZoomActionWidget *control);
+void ev_zoom_action_widget_set_window (EvZoomActionWidget *control,
+ EvWindow *window);
G_END_DECLS
diff --git a/shell/ev-zoom-action.c b/shell/ev-zoom-action.c
index f75d853..920fb9c 100644
--- a/shell/ev-zoom-action.c
+++ b/shell/ev-zoom-action.c
@@ -31,8 +31,8 @@ enum {
struct _EvZoomActionPrivate {
EvDocumentModel *model;
+ EvWindow *window;
gboolean popup_shown;
- float max_zoom;
};
G_DEFINE_TYPE (EvZoomAction, ev_zoom_action, GTK_TYPE_ACTION)
@@ -40,11 +40,11 @@ G_DEFINE_TYPE (EvZoomAction, ev_zoom_action, GTK_TYPE_ACTION)
static guint signals[LAST_SIGNAL] = { 0 };
static void
-popup_shown_cb (GObject *combo,
+popup_shown_cb (GObject *zoom_widget,
GParamSpec *pspec,
EvZoomAction *zoom_action)
{
- g_object_get (combo, "popup-shown", &zoom_action->priv->popup_shown, NULL);
+ g_object_get (zoom_widget, "popup-shown", &zoom_action->priv->popup_shown, NULL);
}
static void
@@ -61,16 +61,13 @@ connect_proxy (GtkAction *action,
if (EV_IS_ZOOM_ACTION_WIDGET (proxy)) {
EvZoomAction *zoom_action = EV_ZOOM_ACTION (action);
EvZoomActionWidget* zoom_widget = EV_ZOOM_ACTION_WIDGET (proxy);
- GtkWidget *combo;
ev_zoom_action_widget_set_model (zoom_widget, zoom_action->priv->model);
- ev_zoom_action_widget_set_max_zoom_level (zoom_widget, zoom_action->priv->max_zoom);
-
- combo = ev_zoom_action_widget_get_combo_box (zoom_widget);
- g_signal_connect (combo, "notify::popup-shown",
+ ev_zoom_action_widget_set_window (zoom_widget, zoom_action->priv->window);
+ g_signal_connect (zoom_widget, "notify::popup-shown",
G_CALLBACK (popup_shown_cb),
action);
- g_signal_connect (gtk_bin_get_child (GTK_BIN (combo)), "activate",
+ g_signal_connect (ev_zoom_action_widget_get_entry (zoom_widget), "activate",
G_CALLBACK (zoom_widget_activated_cb),
action);
}
@@ -124,29 +121,31 @@ ev_zoom_action_set_model (EvZoomAction *action,
}
}
-gboolean
-ev_zoom_action_get_popup_shown (EvZoomAction *action)
-{
- g_return_val_if_fail (EV_IS_ZOOM_ACTION (action), FALSE);
-
- return action->priv->popup_shown;
-}
-
void
-ev_zoom_action_set_max_zoom_level (EvZoomAction *action,
- float max_zoom)
+ev_zoom_action_set_window (EvZoomAction *action,
+ EvWindow *window)
{
+
GSList *proxies, *l;
g_return_if_fail (EV_IS_ZOOM_ACTION (action));
+ g_return_if_fail (EV_IS_WINDOW (window));
- if (action->priv->max_zoom == max_zoom)
+ if (action->priv->window == window)
return;
- action->priv->max_zoom = max_zoom;
+ action->priv->window = window;
proxies = gtk_action_get_proxies (GTK_ACTION (action));
for (l = proxies; l && l->data; l = g_slist_next (l)) {
if (EV_IS_ZOOM_ACTION_WIDGET (l->data))
- ev_zoom_action_widget_set_max_zoom_level (EV_ZOOM_ACTION_WIDGET (l->data), max_zoom);
+ ev_zoom_action_widget_set_window (EV_ZOOM_ACTION_WIDGET (l->data), window);
}
}
+
+gboolean
+ev_zoom_action_get_popup_shown (EvZoomAction *action)
+{
+ g_return_val_if_fail (EV_IS_ZOOM_ACTION (action), FALSE);
+
+ return action->priv->popup_shown;
+}
diff --git a/shell/ev-zoom-action.h b/shell/ev-zoom-action.h
index 4ef66fe..6cb92c5 100644
--- a/shell/ev-zoom-action.h
+++ b/shell/ev-zoom-action.h
@@ -25,6 +25,8 @@
#include <evince-document.h>
#include <evince-view.h>
+#include "ev-window.h"
+
G_BEGIN_DECLS
#define EV_TYPE_ZOOM_ACTION (ev_zoom_action_get_type ())
@@ -48,13 +50,33 @@ struct _EvZoomActionClass {
GtkActionClass parent_class;
};
-GType ev_zoom_action_get_type (void);
+static const struct {
+ const gchar *name;
+ float level;
+} zoom_levels[] = {
+ { "50%", 0.5 },
+ { "70%", 0.7071067811 },
+ { "85%", 0.8408964152 },
+ { "100%", 1.0 },
+ { "125%", 1.1892071149 },
+ { "150%", 1.4142135623 },
+ { "175%", 1.6817928304 },
+ { "200%", 2.0 },
+ { "300%", 2.8284271247 },
+ { "400%", 4.0 },
+ { "800%", 8.0 },
+ { "1600%", 16.0 },
+ { "3200%", 32.0 },
+ { "6400%", 64.0 }
+};
+
+GType ev_zoom_action_get_type (void);
-void ev_zoom_action_set_model (EvZoomAction *action,
- EvDocumentModel *model);
-gboolean ev_zoom_action_get_popup_shown (EvZoomAction *action);
-void ev_zoom_action_set_max_zoom_level (EvZoomAction *action,
- float max_zoom);
+void ev_zoom_action_set_model (EvZoomAction *action,
+ EvDocumentModel *model);
+gboolean ev_zoom_action_get_popup_shown (EvZoomAction *action);
+void ev_zoom_action_set_window (EvZoomAction *action,
+ EvWindow *window);
G_END_DECLS
diff --git a/shell/evince-ui.xml b/shell/evince-ui.xml
index 39e61db..db23f9c 100644
--- a/shell/evince-ui.xml
+++ b/shell/evince-ui.xml
@@ -81,6 +81,13 @@
<menuitem name="SaveAttachmentAs" action="SaveAttachmentAs"/>
</popup>
+ <popup name="ZoomSelectorPopup">
+ <menuitem name="ViewFitPage" action="ViewFitPage"/>
+ <menuitem name="ViewFitWidth" action="ViewFitWidth"/>
+ <separator/>
+ <placeholder name="ViewZoomItems"/>
+ </popup>
+
<accelerator name="PageDownAccel" action="PageDown"/>
<accelerator name="PageUpAccel" action="PageUp"/>
<accelerator name="GoBackwardFastAccel" action="GoBackwardFast"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]