Mercurial > wow > askmrrobot
comparison ui/Ui.lua @ 57:01b63b8ed811 v21
total rewrite to version 21
| author | yellowfive |
|---|---|
| date | Fri, 05 Jun 2015 11:05:15 -0700 |
| parents | |
| children | cf2b6b9a8337 |
comparison
equal
deleted
inserted
replaced
| 56:75431c084aa0 | 57:01b63b8ed811 |
|---|---|
| 1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") | |
| 2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) | |
| 3 local AceGUI = LibStub("AceGUI-3.0") | |
| 4 | |
| 5 -- used to make some stuff layer correctly | |
| 6 Amr.FrameLevels = { | |
| 7 High = 100, | |
| 8 Highest = 125 | |
| 9 } | |
| 10 | |
| 11 -- standard colors used throughout the UI (in standard 0-255 RGB format, game uses 0-1 decimals, but we auto-convert it below) | |
| 12 Amr.Colors = { | |
| 13 White = { R = 255, G = 255, B = 255 }, | |
| 14 Black = { R = 0, G = 0, B = 0 }, | |
| 15 Gray = { R = 153, G = 153, B = 153 }, | |
| 16 Orange = { R = 201, G = 87, B = 1 }, | |
| 17 Green = { R = 77, G = 134, B = 45 }, | |
| 18 Blue = { R = 54, G = 172, B = 204 }, | |
| 19 Red = { R = 204, G = 38, B = 38 }, | |
| 20 Gold = { R = 255, G = 215, B = 0 }, | |
| 21 BrightGreen = { R = 0, G = 255, B = 0 }, | |
| 22 Text = { R = 255, G = 255, B = 255 }, | |
| 23 TextHover = { R = 255, G = 255, B = 0 }, | |
| 24 TextGray = { R = 120, G = 120, B = 120 }, | |
| 25 TextHeaderActive = { R = 223, G = 134, B = 61 }, | |
| 26 TextHeaderDisabled = { R = 188, G = 188, B = 188 }, | |
| 27 TextTan = { R = 223, G = 192, B = 159 }, | |
| 28 BorderBlue = { R = 26, G = 83, B = 98 }, | |
| 29 BorderGray = { R = 96, G = 96, B = 96 }, | |
| 30 Bg = { R = 41, G = 41, B = 41 }, | |
| 31 BgInput = { R = 17, G = 17, B = 17 }, | |
| 32 BarHigh = { R = 114, G = 197, B = 66 }, | |
| 33 BarMed = { R = 255, G = 196, B = 36 }, | |
| 34 BarLow = { R = 201, G = 87, B = 1 } | |
| 35 } | |
| 36 | |
| 37 -- convert from common RGB to 0-1 RGB values | |
| 38 for k,v in pairs(Amr.Colors) do | |
| 39 v.R = v.R / 255 | |
| 40 v.G = v.G / 255 | |
| 41 v.B = v.B / 255 | |
| 42 end | |
| 43 | |
| 44 -- get colors for classes from WoW's constants | |
| 45 Amr.Colors.Classes = {} | |
| 46 for k,v in pairs(RAID_CLASS_COLORS) do | |
| 47 Amr.Colors.Classes[k] = { R = v.r, G = v.g, B = v.b } | |
| 48 end | |
| 49 | |
| 50 -- helper to take 0-1 value and turn into 2-digit hex value | |
| 51 local function decToHex(num) | |
| 52 num = math.ceil(num * 255) | |
| 53 num = string.format("%X", num) | |
| 54 if string.len(num) == 1 then num = "0" .. num end | |
| 55 return num | |
| 56 end | |
| 57 | |
| 58 function Amr.ColorToHex(color, alpha) | |
| 59 return decToHex(alpha) .. decToHex(color.R) .. decToHex(color.G) .. decToHex(color.B) | |
| 60 end | |
| 61 | |
| 62 local function getFontPath(style) | |
| 63 return "Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\Ubuntu-" .. style .. ".ttf" | |
| 64 end | |
| 65 | |
| 66 -- create a font with the specified style (Regular, Bold, Italic), size (pixels, max of 32), color (object with R, G, B), and alpha (if not specified, defaults to 1) | |
| 67 function Amr.CreateFont(style, size, color, a) | |
| 68 local alpha = a or 1 | |
| 69 local id = string.format("%s_%d_%f_%f_%f_%f", style, size, color.R, color.G, color.B, alpha) | |
| 70 local font = CreateFont(id) | |
| 71 font:SetFont(getFontPath(style), size) | |
| 72 font:SetTextColor(color.R, color.G, color.B, alpha) | |
| 73 return font | |
| 74 end | |
| 75 | |
| 76 -- helper to create a solid texture from a color with R,G,B properties | |
| 77 function Amr.CreateTexture(parent, color, alpha, layer) | |
| 78 local t = parent:CreateTexture(nil, layer or "ARTWORK") | |
| 79 t:SetTexture(color.R, color.G, color.B, alpha or 1) | |
| 80 return t | |
| 81 end | |
| 82 | |
| 83 -- helper to create a cheater shadow without having to create custom images | |
| 84 function Amr.DropShadow(frame) | |
| 85 local shadow = frame:CreateTexture(nil, "BACKGROUND") | |
| 86 shadow:SetTexture(0, 0, 0, 0.4) | |
| 87 shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) | |
| 88 shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 1, -1) | |
| 89 | |
| 90 shadow = frame:CreateTexture(nil, "BACKGROUND") | |
| 91 shadow:SetTexture(0, 0, 0, 0.3) | |
| 92 shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) | |
| 93 shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 2, -2) | |
| 94 | |
| 95 shadow = frame:CreateTexture(nil, "BACKGROUND") | |
| 96 shadow:SetTexture(0, 0, 0, 0.1) | |
| 97 shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) | |
| 98 shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 3, -3) | |
| 99 end | |
| 100 | |
| 101 | |
| 102 -- a layout that does nothing, just lets the children position themselves how they prefer | |
| 103 AceGUI:RegisterLayout("None", function(content, children) | |
| 104 if content.obj.LayoutFinished then | |
| 105 content.obj:LayoutFinished(nil, nil) | |
| 106 end | |
| 107 end) | |
| 108 | |
| 109 local _mainFrame = nil | |
| 110 local _mainTabs = nil | |
| 111 local _mainCover = nil | |
| 112 local _activeTab = "Export" | |
| 113 | |
| 114 -- release everything when the UI is closed | |
| 115 local function onMainFrameClose(widget) | |
| 116 AceGUI:Release(widget) | |
| 117 Amr["ReleaseTab" .. _activeTab](Amr) | |
| 118 _mainFrame = nil | |
| 119 _mainTabs = nil | |
| 120 _mainCover = nil | |
| 121 end | |
| 122 | |
| 123 local function onMainTabSelected(container, event, group) | |
| 124 container:ReleaseChildren() | |
| 125 Amr["ReleaseTab" .. _activeTab](Amr) | |
| 126 | |
| 127 _activeTab = group | |
| 128 | |
| 129 -- each section defines its own render method in a separate file (options tab is defined in Core.lua, uses standard Ace config stuff to auto-generate) | |
| 130 Amr["RenderTab" .. group](Amr, container) | |
| 131 end | |
| 132 | |
| 133 -- refresh the currently displayed tab | |
| 134 function Amr:RefreshTab() | |
| 135 if not _mainTabs then return end | |
| 136 | |
| 137 _mainTabs:ReleaseChildren() | |
| 138 Amr["ReleaseTab" .. _activeTab](Amr) | |
| 139 Amr["RenderTab" .. _activeTab](Amr, container) | |
| 140 end | |
| 141 | |
| 142 local function createMainWindow() | |
| 143 | |
| 144 local f = AceGUI:Create("AmrUiFrame") | |
| 145 f:SetStatusTable(Amr.db.profile.window) -- window position is remembered in db | |
| 146 f:SetCallback("OnClose", onMainFrameClose) | |
| 147 f:SetLayout("None") | |
| 148 f:SetWidth(1000) | |
| 149 f:SetHeight(700) | |
| 150 f:SetBorderColor(Amr.Colors.BorderBlue) | |
| 151 f:SetBackgroundColor(Amr.Colors.Bg) | |
| 152 | |
| 153 -- some status text | |
| 154 local lblStatus = AceGUI:Create("AmrUiLabel") | |
| 155 lblStatus:SetWidth(900) | |
| 156 lblStatus:SetFont(Amr.CreateFont("Italic", 12, Amr.Colors.TextTan)) | |
| 157 lblStatus:SetText("Ask Mr. Robot " .. L.MainStatusText("v" .. GetAddOnMetadata(Amr.ADDON_NAME, "Version"), "http://www.askmrrobot.com/wow/addon")) | |
| 158 lblStatus:SetJustifyH("CENTER") | |
| 159 lblStatus:SetWordWrap(false) | |
| 160 lblStatus:SetPoint("TOP", f.content, "BOTTOM") | |
| 161 f:AddChild(lblStatus) | |
| 162 | |
| 163 -- create the main UI container | |
| 164 local c = AceGUI:Create("AmrUiPanel") | |
| 165 c:SetLayout("Fill") | |
| 166 c:SetBackgroundColor(Amr.Colors.Black, 0) | |
| 167 c:SetPoint("TOPLEFT", f.content, "TOPLEFT") | |
| 168 c:SetPoint("BOTTOMRIGHT", f.content, "BOTTOMRIGHT") | |
| 169 f:AddChild(c) | |
| 170 | |
| 171 -- create the main tab strip | |
| 172 local t = AceGUI:Create("AmrUiTabGroup") | |
| 173 t:SetLayout("None") | |
| 174 t:SetTabs({ | |
| 175 {text=L.TabExportText, value="Export"}, | |
| 176 {text=L.TabGearText, value="Gear"}, | |
| 177 {text=L.TabLogText, value="Log"}, | |
| 178 {text=L.TabTeamText, value="Team"}, | |
| 179 {text=L.TabOptionsText, value="Options"} | |
| 180 }) | |
| 181 t:SetCallback("OnGroupSelected", onMainTabSelected) | |
| 182 c:AddChild(t) | |
| 183 | |
| 184 -- create the cover/overlay container | |
| 185 c = AceGUI:Create("AmrUiPanel") | |
| 186 c:SetLayout("None") | |
| 187 c:EnableMouse(true) | |
| 188 c:SetBackgroundColor(Amr.Colors.Black, 0.75) | |
| 189 c:SetPoint("TOPLEFT", f.frame, "TOPLEFT") | |
| 190 c:SetPoint("BOTTOMRIGHT", f.frame, "BOTTOMRIGHT") | |
| 191 f:AddChild(c) | |
| 192 | |
| 193 -- after adding, set cover to sit on top of everything, then hide it | |
| 194 c:SetStrata("FULLSCREEN_DIALOG") | |
| 195 c:SetLevel(Amr.FrameLevels.High) | |
| 196 c:SetVisible(false) | |
| 197 | |
| 198 -- put standard cover ui elements (label, cancel button) | |
| 199 local coverMsg = AceGUI:Create("AmrUiLabel") | |
| 200 coverMsg:SetWidth(600) | |
| 201 coverMsg:SetFont(Amr.CreateFont("Regular", 16, Amr.Colors.TextTan)) | |
| 202 coverMsg:SetJustifyH("MIDDLE") | |
| 203 coverMsg:SetJustifyV("MIDDLE") | |
| 204 coverMsg:SetText("") | |
| 205 coverMsg:SetPoint("CENTER", c.frame, "CENTER", 0, 20) | |
| 206 c:AddChild(coverMsg) | |
| 207 | |
| 208 local coverCancel = AceGUI:Create("AmrUiTextButton") | |
| 209 coverCancel:SetWidth(200) | |
| 210 coverCancel:SetHeight(20) | |
| 211 coverCancel:SetText(L.CoverCancel) | |
| 212 coverCancel:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextHeaderDisabled)) | |
| 213 coverCancel:SetHoverFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextHeaderActive)) | |
| 214 coverCancel:SetPoint("CENTER", c.frame, "CENTER", 0, -20) | |
| 215 c:AddChild(coverCancel) | |
| 216 | |
| 217 coverCancel:SetCallback("OnClick", function(widget) | |
| 218 Amr:HideCover() | |
| 219 end) | |
| 220 | |
| 221 -- create cover content area for custom cover ui (sort of like a modal dialog) | |
| 222 local coverContent = AceGUI:Create("AmrUiPanel") | |
| 223 coverContent:SetLayout("None") | |
| 224 coverContent:SetBackgroundColor(Amr.Colors.Black, 0) | |
| 225 coverContent:SetPoint("TOPLEFT", c.frame, "TOPLEFT") | |
| 226 coverContent:SetPoint("BOTTOMRIGHT", c.frame, "BOTTOMRIGHT") | |
| 227 c:AddChild(coverContent) | |
| 228 | |
| 229 _mainFrame = f | |
| 230 _mainTabs = t | |
| 231 _mainCover = { | |
| 232 panel = c, | |
| 233 content = coverContent, | |
| 234 label = coverMsg, | |
| 235 cancel = coverCancel | |
| 236 } | |
| 237 end | |
| 238 | |
| 239 function Amr:ShowCover(msgOrRenderFunc, disableCancel) | |
| 240 if _mainCover then | |
| 241 _mainCover.panel:SetVisible(true) | |
| 242 | |
| 243 if type(msgOrRenderFunc) == "function" then | |
| 244 _mainCover.label:SetText("") | |
| 245 _mainCover.cancel:SetVisible(false) | |
| 246 | |
| 247 -- render custom content into the cover | |
| 248 msgOrRenderFunc(_mainCover.content) | |
| 249 else | |
| 250 -- standard loading/waiting message with optional cancel button | |
| 251 _mainCover.label:SetText(msgOrRenderFunc or "") | |
| 252 _mainCover.cancel:SetVisible(not disableCancel) | |
| 253 end | |
| 254 end | |
| 255 end | |
| 256 | |
| 257 function Amr:HideCover() | |
| 258 if _mainCover then | |
| 259 _mainCover.panel:SetVisible(false) | |
| 260 | |
| 261 -- release any custom content rendered into the cover | |
| 262 _mainCover.content:ReleaseChildren() | |
| 263 end | |
| 264 end | |
| 265 | |
| 266 -- shows a "modal" alert over the main UI | |
| 267 function Amr:ShowAlert(message, btnText) | |
| 268 | |
| 269 Amr:ShowCover(function(container) | |
| 270 local border = AceGUI:Create("AmrUiPanel") | |
| 271 border:SetLayout("None") | |
| 272 border:SetBackgroundColor(Amr.Colors.BorderBlue) | |
| 273 border:SetWidth(400) | |
| 274 border:SetHeight(150) | |
| 275 border:SetPoint("CENTER", container.frame, "CENTER") | |
| 276 container:AddChild(border) | |
| 277 | |
| 278 local bg = AceGUI:Create("AmrUiPanel") | |
| 279 bg:SetLayout("None") | |
| 280 bg:SetBackgroundColor(Amr.Colors.Bg) | |
| 281 bg:SetPoint("TOPLEFT", border.frame, "TOPLEFT", 1, -1) | |
| 282 bg:SetPoint("BOTTOMRIGHT", border.frame, "BOTTOMRIGHT", -1, 1) | |
| 283 border:AddChild(bg) | |
| 284 | |
| 285 local lbl = AceGUI:Create("AmrUiLabel") | |
| 286 lbl:SetWidth(360) | |
| 287 lbl:SetFont(Amr.CreateFont("Regular", 16, Amr.Colors.Text)) | |
| 288 lbl:SetJustifyH("CENTER") | |
| 289 lbl:SetText(message) | |
| 290 lbl:SetPoint("TOP", bg.content, "TOP", 0, -20) | |
| 291 bg:AddChild(lbl) | |
| 292 | |
| 293 local btn = AceGUI:Create("AmrUiButton") | |
| 294 btn:SetBackgroundColor(Amr.Colors.Orange) | |
| 295 btn:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) | |
| 296 btn:SetWidth(120) | |
| 297 btn:SetHeight(26) | |
| 298 btn:SetText(btnText) | |
| 299 btn:SetPoint("BOTTOM", bg.content, "BOTTOM", 0, 20) | |
| 300 bg:AddChild(btn) | |
| 301 | |
| 302 btn:SetCallback("OnClick", function(widget) | |
| 303 Amr:HideCover() | |
| 304 end) | |
| 305 end) | |
| 306 end | |
| 307 | |
| 308 -- toggle visibility of the UI | |
| 309 function Amr:Toggle() | |
| 310 if not self:IsEnabled() then return end | |
| 311 | |
| 312 if not _mainFrame then | |
| 313 self:Show() | |
| 314 else | |
| 315 self:Hide() | |
| 316 end | |
| 317 end | |
| 318 | |
| 319 -- hide the UI if not already hidden | |
| 320 function Amr:Hide() | |
| 321 if not self:IsEnabled() then return end | |
| 322 if not _mainFrame then return end | |
| 323 | |
| 324 _mainFrame:Hide() | |
| 325 end | |
| 326 | |
| 327 -- show the UI if not shown already, and display the last active tab | |
| 328 function Amr:Show() | |
| 329 if not self:IsEnabled() then return end | |
| 330 | |
| 331 if _mainFrame then | |
| 332 _mainFrame:Show() | |
| 333 else | |
| 334 createMainWindow() | |
| 335 end | |
| 336 | |
| 337 -- show the active tab | |
| 338 _mainTabs:SelectTab(_activeTab) | |
| 339 end | |
| 340 | |
| 341 -- show the UI if not shown already, and select the specified tab | |
| 342 function Amr:ShowTab(tab) | |
| 343 if not self:IsEnabled() then return end | |
| 344 | |
| 345 _activeTab = tab | |
| 346 self:Show() | |
| 347 end | |
| 348 | |
| 349 ---------------------------------------------------------------------------------------- | |
| 350 -- Tooltips | |
| 351 ---------------------------------------------------------------------------------------- | |
| 352 | |
| 353 -- set an item tooltip on any AceGUI widget with OnEnter and OnLeave events | |
| 354 function Amr:SetItemTooltip(obj, itemLink, anchor, x, y) | |
| 355 obj:SetUserData("ttItemLink", itemLink) | |
| 356 obj:SetCallback("OnEnter", function(widget) | |
| 357 local tooltipLink = widget:GetUserData("ttItemLink") | |
| 358 GameTooltip:SetOwner(widget.frame, anchor and anchor or "ANCHOR_CURSOR", x, y) | |
| 359 GameTooltip:SetHyperlink(tooltipLink) | |
| 360 end) | |
| 361 obj:SetCallback("OnLeave", function(widget) | |
| 362 GameTooltip:Hide() | |
| 363 end) | |
| 364 end | |
| 365 | |
| 366 function Amr:SetSpellTooltip(obj, spellId, anchor, x, y) | |
| 367 obj:SetUserData("ttSpellId", spellId) | |
| 368 obj:SetCallback("OnEnter", function(widget) | |
| 369 local ttSpellId = widget:GetUserData("ttSpellId") | |
| 370 GameTooltip:SetOwner(widget.frame, anchor and anchor or "ANCHOR_CURSOR", x, y) | |
| 371 GameTooltip:SetSpellByID(ttSpellId) | |
| 372 end) | |
| 373 obj:SetCallback("OnLeave", function(widget) | |
| 374 GameTooltip:Hide() | |
| 375 end) | |
| 376 end | |
| 377 | |
| 378 function Amr:RenderCoverChrome(container, width, height) | |
| 379 | |
| 380 local border = AceGUI:Create("AmrUiPanel") | |
| 381 border:SetLayout("None") | |
| 382 border:SetBackgroundColor(Amr.Colors.BorderBlue) | |
| 383 border:SetWidth(width + 2) | |
| 384 border:SetHeight(height + 2) | |
| 385 border:SetPoint("CENTER", container.frame, "CENTER") | |
| 386 container:AddChild(border) | |
| 387 | |
| 388 local bg = AceGUI:Create("AmrUiPanel") | |
| 389 bg:SetLayout("None") | |
| 390 bg:SetBackgroundColor(Amr.Colors.Bg) | |
| 391 bg:SetPoint("TOPLEFT", border.frame, "TOPLEFT", 1, -1) | |
| 392 bg:SetPoint("BOTTOMRIGHT", border.frame, "BOTTOMRIGHT", -1, 1) | |
| 393 border:AddChild(bg) | |
| 394 | |
| 395 return bg, border | |
| 396 end |
