annotate AceGUIWidget-DoTimerEditBoxDropDown.lua @ 90:92e0db376858

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