Mercurial > wow > breuesk
view Gui.lua @ 105:c6c748a5823b tip
Collaborative list trimming 80% functional
Updates for the zone-in problem
author | John@Yosemite-PC |
---|---|
date | Sun, 06 May 2012 08:33:34 -0400 |
parents | f844309a0e35 |
children |
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) 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 lids = LootLists:GetAllIds() for _,v in pairs(lids) do local l = LootLists:Select(v) pull[l:GetId()] = l:GetName() if l:GetLength() > 0 then pulldown:SetItemDisabled(i,true) end end pulldown:SetWidth(175) pulldown:SetList(pull) SListPopulator:SetSwidget(pulldown) pulldown:SetCallback("OnValueChanged", function(_,_,value) SListPopulator:PulldownEvent(value) end) if stateactivelist > 0 then SListPopulator:PulldownEvent(stateactivelist) end -- default value return pulldown end local f, right -- important gui elements local escapeButton = { shown = false, ["IsShown"] = function(self) return self.shown end, ["Hide"] = function(self) if f then AceGUI:Release(f); self.shown=false; f=nil 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() function ConvertLe2Line(le) 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()]) return line end local SListPopulator = { filtered = false, widget = nil, swidget = nil, data = nil, lref = nil, ["Release"] = function(self) self.filtered, self.widget, self.swidget, self.data, self.lref = false, nil, 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 = ConvertLe2Line(le) line.disabled = disabled table.insert(self.data,line) end end self.widget:SetList(self.data) SListEventDispatch:Event("Redraw") end, ["SetSwidget"] = function(self,w) if type(w) ~= "table" or type(w.SetList) ~= "function" then _G.error("Bad SetWidget") end self.swidget = w 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,nocomm) self.swidget:SetValue(value) local l = LootLists:Select(value) if l ~= self.lref then self.lref = l self:Redraw() end if nocomm then InitiateActiveList(value) end end, ["PulldownEvent"] = function(self,value) self:SelectList(value) if admin and state == "looting" then InitiateActivateList(value) end end, ["DataEvent"] = function(self) self:Redraw() end, ["StateEvent"] = function(self) -- todo: events still happen even if the gui is closed. protect the api. print("State event in SL: ", state, admin) if state == "bidding" or (state == "looting" and not admin) then self.swidget:SetDisabled(true) self:SelectList(stateactivelist) else self.swidget:SetDisabled(false) end -- if bidding then disable pulldown -- if looting and not admin then disable pulldown -- if looting and admin then enable pulldown -- otherwise enable pulldown end, ["ActiveListEvent"] = function(self) self:SelectList(stateactivelist) 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 = { data = {}, widget = nil, ["Release"] = function(self) self.data = {}; self.widget = nil end, ["ItemListEvent"] = function(self) self:Redraw() end, ["Redraw"]= function(self) self.data = {} for i,v in pairs(stateitemlist) do local entry = {value=i, text=v.link, link=v.link, mlid=v.mlid, disabled=v.disabled} table.insert(self.data,entry) end if self.widget then self.widget:SetList(self.data) LListEventDispatch:Event("Redraw") end 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 = { widget = nil, ["RollEvent"] = function(self) self:Redraw() end, ["Release"] = function(self) self.widget = nil end, ["Redraw"] = function(self) local list = {} for i,v in pairs(statebids) do table.insert(list,v) end for i,v in pairs(staterolls) do local roll for r,s in pairs(staterollvalues) do if s.value == v.value then roll = r break end end print("Inserting a roll ", v.value, roll) local c = copy(v) c.disabled = false c.text = c.text .. " (roll "..roll..")" table.insert(list,c) end self.widget:SetList(list) 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, ["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, } local BZPopulator = { group = nil, ["SetGroup"] = function(self,g) if type(g) ~= "table" or type(g.AddChild) ~= "function" then _G.error("Bad SetGroup for BZPopulator") end self.group = g end, ["Release"] = function(self) self.group = nil; RListEventDispatch:Release(); RListPopulator:Release() end, ["StateEvent"] = function(self) if state == "bidding" then local spacer = AceGUI:Create("Label") spacer:SetText(" ") spacer:SetFullWidth(true) local spacer2 = AceGUI:Create("Label") -- don't try to combine this with "spacer" - you can't add a child more than once spacer2:SetText(" ") spacer2:SetFullWidth(true) local label = AceGUI:Create("Label") label:SetText("Bidding now open for ...") local biddingOn = AceGUI:Create("InteractiveLabel") biddingOn.userdata = { stateitem.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) InitiateBid(SListPopulator:GetMe()) end) local rollButton = AceGUI:Create("Button") rollButton:SetText("Offset Roll") rollButton:SetWidth(100) rollButton:SetCallback("OnClick", function(widget) InitiateRollRequest(SListPopulator:GetMe()) end) -- todo: wrong behavior. GetMe will nil if the person isn't on the currently selected loot list. this could easily happen. return a new thingy instead local retractButton = AceGUI:Create("Button") retractButton:SetText("Retract") retractButton:SetWidth(100) retractButton:SetCallback("OnClick", function(widget) InitiateRetract(SListPopulator:GetMe()) end) 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) InitiateBid(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) InitiateRetract(RListEventDispatch:LatestValue()) end) RListEventDispatch:RegisterListener(adminRetract.userdata) adminRetract:SetDisabled(true) g1:AddChildren(adminForce,adminRetract) end self.group:AddChildren(spacer,label,biddingOn,bidRetractButton,rollButton,retractButton,spacer2,bidTitle,b1) if admin then self.group:AddChildren(g1) end else self.group:ReleaseChildren() RListEventDispatch:Release() RListPopulator:Release() end 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 } AdminLootButtons = { openButton = nil, assignButton = nil, suicideButton = nil, -- todo - open roll button eventsFromLL = { ["Redraw"] = function(self) AdminLootButtons:Redraw() end, ["OnSelection"] = function(self) AdminLootButtons:Redraw() end, ["OnSelectionCleared"] = function(self) AdminLootButtons:Redraw() end, }, eventsFromSL = { ["Redraw"] = function(self) AdminLootButtons:Redraw() end, ["OnSelection"] = function(self) AdminLootButtons:Redraw() end, ["OnSelectionCleared"] = function(self) AdminLootButtons:Redraw() end, }, ["StateEvent"] = function(self) self:Redraw() end, ["RollEvent"] = function(self) self:Redraw() end, ["SetButtons"] = function(self,open,assign,suicide) self.openButton = open self.assignButton = assign self.suicideButton = suicide SListEventDispatch:RegisterListener(self.eventsFromSL) LListEventDispatch:RegisterListener(self.eventsFromLL) self:Redraw() end, ["Release"] = function(self) self.openButton = nil self.assignButton = nil self.suicideButton = nil end, ["Redraw"] = function(self) if state == "neutral" then -- gray all buttons self.openButton:SetText("Open Bids") self.openButton:SetDisabled(true) self.assignButton:SetText("Assign") self.assignButton:SetDisabled(true) self.suicideButton:SetText("Suicide") self.suicideButton:SetDisabled(true) elseif state == "looting" then if LListEventDispatch.line then self.openButton:SetDisabled(false) self.openButton:SetText("Open Bids") self.openButton:SetCallback("OnClick", function(widget) InitiateOpenBid(LListEventDispatch:LatestValue()) end) else self.openButton:SetText("Open Bids") self.openButton:SetDisabled(true) end if LListEventDispatch.line and SListEventDispatch.line then self.assignButton:SetText("Assign") self.assignButton:SetDisabled(false) self.assignButton:SetCallback("OnClick", function(widget) FreeLoot(LListEventDispatch:LatestValue(),SListEventDispatch:LatestValue()) end) self.suicideButton:SetText("Suicide") self.suicideButton:SetDisabled(false) self.suicideButton:SetCallback("OnClick", function(widget) DirectSuicideLoot(LListEventDispatch:LatestValue(),SListEventDispatch:LatestValue(),SListPopulator.lref) end) else self.assignButton:SetText("Assign") self.assignButton:SetDisabled(true) self.suicideButton:SetText("Suicide") self.suicideButton:SetDisabled(true) end -- if item selected, light up Open button -- if item selected and name selected, light up assign/suicide -- buttons elseif state == "bidding" then self.openButton:SetDisabled(false) self.openButton:SetText("Cancel Bidding") self.openButton:SetCallback("OnClick", function(widget) InitiateCloseBidding() end) self.assignButton:SetText("Finish & Assign") self.assignButton:SetDisabled(not (getn(staterolls) > 0 or getn(statebids) > 0)) self.assignButton:SetCallback("OnClick", function(widget) ExpensiveLoot(LListEventDispatch:LatestValue(),SListPopulator.lref) end) -- todo: problem here - use stateitem instead self.suicideButton:SetText(" ") self.suicideButton:SetDisabled(true) -- change open button to cancel -- change assign button to award -- disable ... and rename? the third button end end, } function OnInitializeSetStaticData() SetChangeListener(DataEventDispatch) DataEventDispatch:RegisterListener(SListPopulator) RegisterListenerActiveListChanged(SListPopulator) RegisterListenerStateChange(SListPopulator) RegisterListenerRolls(RListPopulator) RegisterItemListListener(LListPopulator) RegisterListenerStateChange(BZPopulator) if admin then RegisterListenerStateChange(AdminLootButtons) RegisterListenerRolls(AdminLootButtons) end 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 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(); BZPopulator:Release(); AdminLootButtons: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) biddingZone = AceGUI:Create("SimpleGroup") biddingZone:SetLayout("Flow") biddingZone:SetFullWidth(true) BZPopulator:SetGroup(biddingZone) local alb1, alb2, alb3 if admin then alb1 = AceGUI:Create("Button") alb1:SetWidth(120) --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 -- widget:SetText("Open Bids") -- InitiateCloseBidding() -- todo: plug in loot award, etc -- else -- widget:SetText("Close bids") -- InitiateOpenBid(LListEventDispatch:LatestValue()) -- end -- widget.userdata.state = not widget.userdata.state -- end --) alb2 = AceGUI:Create("Button") alb2:SetWidth(120) --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(120) --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) AdminLootButtons:SetButtons(alb1,alb2,alb3) 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