Update e-mail address
[pysize.git] / pysize / ui / gtk / pysize_widget_mouse.py
blob242359828dbc254a3131ed1d6f20ccb59e470118
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2006, 2007, 2008 Guillaume Chazarain <guichaz@gmail.com>
19 import pygtk
20 pygtk.require('2.0')
21 import gtk
22 assert gtk.pygtk_version >= (2, 8)
24 class _point(object):
25 def __init__(self, x, y):
26 self.x = x
27 self.y = y
29 def _event_point(event):
30 if event.is_hint:
31 x, y, state = event.window.get_pointer()
32 point = _point(x, y)
33 else:
34 point = _point(event.x, event.y)
35 return point
37 class PysizeWidget_Mouse(object):
38 def __init__(self, options, args):
39 self.connect('motion-notify-event', type(self)._motion_notify_event)
40 self.connect('button-press-event', type(self)._button_press_event)
41 self.connect('button-release-event', type(self)._button_release_event)
42 self.connect('building-tree-state-changed', type(self)._reset_mouse)
43 self.cursor_node = None
44 self.button_press_node = None
45 self.selected_nodes = set()
46 self.set_cursor_node(None)
48 def set_cursor_node(self, cursor_node):
49 self.cursor_node = cursor_node
50 self.emit('hover-changed', cursor_node)
52 def _reset_mouse(self, unused_tree):
53 self.set_cursor_node(None)
54 self.button_press_node = None
56 def _get_node_here(self, event):
57 point = _point(event.x, event.y)
58 for node in self.tree.root:
59 if node.contains_point(point):
60 return node
62 def _motion_notify_event(self, event):
63 point = _event_point(event)
64 prev_selection = new_selection = self.cursor_node
65 if not (self.cursor_node and self.cursor_node.contains_point(point)):
66 # The cursor is no more in the same node
67 mask = 0x00
68 for node in self.tree.root:
69 if node.contains_point(point) != (node == prev_selection):
70 if node == prev_selection:
71 new_selection = None
72 mask |= 0x1
73 else:
74 new_selection = node
75 mask |= 0x2
76 if mask == 0x3:
77 break
78 if prev_selection != new_selection:
79 self.set_cursor_node(new_selection)
80 self.queue_node_redraw(prev_selection)
81 self.queue_node_redraw(new_selection)
82 return True
84 def handle_double_click(self, node):
85 if node:
86 self.set_paths(node.get_fullpaths())
87 return node is not None
89 def _button_press_event(self, event):
90 if event.button == 1:
91 node = self._get_node_here(event)
92 if event.type == gtk.gdk._2BUTTON_PRESS:
93 return self.handle_double_click(node)
94 if node != self.button_press_node:
95 self.queue_node_redraw(self.button_press_node)
96 self.queue_node_redraw(node)
97 self.button_press_node = node
98 return True
99 return False
101 def _button_release_event(self, event):
102 if event.button == 1:
103 node = self._get_node_here(event)
104 if node == self.button_press_node:
105 if event.state & gtk.gdk.CONTROL_MASK:
106 if node:
107 if node in self.selected_nodes:
108 self.selected_nodes.remove(node)
109 else:
110 self.selected_nodes.add(node)
111 elif event.state & gtk.gdk.SHIFT_MASK:
112 if node:
113 is_in_new_selection = False
114 for current in self.tree.breadth_first():
115 if current is node:
116 if is_in_new_selection:
117 break
118 is_in_new_selection = True
119 if current in self.selected_nodes:
120 if is_in_new_selection:
121 break
122 is_in_new_selection = True
123 if is_in_new_selection:
124 self.selected_nodes.add(current)
125 self.queue_node_redraw(current)
126 self.selected_nodes.add(node)
127 self.queue_node_redraw(node)
128 else:
129 for n in self.get_selected_nodes():
130 self.queue_node_redraw(n)
131 if node:
132 self.selected_nodes = set([node])
133 else:
134 self.selected_nodes = set()
135 self.queue_node_redraw(node)
136 else:
137 self.queue_node_redraw(self.button_press_node)
138 self.button_press_node = None
139 self.emit('hover-changed', self.cursor_node)
140 return True
142 def get_selected_nodes(self):
143 if self.cursor_node:
144 nodes = set([self.cursor_node])
145 else:
146 nodes = set()
147 nodes |= self.selected_nodes
148 return nodes