visual

torsten.philipp [03-30-18 - 16:45]
visual
Filename
TaosGroupTools/ui/groupultimate/CompactSwimlaneList.lua
TaosGroupTools/ui/groupultimate/CompactSwimlaneList.xml
TaosGroupTools/ui/groupultimate/GroupUltimateSelector.lua
TaosGroupTools/ui/groupultimate/GroupUltimateSelector.xml
TaosGroupTools/ui/groupultimate/SimpleList.lua
TaosGroupTools/ui/groupultimate/SimpleList.xml
TaosGroupTools/ui/groupultimate/SwimlaneList.lua
TaosGroupTools/ui/groupultimate/SwimlaneList.xml
TaosGroupTools/ui/groupultimate/UltimateGroupMenu.lua
TaosGroupTools/util/GroupHelper.lua
diff --git a/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.lua b/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.lua
index 0f6c27f..1d59e69 100644
--- a/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.lua
+++ b/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.lua
@@ -1,500 +1,500 @@
---[[
-	Addon: Taos Group Tools
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
---[[
-	Local variables
-]]--
-local LOG_ACTIVE = false
-
-local SWIMLANES = 6
-local ROWS = 6
-local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
-local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
-
-local _logger = nil
-local _control = nil
-
---[[
-	Table CompactSwimlaneList
-]]--
-TGT_CompactSwimlaneList = {}
-TGT_CompactSwimlaneList.__index = TGT_CompactSwimlaneList
-
---[[
-	Table Members
-]]--
-TGT_CompactSwimlaneList.Name = "TGT-CompactSwimlaneList"
-TGT_CompactSwimlaneList.IsMocked = false
-TGT_CompactSwimlaneList.Swimlanes = {}
-
---[[
-	Sets visibility of labels
-]]--
-function TGT_CompactSwimlaneList.RefreshList()
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.RefreshList") end
-
-    -- Check all swimlanes
-    for i,swimlane in ipairs(TGT_CompactSwimlaneList.Swimlanes) do
-        TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlane)
-	end
-end
-
---[[
-	Sorts swimlane
-]]--
-function TGT_CompactSwimlaneList.SortSwimlane(swimlane)
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.SortSwimlane") end
-
-    -- Comparer
-    function compare(playerLeft, playerRight)
-        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
-            return playerLeft.PingTag < playerRight.PingTag
-        else
-            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
-        end
-    end
-
-    table.sort(swimlane.Players, compare)
-
-    -- Sort by name
-
-    -- Update sorted swimlane list
-    for i,swimlanePlayer in ipairs(swimlane.Players) do
-        TGT_CompactSwimlaneList.UpdateListRow(swimlane.SwimlaneControl:GetNamedChild("Row" .. i), swimlanePlayer)
-    end
-end
-
---[[
-	Updates list row
-]]--
-function TGT_CompactSwimlaneList.UpdateListRow(row, player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.UpdateListRow")
-    end
-
-    local playerName = player.PlayerName
-    local nameLength = string.len(playerName)
-
-    if (nameLength > 6) then
-        playerName = string.sub(playerName, 0, 5) .. ".."
-    end
-
-    row:GetNamedChild("SenderNameValueLabel"):SetText(playerName)
-    row:GetNamedChild("RelativeUltimateStatusBar"):SetValue(player.RelativeUltimate)
-
-	if (player.IsPlayerDead) then
-        -- Dead Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(0.5, 0.5, 0.5, 0.8)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.8, 0.03, 0.03, 0.7)
-    elseif (player.RelativeUltimate == 100) then
-		-- Ready Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 1)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.7, 0.03, 0.7)
-	else
-		-- Inprogress Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 0.8)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.03, 0.7, 0.7)
-	end
-
-    row:SetHidden(false)
-end
-
---[[
-	Updates list row
-]]--
-function TGT_CompactSwimlaneList.UpdatePlayer(player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.UpdatePlayer")
-    end
-
-	if (player) then
-        local swimLane = TGT_CompactSwimlaneList.GetSwimLane(player.UltimateGroup.GroupAbilityId)
-
-        if (swimLane) then
-            local row = TGT_CompactSwimlaneList.GetSwimLaneRow(swimLane, player.PlayerName)
-
-            -- Update timestamp
-            if (row ~= nil) then
-                for i,swimlanePlayer in ipairs(swimLane.Players) do
-		            if (swimlanePlayer.PlayerName == player.PlayerName) then
-                        swimlanePlayer.LastMapPingTimestamp = GetTimeStamp()
-                        swimlanePlayer.IsPlayerDead = player.IsPlayerDead
-                        swimlanePlayer.RelativeUltimate = player.RelativeUltimate
-                        break
-                    end
-	            end
-            else
-                -- Add new player
-                local nextFreeRow = 1
-
-                for i,player in ipairs(swimLane.Players) do
-		            nextFreeRow = nextFreeRow + 1
-	            end
-
-                if (nextFreeRow <= ROWS) then
-                    if (LOG_ACTIVE) then
-                        _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
-                    end
-
-                    player.LastMapPingTimestamp = GetTimeStamp()
-                    swimLane.Players[nextFreeRow] = player
-                    row = swimLane.SwimlaneControl:GetNamedChild("Row" .. nextFreeRow)
-                else
-                    if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, too much players for one swimlane " .. tostring(nextFreeRow)) end
-                end
-            end
-
-            -- Only update if player in a row
-            if (row ~= nil) then
-                if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
-                    -- Sort swimlane with all players
-                    TGT_CompactSwimlaneList.SortSwimlane(swimLane)
-                else
-                    -- Directly update row with player
-                    TGT_CompactSwimlaneList.UpdateListRow(row, player)
-                end
-            end
-        else
-            if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, swimlane not found for ultimategroup " .. tostring(ultimateGroup.GroupName)) end
-        end
-	end
-end
-
---[[
-	Get swimlane from current SwimLanes
-]]--
-function TGT_CompactSwimlaneList.GetSwimLane(ultimateGroupId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.GetSwimLane")
-        _logger:logDebug("ultimateGroupId", ultimateGroupId)
-    end
-
-    if (ultimateGroupId ~= 0) then
-        for i,swimLane in ipairs(TGT_CompactSwimlaneList.Swimlanes) do
-		    if (swimLane.UltimateGroupId == ultimateGroupId) then
-                return swimLane
-            end
-	    end
-
-        if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.GetSwimLane, swimLane not found " .. tostring(ultimateGroupId)) end
-        return nil
-    else
-        _logger:logError("TGT_CompactSwimlaneList.GetSwimLane, ultimateGroupId is 0")
-        return nil
-    end
-end
-
---[[
-	Get Player Row from current players in swimlane
-]]--
-function TGT_CompactSwimlaneList.GetSwimLaneRow(swimLane, playerName)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.GetSwimLaneRow")
-        _logger:logDebug("swimLane ID", swimLane.Id)
-    end
-
-    if (swimLane) then
-        for i,player in ipairs(swimLane.Players) do
-            if (LOG_ACTIVE) then _logger:logDebug(player.PlayerName .. " == " .. playerName) end
-		    if (player.PlayerName == playerName) then
-                return swimLane.SwimlaneControl:GetNamedChild("Row" .. i)
-            end
-	    end
-
-        if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.GetSwimLane, player not found " .. tostring(playerName)) end
-        return nil
-    else
-        _logger:logError("TGT_CompactSwimlaneList.GetSwimLane, swimLane is nil")
-        return nil
-    end
-end
-
---[[
-	Clears all players in swimlane
-]]--
-function TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlane)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.ClearPlayersFromSwimlane")
-        _logger:logDebug("swimlane ID", swimlane.Id)
-    end
-
-    if (swimlane) then
-        for i=1, ROWS, 1 do
-            local row = swimlane.SwimlaneControl:GetNamedChild("Row" .. i)
-            local swimlanePlayer = swimlane.Players[i]
-
-            if (swimlanePlayer ~= nil) then
-                local isPlayerNotGrouped = IsUnitGrouped(swimlanePlayer.PingTag) == false
-
-                if (TGT_CompactSwimlaneList.IsMocked) then
-                    isPlayerNotGrouped = false
-                end
-
-                local isPlayerTimedOut = (GetTimeStamp() - swimlanePlayer.LastMapPingTimestamp) > TIMEOUT
-                local isPlayerUltimateNotCorrect = swimlane.UltimateGroupId ~= swimlanePlayer.UltimateGroup.GroupAbilityId
-
-                if (isPlayerNotGrouped or isPlayerTimedOut or isPlayerUltimateNotCorrect) then
-                    if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
-
-                    row:SetHidden(true)
-                    table.remove(swimlane.Players, i)
-                end
-            else
-                if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
-
-                row:SetHidden(true)
-            end
-        end
-    end
-end
-
---[[
-	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
-]]--
-function TGT_CompactSwimlaneList.SetControlMovable(isMovable)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.SetControlMovable")
-        _logger:logDebug("isMovable", isMovable)
-    end
-
-    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
-
-    _control:SetMovable(isMovable)
-	_control:SetMouseEnabled(isMovable)
-end
-
---[[
-	RestorePosition sets TGT_CompactSwimlaneList on settings position
-]]--
-function TGT_CompactSwimlaneList.RestorePosition(posX, posY)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.RestorePosition")
-        _logger:logDebug("posX, posY", posX, posY)
-    end
-
-	_control:ClearAnchors()
-	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
-end
-
---[[
-	OnTGT_CompactSwimlaneListMoveStop saves current TGT_CompactSwimlaneList position to settings
-]]--
-function TGT_CompactSwimlaneList.OnCompactSwimlaneListMoveStop()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.OnCompactSwimlaneListMoveStop") end
-
-	local left = _control:GetLeft()
-	local top = _control:GetTop()
-
-    TGT_SettingsHandler.SavedVariables.PosX = left
-    TGT_SettingsHandler.SavedVariables.PosY = top
-
-    if (LOG_ACTIVE) then
-        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-    end
-end
-
---[[
-	SetControlHidden sets hidden on control
-]]--
-function TGT_CompactSwimlaneList.SetControlHidden(isHidden)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.SetControlHidden")
-        _logger:logDebug("isHidden", isHidden)
-    end
-
-    if (GetIsUnitGrouped()) then
-        _control:SetHidden(isHidden)
-    else
-        _control:SetHidden(true)
-    end
-end
-
---[[
-	SetControlActive sets hidden on control
-]]--
-function TGT_CompactSwimlaneList.SetControlActive()
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.SetControlActive")
-    end
-
-    local isHidden = TGT_SettingsHandler.IsCompactSwimlaneListVisible() == false
-    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
-
-    TGT_CompactSwimlaneList.SetControlHidden(isHidden or CurrentHudHiddenState())
-
-    if (isHidden) then
-        -- Start timeout timer
-	    EVENT_MANAGER:UnregisterForUpdate(TGT_CompactSwimlaneList.Name)
-
-        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_CompactSwimlaneList.RefreshList)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_CompactSwimlaneList.UpdatePlayer)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_CompactSwimlaneList.SetControlMovable)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_CompactSwimlaneList.SetSwimlaneUltimate)
-        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_CompactSwimlaneList.SetControlHidden)
-
-        -- Invis
-        TGT_CompactSwimlaneList.SetControlHidden(isHidden)
-    else
-        TGT_CompactSwimlaneList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
-        TGT_CompactSwimlaneList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-
-        -- Start timeout timer
-	    EVENT_MANAGER:RegisterForUpdate(TGT_CompactSwimlaneList.Name, REFRESHRATE, TGT_CompactSwimlaneList.RefreshList)
-
-        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_CompactSwimlaneList.RefreshList)
-        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_CompactSwimlaneList.UpdatePlayer)
-        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_CompactSwimlaneList.SetControlMovable)
-        CALLBACK_MANAGER:RegisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_CompactSwimlaneList.SetSwimlaneUltimate)
-        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_CompactSwimlaneList.SetControlHidden)
-    end
-end
-
---[[
-	OnSwimlaneHeaderClicked called on header clicked
-]]--
-function TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked(button, swimlaneId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked")
-        _logger:logDebug("swimlaneId", swimlaneId)
-    end
-
-    if (button ~= nil) then
-        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_CompactSwimlaneList.OnSetUltimateGroup)
-        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button, swimlaneId)
-    else
-        _logger:logError("TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked, button nil")
-    end
-end
-
---[[
-	OnSetUltimateGroup called on header clicked
-]]--
-function TGT_CompactSwimlaneList.OnSetUltimateGroup(group, swimlaneId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.OnSetUltimateGroup")
-        _logger:logDebug("group.GroupName, swimlaneId", group.GroupName, swimlaneId)
-    end
-
-    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_CompactSwimlaneList.OnSetUltimateGroup)
-
-    if (group ~= nil and swimlaneId ~= nil and swimlaneId >= 1 and swimlaneId <= 6) then
-        TGT_SettingsHandler.SetSwimlaneUltimateGroupIdSettings(swimlaneId, group)
-    else
-        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil or swimlaneId invalid")
-    end
-end
-
---[[
-	SetSwimlaneUltimate sets the swimlane header icon in base of ultimateGroupId
-]]--
-function TGT_CompactSwimlaneList.SetSwimlaneUltimate(swimlaneId, ultimateGroup)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_CompactSwimlaneList.SetSwimlaneUltimate")
-        _logger:logDebug("ultimateGroup.GroupName, swimlaneId", ultimateGroup.GroupName, swimlaneId)
-    end
-
-    local swimlaneObject = TGT_CompactSwimlaneList.Swimlanes[swimlaneId]
-    local iconControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
-
-    if (ultimateGroup ~= nil and iconControl ~= nil) then
-        iconControl:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
-
-        swimlaneObject.UltimateGroupId = ultimateGroup.GroupAbilityId
-        TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlaneObject)
-    else
-        _logger:logError("TGT_CompactSwimlaneList.SetSwimlaneUltimateIcon, icon is " .. tostring(icon) .. ";" .. tostring(iconControl) .. ";" .. tostring(ultimateGroup))
-    end
-end
-
---[[
-	CreateCompactSwimlaneListHeaders creates swimlane list headers
-]]--
-function TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders") end
-
-	for i=1, SWIMLANES, 1 do
-        local ultimateGroupId = TGT_SettingsHandler.SavedVariables.SwimlaneUltimateGroupIds[i]
-        local ultimateGroup = TGT_UltimateGroupHandler.GetUltimateGroupByAbilityId(ultimateGroupId)
-
-        local swimlaneControlName = "Swimlane" .. tostring(i)
-        local swimlaneControl = _control:GetNamedChild(swimlaneControlName)
-
-        -- Add button
-        local button = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
-        button:SetHandler("OnClicked", function() TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked(button, i) end)
-
-        local swimLane = {}
-        swimLane.Id = i
-        swimLane.SwimlaneControl = swimlaneControl
-        swimLane.Players = {}
-
-        if (ultimateGroup ~= nil) then
-            if (LOG_ACTIVE) then
-                _logger:logDebug("Create Swimlane", i)
-                _logger:logDebug("ultimateGroup.GroupName", ultimateGroup.GroupName)
-                _logger:logDebug("swimlaneControlName", swimlaneControlName)
-            end
-
-            local icon = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
-            icon:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
-
-            swimLane.UltimateGroupId = ultimateGroup.GroupAbilityId
-        else
-            _logger:logError("TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders, ultimateGroup nil.")
-        end
-
-        TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows(swimlaneControl)
-	    TGT_CompactSwimlaneList.Swimlanes[i] = swimLane
-	end
-end
-
---[[
-	CreateCompactSwimlaneListRows creates swimlane lsit rows
-]]--
-function TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows(swimlaneControl)
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows") end
-
-    if (swimlaneControl ~= nil) then
-	    for i=1, ROWS, 1 do
-		    local row = CreateControlFromVirtual("$(parent)Row", swimlaneControl, "CompactGroupUltimateSwimlaneRow", i)
-            if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
-
-		    row:SetHidden(true) -- initial not visible
-
-		    if (i == 1) then
-                row:SetAnchor(TOPLEFT, swimlaneControl, TOPLEFT, 0, 50)
-            elseif (i == 5) then -- Fix pixelbug, Why the hell ZOS?!
-                row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, 0)
-            else
-				row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, -1)
-			end
-
-		    lastRow = row
-	    end
-    else
-        _logger:logError("TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows, swimlaneControl nil.")
-    end
-end
-
---[[
-	Initialize initializes TGT_CompactSwimlaneList
-]]--
-function TGT_CompactSwimlaneList.Initialize(logger, isMocked)
-    if (LOG_ACTIVE) then
-        logger:logTrace("TGT_CompactSwimlaneList.Initialize")
-    end
-
-    _logger = logger
-    _control = TGT_CompactSwimlaneListControl
-
-    TGT_CompactSwimlaneList.IsMocked = isMocked
-
-    TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders()
-
-    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
+--[[
+	Addon: Taos Group Tools
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+--[[
+	Local variables
+]]--
+local LOG_ACTIVE = false
+
+local SWIMLANES = 6
+local ROWS = 6
+local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
+local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
+
+local _logger = nil
+local _control = nil
+
+--[[
+	Table CompactSwimlaneList
+]]--
+TGT_CompactSwimlaneList = {}
+TGT_CompactSwimlaneList.__index = TGT_CompactSwimlaneList
+
+--[[
+	Table Members
+]]--
+TGT_CompactSwimlaneList.Name = "TGT-CompactSwimlaneList"
+TGT_CompactSwimlaneList.IsMocked = false
+TGT_CompactSwimlaneList.Swimlanes = {}
+
+--[[
+	Sets visibility of labels
+]]--
+function TGT_CompactSwimlaneList.RefreshList()
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.RefreshList") end
+
+    -- Check all swimlanes
+    for i,swimlane in ipairs(TGT_CompactSwimlaneList.Swimlanes) do
+        TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlane)
+	end
+end
+
+--[[
+	Sorts swimlane
+]]--
+function TGT_CompactSwimlaneList.SortSwimlane(swimlane)
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.SortSwimlane") end
+
+    -- Comparer
+    function compare(playerLeft, playerRight)
+        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
+            return playerLeft.PingTag < playerRight.PingTag
+        else
+            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
+        end
+    end
+
+    table.sort(swimlane.Players, compare)
+
+    -- Sort by name
+
+    -- Update sorted swimlane list
+    for i,swimlanePlayer in ipairs(swimlane.Players) do
+        TGT_CompactSwimlaneList.UpdateListRow(swimlane.SwimlaneControl:GetNamedChild("Row" .. i), swimlanePlayer)
+    end
+end
+
+--[[
+	Updates list row
+]]--
+function TGT_CompactSwimlaneList.UpdateListRow(row, player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.UpdateListRow")
+    end
+
+    local playerName = player.PlayerName
+    local nameLength = string.len(playerName)
+
+    if (nameLength > 6) then
+        playerName = string.sub(playerName, 0, 5) .. ".."
+    end
+
+    row:GetNamedChild("SenderNameValueLabel"):SetText(playerName)
+    row:GetNamedChild("RelativeUltimateStatusBar"):SetValue(player.RelativeUltimate)
+
+	if (player.IsPlayerDead) then
+        -- Dead Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(0.5, 0.5, 0.5, 0.8)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.8, 0.03, 0.03, 0.7)
+    elseif (player.RelativeUltimate == 100) then
+		-- Ready Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 1)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.7, 0.03, 0.7)
+	else
+		-- Inprogress Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 0.8)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.03, 0.7, 0.7)
+	end
+
+    row:SetHidden(false)
+end
+
+--[[
+	Updates list row
+]]--
+function TGT_CompactSwimlaneList.UpdatePlayer(player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.UpdatePlayer")
+    end
+
+	if (player) then
+        local swimLane = TGT_CompactSwimlaneList.GetSwimLane(player.UltimateGroup.GroupAbilityId)
+
+        if (swimLane) then
+            local row = TGT_CompactSwimlaneList.GetSwimLaneRow(swimLane, player.PlayerName)
+
+            -- Update timestamp
+            if (row ~= nil) then
+                for i,swimlanePlayer in ipairs(swimLane.Players) do
+		            if (swimlanePlayer.PlayerName == player.PlayerName) then
+                        swimlanePlayer.LastMapPingTimestamp = GetTimeStamp()
+                        swimlanePlayer.IsPlayerDead = player.IsPlayerDead
+                        swimlanePlayer.RelativeUltimate = player.RelativeUltimate
+                        break
+                    end
+	            end
+            else
+                -- Add new player
+                local nextFreeRow = 1
+
+                for i,player in ipairs(swimLane.Players) do
+		            nextFreeRow = nextFreeRow + 1
+	            end
+
+                if (nextFreeRow <= ROWS) then
+                    if (LOG_ACTIVE) then
+                        _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
+                    end
+
+                    player.LastMapPingTimestamp = GetTimeStamp()
+                    swimLane.Players[nextFreeRow] = player
+                    row = swimLane.SwimlaneControl:GetNamedChild("Row" .. nextFreeRow)
+                else
+                    if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, too much players for one swimlane " .. tostring(nextFreeRow)) end
+                end
+            end
+
+            -- Only update if player in a row
+            if (row ~= nil) then
+                if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
+                    -- Sort swimlane with all players
+                    TGT_CompactSwimlaneList.SortSwimlane(swimLane)
+                else
+                    -- Directly update row with player
+                    TGT_CompactSwimlaneList.UpdateListRow(row, player)
+                end
+            end
+        else
+            if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.UpdatePlayer, swimlane not found for ultimategroup " .. tostring(ultimateGroup.GroupName)) end
+        end
+	end
+end
+
+--[[
+	Get swimlane from current SwimLanes
+]]--
+function TGT_CompactSwimlaneList.GetSwimLane(ultimateGroupId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.GetSwimLane")
+        _logger:logDebug("ultimateGroupId", ultimateGroupId)
+    end
+
+    if (ultimateGroupId ~= 0) then
+        for i,swimLane in ipairs(TGT_CompactSwimlaneList.Swimlanes) do
+		    if (swimLane.UltimateGroupId == ultimateGroupId) then
+                return swimLane
+            end
+	    end
+
+        if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.GetSwimLane, swimLane not found " .. tostring(ultimateGroupId)) end
+        return nil
+    else
+        _logger:logError("TGT_CompactSwimlaneList.GetSwimLane, ultimateGroupId is 0")
+        return nil
+    end
+end
+
+--[[
+	Get Player Row from current players in swimlane
+]]--
+function TGT_CompactSwimlaneList.GetSwimLaneRow(swimLane, playerName)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.GetSwimLaneRow")
+        _logger:logDebug("swimLane ID", swimLane.Id)
+    end
+
+    if (swimLane) then
+        for i,player in ipairs(swimLane.Players) do
+            if (LOG_ACTIVE) then _logger:logDebug(player.PlayerName .. " == " .. playerName) end
+		    if (player.PlayerName == playerName) then
+                return swimLane.SwimlaneControl:GetNamedChild("Row" .. i)
+            end
+	    end
+
+        if (LOG_ACTIVE) then _logger:logDebug("TGT_CompactSwimlaneList.GetSwimLane, player not found " .. tostring(playerName)) end
+        return nil
+    else
+        _logger:logError("TGT_CompactSwimlaneList.GetSwimLane, swimLane is nil")
+        return nil
+    end
+end
+
+--[[
+	Clears all players in swimlane
+]]--
+function TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlane)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.ClearPlayersFromSwimlane")
+        _logger:logDebug("swimlane ID", swimlane.Id)
+    end
+
+    if (swimlane) then
+        for i=1, ROWS, 1 do
+            local row = swimlane.SwimlaneControl:GetNamedChild("Row" .. i)
+            local swimlanePlayer = swimlane.Players[i]
+
+            if (swimlanePlayer ~= nil) then
+                local isPlayerNotGrouped = IsUnitGrouped(swimlanePlayer.PingTag) == false
+
+                if (TGT_CompactSwimlaneList.IsMocked) then
+                    isPlayerNotGrouped = false
+                end
+
+                local isPlayerTimedOut = (GetTimeStamp() - swimlanePlayer.LastMapPingTimestamp) > TIMEOUT
+                local isPlayerUltimateNotCorrect = swimlane.UltimateGroupId ~= swimlanePlayer.UltimateGroup.GroupAbilityId
+
+                if (isPlayerNotGrouped or isPlayerTimedOut or isPlayerUltimateNotCorrect) then
+                    if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
+
+                    row:SetHidden(true)
+                    table.remove(swimlane.Players, i)
+                end
+            else
+                if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
+
+                row:SetHidden(true)
+            end
+        end
+    end
+end
+
+--[[
+	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
+]]--
+function TGT_CompactSwimlaneList.SetControlMovable(isMovable)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.SetControlMovable")
+        _logger:logDebug("isMovable", isMovable)
+    end
+
+    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
+
+    _control:SetMovable(isMovable)
+	_control:SetMouseEnabled(isMovable)
+end
+
+--[[
+	RestorePosition sets TGT_CompactSwimlaneList on settings position
+]]--
+function TGT_CompactSwimlaneList.RestorePosition(posX, posY)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.RestorePosition")
+        _logger:logDebug("posX, posY", posX, posY)
+    end
+
+	_control:ClearAnchors()
+	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
+end
+
+--[[
+	OnTGT_CompactSwimlaneListMoveStop saves current TGT_CompactSwimlaneList position to settings
+]]--
+function TGT_CompactSwimlaneList.OnCompactSwimlaneListMoveStop()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.OnCompactSwimlaneListMoveStop") end
+
+	local left = _control:GetLeft()
+	local top = _control:GetTop()
+
+    TGT_SettingsHandler.SavedVariables.PosX = left
+    TGT_SettingsHandler.SavedVariables.PosY = top
+
+    if (LOG_ACTIVE) then
+        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+    end
+end
+
+--[[
+	SetControlHidden sets hidden on control
+]]--
+function TGT_CompactSwimlaneList.SetControlHidden(isHidden)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.SetControlHidden")
+        _logger:logDebug("isHidden", isHidden)
+    end
+
+    if (GetIsUnitGrouped()) then
+        _control:SetHidden(isHidden)
+    else
+        _control:SetHidden(true)
+    end
+end
+
+--[[
+	SetControlActive sets hidden on control
+]]--
+function TGT_CompactSwimlaneList.SetControlActive()
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.SetControlActive")
+    end
+
+    local isHidden = TGT_SettingsHandler.IsCompactSwimlaneListVisible() == false
+    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
+
+    TGT_CompactSwimlaneList.SetControlHidden(isHidden or CurrentHudHiddenState())
+
+    if (isHidden) then
+        -- Start timeout timer
+	    EVENT_MANAGER:UnregisterForUpdate(TGT_CompactSwimlaneList.Name)
+
+        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_CompactSwimlaneList.RefreshList)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_CompactSwimlaneList.UpdatePlayer)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_CompactSwimlaneList.SetControlMovable)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_CompactSwimlaneList.SetSwimlaneUltimate)
+        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_CompactSwimlaneList.SetControlHidden)
+
+        -- Invis
+        TGT_CompactSwimlaneList.SetControlHidden(isHidden)
+    else
+        TGT_CompactSwimlaneList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
+        TGT_CompactSwimlaneList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+
+        -- Start timeout timer
+	    EVENT_MANAGER:RegisterForUpdate(TGT_CompactSwimlaneList.Name, REFRESHRATE, TGT_CompactSwimlaneList.RefreshList)
+
+        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_CompactSwimlaneList.RefreshList)
+        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_CompactSwimlaneList.UpdatePlayer)
+        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_CompactSwimlaneList.SetControlMovable)
+        CALLBACK_MANAGER:RegisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_CompactSwimlaneList.SetSwimlaneUltimate)
+        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_CompactSwimlaneList.SetControlHidden)
+    end
+end
+
+--[[
+	OnSwimlaneHeaderClicked called on header clicked
+]]--
+function TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked(button, swimlaneId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked")
+        _logger:logDebug("swimlaneId", swimlaneId)
+    end
+
+    if (button ~= nil) then
+        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_CompactSwimlaneList.OnSetUltimateGroup)
+        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button, swimlaneId)
+    else
+        _logger:logError("TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked, button nil")
+    end
+end
+
+--[[
+	OnSetUltimateGroup called on header clicked
+]]--
+function TGT_CompactSwimlaneList.OnSetUltimateGroup(group, swimlaneId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.OnSetUltimateGroup")
+        _logger:logDebug("group.GroupName, swimlaneId", group.GroupName, swimlaneId)
+    end
+
+    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_CompactSwimlaneList.OnSetUltimateGroup)
+
+    if (group ~= nil and swimlaneId ~= nil and swimlaneId >= 1 and swimlaneId <= 6) then
+        TGT_SettingsHandler.SetSwimlaneUltimateGroupIdSettings(swimlaneId, group)
+    else
+        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil or swimlaneId invalid")
+    end
+end
+
+--[[
+	SetSwimlaneUltimate sets the swimlane header icon in base of ultimateGroupId
+]]--
+function TGT_CompactSwimlaneList.SetSwimlaneUltimate(swimlaneId, ultimateGroup)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_CompactSwimlaneList.SetSwimlaneUltimate")
+        _logger:logDebug("ultimateGroup.GroupName, swimlaneId", ultimateGroup.GroupName, swimlaneId)
+    end
+
+    local swimlaneObject = TGT_CompactSwimlaneList.Swimlanes[swimlaneId]
+    local iconControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
+
+    if (ultimateGroup ~= nil and iconControl ~= nil) then
+        iconControl:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
+
+        swimlaneObject.UltimateGroupId = ultimateGroup.GroupAbilityId
+        TGT_CompactSwimlaneList.ClearPlayersFromSwimlane(swimlaneObject)
+    else
+        _logger:logError("TGT_CompactSwimlaneList.SetSwimlaneUltimateIcon, icon is " .. tostring(icon) .. ";" .. tostring(iconControl) .. ";" .. tostring(ultimateGroup))
+    end
+end
+
+--[[
+	CreateCompactSwimlaneListHeaders creates swimlane list headers
+]]--
+function TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders") end
+
+	for i=1, SWIMLANES, 1 do
+        local ultimateGroupId = TGT_SettingsHandler.SavedVariables.SwimlaneUltimateGroupIds[i]
+        local ultimateGroup = TGT_UltimateGroupHandler.GetUltimateGroupByAbilityId(ultimateGroupId)
+
+        local swimlaneControlName = "Swimlane" .. tostring(i)
+        local swimlaneControl = _control:GetNamedChild(swimlaneControlName)
+
+        -- Add button
+        local button = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
+        button:SetHandler("OnClicked", function() TGT_CompactSwimlaneList.OnSwimlaneHeaderClicked(button, i) end)
+
+        local swimLane = {}
+        swimLane.Id = i
+        swimLane.SwimlaneControl = swimlaneControl
+        swimLane.Players = {}
+
+        if (ultimateGroup ~= nil) then
+            if (LOG_ACTIVE) then
+                _logger:logDebug("Create Swimlane", i)
+                _logger:logDebug("ultimateGroup.GroupName", ultimateGroup.GroupName)
+                _logger:logDebug("swimlaneControlName", swimlaneControlName)
+            end
+
+            local icon = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
+            icon:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
+
+            swimLane.UltimateGroupId = ultimateGroup.GroupAbilityId
+        else
+            _logger:logError("TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders, ultimateGroup nil.")
+        end
+
+        TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows(swimlaneControl)
+	    TGT_CompactSwimlaneList.Swimlanes[i] = swimLane
+	end
+end
+
+--[[
+	CreateCompactSwimlaneListRows creates swimlane lsit rows
+]]--
+function TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows(swimlaneControl)
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows") end
+
+    if (swimlaneControl ~= nil) then
+	    for i=1, ROWS, 1 do
+		    local row = CreateControlFromVirtual("$(parent)Row", swimlaneControl, "CompactGroupUltimateSwimlaneRow", i)
+            if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
+
+		    row:SetHidden(true) -- initial not visible
+
+		    if (i == 1) then
+                row:SetAnchor(TOPLEFT, swimlaneControl, TOPLEFT, 0, 50)
+            elseif (i == 5) then -- Fix pixelbug, Why the hell ZOS?!
+                row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, 0)
+            else
+				row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, -1)
+			end
+
+		    lastRow = row
+	    end
+    else
+        _logger:logError("TGT_CompactSwimlaneList.CreateCompactSwimlaneListRows, swimlaneControl nil.")
+    end
+end
+
+--[[
+	Initialize initializes TGT_CompactSwimlaneList
+]]--
+function TGT_CompactSwimlaneList.Initialize(logger, isMocked)
+    if (LOG_ACTIVE) then
+        logger:logTrace("TGT_CompactSwimlaneList.Initialize")
+    end
+
+    _logger = logger
+    _control = TGT_CompactSwimlaneListControl
+
+    TGT_CompactSwimlaneList.IsMocked = isMocked
+
+    TGT_CompactSwimlaneList.CreateCompactSwimlaneListHeaders()
+
+    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_CompactSwimlaneList.SetControlActive)
 end
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.xml b/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.xml
index 259c67a..4213f67 100644
--- a/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.xml
+++ b/TaosGroupTools/ui/groupultimate/CompactSwimlaneList.xml
@@ -1,40 +1,40 @@
-<GuiXml>
-	<Controls>
-		<TopLevelControl name="TGT_CompactSwimlaneListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
-			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
-			<Dimensions x="310" y="200" />
-			<OnMoveStop>TGT_CompactSwimlaneList:OnCompactSwimlaneListMoveStop()</OnMoveStop>
-
-			<Controls>
-        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
-          <Anchor point="TOPLEFT"/>
-          <Anchor point="BOTTOMRIGHT" />
-        </Control>
-
-        <Control name="$(parent)Swimlane1" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane2" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="52" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane3" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="104" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane4" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="156" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane5" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="208" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane6" inherits="CompactGroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="260" offsetY="0"/>
-        </Control>
-		  </Controls>
-	  </TopLevelControl>
-	</Controls>
+<GuiXml>
+	<Controls>
+		<TopLevelControl name="TGT_CompactSwimlaneListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
+			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
+			<Dimensions x="310" y="200" />
+			<OnMoveStop>TGT_CompactSwimlaneList:OnCompactSwimlaneListMoveStop()</OnMoveStop>
+
+			<Controls>
+        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
+          <Anchor point="TOPLEFT"/>
+          <Anchor point="BOTTOMRIGHT" />
+        </Control>
+
+        <Control name="$(parent)Swimlane1" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane2" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="52" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane3" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="104" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane4" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="156" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane5" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="208" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane6" inherits="CompactGroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="260" offsetY="0"/>
+        </Control>
+		  </Controls>
+	  </TopLevelControl>
+	</Controls>
 </GuiXml>
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.lua b/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.lua
index ead2c6b..6ca3f9b 100644
--- a/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.lua
+++ b/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.lua
@@ -1,187 +1,187 @@
---[[
-	Addon: Taos Group Tools
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
---[[
-	Local variables
-]]--
-local LOG_ACTIVE = false
-
-local _logger = nil
-local _control = nil
-
---[[
-	Table GroupUltimateSelector
-]]--
-TGT_GroupUltimateSelector = {}
-TGT_GroupUltimateSelector.__index = TGT_GroupUltimateSelector
-
---[[
-	Table Members
-]]--
-
---[[
-	SetUltimateIcon sets the button icon in base of staticUltimateID
-]]--
-function TGT_GroupUltimateSelector.SetUltimateIcon(staticUltimateID)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.SetUltimateIcon")
-        _logger:logDebug("staticUltimateID", staticUltimateID)
-    end
-
-    local icon = "/esoui/art/icons/icon_missing.dds"
-
-    if (staticUltimateID ~= 0) then
-        icon = GetAbilityIcon(staticUltimateID)
-    end
-
-    local iconControl = _control:GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
-
-    if (icon ~= nil and iconControl ~= nil) then
-        iconControl:SetTexture(icon)
-    else
-        _logger:logError("TGT_GroupUltimateSelector.SetUltimateIcon, icon is " .. tostring(icon) .. "; iconControl is " .. tostring(iconControl))
-    end
-end
-
---[[
-	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
-]]--
-function TGT_GroupUltimateSelector.SetControlMovable(isMovable)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.SetControlMovable")
-        _logger:logDebug("isMovable", isMovable)
-    end
-
-    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
-
-    _control:SetMovable(isMovable)
-	_control:SetMouseEnabled(isMovable)
-end
-
---[[
-	RestorePosition sets TGT_GroupUltimateSelector on settings position
-]]--
-function TGT_GroupUltimateSelector.RestorePosition(posX, posY)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.RestorePosition")
-        _logger:logDebug("posX, posY", posX, posY)
-    end
-
-	_control:ClearAnchors()
-	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
-end
-
---[[
-	OnTGT_GroupUltimateSelectorMoveStop saves current TGT_GroupUltimateSelector position to settings
-]]--
-function TGT_GroupUltimateSelector.OnGroupUltimateSelectorMoveStop()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_GroupUltimateSelector.OnGroupUltimateSelectorMoveStop") end
-
-	local left = _control:GetLeft()
-	local top = _control:GetTop()
-
-    TGT_SettingsHandler.SavedVariables.SelectorPosX = left
-    TGT_SettingsHandler.SavedVariables.SelectorPosY = top
-
-    if (LOG_ACTIVE) then
-        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.SelectorPosX, TGT_SettingsHandler.SavedVariables.SelectorPosY)
-    end
-end
-
---[[
-	OnGroupUltimateSelectorClicked shows ultimate group menu
-]]--
-function TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked") end
-
-    local button = _control:GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
-
-    if (button ~= nil) then
-        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_GroupUltimateSelector.OnSetUltimateGroup)
-        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button)
-    else
-        _logger:logError("TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked, button nil")
-    end
-end
-
---[[
-	OnSetUltimateGroup sets ultimate group for button
-]]--
-function TGT_GroupUltimateSelector.OnSetUltimateGroup(group)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.OnSetUltimateGroup")
-        _logger:logDebug("group.GroupName", group.GroupName)
-    end
-
-    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_GroupUltimateSelector.OnSetUltimateGroup)
-
-    if (group ~= nil) then
-        TGT_SettingsHandler.SetStaticUltimateIDSettings(group.GroupAbilityId)
-    else
-        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil")
-    end
-end
-
---[[
-	SetControlHidden sets hidden on control
-]]--
-function TGT_GroupUltimateSelector.SetControlHidden(isHidden)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.SetControlHidden")
-        _logger:logDebug("isHidden", isHidden)
-    end
-
-    if (GetIsUnitGrouped()) then
-        _control:SetHidden(isHidden)
-    else
-        _control:SetHidden(true)
-    end
-end
-
---[[
-	SetControlActive activates/deactivates control
-]]--
-function TGT_GroupUltimateSelector.SetControlActive()
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_GroupUltimateSelector.SetControlActive")
-    end
-
-    local isHidden = TGT_SettingsHandler.IsControlsVisible() == false
-    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
-
-    TGT_GroupUltimateSelector.SetControlHidden(isHidden or CurrentHudHiddenState())
-
-    if (isHidden) then
-        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_GroupUltimateSelector.SetControlMovable)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_STATIC_ULTIMATE_ID_CHANGED, TGT_GroupUltimateSelector.SetUltimateIcon)
-        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_GroupUltimateSelector.SetControlHidden)
-    else
-        TGT_GroupUltimateSelector.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
-        TGT_GroupUltimateSelector.RestorePosition(TGT_SettingsHandler.SavedVariables.SelectorPosX, TGT_SettingsHandler.SavedVariables.SelectorPosY)
-        TGT_GroupUltimateSelector.SetUltimateIcon(TGT_SettingsHandler.SavedVariables.StaticUltimateID)
-
-        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_GroupUltimateSelector.SetControlMovable)
-        CALLBACK_MANAGER:RegisterCallback(TGT_STATIC_ULTIMATE_ID_CHANGED, TGT_GroupUltimateSelector.SetUltimateIcon)
-        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_GroupUltimateSelector.SetControlHidden)
-    end
-end
-
---[[
-	Initialize initializes TGT_GroupUltimateSelector
-]]--
-function TGT_GroupUltimateSelector.Initialize(logger)
-    if (LOG_ACTIVE) then
-        logger:logTrace("TGT_GroupUltimateSelector.Initialize")
-    end
-
-    _logger = logger
-    _control = TGT_UltimateSelectorControl
-
-    TGT_GroupUltimateSelector.SetUltimateIcon(staticUltimateID)
-
-    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_GroupUltimateSelector.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_GroupUltimateSelector.SetControlActive)
+--[[
+	Addon: Taos Group Tools
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+--[[
+	Local variables
+]]--
+local LOG_ACTIVE = false
+
+local _logger = nil
+local _control = nil
+
+--[[
+	Table GroupUltimateSelector
+]]--
+TGT_GroupUltimateSelector = {}
+TGT_GroupUltimateSelector.__index = TGT_GroupUltimateSelector
+
+--[[
+	Table Members
+]]--
+
+--[[
+	SetUltimateIcon sets the button icon in base of staticUltimateID
+]]--
+function TGT_GroupUltimateSelector.SetUltimateIcon(staticUltimateID)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.SetUltimateIcon")
+        _logger:logDebug("staticUltimateID", staticUltimateID)
+    end
+
+    local icon = "/esoui/art/icons/icon_missing.dds"
+
+    if (staticUltimateID ~= 0) then
+        icon = GetAbilityIcon(staticUltimateID)
+    end
+
+    local iconControl = _control:GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
+
+    if (icon ~= nil and iconControl ~= nil) then
+        iconControl:SetTexture(icon)
+    else
+        _logger:logError("TGT_GroupUltimateSelector.SetUltimateIcon, icon is " .. tostring(icon) .. "; iconControl is " .. tostring(iconControl))
+    end
+end
+
+--[[
+	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
+]]--
+function TGT_GroupUltimateSelector.SetControlMovable(isMovable)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.SetControlMovable")
+        _logger:logDebug("isMovable", isMovable)
+    end
+
+    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
+
+    _control:SetMovable(isMovable)
+	_control:SetMouseEnabled(isMovable)
+end
+
+--[[
+	RestorePosition sets TGT_GroupUltimateSelector on settings position
+]]--
+function TGT_GroupUltimateSelector.RestorePosition(posX, posY)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.RestorePosition")
+        _logger:logDebug("posX, posY", posX, posY)
+    end
+
+	_control:ClearAnchors()
+	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
+end
+
+--[[
+	OnTGT_GroupUltimateSelectorMoveStop saves current TGT_GroupUltimateSelector position to settings
+]]--
+function TGT_GroupUltimateSelector.OnGroupUltimateSelectorMoveStop()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_GroupUltimateSelector.OnGroupUltimateSelectorMoveStop") end
+
+	local left = _control:GetLeft()
+	local top = _control:GetTop()
+
+    TGT_SettingsHandler.SavedVariables.SelectorPosX = left
+    TGT_SettingsHandler.SavedVariables.SelectorPosY = top
+
+    if (LOG_ACTIVE) then
+        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.SelectorPosX, TGT_SettingsHandler.SavedVariables.SelectorPosY)
+    end
+end
+
+--[[
+	OnGroupUltimateSelectorClicked shows ultimate group menu
+]]--
+function TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked") end
+
+    local button = _control:GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
+
+    if (button ~= nil) then
+        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_GroupUltimateSelector.OnSetUltimateGroup)
+        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button)
+    else
+        _logger:logError("TGT_GroupUltimateSelector.OnGroupUltimateSelectorClicked, button nil")
+    end
+end
+
+--[[
+	OnSetUltimateGroup sets ultimate group for button
+]]--
+function TGT_GroupUltimateSelector.OnSetUltimateGroup(group)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.OnSetUltimateGroup")
+        _logger:logDebug("group.GroupName", group.GroupName)
+    end
+
+    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_GroupUltimateSelector.OnSetUltimateGroup)
+
+    if (group ~= nil) then
+        TGT_SettingsHandler.SetStaticUltimateIDSettings(group.GroupAbilityId)
+    else
+        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil")
+    end
+end
+
+--[[
+	SetControlHidden sets hidden on control
+]]--
+function TGT_GroupUltimateSelector.SetControlHidden(isHidden)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.SetControlHidden")
+        _logger:logDebug("isHidden", isHidden)
+    end
+
+    if (GetIsUnitGrouped()) then
+        _control:SetHidden(isHidden)
+    else
+        _control:SetHidden(true)
+    end
+end
+
+--[[
+	SetControlActive activates/deactivates control
+]]--
+function TGT_GroupUltimateSelector.SetControlActive()
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_GroupUltimateSelector.SetControlActive")
+    end
+
+    local isHidden = TGT_SettingsHandler.IsControlsVisible() == false
+    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
+
+    TGT_GroupUltimateSelector.SetControlHidden(isHidden or CurrentHudHiddenState())
+
+    if (isHidden) then
+        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_GroupUltimateSelector.SetControlMovable)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_STATIC_ULTIMATE_ID_CHANGED, TGT_GroupUltimateSelector.SetUltimateIcon)
+        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_GroupUltimateSelector.SetControlHidden)
+    else
+        TGT_GroupUltimateSelector.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
+        TGT_GroupUltimateSelector.RestorePosition(TGT_SettingsHandler.SavedVariables.SelectorPosX, TGT_SettingsHandler.SavedVariables.SelectorPosY)
+        TGT_GroupUltimateSelector.SetUltimateIcon(TGT_SettingsHandler.SavedVariables.StaticUltimateID)
+
+        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_GroupUltimateSelector.SetControlMovable)
+        CALLBACK_MANAGER:RegisterCallback(TGT_STATIC_ULTIMATE_ID_CHANGED, TGT_GroupUltimateSelector.SetUltimateIcon)
+        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_GroupUltimateSelector.SetControlHidden)
+    end
+end
+
+--[[
+	Initialize initializes TGT_GroupUltimateSelector
+]]--
+function TGT_GroupUltimateSelector.Initialize(logger)
+    if (LOG_ACTIVE) then
+        logger:logTrace("TGT_GroupUltimateSelector.Initialize")
+    end
+
+    _logger = logger
+    _control = TGT_UltimateSelectorControl
+
+    TGT_GroupUltimateSelector.SetUltimateIcon(staticUltimateID)
+
+    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_GroupUltimateSelector.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_GroupUltimateSelector.SetControlActive)
 end
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.xml b/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.xml
index 34de2e0..9563524 100644
--- a/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.xml
+++ b/TaosGroupTools/ui/groupultimate/GroupUltimateSelector.xml
@@ -1,37 +1,37 @@
-<GuiXml>
-	<Controls>
-		<TopLevelControl name="TGT_UltimateSelectorControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
-			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
-			<Dimensions x="75" y="75" />
-			<OnMoveStop>TGT_GroupUltimateSelector:OnGroupUltimateSelectorMoveStop()</OnMoveStop>
-
-			<Controls>
-        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
-          <Anchor point="TOPLEFT"/>
-          <Anchor point="BOTTOMRIGHT" />
-        </Control>
-
-        <Control name="$(parent)SelectorButtonControl">
-          <Dimensions x="50" y="50"/>
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="12.5" offsetY="12.5"/>
-          <Controls>
-            <Button name="$(parent)Button"
-                    ButtonState="BSTATE_NORMAL"
-                    tier="1">
-              <Dimensions x="50" y="50"/>
-              <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"/>
-              <Textures normal="/esoui/art/actionbar/abilityframe64_up.dds"
-                        pressed="/esoui/art/actionbar/abilityframe64_down.dds"
-                        mouseOver="/TaosGroupTools/textures/hover.dds"/>
-              <OnClicked>TGT_GroupUltimateSelector:OnGroupUltimateSelectorClicked()</OnClicked>
-            </Button>
-            <Texture name="$(parent)Icon" tier="0">
-              <Dimensions x="48" y="48"/>
-              <Anchor point="CENTER" relativeTo="$(parent)" relativePoint="CENTER"/>
-            </Texture>
-          </Controls>
-        </Control>
-		  </Controls>
-	  </TopLevelControl>
-	</Controls>
+<GuiXml>
+	<Controls>
+		<TopLevelControl name="TGT_UltimateSelectorControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
+			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
+			<Dimensions x="75" y="75" />
+			<OnMoveStop>TGT_GroupUltimateSelector:OnGroupUltimateSelectorMoveStop()</OnMoveStop>
+
+			<Controls>
+        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
+          <Anchor point="TOPLEFT"/>
+          <Anchor point="BOTTOMRIGHT" />
+        </Control>
+
+        <Control name="$(parent)SelectorButtonControl">
+          <Dimensions x="50" y="50"/>
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="12.5" offsetY="12.5"/>
+          <Controls>
+            <Button name="$(parent)Button"
+                    ButtonState="BSTATE_NORMAL"
+                    tier="1">
+              <Dimensions x="50" y="50"/>
+              <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"/>
+              <Textures normal="/esoui/art/actionbar/abilityframe64_up.dds"
+                        pressed="/esoui/art/actionbar/abilityframe64_down.dds"
+                        mouseOver="/TaosGroupTools/textures/hover.dds"/>
+              <OnClicked>TGT_GroupUltimateSelector:OnGroupUltimateSelectorClicked()</OnClicked>
+            </Button>
+            <Texture name="$(parent)Icon" tier="0">
+              <Dimensions x="48" y="48"/>
+              <Anchor point="CENTER" relativeTo="$(parent)" relativePoint="CENTER"/>
+            </Texture>
+          </Controls>
+        </Control>
+		  </Controls>
+	  </TopLevelControl>
+	</Controls>
 </GuiXml>
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/SimpleList.lua b/TaosGroupTools/ui/groupultimate/SimpleList.lua
index d6a0041..6cd0b2b 100644
--- a/TaosGroupTools/ui/groupultimate/SimpleList.lua
+++ b/TaosGroupTools/ui/groupultimate/SimpleList.lua
@@ -1,321 +1,321 @@
---[[
-	Addon: Taos Group Tools
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
---[[
-	Local variables
-]]--
-local LOG_ACTIVE = false
-
-local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
-local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
-
-local _logger = nil
-local _control = nil
-local _players = {}
-
---[[
-	Table TGT_SimpleList
-]]--
-TGT_SimpleList = {}
-TGT_SimpleList.__index = TGT_SimpleList
-
---[[
-	Table Members
-]]--
-TGT_SimpleList.IsMocked = false
-
---[[
-	Sets visibility of labels
-]]--
-function TGT_SimpleList.RefreshList()
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.RefreshList") end
-
-    for i=1, GROUP_SIZE_MAX, 1 do
-        local row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i)
-        local listPlayer = _players[i]
-
-        if (listPlayer ~= nil) then
-            local isPlayerNotGrouped = IsUnitGrouped(listPlayer.PingTag) == false
-
-            if (TGT_SimpleList.IsMocked) then
-                isPlayerNotGrouped = false
-            end
-
-            local isPlayerTimedOut = (GetTimeStamp() - listPlayer.LastMapPingTimestamp) > TIMEOUT
-
-            if (isPlayerNotGrouped or isPlayerTimedOut) then
-                if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
-
-                row:SetHidden(true)
-                table.remove(_players, i)
-            end
-        else
-            if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
-            row:SetHidden(true)
-        end
-    end
-
-	if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
-		-- Sort list with all players
-		TGT_SimpleList.SortList()
-	end
-end
-
---[[
-	Sorts swimlane
-]]--
-function TGT_SimpleList.SortList()
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.SortList") end
-
-    -- Comparer
-    function compare(playerLeft, playerRight)
-        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
-            return playerLeft.PingTag < playerRight.PingTag
-        else
-            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
-        end
-    end
-
-    table.sort(_players, compare)
-
-    -- Update sorted swimlane list
-    for i,listPlayer in ipairs(_players) do
-        TGT_SimpleList.UpdateListRow(TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i), listPlayer)
-    end
-end
-
---[[
-	Updates list row
-]]--
-function TGT_SimpleList.UpdateListRow(row, player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.UpdateListRow")
-    end
-
-    local localizedUltimateName = zo_strformat(SI_ABILITY_TOOLTIP_NAME, player.UltimateName)
-    local nameLength = string.len(localizedUltimateName)
-
-    if (nameLength > 22) then
-        localizedUltimateName = string.sub(localizedUltimateName, 0, 22) .. "..."
-    end
-
-    row:GetNamedChild("SenderNameValueLabel"):SetText(player.PlayerName)
-	row:GetNamedChild("UltimateValueLabel"):SetText(localizedUltimateName)
-	row:GetNamedChild("ReadyValueLabel"):SetText(player.RelativeUltimate)
-
-	if (player.IsPlayerDead) then
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
-		row:GetNamedChild("UltimateValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
-		row:GetNamedChild("ReadyValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
-    elseif (player.RelativeUltimate == 100) then
-		row:GetNamedChild("SenderNameValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
-		row:GetNamedChild("UltimateValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
-		row:GetNamedChild("ReadyValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
-	else
-		row:GetNamedChild("SenderNameValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
-		row:GetNamedChild("UltimateValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
-		row:GetNamedChild("ReadyValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
-	end
-
-    if (row:IsHidden()) then
-		row:SetHidden(false)
-	end
-end
-
---[[
-	Updates list row
-]]--
-function TGT_SimpleList.UpdatePlayer(player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.UpdatePlayer")
-    end
-
-	if (player) then
-        local row = nil
-
-        for i,listPlayer in ipairs(_players) do
-            if (LOG_ACTIVE) then _logger:logDebug(listPlayer.PlayerName .. " == " .. player.PlayerName) end
-		    if (listPlayer.PlayerName == player.PlayerName) then
-                row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i)
-            end
-	    end
-
-        -- Update timestamp
-		if (row ~= nil) then
-            for i,listPlayer in ipairs(_players) do
-		        if (listPlayer.PlayerName == player.PlayerName) then
-                    listPlayer.LastMapPingTimestamp = GetTimeStamp()
-                    listPlayer.IsPlayerDead = player.IsPlayerDead
-                    listPlayer.RelativeUltimate = player.RelativeUltimate
-                    break
-                end
-	        end
-        else
-            -- Add new player
-            local nextFreeRow = 1
-
-            for i,player in ipairs(_players) do
-		        nextFreeRow = nextFreeRow + 1
-	        end
-
-            if (nextFreeRow <= GROUP_SIZE_MAX) then
-                if (LOG_ACTIVE) then
-                    _logger:logDebug("TGT_SimpleList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
-                end
-
-                player.LastMapPingTimestamp = GetTimeStamp()
-                _players[nextFreeRow] = player
-                row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. nextFreeRow)
-            else
-                if (LOG_ACTIVE) then _logger:logDebug("TGT_SimpleList.UpdatePlayer, too much players for list" .. tostring(nextFreeRow)) end
-            end
-        end
-
-        -- Only update if player in a row
-        if (row ~= nil) then
-            -- Directly update row with player, sorting will be triggered on RefreshList
-			TGT_SimpleList.UpdateListRow(row, player)
-        end
-    end
-end
-
---[[
-	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
-]]--
-function TGT_SimpleList.SetControlMovable(isMovable)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.SetControlMovable")
-        _logger:logDebug("isMovable", isMovable)
-    end
-
-    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
-
-    _control:SetMovable(isMovable)
-	_control:SetMouseEnabled(isMovable)
-end
-
---[[
-	RestorePosition sets TGT_SimpleList on settings position
-]]--
-function TGT_SimpleList.RestorePosition(posX, posY)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.RestorePosition")
-        _logger:logDebug("posX, posY", posX, posY)
-    end
-
-	_control:ClearAnchors()
-	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
-end
-
---[[
-	OnSimpleListMoveStop saves current TGT_SimpleList position to settings
-]]--
-function TGT_SimpleList.OnSimpleListMoveStop()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.OnSimpleListMoveStop") end
-
-	local left = _control:GetLeft()
-	local top = _control:GetTop()
-
-    TGT_SettingsHandler.SavedVariables.PosX = left
-    TGT_SettingsHandler.SavedVariables.PosY = top
-
-    if (LOG_ACTIVE) then
-        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-    end
-end
-
---[[
-	SetControlHidden sets hidden on control
-]]--
-function TGT_SimpleList.SetControlHidden(isHidden)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.SetControlHidden")
-        _logger:logDebug("isHidden", isHidden)
-    end
-
-    if (GetIsUnitGrouped()) then
-        _control:SetHidden(isHidden)
-    else
-        _control:SetHidden(true)
-    end
-end
-
---[[
-	SetControlActive sets hidden on control
-]]--
-function TGT_SimpleList.SetControlActive()
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SimpleList.SetControlActive")
-    end
-
-    local isHidden = TGT_SettingsHandler.IsSimpleListVisible() == false
-    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
-
-    TGT_SimpleList.SetControlHidden(isHidden or CurrentHudHiddenState())
-
-    if (isHidden) then
-		-- Stop timeout timer
-	    EVENT_MANAGER:UnregisterForUpdate(TGT_SimpleList.Name)
-
-        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_SimpleList.RefreshList)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SimpleList.UpdatePlayer)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_SimpleList.SetControlMovable)
-        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SimpleList.SetControlHidden)
-    else
-        TGT_SimpleList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
-        TGT_SimpleList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-
-		-- Start timeout timer
-	    EVENT_MANAGER:RegisterForUpdate(TGT_SimpleList.Name, REFRESHRATE, TGT_SimpleList.RefreshList)
-
-        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_SimpleList.RefreshList)
-        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SimpleList.UpdatePlayer)
-        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_SimpleList.SetControlMovable)
-        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SimpleList.SetControlHidden)
-    end
-end
-
---[[
-	CreateSimpleListRows creates simple list rows
-]]--
-function TGT_SimpleList.CreateSimpleListRows()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.CreateSimpleListRows") end
-
-	for i=1, GROUP_SIZE_MAX, 1 do
-		local row = CreateControlFromVirtual("$(parent)Row", TGT_SimpleListControlContainerScrollChild, "GroupUltimateSimpleListRow", i)
-        if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
-
-		row:SetHidden(true) -- initial not visible
-
-		if i == 1 then
-            row:SetAnchor(TOPLEFT, TGT_SimpleListControlContainerScrollChild, TOPLEFT, 0, 0)
-        else
-            row:SetAnchor(TOP, lastRow, BOTTOM, 0, 0)
-        end
-
-		lastRow = row
-	end
-end
-
---[[
-	Initialize initializes TGT_SimpleList
-]]--
-function TGT_SimpleList.Initialize(logger, isMocked)
-    if (LOG_ACTIVE) then
-        logger:logTrace("TGT_SimpleList.Initialize")
-    end
-
-    _logger = logger
-    _control = TGT_SimpleListControl
-
-    TGT_SimpleList.IsMocked = isMocked
-
-    TGT_SimpleList.CreateSimpleListRows()
-
-    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_SimpleList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_SimpleList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_SimpleList.SetControlActive)
+--[[
+	Addon: Taos Group Tools
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+--[[
+	Local variables
+]]--
+local LOG_ACTIVE = false
+
+local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
+local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
+
+local _logger = nil
+local _control = nil
+local _players = {}
+
+--[[
+	Table TGT_SimpleList
+]]--
+TGT_SimpleList = {}
+TGT_SimpleList.__index = TGT_SimpleList
+
+--[[
+	Table Members
+]]--
+TGT_SimpleList.IsMocked = false
+
+--[[
+	Sets visibility of labels
+]]--
+function TGT_SimpleList.RefreshList()
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.RefreshList") end
+
+    for i=1, GROUP_SIZE_MAX, 1 do
+        local row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i)
+        local listPlayer = _players[i]
+
+        if (listPlayer ~= nil) then
+            local isPlayerNotGrouped = IsUnitGrouped(listPlayer.PingTag) == false
+
+            if (TGT_SimpleList.IsMocked) then
+                isPlayerNotGrouped = false
+            end
+
+            local isPlayerTimedOut = (GetTimeStamp() - listPlayer.LastMapPingTimestamp) > TIMEOUT
+
+            if (isPlayerNotGrouped or isPlayerTimedOut) then
+                if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
+
+                row:SetHidden(true)
+                table.remove(_players, i)
+            end
+        else
+            if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
+            row:SetHidden(true)
+        end
+    end
+
+	if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
+		-- Sort list with all players
+		TGT_SimpleList.SortList()
+	end
+end
+
+--[[
+	Sorts swimlane
+]]--
+function TGT_SimpleList.SortList()
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.SortList") end
+
+    -- Comparer
+    function compare(playerLeft, playerRight)
+        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
+            return playerLeft.PingTag < playerRight.PingTag
+        else
+            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
+        end
+    end
+
+    table.sort(_players, compare)
+
+    -- Update sorted swimlane list
+    for i,listPlayer in ipairs(_players) do
+        TGT_SimpleList.UpdateListRow(TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i), listPlayer)
+    end
+end
+
+--[[
+	Updates list row
+]]--
+function TGT_SimpleList.UpdateListRow(row, player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.UpdateListRow")
+    end
+
+    local localizedUltimateName = zo_strformat(SI_ABILITY_TOOLTIP_NAME, player.UltimateName)
+    local nameLength = string.len(localizedUltimateName)
+
+    if (nameLength > 22) then
+        localizedUltimateName = string.sub(localizedUltimateName, 0, 22) .. "..."
+    end
+
+    row:GetNamedChild("SenderNameValueLabel"):SetText(player.PlayerName)
+	row:GetNamedChild("UltimateValueLabel"):SetText(localizedUltimateName)
+	row:GetNamedChild("ReadyValueLabel"):SetText(player.RelativeUltimate)
+
+	if (player.IsPlayerDead) then
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
+		row:GetNamedChild("UltimateValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
+		row:GetNamedChild("ReadyValueLabel"):SetColor(1.0, 0.0, 0.0, 1)
+    elseif (player.RelativeUltimate == 100) then
+		row:GetNamedChild("SenderNameValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
+		row:GetNamedChild("UltimateValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
+		row:GetNamedChild("ReadyValueLabel"):SetColor(0.0, 1.0, 0.0, 1)
+	else
+		row:GetNamedChild("SenderNameValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
+		row:GetNamedChild("UltimateValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
+		row:GetNamedChild("ReadyValueLabel"):SetColor(1.0, 1.0, 1.0, 1)
+	end
+
+    if (row:IsHidden()) then
+		row:SetHidden(false)
+	end
+end
+
+--[[
+	Updates list row
+]]--
+function TGT_SimpleList.UpdatePlayer(player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.UpdatePlayer")
+    end
+
+	if (player) then
+        local row = nil
+
+        for i,listPlayer in ipairs(_players) do
+            if (LOG_ACTIVE) then _logger:logDebug(listPlayer.PlayerName .. " == " .. player.PlayerName) end
+		    if (listPlayer.PlayerName == player.PlayerName) then
+                row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. i)
+            end
+	    end
+
+        -- Update timestamp
+		if (row ~= nil) then
+            for i,listPlayer in ipairs(_players) do
+		        if (listPlayer.PlayerName == player.PlayerName) then
+                    listPlayer.LastMapPingTimestamp = GetTimeStamp()
+                    listPlayer.IsPlayerDead = player.IsPlayerDead
+                    listPlayer.RelativeUltimate = player.RelativeUltimate
+                    break
+                end
+	        end
+        else
+            -- Add new player
+            local nextFreeRow = 1
+
+            for i,player in ipairs(_players) do
+		        nextFreeRow = nextFreeRow + 1
+	        end
+
+            if (nextFreeRow <= GROUP_SIZE_MAX) then
+                if (LOG_ACTIVE) then
+                    _logger:logDebug("TGT_SimpleList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
+                end
+
+                player.LastMapPingTimestamp = GetTimeStamp()
+                _players[nextFreeRow] = player
+                row = TGT_SimpleListControlContainerScrollChild:GetNamedChild("Row" .. nextFreeRow)
+            else
+                if (LOG_ACTIVE) then _logger:logDebug("TGT_SimpleList.UpdatePlayer, too much players for list" .. tostring(nextFreeRow)) end
+            end
+        end
+
+        -- Only update if player in a row
+        if (row ~= nil) then
+            -- Directly update row with player, sorting will be triggered on RefreshList
+			TGT_SimpleList.UpdateListRow(row, player)
+        end
+    end
+end
+
+--[[
+	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
+]]--
+function TGT_SimpleList.SetControlMovable(isMovable)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.SetControlMovable")
+        _logger:logDebug("isMovable", isMovable)
+    end
+
+    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
+
+    _control:SetMovable(isMovable)
+	_control:SetMouseEnabled(isMovable)
+end
+
+--[[
+	RestorePosition sets TGT_SimpleList on settings position
+]]--
+function TGT_SimpleList.RestorePosition(posX, posY)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.RestorePosition")
+        _logger:logDebug("posX, posY", posX, posY)
+    end
+
+	_control:ClearAnchors()
+	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
+end
+
+--[[
+	OnSimpleListMoveStop saves current TGT_SimpleList position to settings
+]]--
+function TGT_SimpleList.OnSimpleListMoveStop()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.OnSimpleListMoveStop") end
+
+	local left = _control:GetLeft()
+	local top = _control:GetTop()
+
+    TGT_SettingsHandler.SavedVariables.PosX = left
+    TGT_SettingsHandler.SavedVariables.PosY = top
+
+    if (LOG_ACTIVE) then
+        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+    end
+end
+
+--[[
+	SetControlHidden sets hidden on control
+]]--
+function TGT_SimpleList.SetControlHidden(isHidden)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.SetControlHidden")
+        _logger:logDebug("isHidden", isHidden)
+    end
+
+    if (GetIsUnitGrouped()) then
+        _control:SetHidden(isHidden)
+    else
+        _control:SetHidden(true)
+    end
+end
+
+--[[
+	SetControlActive sets hidden on control
+]]--
+function TGT_SimpleList.SetControlActive()
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SimpleList.SetControlActive")
+    end
+
+    local isHidden = TGT_SettingsHandler.IsSimpleListVisible() == false
+    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
+
+    TGT_SimpleList.SetControlHidden(isHidden or CurrentHudHiddenState())
+
+    if (isHidden) then
+		-- Stop timeout timer
+	    EVENT_MANAGER:UnregisterForUpdate(TGT_SimpleList.Name)
+
+        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_SimpleList.RefreshList)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SimpleList.UpdatePlayer)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_SimpleList.SetControlMovable)
+        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SimpleList.SetControlHidden)
+    else
+        TGT_SimpleList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
+        TGT_SimpleList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+
+		-- Start timeout timer
+	    EVENT_MANAGER:RegisterForUpdate(TGT_SimpleList.Name, REFRESHRATE, TGT_SimpleList.RefreshList)
+
+        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_SimpleList.RefreshList)
+        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SimpleList.UpdatePlayer)
+        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_SimpleList.SetControlMovable)
+        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SimpleList.SetControlHidden)
+    end
+end
+
+--[[
+	CreateSimpleListRows creates simple list rows
+]]--
+function TGT_SimpleList.CreateSimpleListRows()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_SimpleList.CreateSimpleListRows") end
+
+	for i=1, GROUP_SIZE_MAX, 1 do
+		local row = CreateControlFromVirtual("$(parent)Row", TGT_SimpleListControlContainerScrollChild, "GroupUltimateSimpleListRow", i)
+        if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
+
+		row:SetHidden(true) -- initial not visible
+
+		if i == 1 then
+            row:SetAnchor(TOPLEFT, TGT_SimpleListControlContainerScrollChild, TOPLEFT, 0, 0)
+        else
+            row:SetAnchor(TOP, lastRow, BOTTOM, 0, 0)
+        end
+
+		lastRow = row
+	end
+end
+
+--[[
+	Initialize initializes TGT_SimpleList
+]]--
+function TGT_SimpleList.Initialize(logger, isMocked)
+    if (LOG_ACTIVE) then
+        logger:logTrace("TGT_SimpleList.Initialize")
+    end
+
+    _logger = logger
+    _control = TGT_SimpleListControl
+
+    TGT_SimpleList.IsMocked = isMocked
+
+    TGT_SimpleList.CreateSimpleListRows()
+
+    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_SimpleList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_SimpleList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_SimpleList.SetControlActive)
 end
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/SimpleList.xml b/TaosGroupTools/ui/groupultimate/SimpleList.xml
index 274c64b..6073a6b 100644
--- a/TaosGroupTools/ui/groupultimate/SimpleList.xml
+++ b/TaosGroupTools/ui/groupultimate/SimpleList.xml
@@ -1,32 +1,32 @@
-<GuiXml>
-	<Controls>
-		<TopLevelControl name="TGT_SimpleListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
-			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
-			<Dimensions x="500" y="520" />
-			<OnMoveStop>TGT_SimpleList:OnSimpleListMoveStop()</OnMoveStop>
-
-			<Controls>
-        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
-          <Anchor point="TOPLEFT"/>
-          <Anchor point="BOTTOMRIGHT" />
-        </Control>
-
-				<!-- Header -->
-				<Label name="$(parent)SenderNameHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Name">
-					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
-				</Label>
-				<Label name="$(parent)UltimateHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Ultimate">
-					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="200" offsetY="0"/>
-				</Label>
-				<Label name="$(parent)ReadyHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Ready %">
-					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="400" offsetY="0"/>
-				</Label>
-
-				<Control name="$(parent)Container" inherits="ZO_ScrollContainer">
-                    <Anchor point="TOPLEFT" offsetY="20" />
-                    <Anchor point="BOTTOMRIGHT" />
-                </Control>
-		  </Controls>
-	  </TopLevelControl>
-	</Controls>
+<GuiXml>
+	<Controls>
+		<TopLevelControl name="TGT_SimpleListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
+			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
+			<Dimensions x="500" y="520" />
+			<OnMoveStop>TGT_SimpleList:OnSimpleListMoveStop()</OnMoveStop>
+
+			<Controls>
+        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
+          <Anchor point="TOPLEFT"/>
+          <Anchor point="BOTTOMRIGHT" />
+        </Control>
+
+				<!-- Header -->
+				<Label name="$(parent)SenderNameHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Name">
+					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
+				</Label>
+				<Label name="$(parent)UltimateHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Ultimate">
+					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="200" offsetY="0"/>
+				</Label>
+				<Label name="$(parent)ReadyHeaderLabel" inherits="GroupUltimateHeaderLabel" text="Ready %">
+					<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="400" offsetY="0"/>
+				</Label>
+
+				<Control name="$(parent)Container" inherits="ZO_ScrollContainer">
+                    <Anchor point="TOPLEFT" offsetY="20" />
+                    <Anchor point="BOTTOMRIGHT" />
+                </Control>
+		  </Controls>
+	  </TopLevelControl>
+	</Controls>
 </GuiXml>
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/SwimlaneList.lua b/TaosGroupTools/ui/groupultimate/SwimlaneList.lua
index c03db0f..70ad8b0 100644
--- a/TaosGroupTools/ui/groupultimate/SwimlaneList.lua
+++ b/TaosGroupTools/ui/groupultimate/SwimlaneList.lua
@@ -1,501 +1,501 @@
---[[
-	Addon: Taos Group Tools
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
---[[
-	Local variables
-]]--
-local LOG_ACTIVE = false
-
-local SWIMLANES = 6
-local ROWS = 6
-local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
-local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
-
-local _logger = nil
-local _control = nil
-
---[[
-	Table TGT_SwimlaneList
-]]--
-TGT_SwimlaneList = {}
-TGT_SwimlaneList.__index = TGT_SwimlaneList
-
---[[
-	Table Members
-]]--
-TGT_SwimlaneList.Name = "TGT-SwimlaneList"
-TGT_SwimlaneList.IsMocked = false
-TGT_SwimlaneList.Swimlanes = {}
-
---[[
-	Sets visibility of labels
-]]--
-function TGT_SwimlaneList.RefreshList()
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.RefreshList") end
-
-    -- Check all swimlanes
-    for i,swimlane in ipairs(TGT_SwimlaneList.Swimlanes) do
-        TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlane)
-	end
-end
-
---[[
-	Sorts swimlane
-]]--
-function TGT_SwimlaneList.SortSwimlane(swimlane)
-	if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.SortSwimlane") end
-
-    -- Comparer
-    function compare(playerLeft, playerRight)
-        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
-            return playerLeft.PingTag < playerRight.PingTag
-        else
-            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
-        end
-    end
-
-    table.sort(swimlane.Players, compare)
-
-    -- Update sorted swimlane list
-    for i,swimlanePlayer in ipairs(swimlane.Players) do
-        TGT_SwimlaneList.UpdateListRow(swimlane.SwimlaneControl:GetNamedChild("Row" .. i), swimlanePlayer)
-    end
-end
-
---[[
-	Updates list row
-]]--
-function TGT_SwimlaneList.UpdateListRow(row, player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.UpdateListRow")
-    end
-
-    local playerName = player.PlayerName
-    local nameLength = string.len(playerName)
-
-    if (nameLength > 10) then
-        playerName = string.sub(playerName, 0, 10) .. "..."
-    end
-
-    row:GetNamedChild("SenderNameValueLabel"):SetText(playerName)
-    row:GetNamedChild("RelativeUltimateStatusBar"):SetValue(player.RelativeUltimate)
-
-	if (player.IsPlayerDead) then
-        -- Dead Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(0.5, 0.5, 0.5, 0.8)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.8, 0.03, 0.03, 0.7)
-    elseif (player.RelativeUltimate == 100) then
-		-- Ready Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 1)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.7, 0.03, 0.7)
-	else
-		-- Inprogress Color
-        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 0.8)
-        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.03, 0.7, 0.7)
-	end
-
-    if (row:IsHidden()) then
-		row:SetHidden(false)
-	end
-end
-
---[[
-	Updates list player
-]]--
-function TGT_SwimlaneList.UpdatePlayer(player)
-	if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.UpdatePlayer")
-    end
-
-	if (player) then
-        local swimLane = TGT_SwimlaneList.GetSwimLane(player.UltimateGroup.GroupAbilityId)
-
-        if (swimLane) then
-            local row = TGT_SwimlaneList.GetSwimLaneRow(swimLane, player.PlayerName)
-
-            -- Update player
-            if (row ~= nil) then
-                for i,swimlanePlayer in ipairs(swimLane.Players) do
-		            if (swimlanePlayer.PlayerName == player.PlayerName) then
-                        swimlanePlayer.LastMapPingTimestamp = GetTimeStamp()
-                        swimlanePlayer.IsPlayerDead = player.IsPlayerDead
-                        swimlanePlayer.RelativeUltimate = player.RelativeUltimate
-                        break
-                    end
-	            end
-            else
-                -- Add new player
-                local nextFreeRow = 1
-
-                for i,player in ipairs(swimLane.Players) do
-		            nextFreeRow = nextFreeRow + 1
-	            end
-
-                if (nextFreeRow <= ROWS) then
-                    if (LOG_ACTIVE) then
-                        _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
-                    end
-
-                    player.LastMapPingTimestamp = GetTimeStamp()
-                    swimLane.Players[nextFreeRow] = player
-                    row = swimLane.SwimlaneControl:GetNamedChild("Row" .. nextFreeRow)
-                else
-                    if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, too much players for one swimlane " .. tostring(nextFreeRow)) end
-                end
-            end
-
-            -- Only update if player in a row
-            if (row ~= nil) then
-                if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
-                    -- Sort swimlane with all players
-                    TGT_SwimlaneList.SortSwimlane(swimLane)
-                else
-                    -- Directly update row with player
-                    TGT_SwimlaneList.UpdateListRow(row, player)
-                end
-            end
-        else
-            if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, swimlane not found for ultimategroup " .. tostring(ultimateGroup.GroupName)) end
-        end
-	end
-end
-
---[[
-	Get swimlane from current SwimLanes
-]]--
-function TGT_SwimlaneList.GetSwimLane(ultimateGroupId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.GetSwimLane")
-        _logger:logDebug("ultimateGroupId", ultimateGroupId)
-    end
-
-    if (ultimateGroupId ~= 0) then
-        for i,swimLane in ipairs(TGT_SwimlaneList.Swimlanes) do
-		    if (swimLane.UltimateGroupId == ultimateGroupId) then
-                return swimLane
-            end
-	    end
-
-        if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.GetSwimLane, swimLane not found " .. tostring(ultimateGroupId)) end
-        return nil
-    else
-        _logger:logError("TGT_SwimlaneList.GetSwimLane, ultimateGroupId is 0")
-        return nil
-    end
-end
-
---[[
-	Get Player Row from current players in swimlane
-]]--
-function TGT_SwimlaneList.GetSwimLaneRow(swimLane, playerName)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.GetSwimLaneRow")
-        _logger:logDebug("swimLane ID", swimLane.Id)
-    end
-
-    if (swimLane) then
-        for i,player in ipairs(swimLane.Players) do
-            if (LOG_ACTIVE) then _logger:logDebug(player.PlayerName .. " == " .. playerName) end
-		    if (player.PlayerName == playerName) then
-                return swimLane.SwimlaneControl:GetNamedChild("Row" .. i)
-            end
-	    end
-
-        if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.GetSwimLane, player not found " .. tostring(playerName)) end
-        return nil
-    else
-        _logger:logError("TGT_SwimlaneList.GetSwimLane, swimLane is nil")
-        return nil
-    end
-end
-
---[[
-	Clears all players in swimlane
-]]--
-function TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlane)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.ClearPlayersFromSwimlane")
-        _logger:logDebug("swimlane ID", swimlane.Id)
-    end
-
-    if (swimlane) then
-        for i=1, ROWS, 1 do
-            local row = swimlane.SwimlaneControl:GetNamedChild("Row" .. i)
-            local swimlanePlayer = swimlane.Players[i]
-
-            if (swimlanePlayer ~= nil) then
-                local isPlayerNotGrouped = IsUnitGrouped(swimlanePlayer.PingTag) == false
-
-                if (TGT_SwimlaneList.IsMocked) then
-                    isPlayerNotGrouped = false
-                end
-
-                local isPlayerTimedOut = (GetTimeStamp() - swimlanePlayer.LastMapPingTimestamp) > TIMEOUT
-                local isPlayerUltimateNotCorrect = swimlane.UltimateGroupId ~= swimlanePlayer.UltimateGroup.GroupAbilityId
-
-                if (isPlayerNotGrouped or isPlayerTimedOut or isPlayerUltimateNotCorrect) then
-                    if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
-
-                    table.remove(swimlane.Players, i)
-                    row:SetHidden(true)
-                end
-            else
-                if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
-                row:SetHidden(true)
-            end
-        end
-    end
-end
-
---[[
-	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
-]]--
-function TGT_SwimlaneList.SetControlMovable(isMovable)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.SetControlMovable")
-        _logger:logDebug("isMovable", isMovable)
-    end
-
-    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
-
-    _control:SetMovable(isMovable)
-	_control:SetMouseEnabled(isMovable)
-end
-
---[[
-	RestorePosition sets TGT_SwimlaneList on settings position
-]]--
-function TGT_SwimlaneList.RestorePosition(posX, posY)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.RestorePosition")
-        _logger:logDebug("posX, posY", posX, posY)
-    end
-
-	_control:ClearAnchors()
-	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
-end
-
---[[
-	OnSwimlaneListMoveStop saves current TGT_SwimlaneList position to settings
-]]--
-function TGT_SwimlaneList.OnSwimlaneListMoveStop()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.OnSwimlaneListMoveStop") end
-
-	local left = _control:GetLeft()
-	local top = _control:GetTop()
-
-    TGT_SettingsHandler.SavedVariables.PosX = left
-    TGT_SettingsHandler.SavedVariables.PosY = top
-
-    if (LOG_ACTIVE) then
-        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-    end
-end
-
---[[
-	SetControlHidden sets hidden on control
-]]--
-function TGT_SwimlaneList.SetControlHidden(isHidden)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.SetControlHidden")
-        _logger:logDebug("isHidden", isHidden)
-    end
-
-    if (GetIsUnitGrouped()) then
-        _control:SetHidden(isHidden)
-    else
-        _control:SetHidden(true)
-    end
-end
-
---[[
-	SetControlActive sets hidden on control
-]]--
-function TGT_SwimlaneList.SetControlActive()
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.SetControlActive")
-    end
-
-    local isHidden = TGT_SettingsHandler.IsSwimlaneListVisible() == false
-    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
-
-    TGT_SwimlaneList.SetControlHidden(isHidden or CurrentHudHiddenState())
-
-    if (isHidden) then
-        -- Start timeout timer
-	    EVENT_MANAGER:UnregisterForUpdate(TGT_SwimlaneList.Name)
-
-        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_SwimlaneList.RefreshList)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SwimlaneList.UpdatePlayer)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_SwimlaneList.SetControlMovable)
-        CALLBACK_MANAGER:UnregisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_SwimlaneList.SetSwimlaneUltimate)
-        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SwimlaneList.SetControlHidden)
-    else
-        TGT_SwimlaneList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
-        TGT_SwimlaneList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
-
-        -- Start timeout timer
-	    EVENT_MANAGER:RegisterForUpdate(TGT_SwimlaneList.Name, REFRESHRATE, TGT_SwimlaneList.RefreshList)
-
-        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_SwimlaneList.RefreshList)
-        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SwimlaneList.UpdatePlayer)
-        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_SwimlaneList.SetControlMovable)
-        CALLBACK_MANAGER:RegisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_SwimlaneList.SetSwimlaneUltimate)
-        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SwimlaneList.SetControlHidden)
-    end
-end
-
---[[
-	OnSwimlaneHeaderClicked called on header clicked
-]]--
-function TGT_SwimlaneList.OnSwimlaneHeaderClicked(button, swimlaneId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.OnSwimlaneHeaderClicked")
-        _logger:logDebug("swimlaneId", swimlaneId)
-    end
-
-    if (button ~= nil) then
-        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_SwimlaneList.OnSetUltimateGroup)
-        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button, swimlaneId)
-    else
-        _logger:logError("TGT_SwimlaneList.OnSwimlaneHeaderClicked, button nil")
-    end
-end
-
---[[
-	OnSetUltimateGroup called on header clicked
-]]--
-function TGT_SwimlaneList.OnSetUltimateGroup(group, swimlaneId)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.OnSetUltimateGroup")
-        _logger:logDebug("group.GroupName, swimlaneId", group.GroupName, swimlaneId)
-    end
-
-    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_SwimlaneList.OnSetUltimateGroup)
-
-    if (group ~= nil and swimlaneId ~= nil and swimlaneId >= 1 and swimlaneId <= 6) then
-        TGT_SettingsHandler.SetSwimlaneUltimateGroupIdSettings(swimlaneId, group)
-    else
-        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil or swimlaneId invalid")
-    end
-end
-
---[[
-	SetSwimlaneUltimate sets the swimlane header icon in base of ultimateGroupId
-]]--
-function TGT_SwimlaneList.SetSwimlaneUltimate(swimlaneId, ultimateGroup)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_SwimlaneList.SetSwimlaneUltimate")
-        _logger:logDebug("ultimateGroup.GroupName, swimlaneId", ultimateGroup.GroupName, swimlaneId)
-    end
-
-    local swimlaneObject = TGT_SwimlaneList.Swimlanes[swimlaneId]
-    local iconControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
-    local labelControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("UltimateLabel")
-
-    if (ultimateGroup ~= nil and iconControl ~= nil and labelControl ~= nil) then
-        iconControl:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
-        labelControl:SetText(ultimateGroup.GroupName)
-
-        swimlaneObject.UltimateGroupId = ultimateGroup.GroupAbilityId
-        TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlaneObject)
-    else
-        _logger:logError("TGT_SwimlaneList.SetSwimlaneUltimateIcon, icon is " .. tostring(icon) .. ";" .. tostring(iconControl) .. ";" .. tostring(ultimateGroup))
-    end
-end
-
---[[
-	CreateSwimLaneListHeaders creates swimlane list headers
-]]--
-function TGT_SwimlaneList.CreateSwimLaneListHeaders()
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.CreateSwimLaneListHeaders") end
-
-	for i=1, SWIMLANES, 1 do
-        local ultimateGroupId = TGT_SettingsHandler.SavedVariables.SwimlaneUltimateGroupIds[i]
-        local ultimateGroup = TGT_UltimateGroupHandler.GetUltimateGroupByAbilityId(ultimateGroupId)
-
-        local swimlaneControlName = "Swimlane" .. tostring(i)
-        local swimlaneControl = _control:GetNamedChild(swimlaneControlName)
-
-        -- Add button
-        local button = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
-        button:SetHandler("OnClicked", function() TGT_SwimlaneList.OnSwimlaneHeaderClicked(button, i) end)
-
-        local swimLane = {}
-        swimLane.Id = i
-        swimLane.SwimlaneControl = swimlaneControl
-        swimLane.Players = {}
-
-        if (ultimateGroup ~= nil) then
-            if (LOG_ACTIVE) then
-                _logger:logDebug("Create Swimlane", i)
-                _logger:logDebug("ultimateGroup.GroupName", ultimateGroup.GroupName)
-                _logger:logDebug("swimlaneControlName", swimlaneControlName)
-            end
-
-            local icon = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
-            icon:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
-
-            local label = swimlaneControl:GetNamedChild("Header"):GetNamedChild("UltimateLabel")
-            label:SetText(ultimateGroup.GroupName)
-
-            swimLane.UltimateGroupId = ultimateGroup.GroupAbilityId
-        else
-            _logger:logError("TGT_SwimlaneList.CreateSwimLaneListHeaders, ultimateGroup nil.")
-        end
-
-        TGT_SwimlaneList.CreateSwimlaneListRows(swimlaneControl)
-        TGT_SwimlaneList.Swimlanes[i] = swimLane
-	end
-end
-
---[[
-	CreateSwimlaneListRows creates swimlane lsit rows
-]]--
-function TGT_SwimlaneList.CreateSwimlaneListRows(swimlaneControl)
-    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.CreateSwimlaneListRows") end
-
-    if (swimlaneControl ~= nil) then
-	    for i=1, ROWS, 1 do
-		    local row = CreateControlFromVirtual("$(parent)Row", swimlaneControl, "GroupUltimateSwimlaneRow", i)
-            if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
-
-		    row:SetHidden(true) -- initial not visible
-
-		    if (i == 1) then
-                row:SetAnchor(TOPLEFT, swimlaneControl, TOPLEFT, 0, 25)
-            elseif (i == 5) then -- Fix pixelbug, Why the hell ZOS?!
-                row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, 0)
-            else
-				row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, -1)
-			end
-
-		    lastRow = row
-	    end
-    else
-        _logger:logError("TGT_SwimlaneList.CreateSwimlaneListRows, swimlaneControl nil.")
-    end
-end
-
---[[
-	Initialize initializes TGT_SwimlaneList
-]]--
-function TGT_SwimlaneList.Initialize(logger, isMocked)
-    if (LOG_ACTIVE) then
-        logger:logTrace("TGT_SwimlaneList.Initialize")
-    end
-
-    _logger = logger
-    _control = TGT_SwimlaneListControl
-
-    TGT_SwimlaneList.IsMocked = isMocked
-
-    TGT_SwimlaneList.CreateSwimLaneListHeaders()
-
-    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_SwimlaneList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_SwimlaneList.SetControlActive)
-    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_SwimlaneList.SetControlActive)
+--[[
+	Addon: Taos Group Tools
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+--[[
+	Local variables
+]]--
+local LOG_ACTIVE = false
+
+local SWIMLANES = 6
+local ROWS = 6
+local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds
+local TIMEOUT = 4 -- s; GetTimeStamp() is in seconds
+
+local _logger = nil
+local _control = nil
+
+--[[
+	Table TGT_SwimlaneList
+]]--
+TGT_SwimlaneList = {}
+TGT_SwimlaneList.__index = TGT_SwimlaneList
+
+--[[
+	Table Members
+]]--
+TGT_SwimlaneList.Name = "TGT-SwimlaneList"
+TGT_SwimlaneList.IsMocked = false
+TGT_SwimlaneList.Swimlanes = {}
+
+--[[
+	Sets visibility of labels
+]]--
+function TGT_SwimlaneList.RefreshList()
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.RefreshList") end
+
+    -- Check all swimlanes
+    for i,swimlane in ipairs(TGT_SwimlaneList.Swimlanes) do
+        TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlane)
+	end
+end
+
+--[[
+	Sorts swimlane
+]]--
+function TGT_SwimlaneList.SortSwimlane(swimlane)
+	if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.SortSwimlane") end
+
+    -- Comparer
+    function compare(playerLeft, playerRight)
+        if (playerLeft.RelativeUltimate == playerRight.RelativeUltimate) then
+            return playerLeft.PingTag < playerRight.PingTag
+        else
+            return playerLeft.RelativeUltimate > playerRight.RelativeUltimate
+        end
+    end
+
+    table.sort(swimlane.Players, compare)
+
+    -- Update sorted swimlane list
+    for i,swimlanePlayer in ipairs(swimlane.Players) do
+        TGT_SwimlaneList.UpdateListRow(swimlane.SwimlaneControl:GetNamedChild("Row" .. i), swimlanePlayer)
+    end
+end
+
+--[[
+	Updates list row
+]]--
+function TGT_SwimlaneList.UpdateListRow(row, player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.UpdateListRow")
+    end
+
+    local playerName = player.PlayerName
+    local nameLength = string.len(playerName)
+
+    if (nameLength > 10) then
+        playerName = string.sub(playerName, 0, 10) .. "..."
+    end
+
+    row:GetNamedChild("SenderNameValueLabel"):SetText(playerName)
+    row:GetNamedChild("RelativeUltimateStatusBar"):SetValue(player.RelativeUltimate)
+
+	if (player.IsPlayerDead) then
+        -- Dead Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(0.5, 0.5, 0.5, 0.8)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.8, 0.03, 0.03, 0.7)
+    elseif (player.RelativeUltimate == 100) then
+		-- Ready Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 1)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.7, 0.03, 0.7)
+	else
+		-- Inprogress Color
+        row:GetNamedChild("SenderNameValueLabel"):SetColor(1, 1, 1, 0.8)
+        row:GetNamedChild("RelativeUltimateStatusBar"):SetColor(0.03, 0.03, 0.7, 0.7)
+	end
+
+    if (row:IsHidden()) then
+		row:SetHidden(false)
+	end
+end
+
+--[[
+	Updates list player
+]]--
+function TGT_SwimlaneList.UpdatePlayer(player)
+	if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.UpdatePlayer")
+    end
+
+	if (player) then
+        local swimLane = TGT_SwimlaneList.GetSwimLane(player.UltimateGroup.GroupAbilityId)
+
+        if (swimLane) then
+            local row = TGT_SwimlaneList.GetSwimLaneRow(swimLane, player.PlayerName)
+
+            -- Update player
+            if (row ~= nil) then
+                for i,swimlanePlayer in ipairs(swimLane.Players) do
+		            if (swimlanePlayer.PlayerName == player.PlayerName) then
+                        swimlanePlayer.LastMapPingTimestamp = GetTimeStamp()
+                        swimlanePlayer.IsPlayerDead = player.IsPlayerDead
+                        swimlanePlayer.RelativeUltimate = player.RelativeUltimate
+                        break
+                    end
+	            end
+            else
+                -- Add new player
+                local nextFreeRow = 1
+
+                for i,player in ipairs(swimLane.Players) do
+		            nextFreeRow = nextFreeRow + 1
+	            end
+
+                if (nextFreeRow <= ROWS) then
+                    if (LOG_ACTIVE) then
+                        _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, add player " .. tostring(player.PlayerName) .. " to row " .. tostring(nextFreeRow))
+                    end
+
+                    player.LastMapPingTimestamp = GetTimeStamp()
+                    swimLane.Players[nextFreeRow] = player
+                    row = swimLane.SwimlaneControl:GetNamedChild("Row" .. nextFreeRow)
+                else
+                    if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, too much players for one swimlane " .. tostring(nextFreeRow)) end
+                end
+            end
+
+            -- Only update if player in a row
+            if (row ~= nil) then
+                if (TGT_SettingsHandler.SavedVariables.IsSortingActive) then
+                    -- Sort swimlane with all players
+                    TGT_SwimlaneList.SortSwimlane(swimLane)
+                else
+                    -- Directly update row with player
+                    TGT_SwimlaneList.UpdateListRow(row, player)
+                end
+            end
+        else
+            if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.UpdatePlayer, swimlane not found for ultimategroup " .. tostring(ultimateGroup.GroupName)) end
+        end
+	end
+end
+
+--[[
+	Get swimlane from current SwimLanes
+]]--
+function TGT_SwimlaneList.GetSwimLane(ultimateGroupId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.GetSwimLane")
+        _logger:logDebug("ultimateGroupId", ultimateGroupId)
+    end
+
+    if (ultimateGroupId ~= 0) then
+        for i,swimLane in ipairs(TGT_SwimlaneList.Swimlanes) do
+		    if (swimLane.UltimateGroupId == ultimateGroupId) then
+                return swimLane
+            end
+	    end
+
+        if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.GetSwimLane, swimLane not found " .. tostring(ultimateGroupId)) end
+        return nil
+    else
+        _logger:logError("TGT_SwimlaneList.GetSwimLane, ultimateGroupId is 0")
+        return nil
+    end
+end
+
+--[[
+	Get Player Row from current players in swimlane
+]]--
+function TGT_SwimlaneList.GetSwimLaneRow(swimLane, playerName)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.GetSwimLaneRow")
+        _logger:logDebug("swimLane ID", swimLane.Id)
+    end
+
+    if (swimLane) then
+        for i,player in ipairs(swimLane.Players) do
+            if (LOG_ACTIVE) then _logger:logDebug(player.PlayerName .. " == " .. playerName) end
+		    if (player.PlayerName == playerName) then
+                return swimLane.SwimlaneControl:GetNamedChild("Row" .. i)
+            end
+	    end
+
+        if (LOG_ACTIVE) then _logger:logDebug("TGT_SwimlaneList.GetSwimLane, player not found " .. tostring(playerName)) end
+        return nil
+    else
+        _logger:logError("TGT_SwimlaneList.GetSwimLane, swimLane is nil")
+        return nil
+    end
+end
+
+--[[
+	Clears all players in swimlane
+]]--
+function TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlane)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.ClearPlayersFromSwimlane")
+        _logger:logDebug("swimlane ID", swimlane.Id)
+    end
+
+    if (swimlane) then
+        for i=1, ROWS, 1 do
+            local row = swimlane.SwimlaneControl:GetNamedChild("Row" .. i)
+            local swimlanePlayer = swimlane.Players[i]
+
+            if (swimlanePlayer ~= nil) then
+                local isPlayerNotGrouped = IsUnitGrouped(swimlanePlayer.PingTag) == false
+
+                if (TGT_SwimlaneList.IsMocked) then
+                    isPlayerNotGrouped = false
+                end
+
+                local isPlayerTimedOut = (GetTimeStamp() - swimlanePlayer.LastMapPingTimestamp) > TIMEOUT
+                local isPlayerUltimateNotCorrect = swimlane.UltimateGroupId ~= swimlanePlayer.UltimateGroup.GroupAbilityId
+
+                if (isPlayerNotGrouped or isPlayerTimedOut or isPlayerUltimateNotCorrect) then
+                    if (LOG_ACTIVE) then _logger:logDebug("Player invalid, hide row: " .. tostring(i)) end
+
+                    table.remove(swimlane.Players, i)
+                    row:SetHidden(true)
+                end
+            else
+                if (LOG_ACTIVE) then _logger:logDebug("Row empty, hide: " .. tostring(i)) end
+                row:SetHidden(true)
+            end
+        end
+    end
+end
+
+--[[
+	SetControlMovable sets the Movable and MouseEnabled flag in UI elements
+]]--
+function TGT_SwimlaneList.SetControlMovable(isMovable)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.SetControlMovable")
+        _logger:logDebug("isMovable", isMovable)
+    end
+
+    _control:GetNamedChild("MovableControl"):SetHidden(isMovable == false)
+
+    _control:SetMovable(isMovable)
+	_control:SetMouseEnabled(isMovable)
+end
+
+--[[
+	RestorePosition sets TGT_SwimlaneList on settings position
+]]--
+function TGT_SwimlaneList.RestorePosition(posX, posY)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.RestorePosition")
+        _logger:logDebug("posX, posY", posX, posY)
+    end
+
+	_control:ClearAnchors()
+	_control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, posX, posY)
+end
+
+--[[
+	OnSwimlaneListMoveStop saves current TGT_SwimlaneList position to settings
+]]--
+function TGT_SwimlaneList.OnSwimlaneListMoveStop()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.OnSwimlaneListMoveStop") end
+
+	local left = _control:GetLeft()
+	local top = _control:GetTop()
+
+    TGT_SettingsHandler.SavedVariables.PosX = left
+    TGT_SettingsHandler.SavedVariables.PosY = top
+
+    if (LOG_ACTIVE) then
+        _logger:logDebug("PosX, PosY", TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+    end
+end
+
+--[[
+	SetControlHidden sets hidden on control
+]]--
+function TGT_SwimlaneList.SetControlHidden(isHidden)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.SetControlHidden")
+        _logger:logDebug("isHidden", isHidden)
+    end
+
+    if (GetIsUnitGrouped()) then
+        _control:SetHidden(isHidden)
+    else
+        _control:SetHidden(true)
+    end
+end
+
+--[[
+	SetControlActive sets hidden on control
+]]--
+function TGT_SwimlaneList.SetControlActive()
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.SetControlActive")
+    end
+
+    local isHidden = TGT_SettingsHandler.IsSwimlaneListVisible() == false
+    if (LOG_ACTIVE) then _logger:logDebug("isHidden", isHidden) end
+
+    TGT_SwimlaneList.SetControlHidden(isHidden or CurrentHudHiddenState())
+
+    if (isHidden) then
+        -- Start timeout timer
+	    EVENT_MANAGER:UnregisterForUpdate(TGT_SwimlaneList.Name)
+
+        CALLBACK_MANAGER:UnregisterCallback(TAO_GROUP_CHANGED, TGT_SwimlaneList.RefreshList)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SwimlaneList.UpdatePlayer)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_MOVABLE_CHANGED, TGT_SwimlaneList.SetControlMovable)
+        CALLBACK_MANAGER:UnregisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_SwimlaneList.SetSwimlaneUltimate)
+        CALLBACK_MANAGER:UnregisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SwimlaneList.SetControlHidden)
+    else
+        TGT_SwimlaneList.SetControlMovable(TGT_SettingsHandler.SavedVariables.Movable)
+        TGT_SwimlaneList.RestorePosition(TGT_SettingsHandler.SavedVariables.PosX, TGT_SettingsHandler.SavedVariables.PosY)
+
+        -- Start timeout timer
+	    EVENT_MANAGER:RegisterForUpdate(TGT_SwimlaneList.Name, REFRESHRATE, TGT_SwimlaneList.RefreshList)
+
+        CALLBACK_MANAGER:RegisterCallback(TAO_GROUP_CHANGED, TGT_SwimlaneList.RefreshList)
+        CALLBACK_MANAGER:RegisterCallback(TGT_PLAYER_DATA_CHANGED, TGT_SwimlaneList.UpdatePlayer)
+        CALLBACK_MANAGER:RegisterCallback(TGT_MOVABLE_CHANGED, TGT_SwimlaneList.SetControlMovable)
+        CALLBACK_MANAGER:RegisterCallback(TGT_SWIMLANE_ULTIMATE_GROUP_ID_CHANGED, TGT_SwimlaneList.SetSwimlaneUltimate)
+        CALLBACK_MANAGER:RegisterCallback(TAO_HUD_HIDDEN_STATE_CHANGED, TGT_SwimlaneList.SetControlHidden)
+    end
+end
+
+--[[
+	OnSwimlaneHeaderClicked called on header clicked
+]]--
+function TGT_SwimlaneList.OnSwimlaneHeaderClicked(button, swimlaneId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.OnSwimlaneHeaderClicked")
+        _logger:logDebug("swimlaneId", swimlaneId)
+    end
+
+    if (button ~= nil) then
+        CALLBACK_MANAGER:RegisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_SwimlaneList.OnSetUltimateGroup)
+        CALLBACK_MANAGER:FireCallbacks(TGT_SHOW_ULTIMATE_GROUP_MENU, button, swimlaneId)
+    else
+        _logger:logError("TGT_SwimlaneList.OnSwimlaneHeaderClicked, button nil")
+    end
+end
+
+--[[
+	OnSetUltimateGroup called on header clicked
+]]--
+function TGT_SwimlaneList.OnSetUltimateGroup(group, swimlaneId)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.OnSetUltimateGroup")
+        _logger:logDebug("group.GroupName, swimlaneId", group.GroupName, swimlaneId)
+    end
+
+    CALLBACK_MANAGER:UnregisterCallback(TGT_SET_ULTIMATE_GROUP, TGT_SwimlaneList.OnSetUltimateGroup)
+
+    if (group ~= nil and swimlaneId ~= nil and swimlaneId >= 1 and swimlaneId <= 6) then
+        TGT_SettingsHandler.SetSwimlaneUltimateGroupIdSettings(swimlaneId, group)
+    else
+        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, group nil or swimlaneId invalid")
+    end
+end
+
+--[[
+	SetSwimlaneUltimate sets the swimlane header icon in base of ultimateGroupId
+]]--
+function TGT_SwimlaneList.SetSwimlaneUltimate(swimlaneId, ultimateGroup)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_SwimlaneList.SetSwimlaneUltimate")
+        _logger:logDebug("ultimateGroup.GroupName, swimlaneId", ultimateGroup.GroupName, swimlaneId)
+    end
+
+    local swimlaneObject = TGT_SwimlaneList.Swimlanes[swimlaneId]
+    local iconControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
+    local labelControl = swimlaneObject.SwimlaneControl:GetNamedChild("Header"):GetNamedChild("UltimateLabel")
+
+    if (ultimateGroup ~= nil and iconControl ~= nil and labelControl ~= nil) then
+        iconControl:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
+        labelControl:SetText(ultimateGroup.GroupName)
+
+        swimlaneObject.UltimateGroupId = ultimateGroup.GroupAbilityId
+        TGT_SwimlaneList.ClearPlayersFromSwimlane(swimlaneObject)
+    else
+        _logger:logError("TGT_SwimlaneList.SetSwimlaneUltimateIcon, icon is " .. tostring(icon) .. ";" .. tostring(iconControl) .. ";" .. tostring(ultimateGroup))
+    end
+end
+
+--[[
+	CreateSwimLaneListHeaders creates swimlane list headers
+]]--
+function TGT_SwimlaneList.CreateSwimLaneListHeaders()
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.CreateSwimLaneListHeaders") end
+
+	for i=1, SWIMLANES, 1 do
+        local ultimateGroupId = TGT_SettingsHandler.SavedVariables.SwimlaneUltimateGroupIds[i]
+        local ultimateGroup = TGT_UltimateGroupHandler.GetUltimateGroupByAbilityId(ultimateGroupId)
+
+        local swimlaneControlName = "Swimlane" .. tostring(i)
+        local swimlaneControl = _control:GetNamedChild(swimlaneControlName)
+
+        -- Add button
+        local button = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Button")
+        button:SetHandler("OnClicked", function() TGT_SwimlaneList.OnSwimlaneHeaderClicked(button, i) end)
+
+        local swimLane = {}
+        swimLane.Id = i
+        swimLane.SwimlaneControl = swimlaneControl
+        swimLane.Players = {}
+
+        if (ultimateGroup ~= nil) then
+            if (LOG_ACTIVE) then
+                _logger:logDebug("Create Swimlane", i)
+                _logger:logDebug("ultimateGroup.GroupName", ultimateGroup.GroupName)
+                _logger:logDebug("swimlaneControlName", swimlaneControlName)
+            end
+
+            local icon = swimlaneControl:GetNamedChild("Header"):GetNamedChild("SelectorButtonControl"):GetNamedChild("Icon")
+            icon:SetTexture(GetAbilityIcon(ultimateGroup.GroupAbilityId))
+
+            local label = swimlaneControl:GetNamedChild("Header"):GetNamedChild("UltimateLabel")
+            label:SetText(ultimateGroup.GroupName)
+
+            swimLane.UltimateGroupId = ultimateGroup.GroupAbilityId
+        else
+            _logger:logError("TGT_SwimlaneList.CreateSwimLaneListHeaders, ultimateGroup nil.")
+        end
+
+        TGT_SwimlaneList.CreateSwimlaneListRows(swimlaneControl)
+        TGT_SwimlaneList.Swimlanes[i] = swimLane
+	end
+end
+
+--[[
+	CreateSwimlaneListRows creates swimlane lsit rows
+]]--
+function TGT_SwimlaneList.CreateSwimlaneListRows(swimlaneControl)
+    if (LOG_ACTIVE) then _logger:logTrace("TGT_SwimlaneList.CreateSwimlaneListRows") end
+
+    if (swimlaneControl ~= nil) then
+	    for i=1, ROWS, 1 do
+		    local row = CreateControlFromVirtual("$(parent)Row", swimlaneControl, "GroupUltimateSwimlaneRow", i)
+            if (LOG_ACTIVE) then _logger:logDebug("Row created " .. row:GetName()) end
+
+		    row:SetHidden(true) -- initial not visible
+
+		    if (i == 1) then
+                row:SetAnchor(TOPLEFT, swimlaneControl, TOPLEFT, 0, 25)
+            elseif (i == 5) then -- Fix pixelbug, Why the hell ZOS?!
+                row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, 0)
+            else
+				row:SetAnchor(TOPLEFT, lastRow, BOTTOMLEFT, 0, -1)
+			end
+
+		    lastRow = row
+	    end
+    else
+        _logger:logError("TGT_SwimlaneList.CreateSwimlaneListRows, swimlaneControl nil.")
+    end
+end
+
+--[[
+	Initialize initializes TGT_SwimlaneList
+]]--
+function TGT_SwimlaneList.Initialize(logger, isMocked)
+    if (LOG_ACTIVE) then
+        logger:logTrace("TGT_SwimlaneList.Initialize")
+    end
+
+    _logger = logger
+    _control = TGT_SwimlaneListControl
+
+    TGT_SwimlaneList.IsMocked = isMocked
+
+    TGT_SwimlaneList.CreateSwimLaneListHeaders()
+
+    CALLBACK_MANAGER:RegisterCallback(TGT_STYLE_CHANGED, TGT_SwimlaneList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TGT_IS_ZONE_CHANGED, TGT_SwimlaneList.SetControlActive)
+    CALLBACK_MANAGER:RegisterCallback(TAO_UNIT_GROUPED_CHANGED, TGT_SwimlaneList.SetControlActive)
 end
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/SwimlaneList.xml b/TaosGroupTools/ui/groupultimate/SwimlaneList.xml
index 7830f9a..eb05385 100644
--- a/TaosGroupTools/ui/groupultimate/SwimlaneList.xml
+++ b/TaosGroupTools/ui/groupultimate/SwimlaneList.xml
@@ -1,40 +1,40 @@
-<GuiXml>
-	<Controls>
-		<TopLevelControl name="TGT_SwimlaneListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
-			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
-			<Dimensions x="610" y="265" />
-			<OnMoveStop>TGT_SwimlaneList:OnSwimlaneListMoveStop()</OnMoveStop>
-
-			<Controls>
-        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
-          <Anchor point="TOPLEFT"/>
-          <Anchor point="BOTTOMRIGHT" />
-        </Control>
-
-        <Control name="$(parent)Swimlane1" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane2" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="102" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane3" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="204" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane4" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="306" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane5" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="408" offsetY="0"/>
-        </Control>
-
-        <Control name="$(parent)Swimlane6" inherits="GroupUltimateSwimlane">
-          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="510" offsetY="0"/>
-        </Control>
-		  </Controls>
-	  </TopLevelControl>
-	</Controls>
+<GuiXml>
+	<Controls>
+		<TopLevelControl name="TGT_SwimlaneListControl" hidden="true" layer="OVERLAY" level="1" allowBringToTop="false" mouseEnabled="true" movable="true" clampedToScreen="true">
+			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT"/>
+			<Dimensions x="610" y="265" />
+			<OnMoveStop>TGT_SwimlaneList:OnSwimlaneListMoveStop()</OnMoveStop>
+
+			<Controls>
+        <Control name="$(parent)MovableControl" tier="PARENT" inherits="MovableBackdropControl">
+          <Anchor point="TOPLEFT"/>
+          <Anchor point="BOTTOMRIGHT" />
+        </Control>
+
+        <Control name="$(parent)Swimlane1" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane2" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="102" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane3" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="204" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane4" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="306" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane5" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="408" offsetY="0"/>
+        </Control>
+
+        <Control name="$(parent)Swimlane6" inherits="GroupUltimateSwimlane">
+          <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="510" offsetY="0"/>
+        </Control>
+		  </Controls>
+	  </TopLevelControl>
+	</Controls>
 </GuiXml>
\ No newline at end of file
diff --git a/TaosGroupTools/ui/groupultimate/UltimateGroupMenu.lua b/TaosGroupTools/ui/groupultimate/UltimateGroupMenu.lua
index 2613d87..56d951a 100644
--- a/TaosGroupTools/ui/groupultimate/UltimateGroupMenu.lua
+++ b/TaosGroupTools/ui/groupultimate/UltimateGroupMenu.lua
@@ -1,76 +1,76 @@
---[[
-	Addon: Taos Group Tools
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
---[[
-	Global callbacks
-]]--
-TGT_SHOW_ULTIMATE_GROUP_MENU = "TGT-ShowUltimateGroupMenu"
-TGT_SET_ULTIMATE_GROUP = "TGT-SetUltimateGroup"
-
---[[
-	Local variables
-]]--
-local LOG_ACTIVE = false
-local _logger = nil
-
---[[
-	Table TGT_UltimateGroupMenu
-]]--
-TGT_UltimateGroupMenu = {}
-TGT_UltimateGroupMenu.__index = TGT_UltimateGroupMenu
-
---[[
-	Table Members
-]]--
-
---[[
-	SetUltimateGroup shows ultimate group menu
-]]--
-function TGT_UltimateGroupMenu.SetUltimateGroup(group, arg)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_UltimateGroupMenu.SetultimateGroup")
-        _logger:logDebug("group.GroupName, arg", group.GroupName, arg)
-    end
-
-    CALLBACK_MANAGER:FireCallbacks(TGT_SET_ULTIMATE_GROUP, group, arg)
-end
-
---[[
-	ShowUltimateGroupMenu shows ultimate group menu
-]]--
-function TGT_UltimateGroupMenu.ShowUltimateGroupMenu(control, arg)
-    if (LOG_ACTIVE) then
-        _logger:logTrace("TGT_UltimateGroupMenu.ShowUltimateGroupMenu")
-        _logger:logDebug("arg", arg)
-    end
-
-    if (control ~= nil) then
-        ClearMenu()
-
-        local ultimateGroups = TGT_UltimateGroupHandler.GetUltimateGroups()
-
-        for i, group in pairs(ultimateGroups) do
-            AddMenuItem(group.GroupName .. " - " .. group.GroupDescription, function() TGT_UltimateGroupMenu.SetUltimateGroup(group, arg) end)
-        end
-
-        ShowMenu(control)
-    else
-        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, control nil")
-    end
-end
-
---[[
-	Initialize initializes TGT_UltimateGroupMenu
-]]--
-function TGT_UltimateGroupMenu.Initialize(logger)
-    if (LOG_ACTIVE) then
-        logger:logTrace("TGT_UltimateGroupMenu.Initialize")
-    end
-
-    _logger = logger
-
-    CALLBACK_MANAGER:RegisterCallback(TGT_SHOW_ULTIMATE_GROUP_MENU, TGT_UltimateGroupMenu.ShowUltimateGroupMenu)
+--[[
+	Addon: Taos Group Tools
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+--[[
+	Global callbacks
+]]--
+TGT_SHOW_ULTIMATE_GROUP_MENU = "TGT-ShowUltimateGroupMenu"
+TGT_SET_ULTIMATE_GROUP = "TGT-SetUltimateGroup"
+
+--[[
+	Local variables
+]]--
+local LOG_ACTIVE = false
+local _logger = nil
+
+--[[
+	Table TGT_UltimateGroupMenu
+]]--
+TGT_UltimateGroupMenu = {}
+TGT_UltimateGroupMenu.__index = TGT_UltimateGroupMenu
+
+--[[
+	Table Members
+]]--
+
+--[[
+	SetUltimateGroup shows ultimate group menu
+]]--
+function TGT_UltimateGroupMenu.SetUltimateGroup(group, arg)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_UltimateGroupMenu.SetultimateGroup")
+        _logger:logDebug("group.GroupName, arg", group.GroupName, arg)
+    end
+
+    CALLBACK_MANAGER:FireCallbacks(TGT_SET_ULTIMATE_GROUP, group, arg)
+end
+
+--[[
+	ShowUltimateGroupMenu shows ultimate group menu
+]]--
+function TGT_UltimateGroupMenu.ShowUltimateGroupMenu(control, arg)
+    if (LOG_ACTIVE) then
+        _logger:logTrace("TGT_UltimateGroupMenu.ShowUltimateGroupMenu")
+        _logger:logDebug("arg", arg)
+    end
+
+    if (control ~= nil) then
+        ClearMenu()
+
+        local ultimateGroups = TGT_UltimateGroupHandler.GetUltimateGroups()
+
+        for i, group in pairs(ultimateGroups) do
+            AddMenuItem(group.GroupName .. " - " .. group.GroupDescription, function() TGT_UltimateGroupMenu.SetUltimateGroup(group, arg) end)
+        end
+
+        ShowMenu(control)
+    else
+        _logger:logError("TGT_UltimateGroupMenu.ShowUltimateGroupMenu, control nil")
+    end
+end
+
+--[[
+	Initialize initializes TGT_UltimateGroupMenu
+]]--
+function TGT_UltimateGroupMenu.Initialize(logger)
+    if (LOG_ACTIVE) then
+        logger:logTrace("TGT_UltimateGroupMenu.Initialize")
+    end
+
+    _logger = logger
+
+    CALLBACK_MANAGER:RegisterCallback(TGT_SHOW_ULTIMATE_GROUP_MENU, TGT_UltimateGroupMenu.ShowUltimateGroupMenu)
 end
\ No newline at end of file
diff --git a/TaosGroupTools/util/GroupHelper.lua b/TaosGroupTools/util/GroupHelper.lua
index 03b34b7..370541c 100644
--- a/TaosGroupTools/util/GroupHelper.lua
+++ b/TaosGroupTools/util/GroupHelper.lua
@@ -1,79 +1,79 @@
---[[
-	Addon: util
-	Author: TProg Taonnor
-	Created by @Taonnor
-]]--
-
--- Version Control
-local VERSION = 1
-
---[[
-	Class definition (Static class)
-]]--
--- A table in hole lua workspace must be unique
--- The group helper is global util table, used in several of my addons
--- The table is created as "static" class without constructor and static helper methods
-if (TaosGroupHelper == nil or TaosGroupHelper.Version == nil or TaosGroupHelper.Version < VERSION) then
-	TaosGroupHelper = {}
-	TaosGroupHelper.__index = TaosGroupHelper
-    TaosGroupHelper.Version = VERSION
-
-    -- Global Callback Variables
-    TAO_GROUP_CHANGED = "TAO-GroupChanged"
-    TAO_UNIT_GROUPED_CHANGED = "TAO-UnitGroupedChanged"
-
-	-- local members
-    local name = "TaosGroupHelper"
-    local isUnitGrouped = IsUnitGrouped("player") -- Initial state
-
-    --[[
-        GetIsUnitGrouped Gets the current UnitGrouped state
-    ]]--
-    function GetIsUnitGrouped()
-        return isUnitGrouped
-    end
-
-    --[[
-	    Called when group updated
-    ]]--
-    local function OnGroupUpdate()
-        local isGrouped = IsUnitGrouped("player")
-
-        if (isGrouped ~= isUnitGrouped) then
-            isUnitGrouped = isGrouped
-            CALLBACK_MANAGER:FireCallbacks(TAO_UNIT_GROUPED_CHANGED, isGrouped)
-        end
-    end
-
-    --[[
-	    Called when group member joined group
-    ]]--
-    local function OnGroupMemberJoined()
-        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
-        OnGroupUpdate()
-    end
-
-    --[[
-	    Called when group member left group
-    ]]--
-    local function OnGroupMemberLeft()
-        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
-        OnGroupUpdate()
-    end
-
-    --[[
-	    Called when loading UI finished
-    ]]--
-    local function OnPlayerActivated(eventCode)
-        CALLBACK_MANAGER:FireCallbacks(TAO_UNIT_GROUPED_CHANGED, isUnitGrouped)
-        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
-    end
-
-    --[[
-        Register events
-    ]]--
-	EVENT_MANAGER:RegisterForEvent(name, EVENT_GROUP_MEMBER_JOINED, OnGroupMemberJoined)
-	EVENT_MANAGER:RegisterForEvent(name, EVENT_GROUP_MEMBER_LEFT, OnGroupMemberLeft)
-    EVENT_MANAGER:RegisterForEvent(name, EVENT_PLAYER_ACTIVATED, OnPlayerActivated)
-
+--[[
+	Addon: util
+	Author: TProg Taonnor
+	Created by @Taonnor
+]]--
+
+-- Version Control
+local VERSION = 1
+
+--[[
+	Class definition (Static class)
+]]--
+-- A table in hole lua workspace must be unique
+-- The group helper is global util table, used in several of my addons
+-- The table is created as "static" class without constructor and static helper methods
+if (TaosGroupHelper == nil or TaosGroupHelper.Version == nil or TaosGroupHelper.Version < VERSION) then
+	TaosGroupHelper = {}
+	TaosGroupHelper.__index = TaosGroupHelper
+    TaosGroupHelper.Version = VERSION
+
+    -- Global Callback Variables
+    TAO_GROUP_CHANGED = "TAO-GroupChanged"
+    TAO_UNIT_GROUPED_CHANGED = "TAO-UnitGroupedChanged"
+
+	-- local members
+    local name = "TaosGroupHelper"
+    local isUnitGrouped = IsUnitGrouped("player") -- Initial state
+
+    --[[
+        GetIsUnitGrouped Gets the current UnitGrouped state
+    ]]--
+    function GetIsUnitGrouped()
+        return isUnitGrouped
+    end
+
+    --[[
+	    Called when group updated
+    ]]--
+    local function OnGroupUpdate()
+        local isGrouped = IsUnitGrouped("player")
+
+        if (isGrouped ~= isUnitGrouped) then
+            isUnitGrouped = isGrouped
+            CALLBACK_MANAGER:FireCallbacks(TAO_UNIT_GROUPED_CHANGED, isGrouped)
+        end
+    end
+
+    --[[
+	    Called when group member joined group
+    ]]--
+    local function OnGroupMemberJoined()
+        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
+        OnGroupUpdate()
+    end
+
+    --[[
+	    Called when group member left group
+    ]]--
+    local function OnGroupMemberLeft()
+        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
+        OnGroupUpdate()
+    end
+
+    --[[
+	    Called when loading UI finished
+    ]]--
+    local function OnPlayerActivated(eventCode)
+        CALLBACK_MANAGER:FireCallbacks(TAO_UNIT_GROUPED_CHANGED, isUnitGrouped)
+        CALLBACK_MANAGER:FireCallbacks(TAO_GROUP_CHANGED)
+    end
+
+    --[[
+        Register events
+    ]]--
+	EVENT_MANAGER:RegisterForEvent(name, EVENT_GROUP_MEMBER_JOINED, OnGroupMemberJoined)
+	EVENT_MANAGER:RegisterForEvent(name, EVENT_GROUP_MEMBER_LEFT, OnGroupMemberLeft)
+    EVENT_MANAGER:RegisterForEvent(name, EVENT_PLAYER_ACTIVATED, OnPlayerActivated)
+
 end
\ No newline at end of file