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