File size: 4,999 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
local max_thumb_value = (1 << 15) - 1
DefineClass.MouseViaGamepad = {
__parents = { "XWindow", "TerminalTarget" },
properties = {
{ category = "General", id = "enabled", name = "Enabled", editor = "bool", default = false },
},
Id = "idMouseViaGamepad",
IdNode = true,
HandleMouse = false,
Dock = "box",
ZOrder = 10000000, -- above everything, even above loading screens
DrawOnTop = true,
Clip = false,
UseClipBox = false,
LeftClickButton = "ButtonA",
RightClickButton = "ButtonB",
LastClickTimes = false,
DoubleClickTime = 300, --ms
}
function MouseViaGamepad:Init()
terminal.AddTarget(self)
self.LastClickTimes = { }
local image = XImage:new({
Id = "idCursor",
HAlign = "left",
VAlign = "top",
Clip = false,
UseClipBox = false,
}, self)
image:AddDynamicPosModifier({id = "cursor", target = "gamepad"})
end
function MouseViaGamepad:Done()
terminal.RemoveTarget(self)
end
function MouseViaGamepad:OnXNewPacket(_, controller_id, last_state, current_state)
if not self.enabled then return end
local left_trigger = current_state.LeftTrigger > 0
local right_trigger = current_state.RightTrigger > 0
hr.GamepadMouseEnabled = not left_trigger and not right_trigger
end
function MouseViaGamepad:OnXButtonDown(button, controller_id)
if not self.enabled then return end
if not self.visible then
ForceHideMouseCursor("MouseViaGamepad")
self:SetVisible(true)
GamepadMouseSetPos(terminal.GetMousePos())
end
local mouse_btn = (button == self.LeftClickButton and "L") or (button == self.RightClickButton and "R")
if mouse_btn then
local pt = GamepadMouseGetPos()
local now = now()
local last_click_time = self.LastClickTimes[mouse_btn]
self.LastClickTimes[mouse_btn] = now
local is_double_click = last_click_time and (now - last_click_time) <= self.DoubleClickTime
if is_double_click then
return terminal.MouseEvent("OnMouseButtonDoubleClick", pt, mouse_btn, "gamepad")
else
return terminal.MouseEvent("OnMouseButtonDown", pt, mouse_btn, "gamepad")
end
end
return "continue"
end
function MouseViaGamepad:OnXButtonUp(button, controller_id)
local mouse_btn = (button == self.LeftClickButton and "L") or (button == self.RightClickButton and "R")
if mouse_btn then
local pt = GamepadMouseGetPos()
return terminal.MouseEvent("OnMouseButtonUp", pt, mouse_btn)
end
return "continue"
end
function MouseViaGamepad:OnMousePos(pt)
if not self.enabled then return end
if self.visible then
UnforceHideMouseCursor("MouseViaGamepad")
self:SetVisible(false)
end
GamepadMouseSetPos(pt)
return "continue"
end
function MouseViaGamepad:SetEnabled(enabled)
self.enabled = enabled
hr.GamepadMouseEnabled = enabled
if enabled then
if not self:IsThreadRunning("UpdateMousePosThread") then
self:CreateThread("UpdateMousePosThread", self.UpdateMousePosThread, self)
end
else
UnforceHideMouseCursor("MouseViaGamepad")
if self:IsThreadRunning("UpdateMousePosThread") then
self:DeleteThread("UpdateMousePosThread")
end
end
end
function MouseViaGamepad:SetCursorImage(image)
self.idCursor:SetImage(image)
end
function MouseViaGamepad:UpdateMousePosThread()
GamepadMouseSetPos(terminal.GetMousePos())
local previous_pos
while true do
WaitNextFrame()
local pos = GamepadMouseGetPos()
if pos ~= previous_pos then
terminal.SetMousePos(pos)
self.parent:MouseEvent("OnMousePos", pos)
previous_pos = pos
end
end
end
----------------------
function GetMouseViaGamepadCtrl()
return terminal.desktop and rawget(terminal.desktop, "idMouseViaGamepad")
end
MouseViaGamepadHideSkipReasons = {
["MouseViaGamepad"] = true,
}
function OnMsg.ShowMouseCursor(visible)
local mouse_win = GetMouseViaGamepadCtrl()
if not mouse_win then return end
local show = not not next(ShowMouseReasons)
local force_hide
for reason in pairs(ForceHideMouseReasons) do
if not MouseViaGamepadHideSkipReasons[reason] then
force_hide = true
break
end
end
local my_visible = show and not force_hide
mouse_win:SetVisible(my_visible)
end
function OnMsg.MouseCursor(cursor)
local mouse_win = GetMouseViaGamepadCtrl()
if not mouse_win then return end
local path, name, ext = SplitPath(cursor)
--local gamepad_cursor = string.format("%s%s_pad%s", path, name, ext)
local gamepad_cursor = string.format("%s%s%s", path, name, ext)
mouse_win:SetCursorImage(gamepad_cursor)
end
function ShowMouseViaGamepad(show)
local mouse_win = GetMouseViaGamepadCtrl()
if not mouse_win and show then
mouse_win = MouseViaGamepad:new({}, terminal.desktop)
end
if mouse_win then
if show then
ForceHideMouseCursor("MouseViaGamepad")
mouse_win:SetVisible(true)
GamepadMouseSetPos(terminal.GetMousePos())
end
mouse_win:SetEnabled(show)
end
end
function DeleteMouseViaGamepad()
local mouse_win = GetMouseViaGamepadCtrl()
if mouse_win then
mouse_win:delete()
end
end
function IsMouseViaGamepadActive()
return hr.GamepadMouseEnabled == true or hr.GamepadMouseEnabled == 1
end
|