2
* Copyright (C) 2003, 2004 Marco Pesenti Gritti
3
* Copyright (C) 2003, 2004 Christian Persch
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2, or (at your option)
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include "ev-navigation-action-widget.h"
23
#include <glib/gi18n.h>
26
static void ev_navigation_action_widget_init (EvNavigationActionWidget *action_widget);
27
static void ev_navigation_action_widget_class_init (EvNavigationActionWidgetClass *action_widget);
28
static void ev_navigation_action_widget_toggled (GtkToggleToolButton *toggle);
29
static gboolean ev_navigation_action_widget_button_press_event (GtkWidget *widget,
30
GdkEventButton *event);
32
G_DEFINE_TYPE (EvNavigationActionWidget, ev_navigation_action_widget, GTK_TYPE_TOGGLE_TOOL_BUTTON)
40
static gint signals[LAST_SIGNAL];
43
ev_navigation_action_widget_init (EvNavigationActionWidget *action_widget)
49
ev_navigation_action_widget_class_init (EvNavigationActionWidgetClass *klass)
51
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
52
GtkToggleToolButtonClass *toggle_tool_button_class = GTK_TOGGLE_TOOL_BUTTON_CLASS (klass);
54
widget_class->button_press_event = ev_navigation_action_widget_button_press_event;
55
toggle_tool_button_class->toggled = ev_navigation_action_widget_toggled;
59
g_signal_new ("show-menu",
60
G_OBJECT_CLASS_TYPE (klass),
62
G_STRUCT_OFFSET (EvNavigationActionWidgetClass, show_menu),
64
g_cclosure_marshal_VOID__VOID,
69
menu_deactivate_cb (GtkMenuShell *menu_shell,
70
EvNavigationActionWidget *widget)
72
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (widget), FALSE);
77
menu_detacher (GtkWidget *widget,
80
EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (widget);
81
g_return_if_fail (button->menu == menu);
86
ev_navigation_action_widget_set_menu(EvNavigationActionWidget *button, GtkWidget *menu)
89
if (button->menu == GTK_MENU (menu))
92
if (button->menu && GTK_WIDGET_VISIBLE (button->menu))
93
gtk_menu_shell_deactivate (GTK_MENU_SHELL (button->menu));
96
g_signal_handlers_disconnect_by_func (button->menu,
99
gtk_menu_detach (button->menu);
102
button->menu = GTK_MENU (menu);
105
gtk_menu_attach_to_widget (button->menu, GTK_WIDGET (button),
107
g_signal_connect (button->menu, "deactivate",
108
G_CALLBACK (menu_deactivate_cb), button);
113
menu_position_func (GtkMenu *menu,
117
EvNavigationActionWidget *button)
119
GtkWidget *widget = GTK_WIDGET (button);
120
GtkRequisition menu_req;
121
GtkTextDirection direction;
122
GdkRectangle monitor;
126
gtk_widget_size_request (GTK_WIDGET (button->menu), &menu_req);
127
direction = gtk_widget_get_direction (widget);
128
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
130
monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
133
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
135
gdk_window_get_origin (widget->window, x, y);
136
*x += widget->allocation.x;
137
*y += widget->allocation.y;
139
if (direction == GTK_TEXT_DIR_LTR)
140
*x += MAX (widget->allocation.width - menu_req.width, 0);
141
else if (menu_req.width > widget->allocation.width)
142
*x -= menu_req.width - widget->allocation.width;
144
if ((*y + widget->allocation.height + menu_req.height) <= monitor.y + monitor.height)
145
*y += widget->allocation.height;
146
else if ((*y - menu_req.height) >= monitor.y)
147
*y -= menu_req.height;
148
else if (monitor.y + monitor.height - (*y + widget->allocation.height) > *y)
149
*y += widget->allocation.height;
151
*y -= menu_req.height;
157
popup_menu_under_arrow (EvNavigationActionWidget *button,
158
GdkEventButton *event)
163
g_signal_emit (button, signals[SHOW_MENU], 0);
165
gtk_menu_popup (button->menu, NULL, NULL,
166
(GtkMenuPositionFunc) menu_position_func,
168
event ? event->button : 0,
169
event ? event->time : gtk_get_current_event_time ());
173
ev_navigation_action_widget_toggled (GtkToggleToolButton *toggle)
175
EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (toggle);
179
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button)) &&
180
!GTK_WIDGET_VISIBLE (button->menu)) {
181
/* we get here only when the menu is activated by a key
182
* press, so that we can select the first menu item */
183
popup_menu_under_arrow (button, NULL);
184
gtk_menu_shell_select_first (GTK_MENU_SHELL (button->menu), FALSE);
189
ev_navigation_action_widget_button_press_event (GtkWidget *widget,
190
GdkEventButton *event)
192
EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (widget);
193
if (event->button == 1) {
194
popup_menu_under_arrow (button, event);
195
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (button), TRUE);