centralize management of mouse state

develop
Myk Taylor 2023-10-01 16:28:18 -07:00
parent 8ed4890160
commit 5d295400d2
No known key found for this signature in database
9 changed files with 46 additions and 47 deletions

@ -222,9 +222,6 @@ local function click_top_title_button(scr)
df.global.gps.mouse_y = (sh // 2) + 3
end
df.global.gps.precise_mouse_y = df.global.gps.mouse_y * df.global.gps.tile_pixel_y
df.global.enabler.tracking_on = 1
df.global.enabler.mouse_lbut = 1
df.global.enabler.mouse_lbut_down = 1
gui.simulateInput(scr, '_MOUSE_L')
end

@ -3952,6 +3952,14 @@ Misc
of keycodes to *true* or *false*. For instance, it is possible to use the
table passed as argument to ``onInput``.
You can send mouse clicks as will by setting the ``_MOUSE_L`` key or other
mouse-related pseudo-keys documented with the ``screen:onInput(keys)``
function above. Note that if you are simulating a click at a specific spot on
the screen, you must set ``df.global.gps.mouse_x`` and
``df.global.gps.mouse_y`` if you are clicking on the interface layer or
``df.global.gps.precise_mouse_x`` and ``df.global.gps.precise_mouse_y`` if
you are clickin on the map.
* ``mkdims_xy(x1,y1,x2,y2)``
Returns a table containing the arguments as fields, and also ``width`` and

@ -391,6 +391,7 @@ namespace DFHack
virtual ~dfhack_lua_viewscreen();
static df::viewscreen *get_pointer(lua_State *L, int idx, bool make);
static void markInputAsHandled();
virtual bool is_lua_screen() { return true; }
virtual bool isFocused() { return !defocused; }

@ -15,8 +15,8 @@ TRANSPARENT_PEN = to_pen{tile=0, ch=0}
KEEP_LOWER_PEN = to_pen{ch=32, fg=0, bg=0, keep_lower=true}
local MOUSE_KEYS = {
_MOUSE_L = true,
_MOUSE_R = true,
_MOUSE_L = function(is_set) df.global.enabler.mouse_lbut = is_set and 1 or 0 end,
_MOUSE_R = function(is_set) df.global.enabler.mouse_rbut = is_set and 1 or 0 end,
_MOUSE_M = true,
_MOUSE_L_DOWN = true,
_MOUSE_R_DOWN = true,
@ -27,7 +27,7 @@ local FAKE_INPUT_KEYS = copyall(MOUSE_KEYS)
FAKE_INPUT_KEYS._STRING = true
function simulateInput(screen,...)
local keys = {}
local keys, enabled_mouse_keys = {}, {}
local function push_key(arg)
local kv = arg
if type(arg) == 'string' then
@ -35,6 +35,10 @@ function simulateInput(screen,...)
if kv == nil and not FAKE_INPUT_KEYS[arg] then
error('Invalid keycode: '..arg)
end
if MOUSE_KEYS[arg] then
df.global.enabler.tracking_on = 1
enabled_mouse_keys[arg] = true
end
end
if type(kv) == 'number' then
keys[#keys+1] = kv
@ -57,6 +61,11 @@ function simulateInput(screen,...)
end
end
end
for mk, fn in pairs(MOUSE_KEYS) do
if type(fn) == 'function' then
fn(enabled_mouse_keys[mk])
end
end
dscreen._doSimulateInput(screen, keys)
end
@ -696,17 +705,6 @@ end
DEFAULT_INITIAL_PAUSE = true
-- ensure underlying DF screens don't also react to handled clicks
function markMouseClicksHandled(keys)
if keys._MOUSE_L then
df.global.enabler.mouse_lbut = 0
end
if keys._MOUSE_R then
df.global.enabler.mouse_rbut_down = 0
df.global.enabler.mouse_rbut = 0
end
end
ZScreen = defclass(ZScreen, Screen)
ZScreen.ATTRS{
defocusable=true,
@ -791,23 +789,17 @@ function ZScreen:onInput(keys)
self:raise()
else
self:sendInputToParent(keys)
return
return true
end
end
if ZScreen.super.onInput(self, keys) then
markMouseClicksHandled(keys)
return
end
if self.pass_mouse_clicks and keys._MOUSE_L and not has_mouse then
-- noop
elseif self.pass_mouse_clicks and keys._MOUSE_L and not has_mouse then
self.defocused = self.defocusable
self:sendInputToParent(keys)
return
elseif keys.LEAVESCREEN or keys._MOUSE_R then
self:dismiss()
markMouseClicksHandled(keys)
return
else
local passit = self.pass_pause and keys.D_PAUSE
if not passit and self.pass_mouse_clicks then
@ -829,8 +821,8 @@ function ZScreen:onInput(keys)
if passit then
self:sendInputToParent(keys)
end
return
end
return true
end
function ZScreen:raise()

@ -64,13 +64,9 @@ function MessageBox:onInput(keys)
elseif (keys.LEAVESCREEN or keys._MOUSE_R) and self.on_cancel then
self.on_cancel()
end
gui.markMouseClicksHandled(keys)
return true
end
if self:inputToSubviews(keys) then
gui.markMouseClicksHandled(keys)
return true
end
return self:inputToSubviews(keys)
end
function showMessage(title, text, tcolor, on_close)
@ -137,13 +133,9 @@ function InputBox:onInput(keys)
if self.on_cancel then
self.on_cancel()
end
gui.markMouseClicksHandled(keys)
return true
end
if self:inputToSubviews(keys) then
gui.markMouseClicksHandled(keys)
return true
end
return self:inputToSubviews(keys)
end
function showInputPrompt(title, text, tcolor, input, on_input, on_cancel, min_width)
@ -242,13 +234,9 @@ function ListBox:onInput(keys)
if self.on_cancel then
self.on_cancel()
end
gui.markMouseClicksHandled(keys)
return true
end
if self:inputToSubviews(keys) then
gui.markMouseClicksHandled(keys)
return true
end
return self:inputToSubviews(keys)
end
function showListPrompt(title, text, tcolor, choices, on_select, on_cancel, min_width, filter)

@ -956,6 +956,18 @@ int dfhack_lua_viewscreen::do_notify(lua_State *L)
return 1;
}
void dfhack_lua_viewscreen::markInputAsHandled() {
if (!enabler)
return;
// clear text buffer
enabler->last_text_input[0] = '\0';
// mark clicked mouse buttons as handled
enabler->mouse_lbut = 0;
enabler->mouse_rbut = 0;
}
int dfhack_lua_viewscreen::do_input(lua_State *L)
{
auto self = get_self(L);
@ -977,7 +989,11 @@ int dfhack_lua_viewscreen::do_input(lua_State *L)
lua_pushvalue(L, -2);
Lua::PushInterfaceKeys(L, Screen::normalize_text_keys(*keys));
lua_call(L, 2, 0);
lua_call(L, 2, 1);
if (lua_toboolean(L, -1))
markInputAsHandled();
lua_pop(L, 1);
self->update_focus(L, -1);
return 0;
}

@ -280,14 +280,12 @@ function Menu:onInput(keys)
local x = list:getMousePos()
if x == 0 then -- clicked on icon
self:onSubmit2(list:getSelected())
gui.markMouseClicksHandled(keys)
return true
end
if not self:getMouseFramePos() then
self.parent_view:dismiss()
return true
end
gui.markMouseClicksHandled(keys)
end
self:inputToSubviews(keys)
return true -- we're modal

@ -506,7 +506,6 @@ function feed_viewscreen_widgets(vs_name, vs, keys)
not _feed_viewscreen_widgets('all', nil, keys) then
return false
end
gui.markMouseClicksHandled(keys)
return true
end

@ -86,7 +86,7 @@ struct viewscreen_overlay : T {
if (!input_is_handled)
INTERPOSE_NEXT(feed)(input);
else
enabler->last_text_input[0] = '\0';
dfhack_lua_viewscreen::markInputAsHandled();
}
DEFINE_VMETHOD_INTERPOSE(void, render, ()) {
INTERPOSE_NEXT(render)();