Mercurial > wow > breuesk
view Gui.lua @ 69:b7352f007028
Working on bids/rolls in the GUI
Added debug mode to populate things with dummy data.
author | John@Yosemite-PC |
---|---|
date | Thu, 29 Mar 2012 20:17:59 -0400 |
parents | a177b863ed6c |
children | 236117ab8a49 |
line wrap: on
line source
local AceGUI = LibStub("AceGUI-3.0") local bsk=bsk local _G=_G local table=table local pairs=pairs local setmetatable=setmetatable local ipairs=ipairs local string=string local sformat=string.format local tostring=tostring local type=type local getn=getn setfenv(1,bsk) -- todo: switching lists should close a presently-open bid local copy = function(t) local c = {} if not t then return c end for i,v in pairs(t) do c[i] = v end return c end local colorize = function(str,color) if str==nil or str=="" then return "" end if type(color) == "table" then color = string.format("%02x%02x%02x",255*color.r,255*color.g,255*color.b) end if color == nil then return str end return "|cff"..tostring(color or "ffffff")..str.."|r" end local CreateListSelector = function(SListPopulator) PersonList:RefreshRaidList() local pulldown = AceGUI:Create("Dropdown") local pull = {} local ltemp = 0 local lids = LootLists:GetAllIds() for _,v in pairs(lids) do local l = LootLists:Select(v) pull[l:GetId()] = l:GetName() --local entry = {value=i,text=v.name} if l:GetLength() > 0 then pulldown:SetItemDisabled(i,true) if ltemp == 0 then ltemp = l:GetId() end end end pulldown:SetWidth(175) pulldown:SetList(pull) pulldown:SetCallback("OnValueChanged", function(_,_,value) SListPopulator:SelectList(value) end) if ltemp > 0 then pulldown:SetValue(ltemp); SListPopulator:SelectList(ltemp) end -- sadly, SetValue doesn't fire a OnValueChanged return pulldown end local f, right local escapeButton = { shown = false, ["IsShown"] = function(self) return self.shown end, ["Hide"] = function(self) if f then AceGUI:Release(f); self.shown=false end end } SelectorListEventDispatcher = { listeners = nil, target = nil, line = nil, ["SetTarget"] = function(self,other) self.target = other self.target:SetCallback("OnSelectionCleared",function(...) self:OnSelectionCleared(...) end) self.target:SetCallback("OnSelection",function(...) self:OnSelection(...) end) end, ["RegisterListener"] = function(self,other) table.insert(self.listeners,other) end, ["OnSelectionCleared"] = function(self,_) self.line = nil self:Event("OnSelectionCleared") end, ["OnSelection"] = function(self,_,_,line) self.line = line self:Event("OnSelection",line) end, ["Event"] = function(self,event,arg) if not self.target then error("Event called with no listener...") end if not self.listeners then return end for i,v in pairs(self.listeners) do --bsk.print("listener") if type(v) == "table" then if v[event] then v[event](v,arg) end elseif type(v) == "function" then v(event,arg) elseif type(v) ~= "nil" then -- allow nils to pass quietly _G.error("Bad listener - "..type(v)) end end end, ["Release"] = function(self) self.listeners = {}; self.target=nil; self.line=nil end, ["LatestValue"] = function(self) return self.line end } function SelectorListEventDispatcher:new() local t = {} setmetatable(t,SelectorListEventDispatcher) self.__index = self t.listeners = {} return t end SListEventDispatch = SelectorListEventDispatcher:new() LListEventDispatch = SelectorListEventDispatcher:new() RListEventDispatch = SelectorListEventDispatcher:new() local SListPopulator = { filtered = false, widget = nil, data = nil, lref = nil, ["Release"] = function(self) self.filtered, self.widget, self.data, self.lref = false, nil, nil, nil end, ["Redraw"] = function(self) if self.lref == nil or self.widget == nil then return end -- don't do work if not fully initialized self.data = {} for le in self.lref:OrderedListEntryIter() do local disabled = not PersonList:IsActive(le:GetId()) if not self.filtered or not disabled then local line = {value=le:GetId(),text=le:GetName(),icon=[[Interface\Glues\CharacterCreate\UI-CharacterCreate-Classes]]} line.iconCoords=_G.CLASS_ICON_TCOORDS[le:GetClass()] line.textPlain = line.text line.text=colorize(line.text,_G.RAID_CLASS_COLORS[le:GetClass()]) line.disabled = disabled table.insert(self.data,line) end end self.widget:SetList(self.data) SListEventDispatch:Event("Redraw") end, ["SetWidget"] = function(self,w) if type(w) ~= "table" or type(w.SetList) ~= "function" then _G.error("Bad SetWidget") end self.widget = w end, ["SetFiltered"] = function(self,value) self.filtered = value self:Redraw() end, ["SelectList"] = function(self,value) self.lref = LootLists:Select(value) self:Redraw() end, ["DataEvent"] = function(self) self:Redraw() end, ["GetMe"] = function(self) local me = _G.UnitName("player") for i,v in pairs(self.data) do if v.textPlain == me then return v end end end, } local LListPopulator = { -- todo: set event receivers from the comm and for loot data = {}, widget = nil, ["Release"] = function(self) self.data = {}; self.widget = nil end, ["Redraw"]= function(self) self.widget:SetList(self.data) LListEventDispatch:Event("Redraw") end, ["SetWidget"] = function(self,w) if type(w) ~= "table" or type(w.SetList) ~= "function" then _G.error("Bad SetWidget") end self.widget = w if debug then self.data = { { value=1, text = "|cffa335ee|Hitem:77109:4080:4009:0:0:0:0:0:85:0|h[Band of Reconstruction]|h|r", link = "|cffa335ee|Hitem:77109:4080:4009:0:0:0:0:0:85:0|h[Band of Reconstruction]|h|r", }, { value=2, text = "|cffa335ee|Hitem:19351:0:0:0:0:0:0:0:85:0|h[Maladath, Runed Blade of the Black Flight]|h|r", link = "|cffa335ee|Hitem:19351:0:0:0:0:0:0:0:85:0|h[Maladath, Runed Blade of the Black Flight]|h|r" }, { value=3, text = "|cffa335ee|Hitem:31986:0:0:0:0:0:0:0:85:0|h[Merciless Gladiator's Crossbow of the Phoenix]|h|r", link = "|cffa335ee|Hitem:31986:0:0:0:0:0:0:0:85:0|h[Merciless Gladiator's Crossbow of the Phoenix]|h|r" }, { value=4, text = "|cffa335ee|Hitem:65003:0:0:0:0:0:0:0:85:0|h[Reclaimed Ashkandi, Greatsword of the Brotherhood]|h|r", link = "|cffa335ee|Hitem:65003:0:0:0:0:0:0:0:85:0|h[Reclaimed Ashkandi, Greatsword of the Brotherhood]|h|r" }, { value=5, text = "|cffff8000|Hitem:19019:0:0:0:0:0:0:0:85:0|h[Thunderfury, Blessed Blade of the Windseeker]|h|r", link = "|cffff8000|Hitem:19019:0:0:0:0:0:0:0:85:0|h[Thunderfury, Blessed Blade of the Windseeker]|h|r" }, } end self:Redraw() end, } local RListPopulator = { data = {}, widget = nil, ["Release"] = function(self) self.data = {}; self.widget = nil end, ["Redraw"] = function(self) self.widget:SetList(self.data) RListEventDispatch:Event("Redraw") end, ["SetWidget"] = function(self,w) if type(w) ~= "table" or type(w.SetList) ~= "function" then _G.error("Bad SetWidget") end self.widget = w if debug then local dummydata = {} local tree = SListPopulator.data for i,v in pairs(tree) do dummydata[i] = copy(v); dummydata[i].disabled = false end if dummydata[2] then dummydata[2].text = dummydata[2].text .. " (roll 73)" end self.data = dummydata end self:Redraw() end, ["Force"] = function(self,who) for i,v in pairs(self.data) do if who.value == v.value then print(who.value .. " is already on the list") return -- no double adds please end end local new = self.Convert(who,72) table.insert(self.data,new) -- todo: keep this list sorted self:Redraw() end, ["Retract"] = function(self,who) for i,v in pairs(self.data) do if who.value == v.value then table.remove(self.data,i) end end self:Redraw() end, ["Convert"] = function(who,roll) -- convert an LE object into one suitable to put in a SelectorList local new = copy(who) new.disabled = false -- todo: should be unnessary - they can't get on the list like this if roll then new.text = new.text .. " (roll 73)" end return new end, } DataEventDispatch = { -- todo: batch events listeners = {}, ["DataEvent"] = function(self,_) --todo: pass along the received event for i,v in pairs(self.listeners) do if v and v["DataEvent"] then v:DataEvent() end end end, ["RegisterListener"] = function(self,listener) if not listener or not listener["DataEvent"] then _G.error("Bad listener") end table.insert(self.listeners,listener) end } function OnInitializeSetStaticData() SetChangeListener(DataEventDispatch) DataEventDispatch:RegisterListener(SListPopulator) end function CreateGUI() -- special registration procedure to be closable with the escape button --escapeButton.shown = true --_G["BSK_ESCAPEBUTTON"] = escapeButton --table.insert(_G.UISpecialFrames, "BSK_ESCAPEBUTTON") if f then return end -- no second gui please local admin = admin or true f = AceGUI:Create("Frame") f:SetCallback("OnClose",function(widget) escapeButton.shown = false; AceGUI:Release(widget); f=nil; right=nil; SListEventDispatch:Release(); LListEventDispatch:Release(); SListPopulator:Release(); RListEventDispatch:Release(); LListPopulator:Release(); RListPopulator:Release() end) f:SetTitle("BSK") f:SetLayout("Flow") f:SetHeight(680) f:SetWidth(580) local left = AceGUI:Create("InlineGroup") left:SetLayout("List") left:SetWidth(175) left:SetFullHeight(true) left.alignoffset=0.25 -- hack, as per http://forums.wowace.com/showthread.php?t=17114 right = AceGUI:Create("InlineGroup") right:SetLayout("Flow") right:SetWidth(700-175-160) right:SetFullHeight(true) right.alignoffset=0.25 local t1 = AceGUI:Create("SelectorList") t1:SetNumLines(25) t1:SetFullWidth(true) t1:SetInteractive(admin) SListEventDispatch:SetTarget(t1) SListPopulator:SetWidget(t1) local p1 = CreateListSelector(SListPopulator) p1:SetFullWidth(true) left:AddChild(p1) left:AddChild(t1) local t2 = AceGUI:Create("SelectorList") t2:SetNumLines(7) t2:SetFullWidth(true) t2:EnableButtonTooltips(true) LListEventDispatch:SetTarget(t2) LListPopulator:SetWidget(t2) local biddingZone = AceGUI:Create("SimpleGroup") biddingZone:SetLayout("Flow") biddingZone:SetFullWidth(true) local alb1, alb2, alb3 if admin then alb1 = AceGUI:Create("Button") alb1:SetWidth(100) alb1:SetText("Open Bids") alb1.userdata = { state = false, widget = alb1, ["Redraw"] = function(self,_) self.widget:SetDisabled(true); self.item = nil end, ["OnSelection"] = function(self,value) self.widget:SetDisabled(false); self.item = value end, ["OnSelectionCleared"] = function(self) self.widget:SetDisabled(true); self.item = nil end } alb1:SetDisabled(true) LListEventDispatch:RegisterListener(alb1.userdata) alb1:SetCallback("OnClick", function(widget) if widget.userdata.state then -- we were bidding when the button was pressed biddingZone:ReleaseChildren() widget:SetText("Open Bids") RListEventDispatch:Release() else widget:SetText("Close bids") local spacer = AceGUI:Create("Label") spacer:SetText(" ") spacer:SetFullWidth(true) local spacer2 = AceGUI:Create("Label") spacer2:SetText(" ") spacer2:SetFullWidth(true) local label = AceGUI:Create("Label") label:SetText("Bidding now open for ...") local biddingOn = AceGUI:Create("InteractiveLabel") biddingOn.userdata = { LListEventDispatch:LatestValue().link } biddingOn:SetText(biddingOn.userdata[1]) biddingOn:SetFullWidth(true) biddingOn:SetCallback("OnEnter", function(widget) _G.GameTooltip:SetOwner(widget.frame,"ANCHOR_RIGHT"); _G.GameTooltip:SetHyperlink(widget.userdata[1]); _G.GameTooltip:Show() end ) biddingOn:SetCallback("OnLeave", function(widget) _G.GameTooltip:Hide() end ) local b1 = AceGUI:Create("SelectorList") b1:SetNumLines(6) b1:SetInteractive(admin) local bidTitle = AceGUI:Create("Label") bidTitle:SetText("Current bids") bidTitle:SetFullWidth(true) local bidRetractButton = AceGUI:Create("Button") bidRetractButton:SetText("Place Bid") bidRetractButton:SetWidth(100) bidRetractButton:SetCallback("OnClick", function(widget) RListPopulator:Force(SListPopulator:GetMe()) end) local rollButton = AceGUI:Create("Button") rollButton:SetText("Offset Roll") rollButton:SetWidth(100) RListEventDispatch:SetTarget(b1) RListPopulator:SetWidget(b1) local g1 if admin then b1.alignoffset = 0.25 -- or else g1 won't align well g1 = AceGUI:Create("SimpleGroup") g1.alignoffset = 0.25 g1:SetWidth(120) g1:SetLayout("List") -- todo: convoluted and repetitive - surely there's a -- better way than this ... adminForce = AceGUI:Create("Button") if SListEventDispatch:LatestValue() then adminForce:SetText(sformat("Force bid (%s)",SListEventDispatch:LatestValue().textPlain)) adminForce:SetDisabled(false) else adminForce:SetText("Force bid") adminForce:SetDisabled(true) end adminForce:SetWidth(160) adminForce:SetCallback("OnClick",function(widget) RListPopulator:Force(SListEventDispatch:LatestValue()) end) adminForce.userdata = { widget = adminForce, ["Redraw"] = function(self,_) self.widget:SetDisabled(true); self.widget:SetText("Force bid") end, ["OnSelection"] = function(self,_) self.widget:SetDisabled(false); self.widget:SetText(sformat("Force bid (%s)",SListEventDispatch:LatestValue().textPlain)) end, ["OnSelectionCleared"] = function(self) self.widget:SetDisabled(true); self.widget:SetText("Force bid") end } SListEventDispatch:RegisterListener(adminForce.userdata) adminRetract = AceGUI:Create("Button") if RListEventDispatch:LatestValue() then adminRetract:SetText(sformat("Retract bid (%s)",RListEventDispatch:LatestValue().textPlain)) adminRetract:SetDisabled(false) else adminRetract:SetText("Retract bid") adminRetract:SetDisabled(true) end adminRetract:SetWidth(160) adminRetract.userdata = { widget = adminRetract, ["Redraw"] = function(self,_) self.widget:SetDisabled(true); self.widget:SetText("Retract bid") end, ["OnSelection"] = function(self,_) self.widget:SetDisabled(false); self.widget:SetText(sformat("Retract bid (%s)",RListEventDispatch:LatestValue().textPlain)) end, ["OnSelectionCleared"] = function(self) self.widget:SetDisabled(true); self.widget:SetText("Retract bid") end } adminRetract:SetCallback("OnClick",function(widget) RListPopulator:Retract(RListEventDispatch:LatestValue()) end) RListEventDispatch:RegisterListener(adminRetract.userdata) adminRetract:SetDisabled(true) g1:AddChildren(adminForce,adminRetract) end biddingZone:AddChildren(spacer,label,biddingOn,bidRetractButton,rollButton,spacer2,bidTitle,b1) if admin then biddingZone:AddChildren(g1) end end widget.userdata.state = not widget.userdata.state end ) alb2 = AceGUI:Create("Button") alb2:SetWidth(100) alb2:SetText("Assign") alb2.userdata = { widget = alb2, ["OnUpdate"] = function(self) self.widget:SetDisabled(not (self.slist.checked and self.llist.checked)) end, } alb2.userdata.slist = { parent = alb2.userdata, checked = false, ["Redraw"] = function(self) self.checked = false; self.parent:OnUpdate() end, ["OnSelection"] = function(self) self.checked = true; self.parent:OnUpdate() end, ["OnSelectionCleared"] = function(self) self.checked = false; self.parent:OnUpdate() end, } alb2.userdata.llist = { parent = alb2.userdata, checked = false, ["Redraw"] = function(self) self.checked = false; self.parent:OnUpdate() end, ["OnSelection"] = function(self) self.checked = true; self.parent:OnUpdate() end, ["OnSelectionCleared"] = function(self) self.checked = false; self.parent:OnUpdate() end, } SListEventDispatch:RegisterListener(alb2.userdata.slist) LListEventDispatch:RegisterListener(alb2.userdata.llist) alb3 = AceGUI:Create("Button") alb3:SetWidth(100) alb3:SetText("Suicide") alb3.userdata = -- TODO: holy hell, come up with a pattern or something for this .... { widget = alb3, ["OnUpdate"] = function(self) self.widget:SetDisabled(not (self.slist.checked and self.llist.checked)) end, } alb3.userdata.slist = { parent = alb3.userdata, checked = false, ["Redraw"] = function(self) self.checked = false; self.parent:OnUpdate() end, ["OnSelection"] = function(self) self.checked = true; self.parent:OnUpdate() end, ["OnSelectionCleared"] = function(self) self.checked = false; self.parent:OnUpdate() end, } alb3.userdata.llist = { parent = alb3.userdata, checked = false, ["Redraw"] = function(self) self.checked = false; self.parent:OnUpdate() end, ["OnSelection"] = function(self) self.checked = true; self.parent:OnUpdate() end, ["OnSelectionCleared"] = function(self) self.checked = false; self.parent:OnUpdate() end, } SListEventDispatch:RegisterListener(alb3.userdata.slist) LListEventDispatch:RegisterListener(alb3.userdata.llist) end local suicideSelected, undo if admin then suicideSelected = AceGUI:Create("Button") suicideSelected:SetFullWidth(true) suicideSelected:SetText("Suicide") suicideSelected:SetCallback("OnClick", function(_) local p = SListEventDispatch:LatestValue() local lref = SListPopulator.lref lref:SuicidePerson(p.value) end ) -- use userdata + SListEventDispatch to toggle state suicideSelected.userdata = { widget = suicideSelected, ["Redraw"] = function(self,_) self.widget:SetDisabled(true) end, ["OnSelection"] = function(self,_) self.widget:SetDisabled(false) end, ["OnSelectionCleared"] = function(self) self.widget:SetDisabled(true) end } SListEventDispatch:RegisterListener(suicideSelected.userdata) undo = AceGUI:Create("Button") undo:SetText("Undo / out of order") undo:SetFullWidth(true) undo:SetDisabled(true) end local filter = AceGUI:Create("CheckBox") filter:SetLabel("Only show active") filter:SetFullWidth(true) filter:SetValue(false) SListPopulator:SetFiltered(false) filter:SetCallback("OnValueChanged",function(widget,_,value) SListPopulator:SetFiltered(value) end) left:AddChildren(filter) if admin then left:AddChildren(suicideSelected,undo) end right:AddChildren(t2) if admin then right:AddChildren(alb1,alb2,alb3) end right:AddChildren(biddingZone) f:AddChildren(left,right) end