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