Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,10 @@ DF.PartyDefaults = {
"WARLOCK",
"WARRIOR",
},

-- Sorting
sortEnabled = true,
sortByPartyOrder = false, -- keep units in their original party/raid index order
sortRoleOrder = {"TANK", "HEALER", "MELEE", "RANGED"},
sortSelfPosition = "SORTED",
sortSeparateMeleeRanged = false,
Expand Down Expand Up @@ -2848,7 +2851,10 @@ DF.RaidDefaults = {
"WARLOCK",
"WARRIOR",
},

-- Sorting
sortEnabled = true,
sortByPartyOrder = false, -- keep units in their original party/raid index order
sortRoleOrder = {"TANK", "HEALER", "MELEE", "RANGED"},
sortSelfPosition = "SORTED",
sortSeparateMeleeRanged = false,
Expand Down
1 change: 1 addition & 0 deletions ExportCategories.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ DF.ExportCategories = {

-- Sorting
"sortEnabled",
"sortByPartyOrder",
"sortAlphabetical",
"sortByClass",
"sortClassOrder",
Expand Down
6 changes: 5 additions & 1 deletion Features/FlatRaidFrames.lua
Original file line number Diff line number Diff line change
Expand Up @@ -883,12 +883,16 @@ function FlatRaidFrames:UpdateSorting()

-- Check sorting settings
local sortEnabled = db.sortEnabled
-- party/raid index option overrides all other custom sorting
if db.sortByPartyOrder then
sortEnabled = false
end
local selfPosition = db.sortSelfPosition or "SORTED"
local separateMeleeRanged = db.sortSeparateMeleeRanged
local sortByClass = db.sortByClass
local sortAlphabetical = db.sortAlphabetical

DebugPrint("UpdateSorting: sortEnabled=", sortEnabled, "selfPosition=", selfPosition)
DebugPrint("UpdateSorting: sortEnabled=", sortEnabled, "selfPosition=", selfPosition, "partyOrder=", tostring(db.sortByPartyOrder))
DebugPrint(" separateMeleeRanged=", separateMeleeRanged, "sortByClass=", sortByClass, "sortAlphabetical=", sortAlphabetical)

-- CRITICAL: Handle sortEnabled=false first
Expand Down
36 changes: 30 additions & 6 deletions Features/SecureSort.lua
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,20 @@ function SecureSort:CreateHandler()
-- STEP 2: Get sort settings
-- =====================================================
local sortEnabled = self:GetAttribute("sortEnabled")
local sortByPartyOrder = self:GetAttribute("sortByPartyOrder") or false
local partyOrderSort = sortByPartyOrder
local selfPosition = self:GetAttribute("selfPosition") or "NORMAL"
local sortAlphabetical = self:GetAttribute("sortAlphabetical") or false
local sortAlphaReverse = (sortAlphabetical == "ZA")
local sortByClass = self:GetAttribute("sortByClass") or false

if sortByPartyOrder then
-- ignore other criteria when using raw party order
sortEnabled = false
sortAlphabetical = false
sortByClass = false
end

-- =====================================================
-- STEP 3: Query roles (if sorting enabled)
-- =====================================================
Expand Down Expand Up @@ -700,11 +709,23 @@ function SecureSort:CreateHandler()
for idx = 0, frameCount - 1 do
local i = visibleFrames[idx]
local unit = frameUnits[i]
local role = unit2role[unit] or "DAMAGER"
local rp = rolePriority[role] or 99
local cls = unit2class[unit]
local cp = sortByClass and (classPriority[cls] or 99) or 0
frameSortKey[idx] = rp * 100 + cp
if partyOrderSort then
-- When using "party/raid index order", we want to KEEP the
-- existing visual order of the frames and only apply the
-- selfPosition override (player first/last/numeric slot).
--
-- The existing order is exactly the order of visibleFrames,
-- so we just use the current index as the sort key. This
-- guarantees non-player units stay in their current order,
-- matching the behavior when sorting is disabled.
frameSortKey[idx] = idx
else
local role = unit2role[unit] or "DAMAGER"
local rp = rolePriority[role] or 99
local cls = unit2class[unit]
local cp = sortByClass and (classPriority[cls] or 99) or 0
frameSortKey[idx] = rp * 100 + cp
end

-- Read name from attribute (pushed by Lua code)
frameName[idx] = self:GetAttribute("frameName" .. i) or ""
Expand All @@ -720,7 +741,7 @@ function SecureSort:CreateHandler()
end

-- Bubble sort by sort key, then by name as tiebreaker
if sortEnabled then
if sortEnabled or partyOrderSort then
for i = 0, frameCount - 2 do
for j = 0, frameCount - 2 - i do
local a = sortOrder[j]
Expand Down Expand Up @@ -2023,6 +2044,7 @@ function SecureSort:PushSortSettings()
self.sortButton:SetAttribute("roleOrder3", roleOrder[3] or "DAMAGER")
self.sortButton:SetAttribute("selfPosition", db.sortSelfPosition or "SORTED")
self.sortButton:SetAttribute("sortEnabled", db.sortEnabled or false)
self.sortButton:SetAttribute("sortByPartyOrder", db.sortByPartyOrder or false)
self.sortButton:SetAttribute("sortByClass", db.sortByClass or false)
self.sortButton:SetAttribute("meleeBeforeRanged", meleeBeforeRanged)
self.sortButton:SetAttribute("sortAlphabetical", db.sortAlphabetical or false)
Expand All @@ -2034,6 +2056,7 @@ function SecureSort:PushSortSettings()
self.handler:SetAttribute("roleOrder3", roleOrder[3] or "DAMAGER")
self.handler:SetAttribute("selfPosition", db.sortSelfPosition or "SORTED")
self.handler:SetAttribute("sortEnabled", db.sortEnabled or false)
self.handler:SetAttribute("sortByPartyOrder", db.sortByPartyOrder or false)
self.handler:SetAttribute("sortByClass", db.sortByClass or false)
self.handler:SetAttribute("meleeBeforeRanged", meleeBeforeRanged)
self.handler:SetAttribute("sortAlphabetical", db.sortAlphabetical or false)
Expand Down Expand Up @@ -2063,6 +2086,7 @@ function SecureSort:PushSortSettings()
DebugPrint("Sort settings pushed: " ..
(roleOrder[1] or "?") .. ">" .. (roleOrder[2] or "?") .. ">" .. (roleOrder[3] or "?") ..
" self=" .. (db.sortSelfPosition or "SORTED") ..
" partyOrder=" .. tostring(db.sortByPartyOrder) ..
" class=" .. tostring(db.sortByClass or false) ..
" alpha=" .. tostring(db.sortAlphabetical or false))

Expand Down
38 changes: 38 additions & 0 deletions Features/Sort.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ local addonName, DF = ...
local pairs, ipairs, type, wipe = pairs, ipairs, type, wipe
local sort = table.sort
local tinsert = table.insert

local UnitExists = UnitExists
local UnitGUID = UnitGUID
local UnitGroupRolesAssigned = UnitGroupRolesAssigned
local UnitClass = UnitClass
local UnitIsUnit = UnitIsUnit
local UnitName = UnitName
local GetSpecializationInfoByID = GetSpecializationInfoByID
local GetSpecialization = GetSpecialization
local InCombatLockdown = InCombatLockdown

-- NOTE: Previously used reusable tables here, but that caused bugs when
-- SortFrameList was called while iterating over a previous result.
Expand Down Expand Up @@ -157,6 +162,31 @@ end

-- Compare function for sorting frames
function Sort:CompareUnits(unitA, unitB, db)
-- Option to ignore role/class/name and simply use party/raid index
if db.sortByPartyOrder then
local function GetIndex(u)
if not u then return 9999 end
if UnitIsUnit(u, "player") then return 0 end

-- Prefer a GUID->party slot lookup so the "index order" matches the actual party roster
-- even if the unit-id on a frame isn't literally "partyN" (e.g. raidN assignment).
local guid = UnitGUID(u)
if guid then
for i = 1, 4 do
local pu = "party" .. i
if UnitExists(pu) and UnitGUID(pu) == guid then
return i
end
end
end

-- Fallback: parse digits from the unit string (party1/raid1/etc)
local num = tonumber((u:match("%d+")))
return num or 9999
end
return GetIndex(unitA) < GetIndex(unitB)
end

local roleA = self:GetUnitRole(unitA)
local roleB = self:GetUnitRole(unitB)

Expand Down Expand Up @@ -199,6 +229,13 @@ end

-- Compare function for test mode using test data
function Sort:CompareTestData(dataA, dataB, db)
-- If party-order sorting is requested, use the precomputed index
if db.sortByPartyOrder then
local idxA = dataA.index or 9999
local idxB = dataB.index or 9999
return idxA < idxB
end

-- Get roles from test data
local roleA = dataA.role or "DAMAGER"
local roleB = dataB.role or "DAMAGER"
Expand Down Expand Up @@ -424,6 +461,7 @@ SlashCmdList["DFSORT"] = function(msg)
print(" sortByClass:", db.sortByClass)
print(" sortAlphabetical:", tostring(db.sortAlphabetical))
print(" sortSeparateMeleeRanged:", db.sortSeparateMeleeRanged)
print(" sortByPartyOrder:", tostring(db.sortByPartyOrder))
print(" sortRoleOrder:", table.concat(db.sortRoleOrder or {}, ", "))
if db.sortByClass then
print(" sortClassOrder:", table.concat(db.sortClassOrder or {}, ", "))
Expand Down
83 changes: 74 additions & 9 deletions Frames/Headers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3928,6 +3928,7 @@ function DF:ApplyRaidGroupSorting()
end

-- Determine if we need nameList for advanced sorting
-- Party order option disables custom sorting entirely (sortEnabled=false above)
-- Use nameList for ALL groups when:
-- - Player position is FIRST/LAST (player's group only)
-- - OR any advanced option is enabled (all groups need it)
Expand Down Expand Up @@ -4323,19 +4324,78 @@ function DF:BuildRaidGroupNameList(groupIndex, selfPosition)
return DF:BuildSortedNameList(members, DF:GetRaidDB(), selfPosition, playerInGroup)
end

-- Build a namelist for party that puts player first or last, sorted by role priority
-- Build a nameList for party, honoring sortByPartyOrder and selfPosition
function DF:BuildPartyNameList(selfPosition)
-- Get members in party (player + party1-4)
local members = {}
local db = DF:GetDB()
local playerName = UnitName("player")


if db.sortByPartyOrder then
local names = {}

local partyNames = {}
for i = 1, 4 do
local unit = "party" .. i
if UnitExists(unit) and not UnitIsUnit(unit, "player") then
local name, realm = UnitName(unit)
if name then
local fullName = name
if realm and realm ~= "" then
fullName = name .. "-" .. realm
end
table.insert(partyNames, fullName)
end
end
end

local targetPos
if selfPosition == "FIRST" or selfPosition == "1" then
targetPos = 1
elseif selfPosition == "LAST" then
targetPos = #partyNames + 1
else
local n = tonumber(selfPosition)
if n and n >= 1 then
if n > (#partyNames + 1) then n = #partyNames + 1 end
targetPos = n
else
targetPos = nil
end
end

if targetPos then
local inserted = false
for i = 1, #partyNames + 1 do
if i == targetPos then
table.insert(names, playerName)
inserted = true
end
if i <= #partyNames then
table.insert(names, partyNames[i])
end
end
if not inserted then
table.insert(names, playerName)
end
else
table.insert(names, playerName)
for _, n in ipairs(partyNames) do
table.insert(names, n)
end
end

return table.concat(names, ",")
end

-- Default path: role/class/name sorting via unified function
local members = {}

-- Add player
table.insert(members, {
unit = "player",
name = playerName,
isPlayer = true
})

-- Add party members
for i = 1, 4 do
local unit = "party" .. i
Expand All @@ -4355,8 +4415,7 @@ function DF:BuildPartyNameList(selfPosition)
end
end

-- Use the unified sorting function
return DF:BuildSortedNameList(members, DF:GetDB(), selfPosition, true)
return DF:BuildSortedNameList(members, db, selfPosition, true)
end

-- ============================================================
Expand Down Expand Up @@ -5750,8 +5809,12 @@ function DF:ApplyPartyGroupSorting()
local sortByClass = db.sortByClass
local sortAlphabetical = db.sortAlphabetical

-- Determine if we need nameList (any advanced option or FIRST/LAST)
local needsNameList = (selfPosition ~= "SORTED") or separateMeleeRanged or sortByClass or sortAlphabetical
-- Determine if we need nameList (any advanced option, FIRST/LAST, or party-index mode)
local needsNameList = db.sortByPartyOrder
or (selfPosition ~= "SORTED")
or separateMeleeRanged
or sortByClass
or sortAlphabetical

if DF.debugHeaders then
print("|cFF00FF00[DF Headers]|r ApplyPartyGroupSorting:")
Expand Down Expand Up @@ -6780,10 +6843,12 @@ function DF:DumpHeaderInfo()
print(" growthAnchor:", db.growthAnchor or "nil")
print(" sortSelfPosition:", db.sortSelfPosition or "nil")
print(" sortEnabled:", db.sortEnabled and "true" or "false")
print(" sortByPartyOrder:", db.sortByPartyOrder and "true" or "false")
print("Raid Settings:")
print(" raidUseGroups:", raidDb.raidUseGroups and "true" or "false")
print(" raidEnabled:", raidDb.raidEnabled and "true" or "false")
print(" sortEnabled:", raidDb.sortEnabled and "true" or "false")
print(" sortByPartyOrder:", raidDb.sortByPartyOrder and "true" or "false")
print(" sortSelfPosition:", raidDb.sortSelfPosition or "nil")
print(" sortSeparateMeleeRanged:", raidDb.sortSeparateMeleeRanged and "true" or "false")
print(" sortByClass:", raidDb.sortByClass and "true" or "false")
Expand Down
Loading