Mercurial > wow > ouroloot
comparison AceGUIWidget-DoTimerEditBoxDropDown.lua @ 1:822b6ca3ef89
Import of 2.15, moving to wowace svn.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Sat, 16 Apr 2011 06:03:29 +0000 |
parents | |
children | 6d5fcbdc0590 |
comparison
equal
deleted
inserted
replaced
0:0f14a1e5364d | 1:822b6ca3ef89 |
---|---|
1 local Type, Version = "EditBoxDropDown", 3 | |
2 local AceGUI = LibStub and LibStub("AceGUI-3.0", true) | |
3 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end | |
4 | |
5 --[[ | |
6 This is a from-scratch AceGUI-style implementation of the combination drop- | |
7 down editboxes seen in DoTimer's option menus. Typing in the editbox adds | |
8 entries to a list; clicking the scrolldown button displays the list in a | |
9 dropdown; clicking on an entry in the dropdown removes it from the list. | |
10 | |
11 (This type of widget may actually have a more formal name already. I first | |
12 encountered it in DoTimer, so that's what I named it after.) | |
13 | |
14 The implementation does not borrow any of DoTimer's actual code. I've tried | |
15 writing this to imitate the look-and-feel of an interface that many players | |
16 will find familiar and easy to use. | |
17 | |
18 Version 2 is a rehash to follow the same form of the rest of the AceGUI widgets | |
19 after their rewrite, and to work with the new EditBox behavior. | |
20 | |
21 Version 3 adds the EditBoxDropDownOptionControl variant, specifically for use | |
22 as a 'dialogControl' in AceConfig option tables. Details follow; the more | |
23 disappointing restrictions are because AceConfig never gives the end user any | |
24 direct link to the widgets in use. | |
25 - 'desc' option field ignored | |
26 - 'name' field may contain an embedded tab ('\t') followed by more text to be | |
27 used as the tooltip text when hovering over the editbox field | |
28 - 'get' field must be a function, returning a function to be used as the | |
29 OnTextEnterPressed callback; this is typically how new entries should be | |
30 added to data | |
31 - 'values' field must be a function, returning the usual list of entries, PLUS | |
32 the callback used for 'get', e.g., | |
33 values = function() | |
34 local ret = build_real_dropdown_values() | |
35 ret[get_callback] = true -- assuming "function get_callback (widget, event, text)" | |
36 return ret | |
37 end | |
38 The callback will be immediately removed from the table, but is required to | |
39 be present to pass tests in the AceConfig source. | |
40 - 'set' receives the key of the dropdown table, but that entry will already be | |
41 removed by the time the 'set' function is called | |
42 | |
43 | |
44 EditBoxDropDown API | |
45 | |
46 :SetLabel(txt) | |
47 forwards to the editbox's SetLabel | |
48 | |
49 :SetText(txt) | |
50 forwards to the editbox's SetText | |
51 | |
52 :SetEditBoxTooltip(txt) | |
53 sets text for the tooltip shown when hovering over the editbox | |
54 no default | |
55 | |
56 :SetButtonTooltip(txt) | |
57 sets text for the tooltip shown when hovering over the dropdown button | |
58 default "Click on entries to remove them." | |
59 | |
60 :SetList(t) | |
61 T is a table to be shown in the dropdown list; the values will be displayed | |
62 in the dropdown | |
63 When entries are clicked, they will be removed from T. T is not copied, | |
64 the table is edited "live" before firing the callback below. | |
65 | |
66 | |
67 EditBoxDropDown Callbacks | |
68 | |
69 OnTextEnterPressed | |
70 same as the editbox's OnEnterPressed | |
71 | |
72 OnListItemClicked | |
73 similar to a Dropdown widget's OnValueChanged, the key and value from the | |
74 table given to :SetList are passed | |
75 | |
76 | |
77 farmbuyer | |
78 ]] | |
79 | |
80 local button_hover_text_default = "Click on entries to remove them." | |
81 local maps -- from actual editbox frame back to this widget | |
82 | |
83 | |
84 local function Menu_OnClick (button, userlist_key, widget) | |
85 local v = widget.list[userlist_key] | |
86 widget.list[userlist_key] = nil | |
87 widget.dropdown.is_on = nil | |
88 -- firing these off changes widget contents, must be done last :-( | |
89 widget:Fire("OnListItemClicked", userlist_key, v) | |
90 widget:Fire("OnValueChanged", userlist_key) | |
91 end | |
92 | |
93 local function BuildList (widget) | |
94 local ret = {} | |
95 if widget.list then for k,v in pairs(widget.list) do | |
96 table.insert (ret, { | |
97 text = tostring(v) or tostring(k), | |
98 func = Menu_OnClick, | |
99 arg1 = k, | |
100 arg2 = widget, | |
101 notCheckable = true, | |
102 }) | |
103 end end | |
104 return ret | |
105 end | |
106 | |
107 | |
108 local function ddEditBox_OnMouseEnter (editbox) | |
109 if editbox.tooltip_text then | |
110 GameTooltip:SetOwner(editbox.frame, "ANCHOR_RIGHT") | |
111 GameTooltip:SetText(editbox.tooltip_text, nil, nil, nil, nil, 1) | |
112 end | |
113 end | |
114 | |
115 local function ddEditBox_OnMouseLeave (editbox_or_button) | |
116 GameTooltip:Hide() | |
117 end | |
118 | |
119 local function ddEditBox_Clear (editboxframe) | |
120 editboxframe:SetText("") | |
121 end | |
122 | |
123 local function ddEditBox_Reset (editboxframe) -- :ClearFocus triggers this | |
124 editboxframe:SetText(maps[editboxframe].editbox_basetext or "") | |
125 end | |
126 | |
127 local function ddEditBox_OnEnterPressed (editbox, _, text) | |
128 editbox.obj:Fire("OnTextEnterPressed", text) | |
129 ddEditBox_Reset(editbox.editbox) | |
130 editbox.editbox:ClearFocus() -- cursor still blinking in there, one more time | |
131 end | |
132 | |
133 local function Button_OnClick (button) | |
134 local dd = button.obj.dropdown | |
135 -- Annoyingly, it's very tedious to find the correct nested frame to use | |
136 -- for :IsShown() here. We'll avoid it all by using our own flag. | |
137 if dd.is_on then | |
138 dd.is_on = nil | |
139 HideDropDownMenu(--[[level=]]1) -- EasyMenu always uses top/1 level | |
140 else | |
141 dd.is_on = true | |
142 local t = BuildList(button.obj) | |
143 EasyMenu (t, button.obj.dropdown, button.obj.frame, 0, 0, "MENU") | |
144 PlaySound("igMainMenuOptionCheckBoxOn") | |
145 end | |
146 end | |
147 | |
148 local function Button_OnEnter (button) | |
149 if button.tooltip_text then | |
150 GameTooltip:SetOwner(button, "ANCHOR_RIGHT") | |
151 GameTooltip:SetText(button.tooltip_text, nil, nil, nil, nil, 1) | |
152 end | |
153 end | |
154 | |
155 | |
156 local methods = { | |
157 ["OnAcquire"] = function (self) | |
158 self:SetHeight(20) | |
159 self:SetWidth(100) | |
160 self.button.tooltip_text = button_hover_text_default | |
161 self:SetList(nil) | |
162 self.editbox:DisableButton(true) | |
163 | |
164 maps = maps or {} | |
165 maps[self.editbox.editbox] = self | |
166 end, | |
167 | |
168 ["OnRelease"] = function (self) | |
169 self.frame:ClearAllPoints() | |
170 self.frame:Hide() | |
171 self.editbox.tooltip_text = nil | |
172 self.button.tooltip_text = nil | |
173 self:SetList(nil) | |
174 maps[self.editbox.editbox] = nil | |
175 end, | |
176 | |
177 ["SetParent"] = function (self, parent) | |
178 self.frame:SetParent(nil) | |
179 self.frame:SetParent(parent.content) | |
180 self.parent = parent | |
181 self.editbox:SetParent(parent) | |
182 end, | |
183 | |
184 ["SetText"] = function (self, text) | |
185 self.editbox_basetext = text | |
186 return self.editbox:SetText(text) | |
187 end, | |
188 | |
189 ["SetLabel"] = function (self, text) | |
190 return self.editbox:SetLabel(text) | |
191 end, | |
192 | |
193 ["SetDisabled"] = function (self, disabled) | |
194 self.editbox:SetDisabled(disabled) | |
195 if disabled then | |
196 self.button:Disable() | |
197 else | |
198 self.button:Enable() | |
199 end | |
200 end, | |
201 | |
202 ["SetList"] = function (self, list) | |
203 self.list = list | |
204 end, | |
205 | |
206 ["SetEditBoxTooltip"] = function (self, text) | |
207 self.editbox.tooltip_text = text | |
208 end, | |
209 | |
210 ["SetButtonTooltip"] = function (self, text) | |
211 self.button.tooltip_text = text | |
212 end, | |
213 } | |
214 | |
215 -- called with the 'name' entry | |
216 local function optcontrol_SetLabel (self, text) | |
217 local name, desc = ('\t'):split(text) | |
218 if desc then | |
219 self:SetEditBoxTooltip(desc) | |
220 end | |
221 self.editbox:SetLabel(name) | |
222 end | |
223 | |
224 local function optcontrol_SetValue (self, epcallback) | |
225 -- set the callback | |
226 self:SetCallback("OnTextEnterPressed", epcallback) | |
227 -- remove the fake entry from the values table | |
228 self.list[epcallback] = nil | |
229 end | |
230 | |
231 | |
232 local function Constructor(is_option_control) | |
233 local num = AceGUI:GetNextWidgetNum(Type) | |
234 | |
235 -- Its frame becomes our widget frame, else its frame is never shown. Gluing | |
236 -- them together seems a little evil, but it beats making this widget into a | |
237 -- formal containter. Inspired by new-style InteractiveLabel. | |
238 local editbox = AceGUI:Create("EditBox") | |
239 local frame = editbox.frame | |
240 editbox:SetHeight(20) | |
241 editbox:SetWidth(100) | |
242 frame:SetWidth(frame:GetWidth()+6) | |
243 editbox:SetCallback("OnEnter", ddEditBox_OnMouseEnter) | |
244 editbox:SetCallback("OnLeave", ddEditBox_OnMouseLeave) | |
245 editbox:SetCallback("OnEnterPressed", ddEditBox_OnEnterPressed) | |
246 editbox.editbox:SetScript("OnEditFocusGained", ddEditBox_Clear) | |
247 editbox.editbox:SetScript("OnEditFocusLost", ddEditBox_Reset) | |
248 --editbox.editbox:SetScript("OnEscapePressed", ddEditBox_Reset) | |
249 | |
250 local button = CreateFrame("Button", nil, frame) | |
251 button:SetHeight(20) | |
252 button:SetWidth(24) | |
253 button:SetPoint("LEFT", editbox.frame, "RIGHT", 0, 0) | |
254 button:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") | |
255 button:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") | |
256 button:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled") | |
257 button:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight","ADD") | |
258 button:SetScript("OnClick", Button_OnClick) | |
259 button:SetScript("OnEnter", Button_OnEnter) | |
260 button:SetScript("OnLeave", ddEditBox_OnMouseLeave) | |
261 button.parent = frame | |
262 | |
263 local dropdown = CreateFrame("Frame", "AceGUI-3.0EditBoxDropDownMenu"..num, nil, "UIDropDownMenuTemplate") | |
264 dropdown:Hide() | |
265 | |
266 local widget = { | |
267 editbox = editbox, | |
268 button = button, | |
269 dropdown = dropdown, | |
270 frame = frame, | |
271 type = Type | |
272 } | |
273 for method, func in pairs(methods) do | |
274 widget[method] = func | |
275 end | |
276 editbox.obj, button.obj, dropdown.obj = widget, widget, widget | |
277 if is_option_control then | |
278 widget.is_option_control = true | |
279 widget.SetLabel = optcontrol_SetLabel | |
280 widget.SetValue = optcontrol_SetValue | |
281 end | |
282 | |
283 return AceGUI:RegisterAsWidget(widget) | |
284 end | |
285 | |
286 AceGUI:RegisterWidgetType (Type, Constructor, Version) | |
287 | |
288 AceGUI:RegisterWidgetType (Type.."OptionControl", function() return Constructor(true) end, Version) | |
289 |