This example does not use preprocessor extension (written before v2.2.0), but can be used as a foundation to replace the windows modal loop.
i will post a remake of this using preprocessor, but though id post this for anyone needing a non-blocking ui drag operation
local ui = require("ui")
local win = ui.Window("Window ASYNC Drag example", "raw", 320, 200)
win.bgcolor = 0xffffff
--Top Bar
local TopBar = ui.Panel(win)
TopBar.height = 16
TopBar.bgcolor = 0x070707
TopBar.align = "top"
--close label (use a png for no backround)
local CloseLB = ui.Label(TopBar, "X", 5, math.floor((TopBar.height / 5))-2)
CloseLB.bgcolor = 0x060606
CloseLB.textalign = "left"
--move label (use a png for no backround)
local MoveLB = ui.Label(TopBar, "#", (CloseLB.width * 2)+1, math.floor((TopBar.height / 5))-2)
MoveLB.bgcolor = 0x060606
MoveLB.textalign = "left"
TopBar.align = "top"
--a task to handle moving the window, using tasks rather than win11 msg loop
local MovUI, IsDrag = sys.Task(function (buttons)
local x, y = ui.mousepos() --prefill so the UI doesnt jump out of cursor inital click spot
while true do
x, y = ui.mousepos()
win.x = (x) - MoveLB.x --this adjusts the grab location to where the label exists
win.y = (y) - 5 --offset for buttons and topbar's size
print("DRAGGING", buttons.left)
sleep(8)
ui.update()
end
end), false
--an example task that runs in the backround while dragging
local BackroundTask = sys.Task(function ()
while true do
print("RUNNING")
sleep(16)
end
end)
--starts moving window if we click the "#" label
function MoveLB:onClick()
IsDrag = true
MovUI({left = true})
end
--Close button, Gives the backround task some time to close as well
function CloseLB:onClick()
IsDrag = false
win:hide()
sleep(100)
MovUI:pause()
end
--OnHover redirect for any element (to avoid getting stuck in the drag operation, OnLeave() is not best for high DPI. though a timer would be better)
function OnHov(x, y, buttons)
if buttons.left == false and IsDrag then
MovUI:pause()
IsDrag = false
print("Quit")
end
end
--Hover events, if hovering on another element then another may be ignored
function MoveLB:onHover(x, y, buttons)
OnHov(x, y, buttons)
end
function CloseLB:onHover(x, y, buttons) --so we can check here
OnHov(x, y, buttons)
end
function TopBar:onHover(x, y, buttons) --but checking topBar is more consistant, same with the window
OnHov(x, y, buttons)
end
function win:onHover(x, y, buttons) --and to catch edge cases we also check the main ui
OnHov(x, y, buttons)
end
--run the backround task (You can also use async, task allows for more control without the new extentions)
BackroundTask()
--start UI (and keep program alive for that, Backround task will close noramlly)
--or call this with async in the backround task before the loop if needed
await(win:showasync())