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)