The Wiki for Tale 7 is in read-only mode and is available for archival and reference purposes only. Please visit the current Tale 11 Wiki in the meantime.
If you have any issues with this Wiki, please post in #wiki-editing on Discord or contact Brad in-game.
User:Obol/common window.mac
From ATITD7
Jump to navigationJump to search-- common_window.inc -- -- Common functions for handling windows: opening, arranging, unpinning -- -- DO NOT INCLUDE THIS FILE! Include common.inc instead -- TOP_LEFT = 0; TOP_RIGHT = 1; BOTTOM_LEFT = 2; BOTTOM_RIGHT = 3; ------------------------------------------------------------------------------- -- stashWindow(sourceX, sourceY, corner, bounds) -- -- Drags a window from a given location to a corner of the screen. -- -- sourceX, sourceY -- location of anchor point to drag window -- corner -- destination corner (TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, -- or BOTTOM_RIGHT) -- bounds (optional) -- bounds of window ------------------------------------------------------------------------------- local stashBit = 0; function stashWindow(sourceX, sourceY, corner, bounds) if not sourceX or not sourceY or not corner then error("Incorrect number of arguments for stashWindow()"); end stashBit = (stashBit + 2) % 4; if not bounds then srReadScreen(); bounds = srGetWindowBorders(sourceX, sourceY); end local size = {}; size[0] = bounds[2] - bounds[0]; size[1] = bounds[3] - bounds[1]; local screen = srGetWindowSize(); local dest = {}; dest[0] = screen[0] - size[0] + (sourceX - bounds[0]) - 5; if corner == TOP_LEFT or corner == BOTTOM_LEFT then dest[0] = sourceX - bounds[0] + 5; end dest[1] = screen[1] - size[1] + (sourceY - bounds[1]) - stashBit - 5; if corner == TOP_LEFT or corner == TOP_RIGHT then dest[1] = sourceY - bounds[1] + stashBit + 5; end safeDrag(sourceX, sourceY, dest[0], dest[1]); srSetMousePos(sourceX, sourceY); lsSleep(click_delay); return dest; end ------------------------------------------------------------------------------- -- stashAllWindows(corner) -- -- Move all windows not in the same quadrant as corner into the given -- corner. Use this twice on different corners to make sure that you -- grab all windows. -- -- corner -- Destination corner ------------------------------------------------------------------------------- function stashAllWindows(corner) if not corner then error("Incorrect number of arguments for stashAllWindows()"); end local top = (corner == TOP_LEFT or corner == TOP_RIGHT); local left = (corner == TOP_LEFT or corner == BOTTOM_LEFT); local screen = srGetWindowSize(); local done = false; local stashes = {}; srReadScreen(); local anchors = findAllImages("ThisIs.png"); while not done do done = true; for i=1,#anchors do if not wasStashed(anchors[i], stashes) then safeClick(anchors[i][0], anchors[i][1]); lsSleep(click_delay); local lastPos = stashWindow(anchors[i][0], anchors[i][1], corner); stashes[#stashes + 1] = lastPos; done = false; end end lsSleep(tick_delay); srReadScreen(); anchors = findAllImages("ThisIs.png"); statusScreen("Stashing Windows"); end end function wasStashed(pos, stashes) local result = false; for i=1,#stashes do local diffX = math.abs(stashes[i][0] - pos[0]); local diffY = math.abs(stashes[i][1] - pos[1]); if diffX < 20 and diffY < 20 then result = true; break; end end return result; end ------------------------------------------------------------------------------- -- openAndPin(x, y, timeout) -- -- Click at the given position to open a window, then pin that window. -- -- x, y -- position to click -- timeout -- time to wait before giving up -- -- Returns true on success. ------------------------------------------------------------------------------- function openAndPin(x, y, timeout) if not x or not y or not timeout then error("Incorrect number of arguments for openAndPin()"); end local success = false; srReadScreen(); local anchors = findAllImages("ThisIs.png"); local startTime = lsGetTimer(); safeBegin(); srSetMousePos(x, y); lsSleep(50); srClickMouse(x, y, 1); lsDoFrame(); statusScreen("Clicking to open window"); local done = false; local anchor = nil; while not done do srReadScreen(); local newAnchors = findAllImages("ThisIs.png"); done = false; local limit = math.min(#anchors, #newAnchors); for i=1,limit do if anchors[i][0] ~= newAnchors[i][0] or anchors[i][1] ~= newAnchors[i][1] then anchor = newAnchors[i]; done = true; break; end end if not done and #anchors ~= #newAnchors then done = true; anchor = newAnchors[#newAnchors]; end if not done and lsGetTimer() > startTime + timeout then done = true; end anchors = newAnchors; statusScreen("Waiting for window to open"); lsSleep(tick_delay); end if anchor then success = true; if not findImageInWindow("UnPin.png", x+5, y) then safeClick(anchor[0], anchor[1], 1); statusScreen("Pinning window"); end end return success; end ------------------------------------------------------------------------------- -- arrangeInGrid(cascade, waterGap) -- -- Arrange all open windows into a grid on the screen. Stashes them first. -- -- cascade (optional) -- arrange windows into an overlapping cascade -- waterGap (optional) -- leave a gap at the top for getting water ------------------------------------------------------------------------------- function arrangeInGrid(cascade, waterGap) stashAllWindows(BOTTOM_LEFT); stashAllWindows(BOTTOM_RIGHT); arrangeStashed(cascade, waterGap); end ------------------------------------------------------------------------------- -- arrangeStashed(cascade, waterGap) -- -- Arrange all open windows into a grid on the screen. Assumes they -- are pre-stashed. -- -- cascade (optional) -- arrange windows into a overlapping cascade -- waterGap (optional) -- leave a gap at the top for getting water ------------------------------------------------------------------------------- function arrangeStashed(cascade, waterGap, varWidth, varHeight) local screen = srGetWindowSize(); local bottomRightX = screen[0] - 20; local bottomRightY = screen[1] - 20; screen[0] = screen[0] - lsGetWindowSize()[0]; local currentX = 0; local currentY = 0; if waterGap then currentX = 10; currentY = 50; end local lastX = 0; local lastY = 0; local xMax = 0; local yMax = 0; srReadScreen(); local window = findImageInWindow("ThisIs.png", bottomRightX, bottomRightY); while window and (window[0] > lastX or window[1] > lastY) do safeClick(window[0], window[1]); lsSleep(click_delay); srReadScreen(); local bounds = srGetWindowBorders(window[0], window[1]); local width, height; if not varWidth then width = bounds[2] - bounds[0]; else width = varWidth; end if not varHeight then height = bounds[3] - bounds[1]; else height = varHeight; end if cascade then if currentY + height >= screen[1] then currentX = currentX + xMax; currentY = 0; xMax = 0; end if currentX + width >= screen[0] then error("Cannot arrange these windows into a cascade."); end else if currentX + width >= screen[0] then currentX = 0; -- increase the Y Gap currentY = currentY + yMax + 15; yMax = 0; end if currentY + height >= screen[1] then error("Cannot arrange these windows into a grid."); end end lastX = window[0] - bounds[0] + currentX; lastY = window[1] - bounds[1] + currentY; safeDrag(window[0], window[1], lastX, lastY); if cascade then currentX = currentX + 8; currentY = currentY + 24; else currentX = currentX + width + 5; end xMax = math.max(xMax, width); yMax = math.max(yMax, height); lsSleep(tick_delay); srReadScreen(); window = findImageInWindow("ThisIs.png", bottomRightX, bottomRightY); statusScreen("Arranging Windows"); end end ------------------------------------------------------------------------------- -- closeAllWindows(x, y, width, height) -- -- Close all open windows. -- -- x, y (optional) -- origin of box to search -- width, height (optional) -- size of box to search ------------------------------------------------------------------------------- function closeAllWindows(x, y, width, height) if not x then x = 0; end if not y then y = 0; end if not width then width = srGetWindowSize()[0]; end if not height then height = srGetWindowSize()[1]; end local closeImages = {"ThisIs.png", "UnPin.png", "Ok.png"}; local closeRight = {1, 1, nil}; local found = true; while found do found = false; for i=1,#closeImages do local image = closeImages[i]; local right = closeRight[i]; srReadScreen(); local images = findAllImagesInRange(image, x, y, width, height); while #images >= 1 do done = true; safeClick(images[#images][0], images[#images][1], right); sleepWithStatus(200, "Closing Windows"); srReadScreen(); images = findAllImagesInRange(image, x, y, width, height); end end end end ------------------------------------------------------------------------------- -- closeEmptyRegions() -- -- Closes all empty windows on the screen -- ------------------------------------------------------------------------------- function closeEmptyRegions() allRegs = findAllTextRegions(); if allRegs then for i = 1, #allRegs do local p = parseRegion(allRegs[i]); if p == nil then unpinRegion(allRegs[i]); end end end end ------------------------------------------------------------------------------- -- windowManager(title, message, allowCascade, allowWaterGap) -- -- Run a window manager interface to let the user open, pin, arrange, -- or clear windows. -- -- title (optional) -- title of window -- message (optional) -- extra instructions for the user -- allowCascade (optional) -- allow the user to arrange in a cascade -- allowWaterGap (optional) -- allow the user to add a water gap ------------------------------------------------------------------------------- pauseForFocus = false; function windowManager(title, message, allowCascade, allowWaterGap) if not title then title = "Window Manager"; end if not message then message = "Tap Ctrl to open and pin a window." end local waterGap = false; local shift = false; local done = false; while not done do local y = 10; lsPrint(10, y, 0, 1.0, 1.0, 0xFFFFFFff, title); y = y + 50; if lsButtonText(30, y, 0, 250, 0x80D080ff, "Form Grid") then lsDoFrame(); if pauseForFocus then askForWindow(focusMessage); end arrangeInGrid(false, waterGap); end y = y + 30; if allowCascade then if lsButtonText(30, y, 0, 250, 0x80D080ff, "Form Cascade") then lsDoFrame(); if pauseForFocus then askForWindow(focusMessage); end arrangeInGrid(true, waterGap); end y = y + 30; end if lsButtonText(30, y, 0, 250, 0x80D080ff, "Stash Windows") then lsDoFrame(); if pauseForFocus then askForWindow(focusMessage); end stashAllWindows(BOTTOM_RIGHT); end y = y + 30; if lsButtonText(30, y, 0, 250, 0x80D080ff, "Un-Pin Windows") then lsDoFrame(); if pauseForFocus then askForWindow(focusMessage); end closeAllWindows(); end y = y + 40; pauseForFocus = lsCheckBox(30, y, 10, 0xffffffff, "Pause for Focus", pauseForFocus); y = y + 30; if allowWaterGap then waterGap = lsCheckBox(30, y, 10, 0xffffffff, "Leave Gap for Water", waterGap); y = y + 30; end lsPrintWrapped(10, y, 0, lsScreenY - 20, 0.7, 0.7, 0xd0d0d0ff, message); if lsButtonText(lsScreenX - 110, lsScreenY - 30, 0, 100, 0xffffffff, "End Script") then error(quit_message); end while lsControlHeld() do checkBreak(); shift = true; end if shift then shift = false; local x = 0; local y = 0; x, y = srMousePos(); openAndPin(x, y, 500); end if lsButtonText(10, lsScreenY - 30, 0, 100, 0xFFFFFFff, "Done") then done = true; end checkBreak(); lsDoFrame(); lsSleep(tick_delay); end end ------------------------------------------------------------------------------- -- unpinManager(title, message) -- -- Interface to help the user clear away all windows when a macro completes. -- -- title (optional) -- title of window -- message (optional) -- extra instructions for the user ------------------------------------------------------------------------------- function unpinManager(title, message) if not title then title = "Unpin Manager"; end if not message then message = ""; end while lsShiftHeld() and lsControlHeld() do lsPrintWrapped(10, 60, 0, lsScreenX - 20, 1, 1, 0x808080ff, "Please release Ctrl+Shift"); lsSleep(tick_delay); lsDoFrame(); end local done = false; while not done do lsPrint(10, 10, 0, 1.0, 1.0, 0xFFFFFFff, title); lsPrintWrapped(10, 60, 0, lsScreenX - 20, 0.7, 0.7, 0xd0d0d0ff, message); if lsButtonText(30, 160, 0, 250, 0x80D080ff, "Un-Pin Windows") then lsDoFrame(); if pauseForFocus then askForWindow(focusMessage); end closeAllWindows(); end if lsButtonText(lsScreenX - 110, lsScreenY - 30, 0, 100, 0xffffffff, "Done") then done = true; end if lsShiftHeld() and lsControlHeld() then done = true; end lsDoFrame(); lsSleep(tick_delay); end end ------------------------------------------------------------------------------- -- unpinRegion(region) -- -- Unpins a region -- -- region - region object to unpin ------------------------------------------------------------------------------- function unpinRegion(region) if region then lsPrintln("Unpinning at: " .. region[0] + region[2] - 15 .. ", " .. region[1] + region[3] + 15); safeClick(region[0] + region[2] - 15, region[1] + 15, 0); end end ------------------------------------------------------------------------------- -- unpinOnExit(f) -- -- Execute function f and present an unpin manager window when it -- completes or if an error is thrown. -- -- f -- function to execute with no arguments ------------------------------------------------------------------------------- function unpinOnExit(f) if not f then error("Incorrect number of arguments for f"); end local status, error = pcall(f); unpinManager("Complete", error); end