annotate ui/AmrUiDropDown.lua @ 79:a892c863c86a v32

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