Written by Nick Gammon - July 2008. Updated September 2010.
On this page:
See also:
In order to allow you to interact with the miniwindows, you can designate hotspots (really, "hot rectangles"). When the mouse is moved inside these designated areas (of which there can be any number per miniwindow), script functions in your plugin can be called. These functions can handle:
In addition, you can specify tooltip text, which automatically appears if the mouse hovers over a hotspot, after a short delay. This can be used to provide short help messages.
You can also add support for mouse dragging (from version 4.40 onwards) using WindowDragHandler, and for the player moving the mouse scroll-wheel with WindowScrollwheelHandler.
Each miniwindow can have any number of hotspots (including zero). Each one designates a rectangle which has some significance if you mouse over it, or click inside it. You should take care not to overlap hotspot rectangles or they may not behave as you expect. When checking for mouse clicks, hotspots are evaluated in ascending alphabetic order by hotspot id.
Hotspots are not, in themselves, visible graphic elements. You would normally associate them with a piece of text (for a hyperlink) or a graphical element such as a button or checkbox. For example, when drawing text, you know the starting point of the text, the height of the text, and the width of the text. This can be used to create a hotspot over the same place the text appeared.
Most of the functionality of hotspots is provided by script plugin "callbacks" - that is, when you mouse over a hotspot, a function in your plugin is called (if you nominate one). Thus hotspots would generally be implemented inside plugins.
In addition to the callbacks defined here, you can also use WindowDragHandler to add callbacks for dragging with the mouse, and WindowScrollwheelHandler for if the scroll-wheel on the mouse is moved.
WindowAddHotspot function prototype:
long WindowAddHotspot(BSTR Name, BSTR HotspotId, long Left, long Top, long Right, long Bottom, BSTR MouseOver, BSTR CancelMouseOver, BSTR MouseDown, BSTR CancelMouseDown, BSTR MouseUp, BSTR TooltipText, long Cursor, long Flags);
This create a hotspot in the miniwindow, and remembers it by the nominated "hotspot id".
Value | Purpose | Lua symbol |
---|---|---|
-1 | No cursor | |
0 | Arrow | |
1 | Hand | |
2 | I-beam | |
3 | + symbol | |
4 | Wait (hour-glass) | |
5 | Up arrow | |
6 | Arrow nw-se | |
7 | Arrow ne-sw | |
8 | Arrow e-w | |
9 | Arrow n-s | |
10 | Arrow - all ways | |
11 | (X) cannot do action | |
12 | Help (? symbol) |
You can use SetCursor to change the cursor shape when you want.
Value | Purpose | Lua symbol |
---|---|---|
1 | If set, all mouse-overs (not just the first) are sent to the mouse-over function. |
WindowAddHotspot(win, "hs1",
10, 10, 60, 20, -- rectangle
"mouseover",
"cancelmouseover",
"mousedown",
"cancelmousedown",
"mouseup",
"Click here to be healed", -- tooltip text
miniwin.cursor_hand, 0) -- hand cursor
The functions specified for WindowAddHotspot do not have to exist - use an empty string if you don't want a particular action to cause a function call. However if the callback function name is not empty it must be a valid function name. There is no error message if the function cannot be found, however if you turn Trace on (Game menu -> Trace) then messages will appear in the output window to warn you about missing (non-empty) functions.
The callback function should look like this:
function mouseover (flags, hotspot_id)
Note ("we moused over hotspot " .. hotspot_id)
return 0 -- needed for some languages
end -- mouseover
Since the hotspot ID is passed to the callback function, you can share the same function amongst all your hotspots. For example, a "mouse down" function could handle all the hyperlinks in a miniwindow - by using the hotspot ID, it could look up in a table what action to perform for this particular hotspot.
The function return code is ignored, however for some languages, like PHP, you should return 0, otherwise you will get a runtime error.
The flags parameter is a bit mask as follows:
Value | Purpose | Lua symbol |
---|---|---|
0x01 (1) | Shift key down | |
0x02 (2) | Control key down | |
0x04 (4) | Alt key down | |
0x10 (16) | LH mouse | |
0x20 (32) | RH mouse | |
0x40 (64) | Double-click | |
0x80 (128) | Not first mouse-over in hotspot | |
0x100 (256) | Scroll wheel scrolled down (towards you) |
So, for example, if the left-hand mouse was double-clicked whilst the shift and control keys were held down, the flags would be:
flags = 0x01 + 0x02 + 0x10 + 0x40 --> namely 0x53 (83 in decimal)
-- that is:
flags = miniwin.hotspot_got_shift + miniwin.hotspot_got_control +
miniwin.hotspot_got_lh_mouse + miniwin.hotspot_got_dbl_click
-- in Lua you might test for a LH mouse click like this:
if bit.band (flags, miniwin.hotspot_got_lh_mouse) ~= 0 then
-- LH mouse clicked
end -- if
If the mouse is clicked inside the hotspot, the "CancelMouseOver" function is called before any "MouseDown" function for the same hotspot.
If the mouse moves over a hotspot, after about half a second the TooltipText string is displayed in a tooltip window (if any is specified). This tool tip will disappear after a few seconds.
The moment the mouse moves over a hotspot the mouse cursor is changed to be the shape specified for the hotspot (Cursor argument).
Suggestions
The MouseOver event (with the corresponding CancelMouseOver where required) can be used to:
The CancelMouseOver event should be used, if necessary to:
Suggestions
The MouseDown event (with the corresponding CancelMouseOver or MouseUp where required) can be used to:
The CancelMouseDown event should be used, if necessary to:
The MouseUp event should be used, if necessary to:
If you no longer require a hotspot it can be deleted by calling WindowDeleteHotspot.
WindowDeleteHotspot function prototype:
long WindowDeleteHotspot(BSTR Name, BSTR HotspotId);
This deletes the hotspot from the miniwindow.
WindowDeleteHotspot (win, "hs1");
If you no longer require your hotspots (perhaps after clearing the window and starting again), you can call WindowDeleteAllHotspots.
WindowDeleteAllHotspots function prototype:
long WindowDeleteAllHotspots(BSTR Name);
This deletes all hotspots from the miniwindow.
WindowDeleteAllHotspots (win);
Note - when WindowCreate is called, all existing hotspots are automatically deleted, if the window previously existed, unless the flag miniwin.create_keep_hotspots was used when calling WindowCreate.
If you need to move a hotspot around you can do it with WindowMoveHotspot.
WindowMoveHotspot function prototype:
long WindowMoveHotspot(BSTR Name, BSTR HotspotId, long Left, long Top, long Right, long Bottom);
This moves a hotspot from one place to another. You might use this in a resize callback function.
WindowMoveHotspot (win, "hs1", 20, 20, 40, 40);
WindowHotspotList function prototype:
VARIANT WindowHotspotList(BSTR Name);
This returns a list of all hotspots loaded into this miniwindow. You could use this to find which hotspots have been created, and then use WindowHotspotInfo to find information about each one.
-- show all hotspots
hotspots = WindowHotspotList(win)
if hotspots then
for _, v in ipairs (hotspots) do
Note (v)
end
end -- if any
WindowHotspotInfo function prototype:
VARIANT WindowHotspotInfo(BSTR Name, BSTR HotspotId, long InfoType);
This returns information about a hotspot. You need to specify the name of the miniwindow, and the hotspot id you used when creating the hotspot.
WindowHotspotTooltip function prototype:
long WindowHotspotTooltip(BSTR Name, BSTR HotspotId, BSTR TooltipText);
This changes the tooltip text for a hotspot (shown if the mouse hovers over the hotspot for a second or so).
function hyperlink_configure_background ()
local new_colour = PickColour (background_colour) -- colour picker
if new_colour ~= -1 then -- if dialog not dismissed
background_colour = new_colour
Display_Map ()
end -- new colour
end -- hyperlink_configure_background
function hyperlink_configure_title ()
local new_colour = PickColour (title_colour) -- colour picker
if new_colour ~= -1 then -- if dialog not dismissed
title_colour = new_colour
Display_Map ()
end -- new colour
end -- hyperlink_configure_title
-- here if they click on the hyperlink
function mousedown (flags, hotspotid)
local f = hyperlink_functions [hotspotid]
if f then
f ()
end -- function found
end -- mousedown
hyperlink_functions = {}
function make_hyperlink (text, id, left, top, action, hint)
-- work out text rectangle size
local height = WindowFontInfo (win, font_id, 1)
local right = left + WindowTextWidth (win, font_id, text)
local bottom = top + height
-- add the hotspot
WindowAddHotspot(win, id,
left, top, right, bottom,
"", -- mouseover (do nothing)
"", -- cancelmouseover (do nothing)
"mousedown",
"", -- cancelmousedown (do nothing)
"", -- mouseup (do nothing)
hint, -- hint text if they hover over it
miniwin.cursor_hand, 0)
-- draw the hyperlink text in the rectangle
WindowText (win, font_id, text, left, top, right, bottom, hyperlink_colour)
-- remember action function
hyperlink_functions [id] = action
end -- make_hyperlink
-- further down, where we draw the map ....
-- hyperlink for title colour
make_hyperlink ("?", "back_colour", width - 15, height - 5 - font_height,
hyperlink_configure_background, "Choose background colour")
-- hyperlink for map body colour
make_hyperlink ("?", "title_colour", width - 15, font_height + 5,
hyperlink_configure_title, "Choose title colour")
With the above code in place, you see the "?" characters in the specified locations. These are the hyperlinks:
Now if you click on one, it opens the colour picker, so you can choose the colour you want:
WindowDragHandler function prototype:
long WindowDragHandler(BSTR Name, BSTR HotspotId, BSTR MoveCallback, BSTR ReleaseCallback, long Flags);
This adds a "mouse drag handler" to the designated hotspot. You need to specify the name of the miniwindow, and the hotspot id you used when creating the hotspot. This provides extra functionality which applies after there is a mouse-down in that hotspot.
The flags passed to the drag handler will be a bit mask as follows:
Value | Purpose | Lua symbol |
---|---|---|
0x01 (1) | Shift key down | |
0x02 (2) | Control key down | |
0x04 (4) | Alt key down |
function dragmove(flags, hotspot_id)
local posx, posy = WindowInfo (win, 17),
WindowInfo (win, 18)
print ("moved to position", posx, posy)
-- move the window to the new location
WindowPosition(win, posx - startx, posy - starty,
miniwin.pos_stretch_to_view,
miniwin.create_absolute_location);
-- change the mouse cursor shape appropriately
if posx < 0 or posx > GetInfo (281) or
posy < 0 or posy > GetInfo (280) then
check (SetCursor (miniwin.cursor_x)) -- X cursor
else
check (SetCursor (miniwin.cursor_hand)) -- hand cursor
end -- if
end -- dragmove
function dragrelease(flags, hotspot_id)
print ("mouse drag release for " .. hotspot_id)
print ("released at position", WindowInfo (win, 17), WindowInfo (win, 18))
end -- dragrelease
WindowDragHandler(win, "hs1", "dragmove", "dragrelease", 0)
WindowScrollwheelHandler function prototype:
long WindowScrollwheelHandler(BSTR WindowName, BSTR HotspotId, BSTR MoveCallback);
Adds a scroll-wheel handler callback to the nominated hotspot. If:
The callback function should look like this:
function wheel_move (flags, hotspot_id)
if bit.band (flags, miniwin.wheel_scroll_back) ~= 0 then
-- wheel scrolled down (towards you)
else
-- wheel scrolled up (away from you)
end -- if
return 0 -- needed for some languages
end -- wheel_move
Since the hotspot ID is passed to the callback function, you can share the same function amongst all your hotspots.
The function return code is ignored, however for some languages, like PHP, you should return 0, otherwise you will get a runtime error.
The flags parameter passed to the move function is a bit mask as follows:
Value | Purpose | Lua symbol |
---|---|---|
0x01 (1) | Shift key down | |
0x02 (2) | Control key down | |
0x04 (4) | Altkey down | |
0x100 (256) | Scroll wheel scrolled down (towards you) |
Comments to:
Gammon Software support
Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )