annotate ui/AmrUiDropDown.lua @ 61:cf2b6b9a8337 v23

6.2 update, shopping list bug fixes, ui scale option
author yellowfive
date Tue, 23 Jun 2015 00:27:21 -0700
parents 01b63b8ed811
children a892c863c86a
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@61 54 self:SetItems()
yellowfive@57 55 self:SelectItem()
yellowfive@57 56 self.frame:ClearAllPoints()
yellowfive@57 57 self.list:Hide()
yellowfive@57 58 end,
yellowfive@57 59
yellowfive@57 60 ["OnRelease"] = function(self)
yellowfive@57 61 self.itemlist = nil
yellowfive@57 62 for _, item in pairs(self.items) do
yellowfive@57 63 item:Hide()
yellowfive@57 64 end
yellowfive@57 65 end,
yellowfive@57 66
yellowfive@57 67 ["OnWidthSet"] = function(self, width)
yellowfive@57 68 self.frame:GetFontString():SetWidth(width)
yellowfive@57 69 self.list:SetWidth(width)
yellowfive@57 70 end,
yellowfive@57 71
yellowfive@57 72 ["OnHeightSet"] = function(self, height)
yellowfive@57 73 self.frame:GetFontString():SetHeight(height)
yellowfive@57 74 end,
yellowfive@57 75
yellowfive@57 76 ["SetFont"] = function(self, font)
yellowfive@57 77 self.frame:SetNormalFontObject(font)
yellowfive@57 78
yellowfive@57 79 local _, h = font:GetFont()
yellowfive@57 80 self.fontHeight = h
yellowfive@57 81 end,
yellowfive@57 82
yellowfive@57 83 ["SelectItem"] = function(self, value)
yellowfive@57 84 -- clear any current selection
yellowfive@57 85 self.frame:SetText()
yellowfive@57 86
yellowfive@57 87 if not self.itemlist or not value then return end
yellowfive@57 88
yellowfive@57 89 local found = nil
yellowfive@57 90 for i, obj in ipairs(self.itemlist) do
yellowfive@57 91 local wasSelected = obj.selected
yellowfive@57 92 obj.selected = obj.value == value
yellowfive@57 93
yellowfive@57 94 if obj.selected then
yellowfive@57 95 self.frame:SetText(obj.text)
yellowfive@57 96 if not wasSelected then
yellowfive@57 97 found = obj.value
yellowfive@57 98 end
yellowfive@57 99 end
yellowfive@57 100 end
yellowfive@57 101
yellowfive@57 102 -- redraw the list if it is open
yellowfive@57 103 if self.list:IsVisible() then
yellowfive@57 104 self:RenderItems()
yellowfive@57 105 end
yellowfive@57 106
yellowfive@57 107 -- only fires if selection actually changed
yellowfive@57 108 if found then
yellowfive@57 109 self:Fire("OnChange", found)
yellowfive@57 110 end
yellowfive@57 111 end,
yellowfive@57 112
yellowfive@57 113 -- the list of items to display, ordered list of objects with value, text, color, and selected properties, only supports single selection
yellowfive@57 114 ["SetItems"] = function(self, items)
yellowfive@57 115 self.itemlist = items
yellowfive@57 116 self:RenderItems()
yellowfive@57 117 end,
yellowfive@57 118
yellowfive@57 119 ["CreateItem"] = function(self, index)
yellowfive@57 120 local itemname = ("AmrUiDropDown%dItem%d"):format(self.num, index)
yellowfive@57 121
yellowfive@57 122 local item = CreateFrame("Button", itemname, self.list)
yellowfive@57 123 item.obj = self
yellowfive@57 124
yellowfive@57 125 item:SetHeight(24)
yellowfive@57 126 item:SetPoint("LEFT", self.list, "LEFT", 1, 0)
yellowfive@57 127 item:SetPoint("RIGHT", self.list, "RIGHT", -1, 0)
yellowfive@57 128
yellowfive@57 129 local txt = item:CreateFontString()
yellowfive@57 130 item:SetFontString(txt)
yellowfive@57 131 txt:SetPoint("LEFT", item, "LEFT", 4, 0)
yellowfive@57 132 txt:SetPoint("RIGHT", item, "RIGHT", -4, 0)
yellowfive@57 133 txt:SetJustifyH("LEFT")
yellowfive@57 134
yellowfive@57 135 item:SetPushedTextOffset(0, 0)
yellowfive@57 136
yellowfive@57 137 -- not perfect, but more or less achieves the effect of lightening the bg color slightly on hover
yellowfive@57 138 local texHigh = item:CreateTexture(nil, "BORDER")
yellowfive@57 139 texHigh:SetTexture(1, 1, 1, 0.1)
yellowfive@57 140 texHigh:SetAllPoints(true)
yellowfive@57 141 item:SetHighlightTexture(texHigh)
yellowfive@57 142
yellowfive@57 143 item:SetScript("OnClick", itemOnClick)
yellowfive@57 144
yellowfive@57 145 return item
yellowfive@57 146 end,
yellowfive@57 147
yellowfive@57 148 ["RenderItems"] = function(self)
yellowfive@57 149 if not self.itemlist then return end
yellowfive@57 150 if not self.list:IsVisible() then return end
yellowfive@57 151
yellowfive@57 152 local prev = nil
yellowfive@57 153 local h = 0
yellowfive@57 154
yellowfive@57 155 for i, obj in ipairs(self.itemlist) do
yellowfive@57 156 local item = self.items[i]
yellowfive@57 157 if not item then
yellowfive@57 158 item = self:CreateItem(i)
yellowfive@57 159 self.items[i] = item
yellowfive@57 160 end
yellowfive@57 161
yellowfive@61 162 item:Show()
yellowfive@57 163 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 164 item:SetText(obj.text)
yellowfive@57 165 item.value = obj.value
yellowfive@61 166
yellowfive@57 167 if prev then
yellowfive@57 168 item:SetPoint("TOP", prev, "BOTTOM")
yellowfive@57 169 else
yellowfive@57 170 item:SetPoint("TOP", self.list, "TOP", 0, -1)
yellowfive@57 171 end
yellowfive@57 172
yellowfive@57 173 h = h + item:GetHeight()
yellowfive@57 174 prev = item
yellowfive@57 175 end
yellowfive@57 176
yellowfive@57 177 self.list:SetHeight(h + 2)
yellowfive@57 178 end,
yellowfive@57 179
yellowfive@57 180 ["SetDisabled"] = function(self, disabled)
yellowfive@57 181 self.disabled = disabled
yellowfive@57 182 if disabled then
yellowfive@57 183 self.frame:Disable()
yellowfive@57 184 else
yellowfive@57 185 self.frame:Enable()
yellowfive@57 186 end
yellowfive@57 187 end,
yellowfive@57 188
yellowfive@57 189 ["SetVisible"] = function(self, visible)
yellowfive@57 190 if visible then
yellowfive@57 191 self.frame:Show()
yellowfive@57 192 else
yellowfive@57 193 self.frame:Hide()
yellowfive@57 194 self.list:Hide()
yellowfive@57 195 end
yellowfive@57 196 end
yellowfive@57 197 }
yellowfive@57 198
yellowfive@57 199 --[[-----------------------------------------------------------------------------
yellowfive@57 200 Constructor
yellowfive@57 201 -------------------------------------------------------------------------------]]
yellowfive@57 202 local function Constructor()
yellowfive@57 203 local num = AceGUI:GetNextWidgetNum(Type)
yellowfive@57 204 local name = "AmrUiDropDown" .. num
yellowfive@57 205 local frame = CreateFrame("Button", name, UIParent)
yellowfive@57 206 frame:Hide()
yellowfive@57 207
yellowfive@57 208 local txt = frame:CreateFontString()
yellowfive@57 209 frame:SetFontString(txt)
yellowfive@57 210 txt:SetPoint("LEFT", frame, "LEFT", 4, 0)
yellowfive@57 211 txt:SetPoint("RIGHT", frame, "RIGHT", -24, 0)
yellowfive@57 212 txt:SetJustifyH("LEFT")
yellowfive@57 213
yellowfive@57 214 frame:SetPushedTextOffset(0, 0)
yellowfive@57 215
yellowfive@57 216 frame:EnableMouse(true)
yellowfive@57 217 frame:SetScript("OnEnter", buttonOnEnter)
yellowfive@57 218 frame:SetScript("OnLeave", buttonOnLeave)
yellowfive@57 219 frame:SetScript("OnClick", buttonOnClick)
yellowfive@57 220
yellowfive@57 221 local border = Amr.CreateTexture(frame, Amr.Colors.BorderGray, 1, "BACKGROUND")
yellowfive@57 222 border:SetAllPoints()
yellowfive@57 223
yellowfive@57 224 local bg = Amr.CreateTexture(frame, Amr.Colors.BgInput, 1, "BORDER")
yellowfive@57 225 bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1)
yellowfive@57 226 bg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1)
yellowfive@57 227
yellowfive@57 228 local arrow = frame:CreateTexture(nil, "ARTWORK")
yellowfive@57 229 arrow:SetWidth(16)
yellowfive@57 230 arrow:SetHeight(16)
yellowfive@57 231 arrow:SetTexture("Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\IconScrollDown")
yellowfive@57 232 arrow:SetPoint("RIGHT", frame, "RIGHT", -4, 0)
yellowfive@57 233
yellowfive@57 234 local list = CreateFrame("Frame", nil, frame)
yellowfive@57 235 list:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1)
yellowfive@57 236 list:Hide()
yellowfive@57 237
yellowfive@57 238 local listBorder = Amr.CreateTexture(list, Amr.Colors.BorderGray, 1, "BACKGROUND")
yellowfive@57 239 listBorder:SetAllPoints()
yellowfive@57 240
yellowfive@57 241 local listBg = Amr.CreateTexture(list, Amr.Colors.BgInput, 1, "BORDER")
yellowfive@57 242 listBg:SetPoint("TOPLEFT", list, "TOPLEFT", 1, -1)
yellowfive@57 243 listBg:SetPoint("BOTTOMRIGHT", list, "BOTTOMRIGHT", -1, 1)
yellowfive@57 244
yellowfive@57 245 local widget = {
yellowfive@57 246 num = num,
yellowfive@57 247 list = list,
yellowfive@57 248 items = {},
yellowfive@57 249 frame = frame,
yellowfive@57 250 type = Type
yellowfive@57 251 }
yellowfive@57 252 for method, func in pairs(methods) do
yellowfive@57 253 widget[method] = func
yellowfive@57 254 end
yellowfive@57 255 frame.obj = widget
yellowfive@57 256
yellowfive@57 257 return AceGUI:RegisterAsWidget(widget)
yellowfive@57 258 end
yellowfive@57 259
yellowfive@57 260 AceGUI:RegisterWidgetType(Type, Constructor, Version)