John@0: -- ideas: last attended data and/or remove people who haven't attended in X days John@0: -- and/or just a "remove from all lists" option John@0: John@0: John@0: -- order of implementation John@0: -- ( ) lists fully functional (/script interface) John@0: -- ( ) lists single-user functional via command line interface John@0: -- ( ) single user + admin gui (manual suicides) John@0: -- ( ) single user + admin gui (master loot) John@0: -- ( ) communication and list trimming John@0: -- ( ) admins John@0: -- ( ) players gui John@0: -- ( ) crypto / protection against tampering John@0: -- ( ) alt tracking John@0: -- ( ) reserves John@0: John@0: -- important things to remember: John@0: -- 1) ipairs iterates from 1 until the first missing int index -> no gaps John@0: -- 2) a.x === a["x"] John@0: -- 3) a["1"] =/= a[1] John@0: John@0: bsk = LibStub("AceAddon-3.0"):NewAddon("bsk","AceConsole-3.0", "AceHook-3.0", "AceComm-3.0", "AceSerializer-3.0") John@0: local L = LibStub("AceLocale-3.0"):GetLocale("bsk", false) John@0: John@0: local AceGUI = LibStub("AceGUI-3.0") John@0: John@0: function bsk:OnInitialize() John@0: John@0: self.db = LibStub("AceDB-3.0"):New("BskDB", self.defaults, "Default") John@0: John@0: self.options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) John@0: LibStub("AceConfig-3.0"):RegisterOptionsTable("bsk", self.options) John@0: self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("bsk", "bsk") John@0: John@0: self:RegisterChatCommand("bsk", "HandleCommand") John@0: bsk:CreateWorkingStateFromChanges() John@0: end John@0: John@0: function bsk:OnEnable() John@0: --self:HandleCommand() John@0: end John@0: John@0: function bsk:HandleCommand(paramIn) John@0: local param = { strsplit(" ", paramIn) } John@0: local FixPlayerName = function(p) John@0: p = p:lower() John@0: -- next two lines from sylvanaar John@0: local MULTIBYTE_FIRST_CHAR = "^([\192-\255]?%a?[\128-\191]*)" John@0: return string.gsub(p, MULTIBYTE_FIRST_CHAR, string.upper, 1) John@0: end John@0: John@0: if param[1] == nil or param[1] == "" then John@0: bsk:Print("need args") John@0: return John@0: end John@0: if param[1] == "players" then John@0: bsk:PrintPlayers() John@0: elseif param[1] == "add" then John@0: if param[2] == nil or param[2] == "" then John@0: bsk:PrintTable(param) John@0: return John@0: end John@0: if param[3] == nil or param[3] == "" then John@0: bsk:PrintTable(param) John@0: return John@0: end John@0: if param[2] == "player" then John@0: --if param[3] == "all" then John@0: -- bsk:Pop John@0: --else John@0: local player = FixPlayerName(param[3]) John@0: bsk:AddPlayer(player) John@0: --end John@0: elseif param[2] == "list" then John@0: bsk:CreateList(param[3]) John@0: end John@0: elseif param[1] == "suicide" then John@0: if param[2] == nil or param[2] == "" or param[3] == nil or param[3] == "" then John@0: bsk:PrintTable(param) John@0: return John@0: end John@0: local player = FixPlayerName(param[2]) John@0: bsk:Print(string.format("Fixed player name %s to %s",param[2],player)) John@0: bsk:SuicidePlayer(player,param[3]) John@0: elseif param[1] == "show" then John@0: if param[2] == nil or param[2] == "" then John@0: bsk:PrintTable(param) John@0: return John@0: end John@0: bsk:PrintLists(param[2]) John@0: end John@0: John@0: -- TODO: add options John@0: -- John@0: -- for now: launch GUI John@0: -- John@0: John@0: --if self.frame == nil then John@0: --self:CreateGUI() John@0: --self:ShowGUI() John@0: --else John@0: --self:ShowGUI() John@0: --end John@0: John@0: end John@0: --MULTIBYTE_FIRST_CHAR = "^([\192-\255]?%a?[\128-\191]*)" John@0: --function GetNamePattern(name) John@0: -- local u = name:match(MULTIBYTE_FIRST_CHAR):upper() John@0: John@0: -- if not u or u:len() == 0 then Prat.Print("GetNamePattern: name error", name) return end John@0: -- local l = u:lower() John@0: -- local namepat John@0: -- if u == l then John@0: -- namepat = name:lower() John@0: -- elseif u:len() == 1 then John@0: -- namepat = "["..u..l.."]"..name:sub(2):lower() John@0: -- elseif u:len() > 1 then John@0: -- namepat = "" John@0: -- for i=1,u:len() do John@0: -- namepat = namepat .. "[" .. u:sub(i,i)..l:sub(i,i).."]" John@0: -- end John@0: -- namepat = namepat .. name:sub(u:len()+1) John@0: -- end John@0: -- return "%f[%a\192-\255]"..namepat.."%f[^%a\128-\255]" John@0: --end John@0: --AnyNamePattern = "%f[%a\192-\255]([%a\192-\255]+)%f[^%a\128-\255]" John@0: John@0: John@0: function bsk:CreateGUI() John@0: John@0: -- Create a container frame John@0: self.frame = AceGUI:Create("Frame") John@0: self.frame:SetCallback("OnClose",function(widget) AceGUI:Release(widget) end) John@0: self.frame:SetTitle("BSK") John@0: self.frame:SetLayout("Flow") John@0: self.frame:SetHeight(700) John@0: self.frame:SetWidth(350) John@0: local tab = AceGUI:Create("TabGroup") John@0: tab:SetLayout("Flow") John@0: tab:SetTabs( John@0: { John@0: { John@0: text="Tab 1", John@0: value="tab1" John@0: }, John@0: John@0: { John@0: text="Tab 2", John@0: value="tab2" John@0: }, John@0: { John@0: text="Tab 3", John@0: value="tab3" John@0: }, John@0: { John@0: text="Tab 4", John@0: value="tab4" John@0: } John@0: } John@0: ) John@0: tab.width = "fill" John@0: tab.height = "fill" John@0: John@0: tab:SetCallback("OnGroupSelected",ChangeTab) John@0: tab:SelectTab("tab1") John@0: self.frame:AddChild(tab) John@0: John@0: -- Create a button John@0: --local btn = AceGUI:Create("Button") John@0: --btn:SetWidth(170) John@0: --btn:SetText("Button !") John@0: --btn:SetCallback("OnClick", function() print("Click!") end) John@0: -- Add the button to the container John@0: --self.frame:AddChild(btn) John@0: end John@0: John@0: bsk.defaults = { John@0: profile = { John@0: players = {}, John@0: changes = {}, John@0: listBase = {} John@0: } John@0: } John@0: John@0: bsk.options = { John@0: name= 'bsk', John@0: type = 'group', John@0: args = John@0: { John@0: version = John@0: { John@0: type = "execute", John@0: name = "Version query", John@0: desc = "Check others' versions", John@0: func = function(self) self:Print("TODO") end John@0: } John@0: } John@0: } John@0: function ChangeTab(container, event, group) John@0: container:ReleaseChildren() John@0: if group == "tab2" then John@0: local desc = AceGUI:Create("Label") John@0: desc:SetText("This is Tab 1") John@0: desc:SetFullWidth(true) John@0: container:AddChild(desc) John@0: John@0: local button = AceGUI:Create("Button") John@0: button:SetText("Tab 1 Button") John@0: button:SetWidth(200) John@0: container:AddChild(button) John@0: elseif group == "tab1" then John@0: local item2 = {string="item2!", color = {r=1,g=0,b=0.5} } John@0: local itemList = {"Item1", item2, "Item3", "Item4"} John@0: John@0: local myMultiSelect = AceGUI:Create("MultiSelect") John@0: myMultiSelect:SetLabel("My Multi Select") John@0: myMultiSelect:SetWidth(200) John@0: myMultiSelect:SetHeight(400) John@0: myMultiSelect:SetItemList(itemList) John@0: myMultiSelect:SetMultiSelect(false) John@0: container:AddChild(myMultiSelect) John@0: end John@0: end John@0: John@0: John@0: John@0: John@0: John@0: John@0: John@0: John@0: John@0: John@0: John@0: --[[---------------------------------- John@0: -- MultiSelect widget for AceGUI-3.0 John@0: -- Written by Shirokuma John@0: --]]---------------------------------- John@0: John@0: John@0: --[[----------------- John@0: -- AceGUI John@0: --]]----------------- John@0: --local AceGUI = LibStub("AceGUI-3.0") John@0: John@0: --[[----------------- John@0: -- Lua APIs John@0: --]]----------------- John@0: local format, pairs, tostring = string.format, pairs, tostring John@0: John@0: --[[----------------- John@0: -- WoW APIs John@0: --]]----------------- John@0: local CreateFrame, UIParent = CreateFrame, UIParent John@0: John@0: --[[----------------- John@0: -- Frame Elements John@0: --]]----------------- John@0: local FrameBackdrop = { John@0: bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", John@0: edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", John@0: tile = true, tileSize = 16, edgeSize = 16, John@0: insets = { left = 3, right = 3, top = 3, bottom = 3 } John@0: } John@0: John@0: John@0: --[[----------------- John@0: -- Widget Info John@0: --]]----------------- John@0: local widgetType = "MultiSelect" John@0: local widgetVersion = 1 John@0: John@0: John@0: --[[----------------- John@0: -- Event Code John@0: --]]----------------- John@0: local function Label_OnEnter(label) John@0: local self = label.obj John@0: local value = label John@0: self:Fire("OnLabelEnter", value) John@0: end John@0: John@0: local function Label_OnLeave(label) John@0: local self = label.obj John@0: local value = label John@0: self:Fire("OnLabelEnter", value) John@0: end John@0: John@0: local function Label_OnClick(label) John@0: local self = label.obj John@0: local value = label John@0: self:Fire("OnLabelClick", value) John@0: AceGUI:ClearFocus() John@0: end John@0: John@0: John@0: --[[----------------- John@0: -- MultiSelect Code John@0: --]]----------------- John@0: do John@0: local function OnAcquire(self) -- set up the default size John@0: self:SetWidth(200) John@0: self:SetHeight(400) John@0: end John@0: John@0: local function SetWidth(self, w) -- override the SetWidth function to include the labelframe John@0: self.frame:SetWidth(w) John@0: self.labelframe:SetWidth(w-33) John@0: end John@0: John@0: local function SetLabel(self, text) -- sets the multiselect label text John@0: self.label:SetText(text) John@0: end John@0: John@0: local function SetMultiSelect(self, value) -- set if multiple values can be selected simultaneously John@0: self.multiselect = value John@0: end John@0: John@0: local function AddItem(self, str, color) -- add an item (create a new item label object) John@0: local color = color John@0: local label = CreateFrame("Button", nil, self.labelframe) John@0: label.selected = false John@0: label.obj = self John@0: label:SetHeight(18) John@0: label:SetPoint("TOPLEFT", self.labelframe, "TOPLEFT", 0, -(getn(self.labels) * 18)) John@0: label:SetPoint("TOPRIGHT", self.labelframe, "TOPRIGHT", 0, -(getn(self.labels) * 18)) John@0: self.labels[getn(self.labels) + 1] = label John@0: self.labelframe:SetHeight(getn(self.labels) * 18) John@0: John@0: local text = label:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") John@0: text:SetJustifyH("LEFT") John@0: text:SetPoint("TOPLEFT",label,"TOPLEFT",5,0) John@0: text:SetPoint("BOTTOMRIGHT",label,"BOTTOMRIGHT",-5,0) John@0: if color ~= nil then John@0: text:SetTextColor(color.r,color.g,color.b) John@0: end John@0: text:SetText(str) John@0: label.text = text John@0: John@0: local highlight = label:CreateTexture(nil, "OVERLAY") John@0: highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") John@0: highlight:SetBlendMode("ADD") John@0: highlight:SetHeight(14) John@0: highlight:ClearAllPoints() John@0: highlight:SetPoint("RIGHT",label,"RIGHT",0,0) John@0: highlight:SetPoint("LEFT",label,"LEFT",0,0) John@0: highlight:Hide() John@0: label.highlight = highlight John@0: John@0: label:SetScript("OnEnter", function(this) John@0: this.highlight:Show() John@0: Label_OnEnter(this) John@0: end) John@0: label:SetScript("OnLeave", function(this) John@0: if not this.selected then John@0: this.highlight:Hide() John@0: end John@0: end) John@0: label:SetScript("OnClick", function(this) John@0: if not this.selected then John@0: this.selected = true John@0: if not self.multiselect then John@0: for index, items in pairs(self.labels) do John@0: if self.labels[index] ~= this and self.labels[index].selected then John@0: self.labels[index].selected = false John@0: self.labels[index].highlight:Hide() John@0: end John@0: end John@0: end John@0: else John@0: this.selected = false John@0: end John@0: Label_OnClick(this) John@0: end) John@0: end John@0: John@0: local function GetItem(self, text) -- find an object based on the text parameter John@0: for _, value in pairs(self.labels) do John@0: if value.text:GetText() == text then John@0: return value John@0: end John@0: end John@0: return nil John@0: end John@0: John@0: local function GetText(self, value) -- get the text of a label object John@0: for _,item in pairs(self.labels) do John@0: if value == item then John@0: return item.text:GetText() John@0: end John@0: end John@0: return nil John@0: end John@0: John@0: local function SetText(self, value, text) -- set the text of a label object John@0: for _, item in pairs(self.labels) do John@0: if value == item then John@0: value.text:SetText(text) John@0: end John@0: end John@0: end John@0: John@0: local function IsSelected(self, value) -- return if the label object is currently selected John@0: for _, item in pairs(self.labels) do John@0: if value == item then John@0: return item.selected John@0: end John@0: end John@0: return nil John@0: end John@0: John@0: local function GetSelected(self) -- return a table of the currently selected label objects John@0: local selectedList = {} John@0: for _, item in pairs(self.labels) do John@0: if item.selected then John@0: table.insert(selectedList, item) John@0: end John@0: end John@0: return selectedList John@0: end John@0: John@0: local function SetItemList(self, list) -- create new labels from a list of strings John@0: for _,item in pairs(self.labels) do John@0: item:Hide() John@0: item:ClearAllPoints() John@0: end John@0: John@0: self.labels = {} John@0: John@0: if list then John@0: for _,item in pairs(list) do John@0: if type(item) == "string" then John@0: self:AddItem(item) John@0: elseif type(item) == "table" then John@0: if item.string ~= nil and type(item.string) == "string" then John@0: if item.color ~= nil then John@0: if type(item.color) == "table" and item.color.r ~= nil and item.color.g ~= nil and item.color.b ~= nil then John@0: self:AddItem(item.string, item.color) John@0: else John@0: assert(false and "setitemlist: item.color is set, but nonsense") John@0: end John@0: else John@0: self:AddItem(item.string) John@0: end John@0: else John@0: assert( false and "setitemlist: item is table without .string member") John@0: end John@0: else John@0: assert(false and "SetItemList: nonsense list entry") John@0: end John@0: end John@0: end John@0: end John@0: John@0: local function RemoveItem(self, item) -- delete an item John@0: local function RedrawFrame() John@0: for index,value in pairs(self.labels) do John@0: value:SetPoint("TOPLEFT", self.labelframe, "TOPLEFT", 0, (-(index-1) * 18)) John@0: value:SetPoint("TOPRIGHT", self.labelframe, "TOPRIGHT", 0,(-(index-1) * 18)) John@0: end John@0: end John@0: John@0: for index, value in pairs(self.labels) do John@0: if value == item then John@0: table.remove(self.labels, index) John@0: item:Hide() John@0: item:ClearAllPoints() John@0: RedrawFrame() John@0: end John@0: end John@0: end John@0: John@0: local function SetSelected(self, item, value) John@0: if value then John@0: if not self.multiselect then -- test John@0: for _, value in pairs(self.labels) do John@0: value.selected = false John@0: value.highlight:Hide() John@0: end John@0: end John@0: item.selected = true John@0: item.highlight:Show() John@0: else John@0: item.selected = false John@0: item.highlight:Hide() John@0: end John@0: end John@0: John@0: local function Constructor() -- widget constructor John@0: local frame = CreateFrame("Frame", nil, UIParent) John@0: local backdrop = CreateFrame("Frame", nil, frame) John@0: local self = {} John@0: local labels = {} John@0: John@0: self.type = widgetType John@0: self.frame = frame John@0: self.backdrop = backdrop John@0: self.labels = {} John@0: self.multiselect = true John@0: frame.obj = self John@0: John@0: local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") John@0: label:SetJustifyH("LEFT") John@0: label:SetPoint("TOPLEFT", 5, 0) John@0: label:SetPoint("TOPRIGHT", -5, 0) John@0: label:SetHeight(14) John@0: label:SetText("MultiSelect") John@0: self.label = label John@0: John@0: backdrop:SetBackdrop(FrameBackdrop) John@0: backdrop:SetBackdropColor(0, 0, 0) John@0: backdrop:SetBackdropBorderColor(0.4, 0.4, 0.4) John@0: backdrop:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -14) John@0: backdrop:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -5, 0) John@0: John@0: local scrollframe = CreateFrame("ScrollFrame", format("%s@%s@%s", widgetType, "ScrollFrame", tostring(self)), frame, "UIPanelScrollFrameTemplate") John@0: scrollframe:SetPoint("TOPLEFT", backdrop, "TOPLEFT", 5, -6) John@0: scrollframe:SetPoint("BOTTOMRIGHT", backdrop, "BOTTOMRIGHT", -28, 6) John@0: scrollframe.obj = self John@0: self.scrollframe = scrollframe John@0: John@0: local labelframe = CreateFrame("Frame", nil, scrollframe) John@0: labelframe:SetAllPoints() John@0: labelframe.obj = self John@0: scrollframe:SetScrollChild(labelframe) John@0: self.labelframe = labelframe John@0: John@0: -- method listing John@0: self.OnAcquire = OnAcquire John@0: self.SetLabel = SetLabel John@0: self.AddItem = AddItem John@0: self.SetWidth = SetWidth John@0: self.SetMultiSelect = SetMultiSelect John@0: self.SetItemList = SetItemList John@0: self.GetItem = GetItem John@0: self.RemoveItem = RemoveItem John@0: self.GetText = GetText John@0: self.SetText = SetText John@0: self.IsSelected = IsSelected John@0: self.GetSelected = GetSelected John@0: self.SetSelected = SetSelected John@0: John@0: AceGUI:RegisterAsWidget(self) John@0: return self John@0: end John@0: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion) John@0: end John@0: