You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
675 lines
25 KiB
675 lines
25 KiB
--========================================================--
|
|
-- Scorpio Secure Group Panel --
|
|
-- --
|
|
-- Author : kurapica125@outlook.com --
|
|
-- Create Date : 2020/11/14 --
|
|
--========================================================--
|
|
|
|
--========================================================--
|
|
Scorpio "Scorpio.Secure.SecureGroupPanel" "1.0.0"
|
|
--========================================================--
|
|
|
|
-----------------------------------------------------------
|
|
-- Secure Element Panel Widget --
|
|
-----------------------------------------------------------
|
|
__Sealed__()
|
|
class "SecureGroupPanel" (function(_ENV)
|
|
inherit "SecurePanel"
|
|
|
|
__Sealed__() enum "GroupType" { "NONE", "GROUP", "CLASS", "ROLE", "ASSIGNEDROLE" }
|
|
|
|
__Sealed__() enum "SortType" { "INDEX", "NAME" }
|
|
|
|
__Sealed__() enum "RoleType" { "MAINTANK", "MAINASSIST", "TANK", "HEALER", "DAMAGER", "NONE" }
|
|
|
|
__Sealed__() enum "PlayerClass" { "WARRIOR", "DEATHKNIGHT", "PALADIN", "MONK", "PRIEST", "SHAMAN", "DRUID", "ROGUE", "MAGE", "WARLOCK", "HUNTER", "DEMONHUNTER" }
|
|
|
|
__Sealed__() struct "GroupFilter" { System.Number }
|
|
|
|
__Sealed__() struct "ClassFilter" { PlayerClass }
|
|
|
|
__Sealed__() struct "RoleFilter" { RoleType }
|
|
|
|
DEFAULT_CLASS_SORT_ORDER = { "WARRIOR", "DEATHKNIGHT", "PALADIN", "MONK", "PRIEST", "SHAMAN", "DRUID", "ROGUE", "MAGE", "WARLOCK", "HUNTER", "DEMONHUNTER" }
|
|
DEFAULT_ROLE_SORT_ORDER = { "MAINTANK", "MAINASSIST", "TANK", "HEALER", "DAMAGER", "NONE"}
|
|
DEFAULT_GROUP_SORT_ORDER = { 1, 2, 3, 4, 5, 6, 7, 8 }
|
|
|
|
-- A shadow refresh system based on the SecureGroupHeaderTemplate
|
|
__SecureTemplate__()
|
|
__Sealed__() class "ShadowGroupHeader" (function(_ENV)
|
|
inherit "SecureFrame"
|
|
|
|
export { min = math.min }
|
|
|
|
-- Delay Refresh Manager
|
|
_DelayManagerFrame = SecureFrame("Scorpio_SecureGroupPanel_RefreshMananger", UIParent, "SecureHandlerStateTemplate")
|
|
_DelayManagerFrame:Hide()
|
|
|
|
_DelayManagerFrame:Execute([=[
|
|
Manager = self
|
|
|
|
_Panel = newtable()
|
|
_Queue = newtable()
|
|
|
|
Manager:SetAttribute("registerDelayAction", [[
|
|
local panel, action = ...
|
|
if panel and action then
|
|
_Queue[panel] = action
|
|
|
|
-- Reset the timer
|
|
Manager:SetAttribute("state-timer", "reset")
|
|
end
|
|
]])
|
|
]=])
|
|
|
|
-- The condition has no real use, just a timer ticker
|
|
_DelayManagerFrame:SetAttribute("_onstate-timer", [=[
|
|
if newstate ~= "reset" then
|
|
for panel, action in pairs(_Queue) do
|
|
_Panel[panel]:RunAttribute(action)
|
|
end
|
|
|
|
wipe(_Queue)
|
|
end
|
|
]=])
|
|
_DelayManagerFrame:RegisterStateDriver("timer", "[pet]pet;nopet;")
|
|
|
|
|
|
-- The Secure Panel Snippets
|
|
_InitHeader = [=[
|
|
Manager = self
|
|
DelayManager = self:GetFrameRef("DelayManager")
|
|
|
|
UnitFrames = newtable()
|
|
ShadowFrames = newtable()
|
|
DeadFrames = newtable()
|
|
|
|
ShadowUnitMap = newtable()
|
|
|
|
Manager:SetAttribute("refreshDeadPlayer", [[
|
|
for i = 1, #DeadFrames do
|
|
local unitFrame = UnitFrames[i]
|
|
|
|
if unitFrame then
|
|
unitFrame:SetAttribute("unit", DeadFrames[i]:GetAttribute("unit"))
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
for i = #DeadFrames + 1, #UnitFrames do
|
|
local unitFrame = UnitFrames[i]
|
|
|
|
if unitFrame:GetAttribute("unit") then
|
|
unitFrame:SetAttribute("unit", nil)
|
|
else
|
|
break
|
|
end
|
|
end
|
|
]])
|
|
|
|
Manager:SetAttribute("newDeadPlayer", [[
|
|
local id = ...
|
|
|
|
if id then
|
|
-- Follow the order
|
|
for i = 1, #DeadFrames + 1 do
|
|
if DeadFrames[i] then
|
|
local oid = DeadFrames[i]:GetID()
|
|
|
|
if oid > id then
|
|
tinsert(DeadFrames, i, ShadowFrames[id])
|
|
break
|
|
elseif oid == id then
|
|
break
|
|
end
|
|
else
|
|
tinsert(DeadFrames, i, ShadowFrames[id])
|
|
end
|
|
end
|
|
|
|
return DelayManager:RunAttribute("registerDelayAction", Manager:GetAttribute("PanelName"), "refreshDeadPlayer")
|
|
end
|
|
]])
|
|
|
|
Manager:SetAttribute("removeDeadPlayer", [[
|
|
local id = ...
|
|
|
|
if id then
|
|
local sfrm = ShadowFrames[id]
|
|
|
|
for i = 1, #DeadFrames do
|
|
if DeadFrames[i] == sfrm then
|
|
tremove(DeadFrames, i)
|
|
return DelayManager:RunAttribute("registerDelayAction", Manager:GetAttribute("PanelName"), "refreshDeadPlayer")
|
|
end
|
|
end
|
|
end
|
|
]])
|
|
|
|
Manager:SetAttribute("updateStateForChild", [[
|
|
local id = ...
|
|
|
|
if id then
|
|
local shadow= ShadowFrames[id]
|
|
local unit = shadow:GetAttribute("unit")
|
|
|
|
UnregisterAttributeDriver(shadow, "isdead")
|
|
shadow:SetAttribute("isdead", nil)
|
|
|
|
if unit then
|
|
RegisterAttributeDriver(shadow, "isdead", format("[@%s,dead]true;false;", unit))
|
|
end
|
|
end
|
|
]])
|
|
|
|
Manager:SetAttribute("refreshUnitFrames", [[
|
|
local count = #ShadowFrames
|
|
for i = 1, count do
|
|
local frm = UnitFrames[i]
|
|
if not frm then return end
|
|
|
|
frm:SetAttribute("unit", ShadowFrames[i]:GetAttribute("unit"))
|
|
end
|
|
|
|
for i = count + 1, #UnitFrames do
|
|
UnitFrames[i]:SetAttribute("unit", nil)
|
|
end
|
|
]])
|
|
|
|
Manager:SetAttribute("onShadowUnitChanged", [[
|
|
local id, unit = ...
|
|
if ShadowUnitMap[id] ~= unit then
|
|
ShadowUnitMap[id] = unit
|
|
DelayManager:RunAttribute("registerDelayAction", Manager:GetAttribute("PanelName"), "refreshUnitFrames")
|
|
end
|
|
]])
|
|
|
|
refreshUnitChange = [[
|
|
local unit = self:GetAttribute("unit")
|
|
local frame = self:GetAttribute("UnitFrame")
|
|
|
|
if frame then
|
|
self:GetAttribute("Manager"):RunAttribute("onShadowUnitChanged", self:GetID(), value)
|
|
elseif self:GetAttribute("Manager"):GetAttribute("showDeadOnly") then
|
|
self:GetAttribute("Manager"):RunAttribute("removeDeadPlayer", self:GetID())
|
|
self:GetAttribute("Manager"):RunAttribute("updateStateForChild", self:GetID())
|
|
end
|
|
]]
|
|
]=]
|
|
|
|
_Onattributechanged = [[
|
|
if name == "unit" then
|
|
if type(value) == "string" then
|
|
value = strlower(value)
|
|
else
|
|
value = nil
|
|
end
|
|
|
|
local frame = self:GetAttribute("UnitFrame")
|
|
|
|
if frame then
|
|
self:GetAttribute("Manager"):RunAttribute("onShadowUnitChanged", self:GetID(), value)
|
|
elseif self:GetAttribute("Manager"):GetAttribute("showDeadOnly") then
|
|
self:GetAttribute("Manager"):RunAttribute("removeDeadPlayer", self:GetID())
|
|
self:GetAttribute("Manager"):RunAttribute("updateStateForChild", self:GetID())
|
|
end
|
|
elseif name == "isdead" then
|
|
if value == "true" then
|
|
self:GetAttribute("Manager"):RunAttribute("newDeadPlayer", self:GetID())
|
|
else
|
|
self:GetAttribute("Manager"):RunAttribute("removeDeadPlayer", self:GetID())
|
|
end
|
|
end
|
|
]]
|
|
|
|
_InitialConfigFunction = [=[
|
|
tinsert(ShadowFrames, self)
|
|
|
|
self:SetWidth(0)
|
|
self:SetHeight(0)
|
|
self:SetID(#ShadowFrames)
|
|
self:SetAttribute("Manager", Manager)
|
|
|
|
-- Binding
|
|
local frame = UnitFrames[#ShadowFrames]
|
|
|
|
if frame and not Manager:GetAttribute("showDeadOnly") then
|
|
self:SetAttribute("UnitFrame", frame)
|
|
end
|
|
|
|
-- Only for the entering game combat
|
|
-- refreshUnitChange won't fire when the unit is set to nil
|
|
self:SetAttribute("refreshUnitChange", refreshUnitChange)
|
|
|
|
Manager:CallMethod("UpdateUnitCount", #ShadowFrames)
|
|
]=]
|
|
|
|
_RegisterUnitFrame = [=[
|
|
local frame = Manager:GetFrameRef("UnitFrame")
|
|
|
|
if frame then
|
|
tinsert(UnitFrames, frame)
|
|
|
|
-- Binding
|
|
if not Manager:GetAttribute("showDeadOnly") then
|
|
local shadow = ShadowFrames[#UnitFrames]
|
|
|
|
if shadow then
|
|
shadow:SetAttribute("UnitFrame", frame)
|
|
frame:SetAttribute("unit", shadow:GetAttribute("unit"))
|
|
end
|
|
else
|
|
if #DeadFrames >= #UnitFrames then
|
|
frame:SetAttribute("unit", DeadFrames[#UnitFrames]:GetAttribute("unit"))
|
|
end
|
|
end
|
|
end
|
|
]=]
|
|
|
|
_Hide = [[
|
|
for i = #ShadowFrames, 1, -1 do
|
|
ShadowFrames[i]:SetAttribute("unit", nil)
|
|
end
|
|
-- Make sure hide all unit frames
|
|
for i = #UnitFrames, 1, -1 do
|
|
UnitFrames[i]:SetAttribute("unit", nil)
|
|
end
|
|
]]
|
|
|
|
_ToggleShowOnlyPlayer = [[
|
|
wipe(ShadowUnitMap)
|
|
|
|
if self:GetAttribute("showDeadOnly") then
|
|
for i = 1, #ShadowFrames do
|
|
ShadowFrames[i]:SetAttribute("UnitFrame", nil)
|
|
end
|
|
for i = 1, #UnitFrames do
|
|
UnitFrames[i]:SetAttribute("unit", nil)
|
|
end
|
|
for i = 1, #ShadowFrames do
|
|
self:RunAttribute("updateStateForChild", i)
|
|
end
|
|
else
|
|
wipe(DeadFrames)
|
|
|
|
for i = 1, #ShadowFrames do
|
|
local shadow = ShadowFrames[i]
|
|
local frame = UnitFrames[i]
|
|
|
|
UnregisterAttributeDriver(shadow, "isdead")
|
|
|
|
if frame then
|
|
ShadowFrames[i]:SetAttribute("UnitFrame", frame)
|
|
frame:SetAttribute("unit", ShadowFrames[i]:GetAttribute("unit"))
|
|
end
|
|
end
|
|
for i = #ShadowFrames + 1, #UnitFrames do
|
|
UnitFrames[i]:SetAttribute("unit", nil)
|
|
end
|
|
end
|
|
]]
|
|
|
|
------------------------------------------------------
|
|
-- Method
|
|
------------------------------------------------------
|
|
__SecureMethod__() __AsyncSingle__(true)
|
|
function UpdateUnitCount(self, count)
|
|
Next() NoCombat()
|
|
|
|
-- Init the panel
|
|
local panel = self:GetParent()
|
|
count = min(count, panel.MaxCount) -- Limit the count
|
|
|
|
for i = self.__InitedCount + 1, count do
|
|
-- Init the child
|
|
local child = self:GetAttribute("child" .. i)
|
|
|
|
child:SetAttribute("refreshUnitChange", nil) -- only used for the entering game combat
|
|
child:SetAttribute("isdead", nil)
|
|
child:SetAttribute("_onattributechanged", _Onattributechanged)
|
|
end
|
|
|
|
self.__InitedCount = count
|
|
|
|
if panel and count and panel.Count < count then
|
|
panel.Count = count
|
|
end
|
|
end
|
|
|
|
-- The default refresh method
|
|
function Refresh(self)
|
|
if self:IsShown() and not InCombatLockdown() then
|
|
-- Well, it's ugly but useful to trigger refreshing
|
|
self:Hide()
|
|
self:Show()
|
|
end
|
|
end
|
|
|
|
-- Register an unit frame
|
|
function RegisterUnitFrame(self, frame)
|
|
self:SetFrameRef("UnitFrame", frame)
|
|
self:Execute(_RegisterUnitFrame)
|
|
end
|
|
|
|
-- Set whether only show dead players
|
|
__NoCombat__()
|
|
function SetShowDeadOnly(self, flag)
|
|
flag = flag and true or false
|
|
|
|
if flag ~= self:IsShowDeadOnly() then
|
|
self:SetAttribute("showDeadOnly", flag)
|
|
self:Execute(_ToggleShowOnlyPlayer)
|
|
end
|
|
end
|
|
|
|
-- Whether only show the dead players
|
|
function IsShowDeadOnly(self)
|
|
return self:GetAttribute("showDeadOnly") and true or false
|
|
end
|
|
|
|
------------------------------------------------------
|
|
-- Property
|
|
------------------------------------------------------
|
|
-- Whether only show the dead players
|
|
property "ShowDeadOnly" {
|
|
get = IsShowDeadOnly,
|
|
set = SetShowDeadOnly,
|
|
type = Boolean,
|
|
}
|
|
|
|
------------------------------------------------------
|
|
-- Constructor
|
|
------------------------------------------------------
|
|
function __ctor(self, ...)
|
|
self.__InitedCount = 0
|
|
|
|
self:SetFrameRef("DelayManager", _DelayManagerFrame)
|
|
self:Execute(_InitHeader)
|
|
|
|
self:SetAttribute("PanelName", self:GetParent():GetName())
|
|
|
|
_DelayManagerFrame:SetFrameRef("GroupPanel", self)
|
|
_DelayManagerFrame:Execute([[
|
|
local panel = self:GetFrameRef("GroupPanel")
|
|
_Panel[panel:GetAttribute("PanelName")] = panel
|
|
]])
|
|
|
|
self:SetAttribute("template", "SecureHandlerAttributeTemplate")
|
|
self:SetAttribute("initialConfigFunction", _InitialConfigFunction)
|
|
self:SetAttribute("strictFiltering", true)
|
|
self:SetAttribute("groupingOrder", "")
|
|
|
|
self:WrapScript(self, "OnHide", _Hide)
|
|
|
|
-- Throw out of the screen
|
|
self:SetPoint("TOPRIGHT", UIParent, "TOPLEFT")
|
|
self:SetAlpha(0)
|
|
end
|
|
end)
|
|
|
|
------------------------------------------------------
|
|
-- Helper functions
|
|
------------------------------------------------------
|
|
local _Cache = {}
|
|
|
|
local function secureSetAttribute(self, attr, value)
|
|
return NoCombat(self.SetAttribute, self, attr, value)
|
|
end
|
|
|
|
local function setupGroupFilter(self)
|
|
local groupFilter = self.GroupFilter or DEFAULT_GROUP_SORT_ORDER
|
|
local classFilter = self.ClassFilter or DEFAULT_CLASS_SORT_ORDER
|
|
|
|
wipe(_Cache)
|
|
|
|
for _, v in ipairs(groupFilter) do tinsert(_Cache, v) end
|
|
for _, v in ipairs(classFilter) do tinsert(_Cache, v) end
|
|
|
|
secureSetAttribute(self.GroupHeader, "groupFilter", tblconcat(_Cache, ","))
|
|
|
|
wipe(_Cache)
|
|
end
|
|
|
|
local function setupRoleFilter(self)
|
|
local roleFilter = self.RoleFilter or DEFAULT_ROLE_SORT_ORDER
|
|
|
|
wipe(_Cache)
|
|
|
|
for _, v in ipairs(roleFilter) do tinsert(_Cache, v) end
|
|
|
|
secureSetAttribute(self.GroupHeader, "roleFilter", tblconcat(_Cache, ","))
|
|
|
|
wipe(_Cache)
|
|
end
|
|
|
|
local function setupGroupingOrder(self)
|
|
local groupBy = self.GroupBy
|
|
local filter
|
|
|
|
if groupBy == "GROUP" then
|
|
filter = self.GroupFilter or DEFAULT_GROUP_SORT_ORDER
|
|
elseif groupBy == "CLASS" then
|
|
filter = self.ClassFilter or DEFAULT_CLASS_SORT_ORDER
|
|
elseif groupBy == "ROLE" or groupBy == "ASSIGNEDROLE" then
|
|
filter = self.RoleFilter or DEFAULT_ROLE_SORT_ORDER
|
|
end
|
|
|
|
wipe(_Cache)
|
|
|
|
if filter then for _, v in ipairs(filter) do tinsert(_Cache, v) end end
|
|
|
|
secureSetAttribute(self.GroupHeader, "groupingOrder", tblconcat(_Cache, ","))
|
|
|
|
wipe(_Cache)
|
|
end
|
|
|
|
------------------------------------------------------
|
|
-- Method
|
|
------------------------------------------------------
|
|
-- The default refresh method
|
|
function Refresh(self)
|
|
if InCombatLockdown() then return end
|
|
|
|
self.GroupHeader:Refresh()
|
|
|
|
return self:RefreshLayout()
|
|
end
|
|
|
|
function SetAutoHide(self, value)
|
|
return self.GroupHeader:SetAutoHide(value)
|
|
end
|
|
|
|
------------------------------------------------------
|
|
-- Property
|
|
------------------------------------------------------
|
|
-- Whether the panel should be shown while in a raid
|
|
property "ShowRaid" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("showRaid") end,
|
|
set = function(self, value) secureSetAttribute(self.GroupHeader, "showRaid", value) end,
|
|
type = Boolean,
|
|
}
|
|
|
|
-- Whether the panel should be shown while in a party and not in a raid
|
|
property "ShowParty" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("showParty") end,
|
|
set = function(self, value) secureSetAttribute(self.GroupHeader, "showParty", value) end,
|
|
type = Boolean,
|
|
}
|
|
|
|
-- Whether the panel should show the player while not in a raid
|
|
property "ShowPlayer" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("showPlayer") end,
|
|
set = function(self, value) secureSetAttribute(self.GroupHeader, "showPlayer", value) end,
|
|
type = Boolean,
|
|
}
|
|
|
|
-- Whether the panel should be shown while not in a group
|
|
property "ShowSolo" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("showSolo") end,
|
|
set = function(self, value) secureSetAttribute(self.GroupHeader, "showSolo", value) end,
|
|
type = Boolean,
|
|
}
|
|
|
|
-- A list of raid group numbers, used as the filter settings and order settings(if GroupBy is "GROUP")
|
|
__Set__(PropertySet.Clone)
|
|
property "GroupFilter" {
|
|
handler = function (self, value)
|
|
setupGroupFilter(self)
|
|
if self.GroupBy == "GROUP" then setupGroupingOrder(self) end
|
|
end,
|
|
type = GroupFilter,
|
|
}
|
|
|
|
-- A list of uppercase class names, used as the filter settings and order settings(if GroupBy is "CLASS")
|
|
__Set__(PropertySet.Clone)
|
|
property "ClassFilter" {
|
|
handler = function (self, value)
|
|
setupGroupFilter(self)
|
|
if self.GroupBy == "CLASS" then setupGroupingOrder(self) end
|
|
end,
|
|
type = ClassFilter,
|
|
}
|
|
|
|
-- A list of uppercase role names, used as the filter settings and order settings(if GroupBy is "ROLE")
|
|
__Set__(PropertySet.Clone)
|
|
property "RoleFilter" {
|
|
handler = function (self, value)
|
|
setupRoleFilter(self)
|
|
if self.GroupBy == "ROLE" or self.GroupBy == "ASSIGNEDROLE" then
|
|
setupGroupingOrder(self)
|
|
end
|
|
end,
|
|
type = RoleFilter,
|
|
}
|
|
|
|
-- Specifies a "grouping" type to apply before regular sorting (Default: nil)
|
|
property "GroupBy" {
|
|
handler = function (self, value)
|
|
if value == "NONE" then value = nil end
|
|
secureSetAttribute(self.GroupHeader, "groupBy", value)
|
|
setupGroupingOrder(self)
|
|
end,
|
|
type = GroupType,
|
|
default = "NONE",
|
|
}
|
|
|
|
-- Defines how the group is sorted (Default: "INDEX")
|
|
property "SortBy" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("sortMethod") end,
|
|
set = function(self, value) secureSetAttribute(self.GroupHeader, "sortMethod", value) end,
|
|
type = SortType,
|
|
default = "INDEX",
|
|
}
|
|
|
|
-- The group header based on the blizzard's SecureGroupHeader
|
|
property "GroupHeader" {
|
|
default = function(self)
|
|
return ShadowGroupHeader(self:GetName() .. "ShadowGroupHeader", self, "SecureGroupHeaderTemplate")
|
|
end,
|
|
type = ShadowGroupHeader
|
|
}
|
|
|
|
-- Whether only show the dead players
|
|
property "ShowDeadOnly" {
|
|
get = function(self) return self.GroupHeader.ShowDeadOnly end,
|
|
set = function(self, value) self.GroupHeader.ShowDeadOnly = value end,
|
|
type = Boolean,
|
|
}
|
|
|
|
------------------------------------------------------
|
|
-- Event Handler
|
|
------------------------------------------------------
|
|
local function OnElementAdd(self, element)
|
|
element.UnitWatchEnabled = false
|
|
element:SetAttribute("unit", nil)
|
|
--element:InstantApplyStyle()
|
|
|
|
self.GroupHeader:RegisterUnitFrame(element)
|
|
end
|
|
|
|
------------------------------------------------------
|
|
-- Constructor
|
|
------------------------------------------------------
|
|
function __ctor(self, ...)
|
|
super(self, ...)
|
|
|
|
Next(function(self)
|
|
while true do
|
|
if not self:IsShown() then
|
|
Next(Observable.From(self.OnShow))
|
|
else
|
|
Next(Wow.FromEvent("GROUP_ROSTER_UPDATE"))
|
|
end
|
|
|
|
Delay(0.2) -- Just enough
|
|
NoCombat()
|
|
|
|
if self:IsShown() then
|
|
self.GroupHeader:Refresh()
|
|
end
|
|
end
|
|
end, self)
|
|
|
|
self.OnElementAdd = self.OnElementAdd + OnElementAdd
|
|
setupGroupFilter(self)
|
|
end
|
|
end)
|
|
|
|
__Sealed__()
|
|
class "SecureGroupPetPanel" (function(_ENV)
|
|
inherit "SecureGroupPanel"
|
|
|
|
------------------------------------------------------
|
|
-- Property
|
|
------------------------------------------------------
|
|
|
|
-- if true, then pet names are used when sorting the list
|
|
property "FilterOnPet" {
|
|
get = function(self) return self.GroupHeader:GetAttribute("filterOnPet") or false end,
|
|
set = function(self, value) NoCombat(self.GroupHeader.SetAttribute, self.GroupHeader, "filterOnPet", value) end,
|
|
type = Boolean,
|
|
}
|
|
|
|
property "GroupHeader" {
|
|
default = function(self)
|
|
return SecureGroupPanel.ShadowGroupHeader(self:GetName() .. "ShadowGroupHeader", self, "SecureGroupPetHeaderTemplate")
|
|
end,
|
|
}
|
|
end)
|
|
|
|
-----------------------------------------------------------
|
|
-- Default Style --
|
|
-----------------------------------------------------------
|
|
Style.UpdateSkin("Default", {
|
|
[SecureGroupPanel] = {
|
|
rowCount = _G.MEMBERS_PER_RAID_GROUP or 5,
|
|
columnCount = _G.NUM_RAID_GROUPS or 8,
|
|
|
|
autoHide = CLEAR,
|
|
|
|
elementWidth = 80,
|
|
elementHeight = 32,
|
|
orientation = "VERTICAL",
|
|
leftToRight = true,
|
|
topToBottom = true,
|
|
hSpacing = 2,
|
|
vSpacing = 2,
|
|
|
|
marginTop = 0,
|
|
marginBottom = 0,
|
|
marginLeft = 0,
|
|
marginRight = 0,
|
|
|
|
showRaid = true,
|
|
showParty = true,
|
|
showSolo = true,
|
|
showPlayer = true,
|
|
},
|
|
[SecureGroupPetPanel] = {
|
|
showRaid = false,
|
|
showParty = true,
|
|
showSolo = true,
|
|
showPlayer = true,
|
|
},
|
|
})
|
|
|