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