1 /*
2  * ROX-Filer, filer for the ROX desktop project
3  * Copyright (C) 2006, Thomas Leonard and others (see changelog for details).
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17  * Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 /* bind.c - converts user gestures (clicks, etc) into actions */
21 
22 #include "config.h"
23 
24 #include <stdlib.h>
25 
26 #include "global.h"
27 
28 #include "options.h"
29 #include "bind.h"
30 
31 Option o_new_button_1, o_single_click;
32 static Option o_single_pinboard;
33 static Option o_dclick_resizes;
34 
35 /****************************************************************
36  *			EXTERNAL INTERFACE			*
37  ****************************************************************/
38 
bind_init(void)39 void bind_init(void)
40 {
41 	option_add_int(&o_new_button_1, "bind_new_button_1", FALSE);
42 	option_add_int(&o_single_click, "bind_single_click", TRUE);
43 	option_add_int(&o_single_pinboard, "bind_single_pinboard", TRUE);
44 	option_add_int(&o_dclick_resizes, "bind_dclick_resizes", TRUE);
45 }
46 
47 /* Call this when a button event occurs and you want to know what
48  * to do.
49  */
bind_lookup_bev(BindContext context,GdkEventButton * event)50 BindAction bind_lookup_bev(BindContext context, GdkEventButton *event)
51 {
52 	gint	b = event->button;
53 	gint	menu_button = 3; /* o_menu_button_2.int_value ? 2 : 3; */
54 	gboolean shift = (event->state & GDK_SHIFT_MASK) != 0;
55 	gboolean ctrl = (event->state & GDK_CONTROL_MASK) != 0;
56 	gboolean icon  = context == BIND_PINBOARD_ICON ||
57 				context == BIND_PANEL_ICON;
58 	gboolean item = icon || context == BIND_DIRECTORY_ICON;
59 	gboolean background = context == BIND_PINBOARD ||
60 				context == BIND_PANEL ||
61 				context == BIND_DIRECTORY;
62 	gboolean press = event->type == GDK_BUTTON_PRESS;
63 	gboolean release = event->type == GDK_BUTTON_RELEASE;
64 	gboolean select = event->button == 1; /* (old RISC OS names) */
65 	gboolean adjust = event->button != 1;
66 
67 	gboolean dclick = event->type == GDK_2BUTTON_PRESS;
68 	gboolean dclick_mode =
69 		(context == BIND_DIRECTORY_ICON && !o_single_click.int_value) ||
70 		(context == BIND_PINBOARD_ICON && !o_single_pinboard.int_value);
71 
72 	if (b > 3)
73 		return ACT_IGNORE;
74 
75 	if (context == BIND_PINBOARD_ICON || context == BIND_PINBOARD)
76 		menu_button = 3;	/* Must work with window manager */
77 
78 	if (b == menu_button)
79 		return press ? ACT_POPUP_MENU : ACT_IGNORE;
80 
81 	if (item && dclick && dclick_mode)
82 		return shift ? ACT_EDIT_ITEM : ACT_OPEN_ITEM;
83 
84 	if (dclick && context == BIND_DIRECTORY && o_dclick_resizes.int_value)
85 		return ACT_RESIZE;
86 
87 	if (!press)
88 	{
89 		if (release && item && (!dclick_mode) && (!ctrl) &&
90 			(select || (adjust && context == BIND_DIRECTORY_ICON)))
91 			return shift ? ACT_EDIT_ITEM : ACT_OPEN_ITEM;
92 		return ACT_IGNORE;
93 	}
94 
95 	if (background)
96 	{
97 		gboolean clear = (!ctrl) && select;
98 
99 		if (context == BIND_PANEL)
100 			return ACT_CLEAR_SELECTION;
101 
102 		return clear ? ACT_LASSO_CLEAR : ACT_LASSO_MODIFY;
103 	}
104 
105 	if (ctrl || (adjust && dclick_mode))
106 		return ACT_PRIME_AND_TOGGLE;
107 
108 	if (context == BIND_PANEL_ICON && adjust)
109 		return ACT_MOVE_ICON;
110 
111 	return dclick_mode ? ACT_PRIME_AND_SELECT : ACT_PRIME_FOR_DND;
112 }
113