Files
Bagshui/Components/Bagshui.Windows.lua
OEVG 896f46f0d1
enUS Localization Update Announcement / localization-update-announcement (push) Canceled after 0s
Bagshui 1.6.4
2026-10-30 15:55:43 +00:00

115 lines
4.1 KiB
Lua

-- Bagshui Core: Windows
-- Window management.
Bagshui:LoadComponent(function()
--- When the escape key is pressed, close all registered frames.
---@param wowApiFunctionName string Hooked WoW API function that triggered this call.
---@param arg1 any
---@param arg2 any
---@param arg3 any
---@return boolean windowsOpen
function Bagshui:CloseAllWindows(wowApiFunctionName, arg1, arg2, arg3)
-- Need to know whether any other windows were closed since CloseAllWindows() is expected
-- to return true if windows were closed to prevent the Game Menu from being opened.
local otherWindowsVisible = self.hooks:OriginalHook(wowApiFunctionName, arg1, arg2, arg3)
-- Close any of our windows there were open.
local bagshuiWindowsVisible = false
local dialogsClosed = false
-- First loop looks for dialogs and closes them.
for frame, _ in pairs(self.framesToCloseOnEscape) do
if frame.isDialog and frame:IsVisible() then
bagshuiWindowsVisible = true
dialogsClosed = true
frame:Hide()
end
end
-- Now we can close anything that isn't a dialog.
if not dialogsClosed then
for frame, _ in pairs(self.framesToCloseOnEscape) do
if frame:IsVisible() then
bagshuiWindowsVisible = true
end
-- Hide the frame if it's clean.
local dirty = false
local hasCursorItem = false
if frame.bagshuiData then
hasCursorItem = frame.bagshuiData.hasCursorItem
dirty = frame.bagshuiData.dirty or frame.bagshuiData.hasModalDialog or hasCursorItem
end
if not dirty then
frame:Hide()
end
-- Frame is dirty and has an onDirty function.
if dirty and frame.bagshuiData.onDirty and not frame.bagshuiData.hasModalDialog then
frame.bagshuiData.onDirty()
end
-- Frame has a cursor item.
if hasCursorItem then
-- This is a quick hack to get Edit Mode cursor clearing on Escape press
-- to work. When something is picked up in Edit Mode, Inventory:ShowEditModeCursor()
-- sets the frame's hasCursorItem property to itself (the class instance).
-- Then we can detect the class instance and call ClearEditModeCursor().
if type(hasCursorItem) == "table" and hasCursorItem.ClearEditModeCursor then
hasCursorItem:ClearEditModeCursor()
else
_G.ClearCursor()
end
end
end
end
-- Return true if any window was closed so WoW knows not to open the Game Menu.
return otherWindowsVisible or bagshuiWindowsVisible
end
--- Add new frame to be closed when CloseAllWindows() fires.
---@param frame table
function Bagshui:RegisterFrameForCloseOnEscape(frame)
self.framesToCloseOnEscape[frame] = true
end
--- When at least one of the frames registered through `Bagshui:RegisterFrameAsChildWindow() is visible, return `true`.
---@return boolean
function Bagshui:ChildWindowsVisible()
for frame, _ in pairs(self.childWindowFrames) do
if frame:IsVisible() then
return true
end
end
return false
end
--- Register frame as a "Child Window" (see `Bagshui:ChildWindowsVisible()`).
---@param frame table
function Bagshui:RegisterFrameAsChildWindow(frame)
self.childWindowFrames[frame] = true
end
local boundaryFramePositions = { "TOP", "RIGHT", "BOTTOM", "LEFT" }
--- These "boundary frames" are used to detect when one of the Bagshui inventory
--- windows gets moved outside the screen area. See `Inventory:RescueWindow()`.
function Bagshui:ManageBoundaryFrames()
if not self.boundaryFrames then
self.boundaryFrames = {}
end
for _, position in ipairs(boundaryFramePositions) do
if not self.boundaryFrames[position] then
self.boundaryFrames[position] = _G.CreateFrame("Frame", "BagshuiBoundary" .. position, _G.UIParent)
self.boundaryFrames[position]:SetHeight(1)
self.boundaryFrames[position]:SetWidth(1)
self.boundaryFrames[position]:SetPoint(position, _G.UIParent, position)
end
self.boundaryFrames[position]:SetScale(BsSettings.windowScale)
end
end
end)