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 |