diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/AmrUiDropDown.lua	Fri Jun 05 11:05:15 2015 -0700
@@ -0,0 +1,258 @@
+--[[-----------------------------------------------------------------------------
+Dropdown picker widget.
+Simple version that handles our limited needs.
+-------------------------------------------------------------------------------]]
+local Type, Version = "AmrUiDropDown", 1
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local _G = _G
+local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
+
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function buttonOnClick(frame, ...)	
+	if frame.obj.list:IsVisible() then
+		frame.obj.list:Hide()
+	else
+		frame.obj.list:Show()
+		frame.obj:RenderItems()
+	end
+end
+
+local function buttonOnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function buttonOnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function itemOnClick(frame, ...)
+	frame.obj:SelectItem(frame.value)
+	frame.obj.list:Hide()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- restore default values
+		self:SetHeight(24)
+		self:SetWidth(200)
+		self:SetDisabled(false)
+		self:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text))
+		self:SelectItem()
+		self.frame:ClearAllPoints()
+		self.list:Hide()
+	end,
+	
+	["OnRelease"] = function(self)
+		self.itemlist = nil
+		for _, item in pairs(self.items) do
+			item:Hide()
+		end
+	end,
+	
+	["OnWidthSet"] = function(self, width)
+		self.frame:GetFontString():SetWidth(width)
+		self.list:SetWidth(width)
+	end,
+	
+	["OnHeightSet"] = function(self, height)
+		self.frame:GetFontString():SetHeight(height)
+	end,
+	
+	["SetFont"] = function(self, font)
+		self.frame:SetNormalFontObject(font)
+		
+		local _, h = font:GetFont()
+		self.fontHeight = h
+	end,
+	
+	["SelectItem"] = function(self, value)
+		-- clear any current selection
+		self.frame:SetText()
+		
+		if not self.itemlist or not value then return end
+		
+		local found = nil
+		for i, obj in ipairs(self.itemlist) do
+			local wasSelected = obj.selected
+			obj.selected = obj.value == value
+			
+			if obj.selected then
+				self.frame:SetText(obj.text)
+				if not wasSelected then
+					found = obj.value
+				end
+			end
+		end
+
+		-- redraw the list if it is open
+		if self.list:IsVisible() then
+			self:RenderItems()
+		end
+		
+		-- only fires if selection actually changed
+		if found then
+			self:Fire("OnChange", found)
+		end
+	end,
+	
+	-- the list of items to display, ordered list of objects with value, text, color, and selected properties, only supports single selection
+	["SetItems"] = function(self, items)
+		self.itemlist = items
+		self:RenderItems()
+	end,
+	
+	["CreateItem"] = function(self, index)
+		local itemname = ("AmrUiDropDown%dItem%d"):format(self.num, index)
+		
+		local item = CreateFrame("Button", itemname, self.list)
+		item.obj = self
+		
+		item:SetHeight(24)
+		item:SetPoint("LEFT", self.list, "LEFT", 1, 0)
+		item:SetPoint("RIGHT", self.list, "RIGHT", -1, 0)
+		
+		local txt = item:CreateFontString()
+		item:SetFontString(txt)
+		txt:SetPoint("LEFT", item, "LEFT", 4, 0)
+		txt:SetPoint("RIGHT", item, "RIGHT", -4, 0)
+		txt:SetJustifyH("LEFT")
+		
+		item:SetPushedTextOffset(0, 0)
+		
+		-- not perfect, but more or less achieves the effect of lightening the bg color slightly on hover
+		local texHigh = item:CreateTexture(nil, "BORDER")
+		texHigh:SetTexture(1, 1, 1, 0.1)
+		texHigh:SetAllPoints(true)
+		item:SetHighlightTexture(texHigh)
+		
+		item:SetScript("OnClick", itemOnClick)
+
+		return item
+	end,
+	
+	["RenderItems"] = function(self)
+		if not self.itemlist then return end
+		if not self.list:IsVisible() then return end
+		
+		local prev = nil
+		local h = 0
+		
+		for i, obj in ipairs(self.itemlist) do
+			local item = self.items[i]
+			if not item then
+				item = self:CreateItem(i)
+				self.items[i] = item
+			end
+			
+			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))
+			item:SetText(obj.text)
+			item.value = obj.value
+		
+			if prev then
+				item:SetPoint("TOP", prev, "BOTTOM")
+			else
+				item:SetPoint("TOP", self.list, "TOP", 0, -1)
+			end
+			
+			h = h + item:GetHeight()
+			prev = item
+		end
+		
+		self.list:SetHeight(h + 2)
+	end,
+	
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end,
+	
+	["SetVisible"] = function(self, visible)
+		if visible then
+			self.frame:Show()
+		else
+			self.frame:Hide()
+			self.list:Hide()
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local num = AceGUI:GetNextWidgetNum(Type)
+	local name = "AmrUiDropDown" .. num
+	local frame = CreateFrame("Button", name, UIParent)
+	frame:Hide()
+	
+	local txt = frame:CreateFontString()
+	frame:SetFontString(txt)
+	txt:SetPoint("LEFT", frame, "LEFT", 4, 0)
+	txt:SetPoint("RIGHT", frame, "RIGHT", -24, 0)
+	txt:SetJustifyH("LEFT")
+	
+	frame:SetPushedTextOffset(0, 0)
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", buttonOnEnter)
+	frame:SetScript("OnLeave", buttonOnLeave)
+	frame:SetScript("OnClick", buttonOnClick)
+	
+	local border = Amr.CreateTexture(frame, Amr.Colors.BorderGray, 1, "BACKGROUND")
+	border:SetAllPoints()
+	
+	local bg = Amr.CreateTexture(frame, Amr.Colors.BgInput, 1, "BORDER")
+	bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1)
+	bg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1)
+	
+	local arrow = frame:CreateTexture(nil, "ARTWORK")
+	arrow:SetWidth(16)
+	arrow:SetHeight(16)
+	arrow:SetTexture("Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\IconScrollDown")
+	arrow:SetPoint("RIGHT", frame, "RIGHT", -4, 0)
+
+	local list = CreateFrame("Frame", nil, frame)
+	list:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1)
+	list:Hide()
+	
+	local listBorder = Amr.CreateTexture(list, Amr.Colors.BorderGray, 1, "BACKGROUND")
+	listBorder:SetAllPoints()
+	
+	local listBg = Amr.CreateTexture(list, Amr.Colors.BgInput, 1, "BORDER")
+	listBg:SetPoint("TOPLEFT", list, "TOPLEFT", 1, -1)
+	listBg:SetPoint("BOTTOMRIGHT", list, "BOTTOMRIGHT", -1, 1)
+	
+	local widget = {
+		num       = num,
+		list      = list,
+		items     = {},
+		frame     = frame,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	frame.obj = widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)