diff MultiSelectWidget.lua @ 1:21c58930f74e

Refactoring
author John@Yosemite-PC
date Fri, 02 Mar 2012 22:32:12 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MultiSelectWidget.lua	Fri Mar 02 22:32:12 2012 -0500
@@ -0,0 +1,316 @@
+
+
+--[[----------------------------------
+--  MultiSelect widget for AceGUI-3.0
+--  Written by Shirokuma
+--]]----------------------------------
+
+
+--[[-----------------
+-- AceGUI
+--]]-----------------
+local AceGUI = LibStub("AceGUI-3.0")
+
+--[[-----------------
+-- Lua APIs
+--]]-----------------
+local format, pairs, tostring = string.format, pairs, tostring
+
+--[[-----------------
+-- WoW APIs
+--]]-----------------
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------
+-- Frame Elements
+--]]-----------------
+local FrameBackdrop = {
+	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 3, bottom = 3 }
+}
+
+
+--[[-----------------
+-- Widget Info
+--]]-----------------
+local widgetType = "MultiSelect"
+local widgetVersion = 1
+
+
+--[[-----------------
+-- Event Code
+--]]-----------------
+local function Label_OnEnter(label)
+	local self = label.obj
+	local value = label
+	self:Fire("OnLabelEnter", value)
+end
+
+local function Label_OnLeave(label)
+	local self = label.obj
+	local value = label
+	self:Fire("OnLabelEnter", value)
+end
+
+local function Label_OnClick(label)
+	local self = label.obj
+	local value = label
+	self:Fire("OnLabelClick", value)
+	AceGUI:ClearFocus()
+end
+
+
+--[[-----------------
+-- MultiSelect Code
+--]]-----------------
+do
+	local function OnAcquire(self)  -- set up the default size
+		self:SetWidth(200)
+		self:SetHeight(400)
+	end
+	
+	local function SetWidth(self, w)  -- override the SetWidth function to include the labelframe
+		self.frame:SetWidth(w)
+		self.labelframe:SetWidth(w-33)
+	end	
+	
+	local function SetLabel(self, text)  -- sets the multiselect label text
+		self.label:SetText(text)
+	end
+	
+	local function SetMultiSelect(self, value)  -- set if multiple values can be selected simultaneously
+		self.multiselect = value
+	end
+	
+	local function AddItem(self, str, color)  -- add an item (create a new item label object)
+	    local color = color
+		local label = CreateFrame("Button", nil, self.labelframe)
+		label.selected = false
+		label.obj = self
+		label:SetHeight(18)
+		label:SetPoint("TOPLEFT", self.labelframe, "TOPLEFT", 0, -(getn(self.labels) * 18))
+		label:SetPoint("TOPRIGHT", self.labelframe, "TOPRIGHT", 0, -(getn(self.labels) * 18))
+		self.labels[getn(self.labels) + 1] = label
+		self.labelframe:SetHeight(getn(self.labels) * 18)
+		
+		local text = label:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+		text:SetJustifyH("LEFT")
+		text:SetPoint("TOPLEFT",label,"TOPLEFT",5,0)
+		text:SetPoint("BOTTOMRIGHT",label,"BOTTOMRIGHT",-5,0)
+		if color ~= nil then
+		    text:SetTextColor(color.r,color.g,color.b)
+		end
+		text:SetText(str)
+		label.text = text
+		
+		local highlight = label:CreateTexture(nil, "OVERLAY")
+		highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+		highlight:SetBlendMode("ADD")
+		highlight:SetHeight(14)
+		highlight:ClearAllPoints()
+		highlight:SetPoint("RIGHT",label,"RIGHT",0,0)
+		highlight:SetPoint("LEFT",label,"LEFT",0,0)
+		highlight:Hide()
+		label.highlight = highlight
+		
+		label:SetScript("OnEnter", function(this)
+			this.highlight:Show()
+			Label_OnEnter(this)
+		end)
+		label:SetScript("OnLeave", function(this)
+			if not this.selected then
+				this.highlight:Hide()
+			end
+		end)
+		label:SetScript("OnClick", function(this)
+			if not this.selected then
+				this.selected = true
+				if not self.multiselect then
+					for index, items in pairs(self.labels) do
+						if self.labels[index] ~= this and self.labels[index].selected then
+							self.labels[index].selected = false
+							self.labels[index].highlight:Hide()
+						end
+					end
+				end
+			else
+				this.selected = false
+			end
+			Label_OnClick(this)
+		end)
+	end
+	
+	local function GetItem(self, text)  -- find an object based on the text parameter
+		for _, value in pairs(self.labels) do
+			if value.text:GetText() == text then
+				return value
+			end
+		end
+		return nil
+	end
+	
+	local function GetText(self, value)  -- get the text of a label object
+		for _,item in pairs(self.labels) do
+			if value == item then
+				return item.text:GetText()
+			end
+		end
+		return nil
+	end
+	
+	local function SetText(self, value, text)  -- set the text of a label object
+		for _, item in pairs(self.labels) do
+			if value == item then
+				value.text:SetText(text)
+			end
+		end
+	end
+	
+	local function IsSelected(self, value)  -- return if the label object is currently selected
+		for _, item in pairs(self.labels) do
+			if value == item then
+				return item.selected
+			end
+		end
+		return nil
+	end
+	
+	local function GetSelected(self)  -- return a table of the currently selected label objects
+		local selectedList = {}
+		for _, item in pairs(self.labels) do
+			if item.selected then
+				table.insert(selectedList, item)
+			end
+		end
+		return selectedList
+	end
+		
+	local function SetItemList(self, list)  -- create new labels from a list of strings
+		for _,item in pairs(self.labels) do
+			item:Hide()
+			item:ClearAllPoints()
+		end
+		
+		self.labels = {}
+		
+		if list then
+			for _,item in pairs(list) do
+			    if type(item) == "string" then
+				    self:AddItem(item)
+                elseif type(item) == "table" then
+                    if item.string ~= nil and type(item.string) == "string" then
+                        if item.color ~= nil then
+                            if type(item.color) == "table" and item.color.r ~= nil and item.color.g ~= nil and item.color.b ~= nil then
+                                self:AddItem(item.string, item.color)
+                            else
+                                assert(false and "setitemlist: item.color is set, but nonsense")
+                            end
+                        else
+                            self:AddItem(item.string)
+                        end
+                    else
+                        assert( false and "setitemlist: item is table without .string member")
+                    end
+                else
+                    assert(false and "SetItemList: nonsense list entry")
+                end
+			end
+		end
+	end
+
+	local function RemoveItem(self, item)  -- delete an item
+		local function RedrawFrame()
+			for index,value in pairs(self.labels) do
+				value:SetPoint("TOPLEFT", self.labelframe, "TOPLEFT", 0, (-(index-1) * 18))
+				value:SetPoint("TOPRIGHT", self.labelframe, "TOPRIGHT", 0,(-(index-1) * 18))
+			end
+		end
+		
+		for index, value in pairs(self.labels) do
+			if value == item then
+				table.remove(self.labels, index)
+				item:Hide()
+				item:ClearAllPoints()
+				RedrawFrame()
+			end
+		end
+	end
+	
+	local function SetSelected(self, item, value)
+		if value then
+			if not self.multiselect then  -- test
+				for _, value in pairs(self.labels) do
+					value.selected = false
+					value.highlight:Hide()
+				end
+			end
+			item.selected = true
+			item.highlight:Show()
+		else
+			item.selected = false
+			item.highlight:Hide()
+		end
+	end
+	
+	local function Constructor()  -- widget constructor
+		local frame = CreateFrame("Frame", nil, UIParent)
+		local backdrop = CreateFrame("Frame", nil, frame)
+		local self = {}
+		local labels = {}
+		
+		self.type = widgetType
+		self.frame = frame
+		self.backdrop = backdrop
+		self.labels = {}
+		self.multiselect = true
+		frame.obj = self
+		
+		local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+		label:SetJustifyH("LEFT")
+		label:SetPoint("TOPLEFT", 5, 0)
+		label:SetPoint("TOPRIGHT", -5, 0)
+		label:SetHeight(14)
+		label:SetText("MultiSelect")
+		self.label = label
+		
+		backdrop:SetBackdrop(FrameBackdrop)
+		backdrop:SetBackdropColor(0, 0, 0)
+		backdrop:SetBackdropBorderColor(0.4, 0.4, 0.4)
+		backdrop:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -14)
+		backdrop:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -5, 0)
+		
+		local scrollframe = CreateFrame("ScrollFrame", format("%s@%s@%s", widgetType, "ScrollFrame", tostring(self)), frame, "UIPanelScrollFrameTemplate")
+		scrollframe:SetPoint("TOPLEFT", backdrop, "TOPLEFT", 5, -6)
+		scrollframe:SetPoint("BOTTOMRIGHT", backdrop, "BOTTOMRIGHT", -28, 6)
+		scrollframe.obj = self
+		self.scrollframe = scrollframe
+		
+		local labelframe = CreateFrame("Frame", nil, scrollframe)
+		labelframe:SetAllPoints()
+		labelframe.obj = self
+		scrollframe:SetScrollChild(labelframe)
+		self.labelframe = labelframe
+
+		-- method listing
+		self.OnAcquire = OnAcquire
+		self.SetLabel = SetLabel
+		self.AddItem = AddItem
+		self.SetWidth  = SetWidth
+		self.SetMultiSelect = SetMultiSelect
+		self.SetItemList = SetItemList
+		self.GetItem = GetItem
+		self.RemoveItem = RemoveItem
+		self.GetText = GetText
+		self.SetText = SetText
+		self.IsSelected = IsSelected
+		self.GetSelected = GetSelected
+		self.SetSelected = SetSelected
+		
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+end
+