- Joined
- Jul 18, 2010
- Messages
- 2,377
This is a Lua resource for UI-Frames. The idea of Window is to provide a basic Frame in which you just stick in a custom content Frame. Window manages the border the WindowTitle and it's close Button.
There is another resource WindowTab which automises the usage of Window to swap between multiple content-Frames of one Window.
Example
To use Window one needs to import the toc and fdf file inside the map.
ChangeLog:
Window1.1)
WindowTab 1.1) Added a TabButton actionFunction which is called as soon that tab becomes active.

Lua:
--[[
Window V1.1 by Tasyen
The idea of Window is to have a standart Frame in which you only have to care about how to manage your content onto the ContentPane without bothering the border etc.
function Window.create([title, hide, createContext, parent])
creates a window using the local players race border.
A Window consists of a Pane, a Head, a Title a closeButton and a Border.
The Pane is mean to carry your custom Frame and contains only the space between the borders of the Window.
The closeButton is part of the Head and has 2 modes:
hide(true) close the window and head when clicked for the local Player. In such a case the user needs a way to show the window.WindowHead again, if that is wanted.
hide (false or nil) The close Button toggles the visibility of the Window, the WindowHead remains visibile.
createContext nil = 0, use a specific one, if you want to access frames over BlzGetFrameByName
parent nil = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0).
The window is posed over windowTable.WindowHead, all other frames of window are linked based on the heads position.
returns the new created windowTable
function Window.setAbsPoint(windowTable, framepoint, x, y)
function Window.setSize(windowTable[, xSize, ySize, tempChange])
without any arguments reset the size to the last non tempChange one
without tempChange the window will change its current size and define a new default size
function Window.destroy(windowTable)
--]]
BlzLoadTOCFile("war3mapimported\\window.toc")
Window = {}
function Window.create(title, hide, createContext, parent)
local windowTable = {}
if not createContext then createContext = 0 end --user does not care use 0.
if not parent then parent = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0) end
windowTable.WindowHead = BlzCreateFrame("WindowHead", parent, 0, createContext)
windowTable.WindowHeadText = BlzGetFrameByName("WindowHeadText", createContext) --styling
windowTable.WindowHeadBackdrop = BlzGetFrameByName("WindowHeadBackdrop", createContext)
windowTable.WindowHeadTrigger = CreateTrigger()
windowTable.Window = BlzGetFrameByName("Window", createContext) --this is the background and border of the ContentPane
if title then
BlzFrameSetText(windowTable.WindowHead, title)
end
windowTable.WindowPane = BlzGetFrameByName("WindowPane", createContext) --the container for the stuff user wants to display
windowTable.WindowCloseButton = BlzGetFrameByName("WindowCloseButton", createContext) --press this to hide the window
windowTable.WindowCloseButtonText = BlzGetFrameByName("WindowCloseButtonText", createContext) --styling
windowTable.WindowCloseButtonTrigger = CreateTrigger()
windowTable.WindowCloseButtonType = hide
windowTable.WindowSizeX = BlzFrameGetWidth(windowTable.Window)
windowTable.WindowSizeY = BlzFrameGetHeight(windowTable.Window)
Window[windowTable.Window] = windowTable --the Window and the WindowHead know the table, the others know the Window by using BlzFrameGetParent
Window[windowTable.WindowHead] = windowTable
windowTable.WindowHeadTriggerAction = TriggerAddAction(windowTable.WindowHeadTrigger, Window.HeadAction)
BlzTriggerRegisterFrameEvent(windowTable.WindowHeadTrigger, windowTable.WindowHead, FRAMEEVENT_CONTROL_CLICK)
windowTable.WindowCloseButtonTriggerAction = TriggerAddAction(windowTable.WindowCloseButtonTrigger, Window.CloseButtonAction)
BlzTriggerRegisterFrameEvent(windowTable.WindowCloseButtonTrigger, windowTable.WindowCloseButton, FRAMEEVENT_CONTROL_CLICK)
return windowTable
end
function Window.setAbsPoint(windowTable, framepoint, x, y)
BlzFrameSetAbsPoint(windowTable.WindowHead, framepoint, x, y)
end
function Window.setSize(windowTable, xSize, ySize, tempChange)
if xSize then
BlzFrameSetSize(windowTable.Window, xSize, ySize)
BlzFrameSetSize(windowTable.WindowPane, xSize - 0.02, ySize - 0.02)
BlzFrameSetSize(windowTable.WindowHead, xSize - 0.025, 0.0275) -- -0.025 is the closebutton
if not tempChange then
windowTable.WindowSizeX = xSize
windowTable.WindowSizeY = ySize
end
else
BlzFrameSetSize(windowTable.Window, windowTable.WindowSizeX, windowTable.WindowSizeY)
BlzFrameSetSize(windowTable.WindowPane, windowTable.WindowSizeX - 0.02, windowTable.WindowSizeY - 0.02)
BlzFrameSetSize(windowTable.WindowHead, windowTable.WindowSizeX - 0.025 , 0.0275)
end
end
function Window.destroy(windowTable)
if windowTable.Tabs then
Window.destroyTabs(windowTable)
end
Window[windowTable.Window] = nil
TriggerRemoveAction(windowTable.WindowCloseButtonTrigger, windowTable.WindowCloseButtonTriggerAction)
DestroyTrigger(windowTable.WindowCloseButtonTrigger)
TriggerRemoveAction(windowTable.WindowHeadTrigger, windowTable.WindowHeadTriggerAction)
DestroyTrigger(windowTable.WindowHeadTrigger)
BlzDestroyFrame(windowTable.WindowCloseButtonText)
BlzDestroyFrame(windowTable.WindowCloseButton)
BlzDestroyFrame(windowTable.WindowPane)
BlzDestroyFrame(windowTable.Window)
BlzDestroyFrame(windowTable.WindowHeadBackdrop)
BlzDestroyFrame(windowTable.WindowHeadText)
BlzDestroyFrame(windowTable.WindowHead)
windowTable.WindowPane = nil
windowTable.Window = nil
windowTable.WindowCloseButton = nil
windowTable.WindowCloseButtonText = nil
windowTable.WindowCloseButtonTrigger = nil
windowTable.WindowCloseButtonTriggerAction = nil
windowTable.WindowSizeX = nil
windowTable.WindowSizeY = nil
windowTable.WindowHeadText = nil
windowTable.WindowHead = nil
windowTable.WindowHeadBackdrop = nil
end
function Window.HeadAction()
--when the title is clicked(released)
local button = BlzGetTriggerFrame()
BlzFrameSetEnable(button, false)
BlzFrameSetEnable(button, true)
end
--more of an attribute hence CamelCase
function Window.CloseButtonAction()
local windowTable = Window[BlzFrameGetParent(BlzGetTriggerFrame())]
if GetLocalPlayer() == GetTriggerPlayer() then
if not windowTable.WindowCloseButtonType then
BlzFrameSetVisible(windowTable.Window, not BlzFrameIsVisible(windowTable.Window))
else
BlzFrameSetVisible(windowTable.WindowHead, false)
end
end
end
There is another resource WindowTab which automises the usage of Window to swap between multiple content-Frames of one Window.
Lua:
--[[
WindowTab V1.1a
plugin for Window by Tasyen.
Instead of placing stuff onto the ContentPane one adds Frames as Tabs (pages). The current shown Tab is swaped by the user clicking TabButtons.
First Create a Window then add a frame as Tab to the Window.
Having a tab does not stopp one from placing something onto the ContentPane itself.
function Window.addTab(windowTable, frame, [buttonText, doNotStretch, xSize, ySize])
adds frame as Tab to windowTable
buttonText is displayed on the Button to swap to this tab
doNotStretch(true) does not alter the size of frame, also pos it with its center to the WindowPane center
xSize and ySize when set, will alter the size of windowTable as long this tab is shown
Does not support SimpleFrames, directly.
frames parent, position, size (without doNotStretch) are altered in the process.
returns the new created windowTabtable
function Window.setTabButtonAction(windowTabTable, actionFunction)
calls actionFunction when this button is clicked and shown.
Beaware that the action is called async.
Inside actionFunction you have windowTable, windowTabTable.
Will instantly call the actionFunction if the tab is the current active tab
function Window.removeTab(windowTable[, windowTabTable])
windowTabTable can be an index, a table or nil. nil will remove the last added one
returns if windowTable has further Tabs remaining
function Window.showTab(windowTable, windowTabTable[, player])
show windowTabTable of windowTable to player
windowTabTable can be a index or a table, the table is expected to be a tabTable of the windowTable
player can be nil to affect all players
doesn't work that well with LeaderBoard, Multiboard, TimerDialog
if you need to use SimpleFrames create a FRAME make it a Tab and create a SIMPLEFRAME put all your SIMPLEFRAMEs into SIMPLEFRAME and clone visiblity and position of FRAME with SIMPLEFRAME the visibility has to be update quite often like every 0.05s.
the frame will survive the destruction of the window, but needs to change parent and position to be visible again.
--]]
function Window.addTab(windowTable, frame, buttonText, doNotStretch, xSize, ySize)
--each Tab is an own Table
local windowTabTable = {}
if not windowTable.Tabs then
--this is the first time this window gets tabs
windowTable.Tabs = {}
windowTable.TabActive = windowTabTable
end
--add the new TabTable into the array of windowTable
table.insert(windowTable.Tabs, windowTabTable)
local tabButton = BlzCreateFrame("WindowTabButton", windowTable.WindowPane, 0, 0)
if buttonText then
BlzFrameSetText(tabButton, buttonText)
else
BlzFrameSetText(tabButton, #windowTable.Tabs)
end
BlzFrameSetSize(tabButton, 0.06, 0.025)
Window[tabButton] = windowTabTable
Window[windowTabTable] = windowTable
--fit the given frame into the Content Pane?
if not doNotStretch then
BlzFrameSetAllPoints(frame, windowTable.WindowPane)
BlzFrameSetSize(frame, BlzFrameGetWidth(windowTable.WindowPane), BlzFrameGetHeight(windowTable.WindowPane))
else
--only center it
BlzFrameClearAllPoints(frame)
BlzFrameSetPoint(frame, FRAMEPOINT_CENTER, windowTable.WindowPane, FRAMEPOINT_CENTER, 0, 0)
end
BlzFrameSetParent(frame, windowTable.WindowPane)
windowTabTable.Button = tabButton
windowTabTable.Frame = frame
windowTabTable.SizeX = xSize
windowTabTable.SizeY = ySize
windowTabTable.ButtonTrigger = CreateTrigger()
windowTabTable.ButtonTriggerAction = TriggerAddAction(windowTabTable.ButtonTrigger, Window.TabButtonAction)
BlzTriggerRegisterFrameEvent(windowTabTable.ButtonTrigger, tabButton, FRAMEEVENT_CONTROL_CLICK)
--pos the tab button
if #windowTable.Tabs == 1 then
--the first button is located at Top Left of the Window
BlzFrameSetVisible(frame, true)
BlzFrameSetPoint(tabButton, FRAMEPOINT_TOPRIGHT, windowTable.Window, FRAMEPOINT_TOPLEFT, 0, 0)
--hide the new tab button, there is nothing to choose yet.
BlzFrameSetVisible(windowTable.Tabs[1].Button, false)
Window.showTab(windowTable, windowTabTable)
else
--further ones are located below to the previous one
--this is not the first added one hide it.
BlzFrameSetVisible(frame, false)
BlzFrameSetPoint(tabButton, FRAMEPOINT_TOP, windowTable.Tabs[#windowTable.Tabs - 1].Button, FRAMEPOINT_BOTTOM, 0, 0.005)
BlzFrameSetVisible(windowTable.Tabs[1].Button, true)
end
return windowTabTable
end
function Window.setTabButtonAction(windowTabTable, actionFunction)
windowTabTable.ShowAction = actionFunction
if Window[windowTabTable].TabActive == windowTabTable then
actionFunction(Window[windowTabTable], windowTabTable)
end
end
-- windowTabTable can be an index, a table or nil. nil will remove the last added one
-- returns true if there are tabs remaining
function Window.removeTab(windowTable, windowTabTable)
if #windowTable.Tabs == 0 then return false end
if not windowTabTable then
Window.destroyTab(windowTable, #windowTable.Tabs, true)
elseif type(windowTabTable) == "number" then
Window.destroyTab(windowTable, windowTabTable, true)
elseif type(windowTabTable) == "table" then
for index, value in ipairs(windowTable.Tabs)
do
if value == windowTabTable then
Window.destroyTab(windowTable, index, true)
break
end
end
end
return #windowTable.Tabs > 0
end
function Window.showTab(windowTable, windowTabTable, player)
if player and player ~= GetLocalPlayer() then return end
if windowTable.TabActive then
BlzFrameSetVisible(windowTable.TabActive.Frame, false)
end
if type(windowTabTable) == "number" then
windowTabTable = windowTable.Tabs[windowTabTable]
end
BlzFrameSetVisible(windowTabTable.Frame, true)
windowTable.TabActive = windowTabTable
if windowTabTable.SizeX then
Window.setSize(windowTable, windowTabTable.SizeX + 0.02, windowTabTable.SizeY + 0.02, true)
BlzFrameSetSize(windowTabTable.Frame, BlzFrameGetWidth(windowTable.WindowPane), BlzFrameGetHeight(windowTable.WindowPane))
else
Window.setSize(windowTable)
end
--custom user action when showing this Tab
if windowTabTable.ShowAction then
windowTabTable.ShowAction(windowTable, windowTabTable)
end
end
-- this is not meant to be called manualy
function Window.destroyTab(windowTable, index, reCalc)
local windowTabTable = windowTable.Tabs[index]
Window[windowTabTable.Button] = nil
Window[windowTabTable] = nil
TriggerRemoveAction(windowTabTable.ButtonTrigger, windowTabTable.ButtonTriggerAction)
DestroyTrigger(windowTabTable.ButtonTrigger)
BlzDestroyFrame(windowTabTable.Button)
--wana repos tab buttons, the array and the shown Active Tab when needed?
if reCalc then
--remove 1 have 2 or more, attach 2. to the 1. slot
if index == 1 and #windowTable.Tabs > 1 then
BlzFrameSetPoint(windowTable.Tabs[index + 1].Button, FRAMEPOINT_TOPRIGHT, windowTable.Window, FRAMEPOINT_TOPLEFT, 0, 0)
--remove 2. put 3. below 1.
elseif index > 1 and #windowTable.Tabs > index then
BlzFrameSetPoint(windowTable.Tabs[index + 1].Button, FRAMEPOINT_TOP, windowTable.Tabs[index - 1].Button, FRAMEPOINT_BOTTOM, 0, 0.005)
end
table.remove(windowTable.Tabs, index)
if windowTable.TabActive == windowTabTable then
BlzFrameSetVisible(windowTable.TabActive.Frame, false)
if #windowTable.Tabs > 0 then
Window.showTab(windowTable, windowTable.Tabs[1])
end
end
end
--this has to be done after the new shown tab was updated.
windowTabTable.Button = nil
windowTabTable.Frame = nil
windowTabTable.ButtonTrigger = nil
windowTabTable.ButtonTriggerAction = nil
windowTabTable.ShowAction = nil
windowTabTable.SizeX = nil
windowTabTable.SizeY = nil
end
--this is called from Window.destroy, if the Window has tabs.
function Window.destroyTabs(windowTable)
for index in ipairs(windowTable.Tabs)
do
Window.destroyTab(windowTable, index, false)
end
windowTable.Tabs = nil
windowTable.TabActive = nil
end
--more of an attribute hence CamelCase
function Window.TabButtonAction()
local button = BlzGetTriggerFrame()
local windowTable = Window[BlzFrameGetParent(BlzFrameGetParent(button))]
local windowTabTable = Window[button]
if GetLocalPlayer() == GetTriggerPlayer() then
Window.showTab(windowTable, windowTabTable)
BlzFrameSetEnable(button, false)
BlzFrameSetEnable(button, true)
end
end
Example
Lua:
onGameStart(function()
local windowObject = Window.create("Test Tabed Window")
Window.setSize(windowObject, 0.2, 0.2)
Window.setAbsPoint(windowObject, FRAMEPOINT_CENTER, 0.2, 0.5)
local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
local icon = BlzCreateFrameByType("BACKDROP", "MYIcon", gameUI, "", 0)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin",0, false)
Window.addTab(windowObject, icon, "Paladin", false, 0.08, 0.08)
icon = BlzCreateFrameByType("BACKDROP", "MYIcon", gameUI, "", 0)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNHeroArchMage",0, false)
Window.addTab(windowObject, icon, "Archmage")
icon = BlzCreateFrameByType("BACKDROP", "MYIcon", gameUI, "", 0)
BlzFrameSetSize(icon, 0.1, 0.1)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNHeroMountainKing",0, false)
Window.addTab(windowObject, icon, nil, true)
icon = BlzCreateFrameByType("BACKDROP", "MYIcon", gameUI, "", 0)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNHeroBloodElfPrince",0, false)
Window.addTab(windowObject, icon)
TimerStart(CreateTimer(), 3, false, function()
--Window.removeTab(windowObject, 3)
local icon = BlzCreateFrameByType("BACKDROP", "MYIcon", gameUI, "", 0)
BlzFrameSetTexture(icon, "ReplaceableTextures\\CommandButtons\\BTNHeroFarseer",0, false)
Window.addTab(windowObject, icon, "Orc Seer")
end)
end)
ChangeLog:
Window1.1)
Window.setSize will now also set the size of WindowPane.
Reduced the Inset of the background in fdf a bit.
Reduced the Inset of the background in fdf a bit.
WindowTab 1.1a)
When activading a tab will copy the size of WindowPane.
The Size given is now the size of the WindowPane previously it was the size of the Window
The Size given is now the size of the WindowPane previously it was the size of the Window
WindowTab 1.1) Added a TabButton actionFunction which is called as soon that tab becomes active.



Attachments
Last edited: