Skip to content

Commit d4d5dac

Browse files
committed
Improved movewindow.lua allows for preprocessing of mouse events
1 parent 80c3097 commit d4d5dac

File tree

1 file changed

+114
-37
lines changed

1 file changed

+114
-37
lines changed

lua/movewindow.lua

Lines changed: 114 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,49 @@ Miniwindow drag-to-move functions.
66
77
Author: Nick Gammon
88
Date: 15th July 2009
9+
Modified: 16th November 2010 to add preprocessing
910
1011
1112
This module is intended to make it easier to add drag handlers for miniwindows.
1213
1314
It implements the following:
1415
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)
1644
1745
movewindow.add_drag_handler (win, left, top, right, bottom, cursor) -- add a drag handler for the nominated rectangle
1846
1947
movewindow.save_state (win) -- saves the miniwindow location to the appropriate variables
2048
2149
It also installs a position-checker that moves the miniwindow into view after 5 seconds, in case
2250
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)
2452
2553
2654
Example of use:
@@ -32,7 +60,7 @@ Example of use:
3260
3361
win = GetPluginID () -- miniwindow ID
3462
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
3664
3765
-- make miniwindow (use locations returned from last time we saved the state)
3866
-- 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:
5280
-- in this case we use 0,0,0,0 as the rectangle (ie. the whole window)
5381
-- typically the height would be the size of the title bar
5482
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)
5784
5885
-- SAVE STATE in OnPluginSaveState
5986
@@ -95,8 +122,15 @@ movewindow = {} -- table to hold functions like movewindow.install
95122
local function make_mousedown_handler (mwi)
96123

97124
return function (flags, hotspot_id)
98-
125+
99126
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
100134

101135
-- find where mouse is so we can adjust window relative to mouse
102136
mwi.startx = WindowInfo (win, 14)
@@ -107,9 +141,13 @@ local function make_mousedown_handler (mwi)
107141
mwi.origy = WindowInfo (win, 11)
108142

109143
-- 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+
}
113151
end -- if
114152
end -- for
115153

@@ -125,17 +163,27 @@ local function make_dragmove_handler (mwi)
125163

126164
local win = mwi.win
127165

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+
128173
-- find where it is now
129174
local posx, posy = WindowInfo (win, 17) - mwi.startx,
130175
WindowInfo (win, 18) - mwi.starty
131176

132177
-- 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);
134179

135180
-- 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))
139187
end -- if
140188
end -- for
141189

@@ -144,15 +192,15 @@ local function make_dragmove_handler (mwi)
144192
posx > GetInfo (281) - mwi.margin or
145193
posy < 0 or -- don't drag title out of view
146194
posy > GetInfo (280) - mwi.margin then
147-
SetCursor (11) -- X cursor
195+
SetCursor (miniwin.cursor_x) -- X cursor
148196
else
149-
SetCursor (1) -- hand cursor
197+
SetCursor (miniwin.cursor_hand) -- hand cursor
150198
end -- if
151199

152200
mwi.window_left = posx -- remember for saving state
153201
mwi.window_top = posy
154202
mwi.window_mode = 0
155-
mwi.window_flags = 2 -- absolute position
203+
mwi.window_flags = miniwin.create_absolute_location -- absolute position
156204

157205
end -- dragmove
158206

@@ -166,6 +214,13 @@ local function make_dragrelease_handler (mwi)
166214

167215
local win = mwi.win
168216

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+
169224
Repaint () -- update window location
170225

171226
-- find where window is now
@@ -177,12 +232,12 @@ local function make_dragrelease_handler (mwi)
177232
newy < 0 or -- don't drag title out of view
178233
newy > GetInfo (280) - mwi.margin then
179234
-- put it back
180-
WindowPosition(win, mwi.origx, mwi.origy, 0, 2)
235+
WindowPosition(win, mwi.origx, mwi.origy, 0, miniwin.create_absolute_location)
181236

182237
mwi.window_left = mwi.origx -- remember for saving state
183238
mwi.window_top = mwi.origy
184239
mwi.window_mode = 0
185-
mwi.window_flags = 2 -- absolute position
240+
mwi.window_flags = miniwin.create_absolute_location -- absolute position
186241

187242
return
188243
end -- if out of bounds
@@ -192,6 +247,21 @@ local function make_dragrelease_handler (mwi)
192247

193248
end -- make_dragrelease_handler
194249

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+
195265
-- make a mouse position-checking function with the movement information as an upvalue
196266

197267
local function make_check_map_position_handler (mwi)
@@ -210,8 +280,8 @@ local function make_check_map_position_handler (mwi)
210280
mwi.window_left > GetInfo (281) - mwi.margin or
211281
mwi.window_top < 0 or -- don't drag title out of view
212282
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
215285
mwi.window_flags = 0
216286
end -- if not visible
217287

@@ -228,17 +298,14 @@ end -- make_check_map_position_handler
228298
-- call movewindow.install in OnPluginInstall to find the position of the window, before creating it
229299
-- - it also creates the handler functions ready for use later
230300

231-
function movewindow.install (win, default_position, default_flags, nocheck, default_friends)
301+
function movewindow.install (win, default_position, default_flags, nocheck, friends, preprocess)
232302

233303
win = win or GetPluginID () -- default to current plugin ID
234304

235305
assert (not string.match (win, "[^A-Za-z0-9_]"), "Invalid window name in movewindow.install: " .. win)
236306

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
238308
default_flags = default_flags or 0
239-
if (default_friends == nil) then
240-
default_friends = {}
241-
end
242309

243310
-- set up handlers and where window should be shown (from saved state, if any)
244311
local movewindow_info = {
@@ -249,18 +316,28 @@ function movewindow.install (win, default_position, default_flags, nocheck, defa
249316
window_top = tonumber (GetVariable ("mw_" .. win .. "_windowy")) or 0,
250317
window_mode = tonumber (GetVariable ("mw_" .. win .. "_windowmode")) or default_position,
251318
window_flags = tonumber (GetVariable ("mw_" .. win .. "_windowflags")) or default_flags,
252-
window_friends = default_friends,
319+
window_friends = friends or {},
253320
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 {},
255323
}
256324

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+
257330
-- handler to reposition window
258331
movewindow_info.check_map_position = make_check_map_position_handler (movewindow_info) -- for startup
259332

260333
-- 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)
264341

265342
-- save table in global namespace
266343
_G ["mw_" .. win .. "_movewindow_info"] = movewindow_info
@@ -293,14 +370,14 @@ function movewindow.add_drag_handler (win, left, top, right, bottom, cursor)
293370

294371
-- make a hotspot
295372
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
302379
"Drag to move window", -- tooltip text
303-
cursor or 1, -- cursor
380+
cursor or miniwin.cursor_hand, -- cursor
304381
0) -- flags
305382

306383
WindowDragHandler (win, hotspot_id,

0 commit comments

Comments
 (0)