@@ -6,21 +6,49 @@ Miniwindow drag-to-move functions.
6
6
7
7
Author: Nick Gammon
8
8
Date: 15th July 2009
9
+ Modified: 16th November 2010 to add preprocessing
9
10
10
11
11
12
This module is intended to make it easier to add drag handlers for miniwindows.
12
13
13
14
It implements the following:
14
15
15
- windowinfo = movewindow.install (win, default_position, flags) -- find previous location
16
+ -- find previous location
17
+ nocheck: if true, don't check if offscreen (boolean)
18
+ friends: other windows to move with this one (table)
19
+ preprocess: preprocessing for mousedown, mouseup etc. (table)
20
+
21
+ Handler names for preprocess table:
22
+
23
+ mousedown
24
+ mouseup
25
+ mouseover
26
+ cancelmouseover
27
+ cancelmousedown
28
+ dragmove
29
+ dragrelease
30
+
31
+ If any preprocess handler returns true (that is, neither nil nor false) then the default handler
32
+ in this module is not used. (The miniwindow name is the third argument)
33
+
34
+ function mousedown (flags, id, win)
35
+ if bit.band (flags, miniwin.hotspot_got_rh_mouse) then
36
+ -- do something different here
37
+ return true
38
+ end -- if
39
+
40
+ return false -- take normal movewindow behaviour
41
+ end -- mousedown
42
+
43
+ windowinfo = movewindow.install (win, default_position, default_flags, nocheck, friends, preprocess)
16
44
17
45
movewindow.add_drag_handler (win, left, top, right, bottom, cursor) -- add a drag handler for the nominated rectangle
18
46
19
47
movewindow.save_state (win) -- saves the miniwindow location to the appropriate variables
20
48
21
49
It also installs a position-checker that moves the miniwindow into view after 5 seconds, in case
22
50
you resize the main world window, and the window is no longer visible. The 5 seconds are to give
23
- the main world window's position and size time to stabilize.
51
+ the main world window's position and size time to stabilize. (Unless nocheck is true)
24
52
25
53
26
54
Example of use:
@@ -32,7 +60,7 @@ Example of use:
32
60
33
61
win = GetPluginID () -- miniwindow ID
34
62
35
- windowinfo = movewindow.install (win, 7 , 0) -- get position (default to right/middle)
63
+ windowinfo = movewindow.install (win, miniwin.pos_center_right , 0) -- default position / flags
36
64
37
65
-- make miniwindow (use locations returned from last time we saved the state)
38
66
-- note that the width and height are not part of the window position info, and can thus change as required
@@ -52,8 +80,7 @@ Example of use:
52
80
-- in this case we use 0,0,0,0 as the rectangle (ie. the whole window)
53
81
-- typically the height would be the size of the title bar
54
82
55
- movewindow.add_drag_handler (win, 0, 0, 0, 0, 10) -- both-ways arrow cursor (10)
56
-
83
+ movewindow.add_drag_handler (win, 0, 0, 0, 0, miniwin.cursor_both_arrow)
57
84
58
85
-- SAVE STATE in OnPluginSaveState
59
86
@@ -95,8 +122,15 @@ movewindow = {} -- table to hold functions like movewindow.install
95
122
local function make_mousedown_handler (mwi )
96
123
97
124
return function (flags , hotspot_id )
98
-
125
+
99
126
local win = mwi .win
127
+
128
+ -- see if other action wanted
129
+ if mwi .preprocess .mousedown then
130
+ if mwi .preprocess .mousedown (flags , hotspot_id , win ) then
131
+ return
132
+ end -- if handled already
133
+ end -- if handler
100
134
101
135
-- find where mouse is so we can adjust window relative to mouse
102
136
mwi .startx = WindowInfo (win , 14 )
@@ -107,9 +141,13 @@ local function make_mousedown_handler (mwi)
107
141
mwi .origy = WindowInfo (win , 11 )
108
142
109
143
-- find where the friends are relative to the window
110
- for i ,v in ipairs (mwi .window_friends ) do
111
- if (v ~= nil ) then
112
- mwi .window_friend_deltas [i ] = {WindowInfo (v , 10 ) - mwi .origx , WindowInfo (v , 11 ) - mwi .origy }
144
+ for i , v in ipairs (mwi .window_friends ) do
145
+ if v then
146
+ mwi .window_friend_deltas [i ] =
147
+ {
148
+ WindowInfo (v , 10 ) - mwi .origx ,
149
+ WindowInfo (v , 11 ) - mwi .origy
150
+ }
113
151
end -- if
114
152
end -- for
115
153
@@ -125,17 +163,27 @@ local function make_dragmove_handler (mwi)
125
163
126
164
local win = mwi .win
127
165
166
+ -- see if other action wanted
167
+ if mwi .preprocess .dragmove then
168
+ if mwi .preprocess .dragmove (flags , hotspot_id , win ) then
169
+ return
170
+ end -- if handled already
171
+ end -- if handler
172
+
128
173
-- find where it is now
129
174
local posx , posy = WindowInfo (win , 17 ) - mwi .startx ,
130
175
WindowInfo (win , 18 ) - mwi .starty
131
176
132
177
-- move the window to the new location - offset by how far mouse was into window
133
- WindowPosition (win , posx , posy , 0 , 2 );
178
+ WindowPosition (win , posx , posy , 0 , miniwin . create_absolute_location );
134
179
135
180
-- move the friends if they still exist
136
- for i ,v in ipairs (mwi .window_friends ) do
137
- if (v ~= nil ) then
138
- WindowPosition (v , posx + mwi .window_friend_deltas [i ][1 ], posy + mwi .window_friend_deltas [i ][2 ], 0 , WindowInfo (v , 8 ))
181
+ for i , v in ipairs (mwi .window_friends ) do
182
+ if v then
183
+ WindowPosition (v , posx + mwi .window_friend_deltas [i ] [1 ],
184
+ posy + mwi .window_friend_deltas [i ] [2 ],
185
+ 0 ,
186
+ WindowInfo (v , 8 ))
139
187
end -- if
140
188
end -- for
141
189
@@ -144,15 +192,15 @@ local function make_dragmove_handler (mwi)
144
192
posx > GetInfo (281 ) - mwi .margin or
145
193
posy < 0 or -- don't drag title out of view
146
194
posy > GetInfo (280 ) - mwi .margin then
147
- SetCursor (11 ) -- X cursor
195
+ SetCursor (miniwin . cursor_x ) -- X cursor
148
196
else
149
- SetCursor (1 ) -- hand cursor
197
+ SetCursor (miniwin . cursor_hand ) -- hand cursor
150
198
end -- if
151
199
152
200
mwi .window_left = posx -- remember for saving state
153
201
mwi .window_top = posy
154
202
mwi .window_mode = 0
155
- mwi .window_flags = 2 -- absolute position
203
+ mwi .window_flags = miniwin . create_absolute_location -- absolute position
156
204
157
205
end -- dragmove
158
206
@@ -166,6 +214,13 @@ local function make_dragrelease_handler (mwi)
166
214
167
215
local win = mwi .win
168
216
217
+ -- see if other action wanted
218
+ if mwi .preprocess .dragrelease then
219
+ if mwi .preprocess .dragrelease (flags , hotspot_id , win ) then
220
+ return
221
+ end -- if handled already
222
+ end -- if handler
223
+
169
224
Repaint () -- update window location
170
225
171
226
-- find where window is now
@@ -177,12 +232,12 @@ local function make_dragrelease_handler (mwi)
177
232
newy < 0 or -- don't drag title out of view
178
233
newy > GetInfo (280 ) - mwi .margin then
179
234
-- put it back
180
- WindowPosition (win , mwi .origx , mwi .origy , 0 , 2 )
235
+ WindowPosition (win , mwi .origx , mwi .origy , 0 , miniwin . create_absolute_location )
181
236
182
237
mwi .window_left = mwi .origx -- remember for saving state
183
238
mwi .window_top = mwi .origy
184
239
mwi .window_mode = 0
185
- mwi .window_flags = 2 -- absolute position
240
+ mwi .window_flags = miniwin . create_absolute_location -- absolute position
186
241
187
242
return
188
243
end -- if out of bounds
@@ -192,6 +247,21 @@ local function make_dragrelease_handler (mwi)
192
247
193
248
end -- make_dragrelease_handler
194
249
250
+ -- make other handler with the movement information as an upvalue
251
+
252
+ local function make_other_handler (mwi , name )
253
+
254
+ return function (flags , hotspot_id )
255
+
256
+ -- send to supplied handler
257
+ if mwi .preprocess [name ] then
258
+ mwi .preprocess [name ] (flags , hotspot_id , mwi .win )
259
+ end -- if handler
260
+
261
+ end -- other
262
+
263
+ end -- make_other_handler
264
+
195
265
-- make a mouse position-checking function with the movement information as an upvalue
196
266
197
267
local function make_check_map_position_handler (mwi )
@@ -210,8 +280,8 @@ local function make_check_map_position_handler (mwi)
210
280
mwi .window_left > GetInfo (281 ) - mwi .margin or
211
281
mwi .window_top < 0 or -- don't drag title out of view
212
282
mwi .window_top > GetInfo (280 ) - mwi .margin then
213
- mwi .window_left , mwi .window_top = 0 , 0 -- reset to top left
214
- mwi .window_mode = 7
283
+ mwi .window_left , mwi .window_top = 0 , 0 -- reset to center right
284
+ mwi .window_mode = miniwin . pos_center_right
215
285
mwi .window_flags = 0
216
286
end -- if not visible
217
287
@@ -228,17 +298,14 @@ end -- make_check_map_position_handler
228
298
-- call movewindow.install in OnPluginInstall to find the position of the window, before creating it
229
299
-- - it also creates the handler functions ready for use later
230
300
231
- function movewindow .install (win , default_position , default_flags , nocheck , default_friends )
301
+ function movewindow .install (win , default_position , default_flags , nocheck , friends , preprocess )
232
302
233
303
win = win or GetPluginID () -- default to current plugin ID
234
304
235
305
assert (not string.match (win , " [^A-Za-z0-9_]" ), " Invalid window name in movewindow.install: " .. win )
236
306
237
- default_position = default_position or 7 -- on right, center top/bottom
307
+ default_position = default_position or miniwin . pos_center_right -- on right, center top/bottom
238
308
default_flags = default_flags or 0
239
- if (default_friends == nil ) then
240
- default_friends = {}
241
- end
242
309
243
310
-- set up handlers and where window should be shown (from saved state, if any)
244
311
local movewindow_info = {
@@ -249,18 +316,28 @@ function movewindow.install (win, default_position, default_flags, nocheck, defa
249
316
window_top = tonumber (GetVariable (" mw_" .. win .. " _windowy" )) or 0 ,
250
317
window_mode = tonumber (GetVariable (" mw_" .. win .. " _windowmode" )) or default_position ,
251
318
window_flags = tonumber (GetVariable (" mw_" .. win .. " _windowflags" )) or default_flags ,
252
- window_friends = default_friends ,
319
+ window_friends = friends or {} ,
253
320
window_friend_deltas = {},
254
- margin = 20 -- how close we can put to the edge of the window
321
+ margin = 20 , -- how close we can put to the edge of the window
322
+ preprocess = preprocess or {},
255
323
}
256
324
325
+ -- check valid
326
+ for k , v in pairs (movewindow_info .preprocess ) do
327
+ assert (type (v ) == " function" , " Handler '" .. k .. " ' is not a function" )
328
+ end -- for
329
+
257
330
-- handler to reposition window
258
331
movewindow_info .check_map_position = make_check_map_position_handler (movewindow_info ) -- for startup
259
332
260
333
-- mouse handlers
261
- movewindow_info .mousedown = make_mousedown_handler (movewindow_info )
262
- movewindow_info .dragmove = make_dragmove_handler (movewindow_info )
263
- movewindow_info .dragrelease = make_dragrelease_handler (movewindow_info )
334
+ movewindow_info .mousedown = make_mousedown_handler (movewindow_info )
335
+ movewindow_info .mouseup = make_other_handler (movewindow_info , " mouseup" )
336
+ movewindow_info .mouseover = make_other_handler (movewindow_info , " mouseover" )
337
+ movewindow_info .cancelmouseover = make_other_handler (movewindow_info , " cancelmouseover" )
338
+ movewindow_info .cancelmousedown = make_other_handler (movewindow_info , " cancelmousedown" )
339
+ movewindow_info .dragmove = make_dragmove_handler (movewindow_info )
340
+ movewindow_info .dragrelease = make_dragrelease_handler (movewindow_info )
264
341
265
342
-- save table in global namespace
266
343
_G [" mw_" .. win .. " _movewindow_info" ] = movewindow_info
@@ -293,14 +370,14 @@ function movewindow.add_drag_handler (win, left, top, right, bottom, cursor)
293
370
294
371
-- make a hotspot
295
372
WindowAddHotspot (win , hotspot_id ,
296
- left or 0 , top or 0 , right or 0 , bottom or 0 , -- rectangle
297
- " " , -- MouseOver
298
- " " , -- CancelMouseOver
299
- " mw_" .. win .. " _movewindow_info.mousedown" , -- MouseDown
300
- " " , -- CancelMouseDown
301
- " " , -- MouseUp
373
+ left or 0 , top or 0 , right or 0 , bottom or 0 , -- rectangle
374
+ " mw_ " .. win .. " _movewindow_info.mouseover " , -- MouseOver
375
+ " mw_ " .. win .. " _movewindow_info.cancelmouseover " , -- CancelMouseOver
376
+ " mw_" .. win .. " _movewindow_info.mousedown" , -- MouseDown
377
+ " mw_ " .. win .. " _movewindow_info.cancelmousedown " , -- CancelMouseDown
378
+ " mw_ " .. win .. " _movewindow_info.mouseup " , -- MouseUp
302
379
" Drag to move window" , -- tooltip text
303
- cursor or 1 , -- cursor
380
+ cursor or miniwin . cursor_hand , -- cursor
304
381
0 ) -- flags
305
382
306
383
WindowDragHandler (win , hotspot_id ,
0 commit comments