]> icculus.org git repositories - mikachu/openbox.git/blob - scripts/motion.py
add a snap variable..
[mikachu/openbox.git] / scripts / motion.py
1 ############################################################################
2 ###    Functions that provide callbacks for motion events to move and    ###
3 ###    resize windows.                                                   ###
4 ############################################################################
5
6 #############################################################################
7 ### Options that can be modified to change the functions' behaviors.      ###
8 ###                                                                       ###
9 # snap - snap windows to other windows and screen edges while moving them ###
10 snap = 1
11 ###
12 # move_popup - display a coordinates popup when moving windows.           ###
13 move_popup = 1                                                            ###
14 ###                                                                       ###
15 # NOT IMPLEMENTED (yet?)                                                  ###
16 # move_rubberband - display an outline while moving instead of moving the ###
17 ###                 actual window, until the move is completed. Good for  ###
18 ###                 slower systems.                                       ###
19 move_rubberband = 0                                                       ###
20 ###                                                                       ###
21 # resize_popup - display a size popup when resizing windows.              ###
22 resize_popup = 1                                                          ###
23 ###                                                                       ###
24 # NOT IMPLEMENTED (yet?)                                                  ###
25 # resize_rubberband - display an outline while resizing instead of        ###
26 ###                   resizing the actual window, until the resize is     ###
27 ###                   completed. Good for slower systems.                 ###
28 resize_rubberband = 0                                                     ###
29 ###                                                                       ###
30 # resize_nearest - 1 to resize from the corner nearest where the mouse    ###
31 ###                is, 0 to resize always from the bottom right corner.   ###
32 resize_nearest = 1                                                        ###
33 ###                                                                       ###
34 ###                                                                       ###
35 # Provides:                                                               ###
36 # def move(data):                                                         ###
37 #     """Moves the window interactively. This should only be used with    ###
38 #        MouseMotion events. If move_popup or move_rubberband is enabled, ###
39 #        then the end_move function needs to be bound as well."""         ###
40 # def end_move(data):                                                     ###
41 #     """Complete the interactive move of a window."""                    ###
42 # def resize(data):                                                       ###
43 #     """Resizes the window interactively. This should only be used with  ###
44 #        MouseMotion events"""                                            ###
45 # def end_resize(data):                                                   ###
46 #     """Complete the interactive resize of a window."""                  ###
47 ###                                                                       ###
48 #############################################################################
49
50 import ob
51 import otk
52
53 _popwidget = 0
54 _poplabel = 0
55
56 # motion state
57 _inmove = 0
58 _inresize = 0
59
60 # last motion data
61 _cx = 0
62 _cy = 0
63 _cw = 0
64 _ch = 0
65 _px = 0
66 _py = 0
67 _dx = 0
68 _dy = 0
69 _client = 0
70 _screen = 0
71
72 _motion_mask = 0
73
74 def _motion_grab(data):
75     global _motion_mask, _inmove, _inresize;
76
77     if data.action == ob.KeyAction.Release:
78         # have all the modifiers this started with been released?
79         if not _motion_mask & data.state:
80             if _inmove:
81                 end_move(data)
82             elif _inresize:
83                 end_resize(data)
84             else:
85                 raise RuntimeError
86
87 def _do_move():
88     global _screen, _client, _cx, _cy, _dx, _dy
89
90     x = _cx + _dx
91     y = _cy + _dy
92
93     global snap
94     if snap:
95         pass
96
97     global move_rubberband
98     if move_rubberband:
99         # draw the outline ...
100         f=0
101     else:
102         _client.move(x, y)
103
104     global move_popup
105     if move_popup:
106         global _popwidget, _poplabel
107         style = ob.openbox.screen(_screen).style()
108         font = style.labelFont()
109         text = "X: " + str(x) + " Y: " + str(y)
110         length = font.measureString(text)
111         if not _popwidget:
112             _popwidget = otk.Widget(ob.openbox, style,
113                                     otk.Widget.Horizontal, 0,
114                                     style.bevelWidth(), 1)
115             _popwidget.setTexture(style.titlebarFocusBackground())
116             _poplabel = otk.Label(_popwidget)
117             _poplabel.setTexture(style.labelFocusBackground())
118             _popwidget.show(1)
119         _poplabel.fitString(text)
120         _poplabel.setText(text)
121         area = otk.display.screenInfo(_screen).rect()
122         _popwidget.update() 
123         _popwidget.move(area.x() + (area.width() -
124                                     _popwidget.width()) / 2,
125                         area.y() + (area.height() -
126                                     _popwidget.height()) / 2)
127
128 def move(data):
129     """Moves the window interactively. This should only be used with
130        MouseMotion events. If move_popup or move_rubberband is enabled, then
131        the end_move function needs to be bound as well."""
132     if not data.client: return
133
134     # not-normal windows dont get moved
135     if not data.client.normal(): return
136
137     global _screen, _client, _cx, _cy, _dx, _dy
138     _screen = data.screen
139     _client = data.client
140     _cx = data.press_clientx
141     _cy = data.press_clienty
142     _dx = data.xroot - data.pressx
143     _dy = data.yroot - data.pressy
144     _do_move()
145     global _inmove
146     if not _inmove:
147         ob.kgrab(_screen, _motion_grab)
148         _inmove = 1
149
150 def end_move(data):
151     """Complete the interactive move of a window."""
152     global move_rubberband, _inmove
153     global _popwidget, _poplabel
154     if _inmove:
155         r = move_rubberband
156         move_rubberband = 0
157         _do_move()
158         move_rubberband = r
159         _inmove = 0
160     _poplabel = 0
161     _popwidget = 0
162     ob.kungrab()
163
164 def _do_resize():
165     global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
166
167     dx = _dx
168     dy = _dy
169     
170     # pick a corner to anchor
171     if not (resize_nearest or _context == ob.MouseContext.Grip):
172         corner = ob.Client.TopLeft
173     else:
174         x = _px - _cx
175         y = _py - _cy
176         if y < _ch / 2:
177             if x < _cw / 2:
178                 corner = ob.Client.BottomRight
179                 dx *= -1
180             else:
181                 corner = ob.Client.BottomLeft
182             dy *= -1
183         else:
184             if x < _cw / 2:
185                 corner = ob.Client.TopRight
186                 dx *= -1
187             else:
188                 corner = ob.Client.TopLeft
189
190     w = _cw + dx
191     h = _ch + dy
192
193     global resize_popup
194     if resize_rubberband:
195         # draw the outline ...
196         f=0
197     else:
198         _client.resize(corner, w, h)
199
200     global resize_popup
201     if resize_popup:
202         global _popwidget, _poplabel
203         style = ob.openbox.screen(_screen).style()
204         ls = _client.logicalSize()
205         text = "W: " + str(ls.x()) + " H: " + str(ls.y())
206         if not _popwidget:
207             _popwidget = otk.Widget(ob.openbox, style,
208                                     otk.Widget.Horizontal, 0,
209                                     style.bevelWidth(), 1)
210             _popwidget.setTexture(style.titlebarFocusBackground())
211             _poplabel = otk.Label(_popwidget)
212             _poplabel.setTexture(style.labelFocusBackground())
213             _popwidget.show(1)
214         _poplabel.fitString(text)
215         _poplabel.setText(text)
216         area = otk.display.screenInfo(_screen).rect()
217         _popwidget.update() 
218         _popwidget.move(area.x() + (area.width() -
219                                     _popwidget.width()) / 2,
220                         area.y() + (area.height() -
221                                     _popwidget.height()) / 2)
222
223 def resize(data):
224     """Resizes the window interactively. This should only be used with
225        MouseMotion events"""
226     if not data.client: return
227
228     # not-normal windows dont get resized
229     if not data.client.normal(): return
230
231     global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy
232     _screen = data.screen
233     _client = data.client
234     _cx = data.press_clientx
235     _cy = data.press_clienty
236     _cw = data.press_clientwidth
237     _ch = data.press_clientheight
238     _px = data.pressx
239     _py = data.pressy
240     _dx = data.xroot - _px
241     _dy = data.yroot - _py
242     _do_resize()
243     global _inresize
244     if not _inresize:
245         ob.kgrab(_screen, _motion_grab)
246         _inresize = 1
247
248 def end_resize(data):
249     """Complete the interactive resize of a window."""
250     global resize_rubberband, _inresize
251     global _popwidget, _poplabel
252     if _inresize:
253         r = resize_rubberband
254         resize_rubberband = 0
255         _do_resize()
256         resize_rubberband = r
257         _inresize = 0
258     _poplabel = 0
259     _popwidget = 0
260     ob.kungrab()