Skip to content

Commit

Permalink
Improved movewindow.lua allows for preprocessing of mouse events
Browse files Browse the repository at this point in the history
  • Loading branch information
nickgammon committed Nov 15, 2010
1 parent 80c3097 commit d4d5dac
Showing 1 changed file with 114 additions and 37 deletions.
151 changes: 114 additions & 37 deletions lua/movewindow.lua
Expand Up @@ -6,21 +6,49 @@ Miniwindow drag-to-move functions.
Author: Nick Gammon
Date: 15th July 2009
Modified: 16th November 2010 to add preprocessing
This module is intended to make it easier to add drag handlers for miniwindows.
It implements the following:
windowinfo = movewindow.install (win, default_position, flags) -- find previous location
-- find previous location
nocheck: if true, don't check if offscreen (boolean)
friends: other windows to move with this one (table)
preprocess: preprocessing for mousedown, mouseup etc. (table)
Handler names for preprocess table:
mousedown
mouseup
mouseover
cancelmouseover
cancelmousedown
dragmove
dragrelease
If any preprocess handler returns true (that is, neither nil nor false) then the default handler
in this module is not used. (The miniwindow name is the third argument)
function mousedown (flags, id, win)
if bit.band (flags, miniwin.hotspot_got_rh_mouse) then
-- do something different here
return true
end -- if
return false -- take normal movewindow behaviour
end -- mousedown
windowinfo = movewindow.install (win, default_position, default_flags, nocheck, friends, preprocess)
movewindow.add_drag_handler (win, left, top, right, bottom, cursor) -- add a drag handler for the nominated rectangle
movewindow.save_state (win) -- saves the miniwindow location to the appropriate variables
It also installs a position-checker that moves the miniwindow into view after 5 seconds, in case
you resize the main world window, and the window is no longer visible. The 5 seconds are to give
the main world window's position and size time to stabilize.
the main world window's position and size time to stabilize. (Unless nocheck is true)
Example of use:
Expand All @@ -32,7 +60,7 @@ Example of use:
win = GetPluginID () -- miniwindow ID
windowinfo = movewindow.install (win, 7, 0) -- get position (default to right/middle)
windowinfo = movewindow.install (win, miniwin.pos_center_right, 0) -- default position / flags
-- make miniwindow (use locations returned from last time we saved the state)
-- note that the width and height are not part of the window position info, and can thus change as required
Expand All @@ -52,8 +80,7 @@ Example of use:
-- in this case we use 0,0,0,0 as the rectangle (ie. the whole window)
-- typically the height would be the size of the title bar
movewindow.add_drag_handler (win, 0, 0, 0, 0, 10) -- both-ways arrow cursor (10)
movewindow.add_drag_handler (win, 0, 0, 0, 0, miniwin.cursor_both_arrow)
-- SAVE STATE in OnPluginSaveState
Expand Down Expand Up @@ -95,8 +122,15 @@ movewindow = {} -- table to hold functions like movewindow.install
local function make_mousedown_handler (mwi)
return function (flags, hotspot_id)
local win = mwi.win
-- see if other action wanted
if mwi.preprocess.mousedown then
if mwi.preprocess.mousedown (flags, hotspot_id, win) then
return
end -- if handled already
end -- if handler
-- find where mouse is so we can adjust window relative to mouse
mwi.startx = WindowInfo (win, 14)
Expand All @@ -107,9 +141,13 @@ local function make_mousedown_handler (mwi)
mwi.origy = WindowInfo (win, 11)
-- find where the friends are relative to the window
for i,v in ipairs(mwi.window_friends) do
if (v ~= nil) then
mwi.window_friend_deltas[i] = {WindowInfo(v, 10) - mwi.origx, WindowInfo(v, 11) - mwi.origy}
for i, v in ipairs (mwi.window_friends) do
if v then
mwi.window_friend_deltas [i] =
{
WindowInfo (v, 10) - mwi.origx,
WindowInfo (v, 11) - mwi.origy
}
end -- if
end -- for
Expand All @@ -125,17 +163,27 @@ local function make_dragmove_handler (mwi)
local win = mwi.win
-- see if other action wanted
if mwi.preprocess.dragmove then
if mwi.preprocess.dragmove (flags, hotspot_id, win) then
return
end -- if handled already
end -- if handler
-- find where it is now
local posx, posy = WindowInfo (win, 17) - mwi.startx,
WindowInfo (win, 18) - mwi.starty
-- move the window to the new location - offset by how far mouse was into window
WindowPosition(win, posx, posy, 0, 2);
WindowPosition(win, posx, posy, 0, miniwin.create_absolute_location);
-- move the friends if they still exist
for i,v in ipairs(mwi.window_friends) do
if (v ~= nil) then
WindowPosition(v, posx+mwi.window_friend_deltas[i][1], posy+mwi.window_friend_deltas[i][2], 0, WindowInfo(v, 8))
for i, v in ipairs(mwi.window_friends) do
if v then
WindowPosition (v, posx + mwi.window_friend_deltas [i] [1],
posy + mwi.window_friend_deltas [i] [2],
0,
WindowInfo (v, 8))
end -- if
end -- for
Expand All @@ -144,15 +192,15 @@ local function make_dragmove_handler (mwi)
posx > GetInfo (281) - mwi.margin or
posy < 0 or -- don't drag title out of view
posy > GetInfo (280) - mwi.margin then
SetCursor (11) -- X cursor
SetCursor (miniwin.cursor_x) -- X cursor
else
SetCursor (1) -- hand cursor
SetCursor (miniwin.cursor_hand) -- hand cursor
end -- if
mwi.window_left = posx -- remember for saving state
mwi.window_top = posy
mwi.window_mode = 0
mwi.window_flags = 2 -- absolute position
mwi.window_flags = miniwin.create_absolute_location -- absolute position
end -- dragmove
Expand All @@ -166,6 +214,13 @@ local function make_dragrelease_handler (mwi)
local win = mwi.win
-- see if other action wanted
if mwi.preprocess.dragrelease then
if mwi.preprocess.dragrelease (flags, hotspot_id, win) then
return
end -- if handled already
end -- if handler
Repaint () -- update window location
-- find where window is now
Expand All @@ -177,12 +232,12 @@ local function make_dragrelease_handler (mwi)
newy < 0 or -- don't drag title out of view
newy > GetInfo (280) - mwi.margin then
-- put it back
WindowPosition(win, mwi.origx, mwi.origy, 0, 2)
WindowPosition(win, mwi.origx, mwi.origy, 0, miniwin.create_absolute_location)
mwi.window_left = mwi.origx -- remember for saving state
mwi.window_top = mwi.origy
mwi.window_mode = 0
mwi.window_flags = 2 -- absolute position
mwi.window_flags = miniwin.create_absolute_location -- absolute position
return
end -- if out of bounds
Expand All @@ -192,6 +247,21 @@ local function make_dragrelease_handler (mwi)
end -- make_dragrelease_handler
-- make other handler with the movement information as an upvalue
local function make_other_handler (mwi, name)
return function (flags, hotspot_id)
-- send to supplied handler
if mwi.preprocess [name] then
mwi.preprocess [name] (flags, hotspot_id, mwi.win)
end -- if handler
end -- other
end -- make_other_handler
-- make a mouse position-checking function with the movement information as an upvalue
local function make_check_map_position_handler (mwi)
Expand All @@ -210,8 +280,8 @@ local function make_check_map_position_handler (mwi)
mwi.window_left > GetInfo (281) - mwi.margin or
mwi.window_top < 0 or -- don't drag title out of view
mwi.window_top > GetInfo (280) - mwi.margin then
mwi.window_left, mwi.window_top = 0, 0 -- reset to top left
mwi.window_mode = 7
mwi.window_left, mwi.window_top = 0, 0 -- reset to center right
mwi.window_mode = miniwin.pos_center_right
mwi.window_flags = 0
end -- if not visible
Expand All @@ -228,17 +298,14 @@ end -- make_check_map_position_handler
-- call movewindow.install in OnPluginInstall to find the position of the window, before creating it
-- - it also creates the handler functions ready for use later
function movewindow.install (win, default_position, default_flags, nocheck, default_friends)
function movewindow.install (win, default_position, default_flags, nocheck, friends, preprocess)
win = win or GetPluginID () -- default to current plugin ID
assert (not string.match (win, "[^A-Za-z0-9_]"), "Invalid window name in movewindow.install: " .. win)
default_position = default_position or 7 -- on right, center top/bottom
default_position = default_position or miniwin.pos_center_right -- on right, center top/bottom
default_flags = default_flags or 0
if (default_friends == nil) then
default_friends = {}
end
-- set up handlers and where window should be shown (from saved state, if any)
local movewindow_info = {
Expand All @@ -249,18 +316,28 @@ function movewindow.install (win, default_position, default_flags, nocheck, defa
window_top = tonumber (GetVariable ("mw_" .. win .. "_windowy")) or 0,
window_mode = tonumber (GetVariable ("mw_" .. win .. "_windowmode")) or default_position,
window_flags = tonumber (GetVariable ("mw_" .. win .. "_windowflags")) or default_flags,
window_friends = default_friends,
window_friends = friends or {},
window_friend_deltas = {},
margin = 20 -- how close we can put to the edge of the window
margin = 20, -- how close we can put to the edge of the window
preprocess = preprocess or {},
}
-- check valid
for k, v in pairs (movewindow_info.preprocess) do
assert (type (v) == "function", "Handler '" .. k .. "' is not a function")
end -- for
-- handler to reposition window
movewindow_info.check_map_position = make_check_map_position_handler (movewindow_info) -- for startup
-- mouse handlers
movewindow_info.mousedown = make_mousedown_handler (movewindow_info)
movewindow_info.dragmove = make_dragmove_handler (movewindow_info)
movewindow_info.dragrelease = make_dragrelease_handler (movewindow_info)
movewindow_info.mousedown = make_mousedown_handler (movewindow_info)
movewindow_info.mouseup = make_other_handler (movewindow_info, "mouseup")
movewindow_info.mouseover = make_other_handler (movewindow_info, "mouseover")
movewindow_info.cancelmouseover = make_other_handler (movewindow_info, "cancelmouseover")
movewindow_info.cancelmousedown = make_other_handler (movewindow_info, "cancelmousedown")
movewindow_info.dragmove = make_dragmove_handler (movewindow_info)
movewindow_info.dragrelease = make_dragrelease_handler (movewindow_info)
-- save table in global namespace
_G ["mw_" .. win .. "_movewindow_info"] = movewindow_info
Expand Down Expand Up @@ -293,14 +370,14 @@ function movewindow.add_drag_handler (win, left, top, right, bottom, cursor)
-- make a hotspot
WindowAddHotspot(win, hotspot_id,
left or 0, top or 0, right or 0, bottom or 0, -- rectangle
"", -- MouseOver
"", -- CancelMouseOver
"mw_" .. win .. "_movewindow_info.mousedown", -- MouseDown
"", -- CancelMouseDown
"", -- MouseUp
left or 0, top or 0, right or 0, bottom or 0, -- rectangle
"mw_" .. win .. "_movewindow_info.mouseover", -- MouseOver
"mw_" .. win .. "_movewindow_info.cancelmouseover", -- CancelMouseOver
"mw_" .. win .. "_movewindow_info.mousedown", -- MouseDown
"mw_" .. win .. "_movewindow_info.cancelmousedown", -- CancelMouseDown
"mw_" .. win .. "_movewindow_info.mouseup", -- MouseUp
"Drag to move window", -- tooltip text
cursor or 1, -- cursor
cursor or miniwin.cursor_hand, -- cursor
0) -- flags
WindowDragHandler (win, hotspot_id,
Expand Down

0 comments on commit d4d5dac

Please sign in to comment.