annotate AceGUIWidget-DoTimerEditBoxDropDown.lua @ 38:bb41be8f13b2

Remove some older commented code. Cosmetic comment changes. Clear stray empty 'count' strings out of rebroadcast loot histories, if restoring previous version's data (and not in combat).
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Fri, 23 Dec 2011 01:08:02 +0000
parents 822b6ca3ef89
children 6d5fcbdc0590
rev   line source
farmbuyer@1 1 local Type, Version = "EditBoxDropDown", 3
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@1 23 disappointing restrictions are because AceConfig never gives the end user 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@1 32 the callback used for 'get', e.g.,
farmbuyer@1 33 values = function()
farmbuyer@1 34 local ret = build_real_dropdown_values()
farmbuyer@1 35 ret[get_callback] = true -- assuming "function get_callback (widget, event, text)"
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@1 43
farmbuyer@1 44 EditBoxDropDown API
farmbuyer@1 45
farmbuyer@1 46 :SetLabel(txt)
farmbuyer@1 47 forwards to the editbox's SetLabel
farmbuyer@1 48
farmbuyer@1 49 :SetText(txt)
farmbuyer@1 50 forwards to the editbox's SetText
farmbuyer@1 51
farmbuyer@1 52 :SetEditBoxTooltip(txt)
farmbuyer@1 53 sets text for the tooltip shown when hovering over the editbox
farmbuyer@1 54 no default
farmbuyer@1 55
farmbuyer@1 56 :SetButtonTooltip(txt)
farmbuyer@1 57 sets text for the tooltip shown when hovering over the dropdown button
farmbuyer@1 58 default "Click on entries to remove them."
farmbuyer@1 59
farmbuyer@1 60 :SetList(t)
farmbuyer@1 61 T is a table to be shown in the dropdown list; the values will be displayed
farmbuyer@1 62 in the dropdown
farmbuyer@1 63 When entries are clicked, they will be removed from T. T is not copied,
farmbuyer@1 64 the table is edited "live" before firing the callback below.
farmbuyer@1 65
farmbuyer@1 66
farmbuyer@1 67 EditBoxDropDown Callbacks
farmbuyer@1 68
farmbuyer@1 69 OnTextEnterPressed
farmbuyer@1 70 same as the editbox's OnEnterPressed
farmbuyer@1 71
farmbuyer@1 72 OnListItemClicked
farmbuyer@1 73 similar to a Dropdown widget's OnValueChanged, the key and value from the
farmbuyer@1 74 table given to :SetList are passed
farmbuyer@1 75
farmbuyer@1 76
farmbuyer@1 77 farmbuyer
farmbuyer@1 78 ]]
farmbuyer@1 79
farmbuyer@1 80 local button_hover_text_default = "Click on entries to remove them."
farmbuyer@1 81 local maps -- from actual editbox frame back to this widget
farmbuyer@1 82
farmbuyer@1 83
farmbuyer@1 84 local function Menu_OnClick (button, userlist_key, widget)
farmbuyer@1 85 local v = widget.list[userlist_key]
farmbuyer@1 86 widget.list[userlist_key] = nil
farmbuyer@1 87 widget.dropdown.is_on = nil
farmbuyer@1 88 -- firing these off changes widget contents, must be done last :-(
farmbuyer@1 89 widget:Fire("OnListItemClicked", userlist_key, v)
farmbuyer@1 90 widget:Fire("OnValueChanged", userlist_key)
farmbuyer@1 91 end
farmbuyer@1 92
farmbuyer@1 93 local function BuildList (widget)
farmbuyer@1 94 local ret = {}
farmbuyer@1 95 if widget.list then for k,v in pairs(widget.list) do
farmbuyer@1 96 table.insert (ret, {
farmbuyer@1 97 text = tostring(v) or tostring(k),
farmbuyer@1 98 func = Menu_OnClick,
farmbuyer@1 99 arg1 = k,
farmbuyer@1 100 arg2 = widget,
farmbuyer@1 101 notCheckable = true,
farmbuyer@1 102 })
farmbuyer@1 103 end end
farmbuyer@1 104 return ret
farmbuyer@1 105 end
farmbuyer@1 106
farmbuyer@1 107
farmbuyer@1 108 local function ddEditBox_OnMouseEnter (editbox)
farmbuyer@1 109 if editbox.tooltip_text then
farmbuyer@1 110 GameTooltip:SetOwner(editbox.frame, "ANCHOR_RIGHT")
farmbuyer@1 111 GameTooltip:SetText(editbox.tooltip_text, nil, nil, nil, nil, 1)
farmbuyer@1 112 end
farmbuyer@1 113 end
farmbuyer@1 114
farmbuyer@1 115 local function ddEditBox_OnMouseLeave (editbox_or_button)
farmbuyer@1 116 GameTooltip:Hide()
farmbuyer@1 117 end
farmbuyer@1 118
farmbuyer@1 119 local function ddEditBox_Clear (editboxframe)
farmbuyer@1 120 editboxframe:SetText("")
farmbuyer@1 121 end
farmbuyer@1 122
farmbuyer@1 123 local function ddEditBox_Reset (editboxframe) -- :ClearFocus triggers this
farmbuyer@1 124 editboxframe:SetText(maps[editboxframe].editbox_basetext or "")
farmbuyer@1 125 end
farmbuyer@1 126
farmbuyer@1 127 local function ddEditBox_OnEnterPressed (editbox, _, text)
farmbuyer@1 128 editbox.obj:Fire("OnTextEnterPressed", text)
farmbuyer@1 129 ddEditBox_Reset(editbox.editbox)
farmbuyer@1 130 editbox.editbox:ClearFocus() -- cursor still blinking in there, one more time
farmbuyer@1 131 end
farmbuyer@1 132
farmbuyer@1 133 local function Button_OnClick (button)
farmbuyer@1 134 local dd = button.obj.dropdown
farmbuyer@1 135 -- Annoyingly, it's very tedious to find the correct nested frame to use
farmbuyer@1 136 -- for :IsShown() here. We'll avoid it all by using our own flag.
farmbuyer@1 137 if dd.is_on then
farmbuyer@1 138 dd.is_on = nil
farmbuyer@1 139 HideDropDownMenu(--[[level=]]1) -- EasyMenu always uses top/1 level
farmbuyer@1 140 else
farmbuyer@1 141 dd.is_on = true
farmbuyer@1 142 local t = BuildList(button.obj)
farmbuyer@1 143 EasyMenu (t, button.obj.dropdown, button.obj.frame, 0, 0, "MENU")
farmbuyer@1 144 PlaySound("igMainMenuOptionCheckBoxOn")
farmbuyer@1 145 end
farmbuyer@1 146 end
farmbuyer@1 147
farmbuyer@1 148 local function Button_OnEnter (button)
farmbuyer@1 149 if button.tooltip_text then
farmbuyer@1 150 GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
farmbuyer@1 151 GameTooltip:SetText(button.tooltip_text, nil, nil, nil, nil, 1)
farmbuyer@1 152 end
farmbuyer@1 153 end
farmbuyer@1 154
farmbuyer@1 155
farmbuyer@1 156 local methods = {
farmbuyer@1 157 ["OnAcquire"] = function (self)
farmbuyer@1 158 self:SetHeight(20)
farmbuyer@1 159 self:SetWidth(100)
farmbuyer@1 160 self.button.tooltip_text = button_hover_text_default
farmbuyer@1 161 self:SetList(nil)
farmbuyer@1 162 self.editbox:DisableButton(true)
farmbuyer@1 163
farmbuyer@1 164 maps = maps or {}
farmbuyer@1 165 maps[self.editbox.editbox] = self
farmbuyer@1 166 end,
farmbuyer@1 167
farmbuyer@1 168 ["OnRelease"] = function (self)
farmbuyer@1 169 self.frame:ClearAllPoints()
farmbuyer@1 170 self.frame:Hide()
farmbuyer@1 171 self.editbox.tooltip_text = nil
farmbuyer@1 172 self.button.tooltip_text = nil
farmbuyer@1 173 self:SetList(nil)
farmbuyer@1 174 maps[self.editbox.editbox] = nil
farmbuyer@1 175 end,
farmbuyer@1 176
farmbuyer@1 177 ["SetParent"] = function (self, parent)
farmbuyer@1 178 self.frame:SetParent(nil)
farmbuyer@1 179 self.frame:SetParent(parent.content)
farmbuyer@1 180 self.parent = parent
farmbuyer@1 181 self.editbox:SetParent(parent)
farmbuyer@1 182 end,
farmbuyer@1 183
farmbuyer@1 184 ["SetText"] = function (self, text)
farmbuyer@1 185 self.editbox_basetext = text
farmbuyer@1 186 return self.editbox:SetText(text)
farmbuyer@1 187 end,
farmbuyer@1 188
farmbuyer@1 189 ["SetLabel"] = function (self, text)
farmbuyer@1 190 return self.editbox:SetLabel(text)
farmbuyer@1 191 end,
farmbuyer@1 192
farmbuyer@1 193 ["SetDisabled"] = function (self, disabled)
farmbuyer@1 194 self.editbox:SetDisabled(disabled)
farmbuyer@1 195 if disabled then
farmbuyer@1 196 self.button:Disable()
farmbuyer@1 197 else
farmbuyer@1 198 self.button:Enable()
farmbuyer@1 199 end
farmbuyer@1 200 end,
farmbuyer@1 201
farmbuyer@1 202 ["SetList"] = function (self, list)
farmbuyer@1 203 self.list = list
farmbuyer@1 204 end,
farmbuyer@1 205
farmbuyer@1 206 ["SetEditBoxTooltip"] = function (self, text)
farmbuyer@1 207 self.editbox.tooltip_text = text
farmbuyer@1 208 end,
farmbuyer@1 209
farmbuyer@1 210 ["SetButtonTooltip"] = function (self, text)
farmbuyer@1 211 self.button.tooltip_text = text
farmbuyer@1 212 end,
farmbuyer@1 213 }
farmbuyer@1 214
farmbuyer@1 215 -- called with the 'name' entry
farmbuyer@1 216 local function optcontrol_SetLabel (self, text)
farmbuyer@1 217 local name, desc = ('\t'):split(text)
farmbuyer@1 218 if desc then
farmbuyer@1 219 self:SetEditBoxTooltip(desc)
farmbuyer@1 220 end
farmbuyer@1 221 self.editbox:SetLabel(name)
farmbuyer@1 222 end
farmbuyer@1 223
farmbuyer@1 224 local function optcontrol_SetValue (self, epcallback)
farmbuyer@1 225 -- set the callback
farmbuyer@1 226 self:SetCallback("OnTextEnterPressed", epcallback)
farmbuyer@1 227 -- remove the fake entry from the values table
farmbuyer@1 228 self.list[epcallback] = nil
farmbuyer@1 229 end
farmbuyer@1 230
farmbuyer@1 231
farmbuyer@1 232 local function Constructor(is_option_control)
farmbuyer@1 233 local num = AceGUI:GetNextWidgetNum(Type)
farmbuyer@1 234
farmbuyer@1 235 -- Its frame becomes our widget frame, else its frame is never shown. Gluing
farmbuyer@1 236 -- them together seems a little evil, but it beats making this widget into a
farmbuyer@1 237 -- formal containter. Inspired by new-style InteractiveLabel.
farmbuyer@1 238 local editbox = AceGUI:Create("EditBox")
farmbuyer@1 239 local frame = editbox.frame
farmbuyer@1 240 editbox:SetHeight(20)
farmbuyer@1 241 editbox:SetWidth(100)
farmbuyer@1 242 frame:SetWidth(frame:GetWidth()+6)
farmbuyer@1 243 editbox:SetCallback("OnEnter", ddEditBox_OnMouseEnter)
farmbuyer@1 244 editbox:SetCallback("OnLeave", ddEditBox_OnMouseLeave)
farmbuyer@1 245 editbox:SetCallback("OnEnterPressed", ddEditBox_OnEnterPressed)
farmbuyer@1 246 editbox.editbox:SetScript("OnEditFocusGained", ddEditBox_Clear)
farmbuyer@1 247 editbox.editbox:SetScript("OnEditFocusLost", ddEditBox_Reset)
farmbuyer@1 248 --editbox.editbox:SetScript("OnEscapePressed", ddEditBox_Reset)
farmbuyer@1 249
farmbuyer@1 250 local button = CreateFrame("Button", nil, frame)
farmbuyer@1 251 button:SetHeight(20)
farmbuyer@1 252 button:SetWidth(24)
farmbuyer@1 253 button:SetPoint("LEFT", editbox.frame, "RIGHT", 0, 0)
farmbuyer@1 254 button:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up")
farmbuyer@1 255 button:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down")
farmbuyer@1 256 button:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled")
farmbuyer@1 257 button:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight","ADD")
farmbuyer@1 258 button:SetScript("OnClick", Button_OnClick)
farmbuyer@1 259 button:SetScript("OnEnter", Button_OnEnter)
farmbuyer@1 260 button:SetScript("OnLeave", ddEditBox_OnMouseLeave)
farmbuyer@1 261 button.parent = frame
farmbuyer@1 262
farmbuyer@1 263 local dropdown = CreateFrame("Frame", "AceGUI-3.0EditBoxDropDownMenu"..num, nil, "UIDropDownMenuTemplate")
farmbuyer@1 264 dropdown:Hide()
farmbuyer@1 265
farmbuyer@1 266 local widget = {
farmbuyer@1 267 editbox = editbox,
farmbuyer@1 268 button = button,
farmbuyer@1 269 dropdown = dropdown,
farmbuyer@1 270 frame = frame,
farmbuyer@1 271 type = Type
farmbuyer@1 272 }
farmbuyer@1 273 for method, func in pairs(methods) do
farmbuyer@1 274 widget[method] = func
farmbuyer@1 275 end
farmbuyer@1 276 editbox.obj, button.obj, dropdown.obj = widget, widget, widget
farmbuyer@1 277 if is_option_control then
farmbuyer@1 278 widget.is_option_control = true
farmbuyer@1 279 widget.SetLabel = optcontrol_SetLabel
farmbuyer@1 280 widget.SetValue = optcontrol_SetValue
farmbuyer@1 281 end
farmbuyer@1 282
farmbuyer@1 283 return AceGUI:RegisterAsWidget(widget)
farmbuyer@1 284 end
farmbuyer@1 285
farmbuyer@1 286 AceGUI:RegisterWidgetType (Type, Constructor, Version)
farmbuyer@1 287
farmbuyer@1 288 AceGUI:RegisterWidgetType (Type.."OptionControl", function() return Constructor(true) end, Version)
farmbuyer@1 289