local version = '0.3' function widget:GetInfo() return { name = "Marker On Click", desc = "Place marker on single click while using hotkey for drawing, ver "..version, author = "Helwor", date = "October 2022", license = "GNU GPL v2", layer = 0, enabled = true, handler = true, } end -- Config local MOVE_THRESHOLD = 4 -- can place a marker until the mouse moved this many pixel from the click position local DOUBLECLICK_TIME = 0.30 -- how long shall we wait for a double click to happen before authorizing to place a marker -- , value try to be as close as possible of the text label trigger -- -- NOTE: since we use Update CallIn, the delay may vary depending on lag, the catching of click is not reliable, so user have to press until the next Update round -- the widget is disabled at start of game if no hotkey is found for drawing on map local spMarkerAddPoint = Spring.MarkerAddPoint local spTraceScreenRay = Spring.TraceScreenRay local spGetMouseState = Spring.GetMouseState local spIsUserWriting = Spring.IsUserWriting local Echo = Spring.Echo local hotkey = {} local catchDrawing, dontCatchThisOne, drawing, _, pos local doubleClickDelay, waitDblClick, waitRelease -- debugging local debugging = true local DebugUp local last_doubleClickTime local textLabel local secondClick local f = debugging and VFS.Include("LuaUI\\Widgets\\UtilsFunc.lua") -- function widget:KeyPress(key,mods,isRepeat) if isRepeat then return end catchDrawing = hotkey[key] end function widget:KeyRelease(key) if hotkey[key] then catchDrawing = false doubleClickDelay = false drawing = false waitRelease = false waitDblClick = false if debugging then measureSecondClick = false secondClick = 0 end end end function widget:Update(dt) if debugging then DebugUp("catchDrawing", catchDrawing) DebugUp("dontCatchThisOne", dontCatchThisOne) DebugUp("drawing", drawing) DebugUp("pos", pos) DebugUp("doubleClickDelay", doubleClickDelay) DebugUp("waitDblClick", waitDblClick) DebugUp("waitRelease", waitRelease) DebugUp("last_doubleClickTime", last_doubleClickTime) DebugUp("textLabel", textLabel) end if not catchDrawing then return end if spIsUserWriting() then doubleClickDelay = false waitDblClick = false drawing = false catchDrawing = false dontCatchThisOne = false if debugging then textLabel = true measureSecondClick = false end return end textLabel = false if doubleClickDelay then doubleClickDelay = doubleClickDelay - dt if doubleClickDelay <= -dt then doubleClickDelay = false end end local mx,my,lmb = spGetMouseState() if debugging then if measureSecondClick then secondClick = secondClick+dt DebugUp("secondClick", secondClick) DebugUp('lastDT',dt) end end if waitRelease then if lmb then return end waitRelease = false end if waitDblClick then if lmb and spIsUserWriting() then -- text label should have been triggered there else waitDblClick = not lmb and doubleClickDelay if not waitDblClick then spMarkerAddPoint(pos[1],pos[2],pos[3]) if debugging then measureSecondClick = false end else return end end end if not drawing then if lmb then last_mx,last_my = mx,my drawing = true doubleClickDelay = DOUBLECLICK_TIME dontCatchThisOne = false if debugging then measureSecondClick = true secondClick = 0 last_doubleClickTime = doubleClickDelay end end else if not lmb then drawing = false end if dontCatchThisOne then return end local delta = ((last_mx-mx)^2 + (last_my-my)^2)^0.5 if delta>MOVE_THRESHOLD then dontCatchThisOne = true return end if not (drawing or dontCatchThisOne) then -- we're half way there, get the pos for our marker _,pos = spTraceScreenRay(mx, my, true, true, false,false) if not pos then return end waitDblClick = true waitRelease = true end end end function widget:Initialize() if debugging then DebugUp = f.DebugWinInit(widget) end for _,key in pairs(WG.crude.GetHotkeys("drawinmap") or {}) do hotkey[key:byte(-1)] = true end if not next(hotkey) then Echo(widget:GetInfo().name .. ' disabled, no hotkey for drawing on map') widgetHandler:RemoveWidget(widget) end end