Mercurial > wow > askmrrobot
comparison ui/AmrUiDropDown.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 --[[----------------------------------------------------------------------------- | |
2 Dropdown picker widget. | |
3 Simple version that handles our limited needs. | |
4 -------------------------------------------------------------------------------]] | |
5 local Type, Version = "AmrUiDropDown", 1 | |
6 local AceGUI = LibStub and LibStub("AceGUI-3.0", true) | |
7 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end | |
8 | |
9 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") | |
10 | |
11 -- Lua APIs | |
12 local pairs = pairs | |
13 | |
14 -- WoW APIs | |
15 local _G = _G | |
16 local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent | |
17 | |
18 | |
19 --[[----------------------------------------------------------------------------- | |
20 Scripts | |
21 -------------------------------------------------------------------------------]] | |
22 local function buttonOnClick(frame, ...) | |
23 if frame.obj.list:IsVisible() then | |
24 frame.obj.list:Hide() | |
25 else | |
26 frame.obj.list:Show() | |
27 frame.obj:RenderItems() | |
28 end | |
29 end | |
30 | |
31 local function buttonOnEnter(frame) | |
32 frame.obj:Fire("OnEnter") | |
33 end | |
34 | |
35 local function buttonOnLeave(frame) | |
36 frame.obj:Fire("OnLeave") | |
37 end | |
38 | |
39 local function itemOnClick(frame, ...) | |
40 frame.obj:SelectItem(frame.value) | |
41 frame.obj.list:Hide() | |
42 end | |
43 | |
44 --[[----------------------------------------------------------------------------- | |
45 Methods | |
46 -------------------------------------------------------------------------------]] | |
47 local methods = { | |
48 ["OnAcquire"] = function(self) | |
49 -- restore default values | |
50 self:SetHeight(24) | |
51 self:SetWidth(200) | |
52 self:SetDisabled(false) | |
53 self:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text)) | |
54 self:SelectItem() | |
55 self.frame:ClearAllPoints() | |
56 self.list:Hide() | |
57 end, | |
58 | |
59 ["OnRelease"] = function(self) | |
60 self.itemlist = nil | |
61 for _, item in pairs(self.items) do | |
62 item:Hide() | |
63 end | |
64 end, | |
65 | |
66 ["OnWidthSet"] = function(self, width) | |
67 self.frame:GetFontString():SetWidth(width) | |
68 self.list:SetWidth(width) | |
69 end, | |
70 | |
71 ["OnHeightSet"] = function(self, height) | |
72 self.frame:GetFontString():SetHeight(height) | |
73 end, | |
74 | |
75 ["SetFont"] = function(self, font) | |
76 self.frame:SetNormalFontObject(font) | |
77 | |
78 local _, h = font:GetFont() | |
79 self.fontHeight = h | |
80 end, | |
81 | |
82 ["SelectItem"] = function(self, value) | |
83 -- clear any current selection | |
84 self.frame:SetText() | |
85 | |
86 if not self.itemlist or not value then return end | |
87 | |
88 local found = nil | |
89 for i, obj in ipairs(self.itemlist) do | |
90 local wasSelected = obj.selected | |
91 obj.selected = obj.value == value | |
92 | |
93 if obj.selected then | |
94 self.frame:SetText(obj.text) | |
95 if not wasSelected then | |
96 found = obj.value | |
97 end | |
98 end | |
99 end | |
100 | |
101 -- redraw the list if it is open | |
102 if self.list:IsVisible() then | |
103 self:RenderItems() | |
104 end | |
105 | |
106 -- only fires if selection actually changed | |
107 if found then | |
108 self:Fire("OnChange", found) | |
109 end | |
110 end, | |
111 | |
112 -- the list of items to display, ordered list of objects with value, text, color, and selected properties, only supports single selection | |
113 ["SetItems"] = function(self, items) | |
114 self.itemlist = items | |
115 self:RenderItems() | |
116 end, | |
117 | |
118 ["CreateItem"] = function(self, index) | |
119 local itemname = ("AmrUiDropDown%dItem%d"):format(self.num, index) | |
120 | |
121 local item = CreateFrame("Button", itemname, self.list) | |
122 item.obj = self | |
123 | |
124 item:SetHeight(24) | |
125 item:SetPoint("LEFT", self.list, "LEFT", 1, 0) | |
126 item:SetPoint("RIGHT", self.list, "RIGHT", -1, 0) | |
127 | |
128 local txt = item:CreateFontString() | |
129 item:SetFontString(txt) | |
130 txt:SetPoint("LEFT", item, "LEFT", 4, 0) | |
131 txt:SetPoint("RIGHT", item, "RIGHT", -4, 0) | |
132 txt:SetJustifyH("LEFT") | |
133 | |
134 item:SetPushedTextOffset(0, 0) | |
135 | |
136 -- not perfect, but more or less achieves the effect of lightening the bg color slightly on hover | |
137 local texHigh = item:CreateTexture(nil, "BORDER") | |
138 texHigh:SetTexture(1, 1, 1, 0.1) | |
139 texHigh:SetAllPoints(true) | |
140 item:SetHighlightTexture(texHigh) | |
141 | |
142 item:SetScript("OnClick", itemOnClick) | |
143 | |
144 return item | |
145 end, | |
146 | |
147 ["RenderItems"] = function(self) | |
148 if not self.itemlist then return end | |
149 if not self.list:IsVisible() then return end | |
150 | |
151 local prev = nil | |
152 local h = 0 | |
153 | |
154 for i, obj in ipairs(self.itemlist) do | |
155 local item = self.items[i] | |
156 if not item then | |
157 item = self:CreateItem(i) | |
158 self.items[i] = item | |
159 end | |
160 | |
161 item:SetNormalFontObject(Amr.CreateFont(obj.selected and "Bold" or "Regular", obj.selected and self.fontHeight + 2 or self.fontHeight, obj.color or Amr.Colors.White, 1)) | |
162 item:SetText(obj.text) | |
163 item.value = obj.value | |
164 | |
165 if prev then | |
166 item:SetPoint("TOP", prev, "BOTTOM") | |
167 else | |
168 item:SetPoint("TOP", self.list, "TOP", 0, -1) | |
169 end | |
170 | |
171 h = h + item:GetHeight() | |
172 prev = item | |
173 end | |
174 | |
175 self.list:SetHeight(h + 2) | |
176 end, | |
177 | |
178 ["SetDisabled"] = function(self, disabled) | |
179 self.disabled = disabled | |
180 if disabled then | |
181 self.frame:Disable() | |
182 else | |
183 self.frame:Enable() | |
184 end | |
185 end, | |
186 | |
187 ["SetVisible"] = function(self, visible) | |
188 if visible then | |
189 self.frame:Show() | |
190 else | |
191 self.frame:Hide() | |
192 self.list:Hide() | |
193 end | |
194 end | |
195 } | |
196 | |
197 --[[----------------------------------------------------------------------------- | |
198 Constructor | |
199 -------------------------------------------------------------------------------]] | |
200 local function Constructor() | |
201 local num = AceGUI:GetNextWidgetNum(Type) | |
202 local name = "AmrUiDropDown" .. num | |
203 local frame = CreateFrame("Button", name, UIParent) | |
204 frame:Hide() | |
205 | |
206 local txt = frame:CreateFontString() | |
207 frame:SetFontString(txt) | |
208 txt:SetPoint("LEFT", frame, "LEFT", 4, 0) | |
209 txt:SetPoint("RIGHT", frame, "RIGHT", -24, 0) | |
210 txt:SetJustifyH("LEFT") | |
211 | |
212 frame:SetPushedTextOffset(0, 0) | |
213 | |
214 frame:EnableMouse(true) | |
215 frame:SetScript("OnEnter", buttonOnEnter) | |
216 frame:SetScript("OnLeave", buttonOnLeave) | |
217 frame:SetScript("OnClick", buttonOnClick) | |
218 | |
219 local border = Amr.CreateTexture(frame, Amr.Colors.BorderGray, 1, "BACKGROUND") | |
220 border:SetAllPoints() | |
221 | |
222 local bg = Amr.CreateTexture(frame, Amr.Colors.BgInput, 1, "BORDER") | |
223 bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1) | |
224 bg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1) | |
225 | |
226 local arrow = frame:CreateTexture(nil, "ARTWORK") | |
227 arrow:SetWidth(16) | |
228 arrow:SetHeight(16) | |
229 arrow:SetTexture("Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\IconScrollDown") | |
230 arrow:SetPoint("RIGHT", frame, "RIGHT", -4, 0) | |
231 | |
232 local list = CreateFrame("Frame", nil, frame) | |
233 list:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1) | |
234 list:Hide() | |
235 | |
236 local listBorder = Amr.CreateTexture(list, Amr.Colors.BorderGray, 1, "BACKGROUND") | |
237 listBorder:SetAllPoints() | |
238 | |
239 local listBg = Amr.CreateTexture(list, Amr.Colors.BgInput, 1, "BORDER") | |
240 listBg:SetPoint("TOPLEFT", list, "TOPLEFT", 1, -1) | |
241 listBg:SetPoint("BOTTOMRIGHT", list, "BOTTOMRIGHT", -1, 1) | |
242 | |
243 local widget = { | |
244 num = num, | |
245 list = list, | |
246 items = {}, | |
247 frame = frame, | |
248 type = Type | |
249 } | |
250 for method, func in pairs(methods) do | |
251 widget[method] = func | |
252 end | |
253 frame.obj = widget | |
254 | |
255 return AceGUI:RegisterAsWidget(widget) | |
256 end | |
257 | |
258 AceGUI:RegisterWidgetType(Type, Constructor, Version) |