AltSystem/UI.lua
2026-04-11 20:27:46 +01:00

241 lines
8.2 KiB
Lua

-- AltSystem UI
-- Creates the main dialog window with all interface elements.
-- Uses the modern DropdownButton API (WoW 10.2.5+ / 12.0+).
AltSystem = AltSystem or {}
local WINDOW_WIDTH = 300
local WINDOW_HEIGHT = 380
local PADDING = 12
local ROW_HEIGHT = 30
local LABEL_WIDTH = 80
-- Helper: Build the skill option list from current AltSystem.Data.Skills
local function BuildSkillOptions()
local options = {}
for _, skill in ipairs(AltSystem.Data.Skills) do
local sign = skill.modifier >= 0 and "+" or ""
local text
if skill.level == "Inept" then
text = skill.name .. " (" .. sign .. skill.modifier .. ")"
else
text = skill.name .. " (" .. skill.level .. " " .. sign .. skill.modifier .. ")"
end
table.insert(options, { text = text })
end
return options
end
-- Helper: Create a modern dropdown (WowStyle1DropdownTemplate)
local function CreateDropdown(parent, name, yOffset, labelText, options, defaultIndex, onSelect)
local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
label:SetPoint("TOPLEFT", parent, "TOPLEFT", PADDING, yOffset)
label:SetText(labelText)
label:SetWidth(LABEL_WIDTH)
label:SetJustifyH("LEFT")
local selectedIndex = defaultIndex or 1
local dropdown = CreateFrame("DropdownButton", name, parent, "WowStyle1DropdownTemplate")
dropdown:SetPoint("LEFT", label, "RIGHT", 4, 0)
dropdown:SetWidth(160)
dropdown:SetupMenu(function(dropdown, rootDescription)
for i, option in ipairs(options) do
rootDescription:CreateRadio(
option.text,
function(data) return data == selectedIndex end,
function(data)
selectedIndex = data
if onSelect then onSelect(data, options[data]) end
end,
i
)
end
end)
return dropdown, function() return selectedIndex end, function(idx) selectedIndex = idx end
end
function AltSystem:CreateMainFrame()
if AltSystem.MainFrame then return end
-- Main frame
local f = CreateFrame("Frame", "AltSystemMainFrame", UIParent, "BasicFrameTemplateWithInset")
f:SetSize(WINDOW_WIDTH, WINDOW_HEIGHT)
f:SetPoint("CENTER")
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", f.StartMoving)
f:SetScript("OnDragStop", f.StopMovingOrSizing)
f:SetClampedToScreen(true)
f.TitleBg:SetHeight(30)
f.title = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
f.title:SetPoint("TOPLEFT", f.TitleBg, "TOPLEFT", 5, -3)
f.title:SetText("AltSystem")
-- Track current Y offset for layout
local yPos = -40
-------------------------
-- Skill dropdown
-------------------------
local skillOptions = BuildSkillOptions()
local skillDropdown, getSkillIndex, setSkillIndex = CreateDropdown(
f, "AltSystemSkillDropdown", yPos, "Skill:", skillOptions,
AltSystem.State.selectedSkillIndex,
function(index)
AltSystem.State.selectedSkillIndex = index
end)
-- Store references for refreshing
AltSystem.SkillDropdown = skillDropdown
AltSystem.GetSkillIndex = getSkillIndex
AltSystem.SetSkillIndex = setSkillIndex
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Item dropdown
-------------------------
local itemOptions = {}
for _, item in ipairs(AltSystem.Data.Items) do
local sign = item.modifier >= 0 and "+" or ""
local modText = item.modifier ~= 0 and (" (" .. sign .. item.modifier .. ")") or ""
table.insert(itemOptions, {
text = item.name .. modText,
})
end
CreateDropdown(f, "AltSystemItemDropdown", yPos, "Item:", itemOptions, AltSystem.State.selectedItemIndex,
function(index)
AltSystem.State.selectedItemIndex = index
end)
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Defense dropdown
-------------------------
local defenseOptions = {}
for _, def in ipairs(AltSystem.Data.Defenses) do
local sign = def.modifier >= 0 and "+" or ""
local modText = " (" .. sign .. def.modifier .. ")"
table.insert(defenseOptions, {
text = def.name .. modText,
})
end
CreateDropdown(f, "AltSystemDefenseDropdown", yPos, "Defense:", defenseOptions, AltSystem.State.selectedDefenseIndex,
function(index)
AltSystem.State.selectedDefenseIndex = index
end)
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Shield checkbox
-------------------------
local shieldLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
shieldLabel:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
shieldLabel:SetText("Shield:")
shieldLabel:SetWidth(LABEL_WIDTH)
shieldLabel:SetJustifyH("LEFT")
local shieldCheck = CreateFrame("CheckButton", "AltSystemShieldCheck", f, "UICheckButtonTemplate")
shieldCheck:SetPoint("LEFT", shieldLabel, "RIGHT", -6, 0)
shieldCheck:SetChecked(AltSystem.State.shieldEnabled)
local shieldText = shieldCheck:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
shieldText:SetPoint("LEFT", shieldCheck, "RIGHT", 2, 0)
shieldText:SetText("+1 modifier")
shieldCheck:SetScript("OnClick", function(self)
AltSystem.State.shieldEnabled = self:GetChecked()
end)
yPos = yPos - ROW_HEIGHT - 12
-------------------------
-- Roll buttons
-------------------------
local btnWidth = (WINDOW_WIDTH - PADDING * 3) / 2
local attackBtn = CreateFrame("Button", "AltSystemAttackRollBtn", f, "UIPanelButtonTemplate")
attackBtn:SetSize(btnWidth, 28)
attackBtn:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
attackBtn:SetText("Attack/Skill Roll")
local defenseBtn = CreateFrame("Button", "AltSystemDefenseRollBtn", f, "UIPanelButtonTemplate")
defenseBtn:SetSize(btnWidth, 28)
defenseBtn:SetPoint("TOPRIGHT", f, "TOPRIGHT", -PADDING, yPos)
defenseBtn:SetText("Defense Roll")
yPos = yPos - 40
-------------------------
-- Roll result area
-------------------------
local resultBg = CreateFrame("Frame", nil, f, "InsetFrameTemplate")
resultBg:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
resultBg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -PADDING, PADDING)
local resultText = resultBg:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
resultText:SetPoint("CENTER")
resultText:SetText("Roll result will appear here")
resultText:SetJustifyH("CENTER")
resultText:SetWidth(resultBg:GetWidth() - 10)
AltSystem.ResultText = resultText
-- Button click handlers
attackBtn:SetScript("OnClick", function()
AltSystem:PerformRoll("attack")
end)
defenseBtn:SetScript("OnClick", function()
AltSystem:PerformRoll("defense")
end)
-- Refresh skills from TRP3 profile each time the window is shown
f:SetScript("OnShow", function()
AltSystem:RefreshSkillDropdown()
end)
f:Hide()
AltSystem.MainFrame = f
end
-- Refresh the skill dropdown with current TRP3 profile data
function AltSystem:RefreshSkillDropdown()
AltSystem.Data:RefreshSkills()
-- Reset selection to 1 (Inept) since the skill list may have changed
AltSystem.State.selectedSkillIndex = 1
if AltSystem.SetSkillIndex then
AltSystem.SetSkillIndex(1)
end
-- Rebuild the dropdown menu with the new skill list
if AltSystem.SkillDropdown then
local skillOptions = BuildSkillOptions()
AltSystem.SkillDropdown:SetupMenu(function(dropdown, rootDescription)
for i, option in ipairs(skillOptions) do
rootDescription:CreateRadio(
option.text,
function(data) return data == AltSystem.State.selectedSkillIndex end,
function(data)
AltSystem.State.selectedSkillIndex = data
if AltSystem.SetSkillIndex then
AltSystem.SetSkillIndex(data)
end
end,
i
)
end
end)
end
end
-- Create the frame on file load so it's ready when Init runs
AltSystem:CreateMainFrame()