Optimize rendering of large number of pairs
This commit is contained in:
@@ -71,7 +71,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
_groupPanel = new(this, uiShared, _pairManager, uidDisplayHandler, _serverManager);
|
_groupPanel = new(this, uiShared, _pairManager, uidDisplayHandler, _serverManager);
|
||||||
_selectGroupForPairUi = new(tagHandler, uidDisplayHandler);
|
_selectGroupForPairUi = new(tagHandler, uidDisplayHandler);
|
||||||
_selectPairsForGroupUi = new(tagHandler, uidDisplayHandler);
|
_selectPairsForGroupUi = new(tagHandler, uidDisplayHandler);
|
||||||
_pairGroupsUi = new(configService, tagHandler, apiController, _selectPairsForGroupUi);
|
_pairGroupsUi = new(configService, tagHandler, uidDisplayHandler, apiController, _selectPairsForGroupUi);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
string dev = "Dev Build";
|
string dev = "Dev Build";
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public abstract class DrawPairBase
|
|||||||
_displayHandler = uIDDisplayHandler;
|
_displayHandler = uIDDisplayHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ImGuiID => _id;
|
||||||
public string UID => _pair.UserData.UID;
|
public string UID => _pair.UserData.UID;
|
||||||
|
|
||||||
public void DrawPairedClient()
|
public void DrawPairedClient()
|
||||||
@@ -30,6 +31,20 @@ public abstract class DrawPairBase
|
|||||||
var pauseIconSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Play);
|
var pauseIconSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Play);
|
||||||
var textSize = ImGui.CalcTextSize(_pair.UserData.AliasOrUID);
|
var textSize = ImGui.CalcTextSize(_pair.UserData.AliasOrUID);
|
||||||
|
|
||||||
|
var startPos = ImGui.GetCursorStartPos();
|
||||||
|
|
||||||
|
var framePadding = ImGui.GetStyle().FramePadding;
|
||||||
|
var lineHeight = textSize.Y + framePadding.Y * 2;
|
||||||
|
|
||||||
|
var off = startPos.Y;
|
||||||
|
var height = UiSharedService.GetWindowContentRegionHeight();
|
||||||
|
|
||||||
|
if ((originalY + off) < -lineHeight || (originalY + off) > height)
|
||||||
|
{
|
||||||
|
ImGui.Dummy(new System.Numerics.Vector2(0f, lineHeight));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var textPosY = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
|
var textPosY = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
|
||||||
DrawLeftSide(textPosY, originalY);
|
DrawLeftSide(textPosY, originalY);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|||||||
@@ -395,63 +395,56 @@ internal sealed class GroupPanel
|
|||||||
ImGui.Indent(20);
|
ImGui.Indent(20);
|
||||||
if (_expandedGroupState[groupDto.GID])
|
if (_expandedGroupState[groupDto.GID])
|
||||||
{
|
{
|
||||||
var visibleUsers = pairsInGroup.Where(u => u.IsVisible)
|
var sortedPairs = pairsInGroup
|
||||||
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
|
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
|
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
|
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
|
||||||
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
|
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase);
|
||||||
.Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, _mainUi.Mediator, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
|
||||||
_uidDisplayHandler))
|
|
||||||
.ToList();
|
|
||||||
var onlineUsers = pairsInGroup.Where(u => u.IsOnline && !u.IsVisible)
|
|
||||||
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
|
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
|
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
|
|
||||||
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
|
|
||||||
.Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, _mainUi.Mediator, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
|
||||||
_uidDisplayHandler))
|
|
||||||
.ToList();
|
|
||||||
var offlineUsers = pairsInGroup.Where(u => !u.IsOnline && !u.IsVisible)
|
|
||||||
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
|
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
|
|
||||||
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
|
|
||||||
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
|
|
||||||
.Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, _mainUi.Mediator, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
|
||||||
_uidDisplayHandler))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (visibleUsers.Any())
|
var visibleUsers = new List<DrawGroupPair>();
|
||||||
|
var onlineUsers = new List<DrawGroupPair>();
|
||||||
|
var offlineUsers = new List<DrawGroupPair>();
|
||||||
|
|
||||||
|
foreach (var pair in sortedPairs)
|
||||||
{
|
{
|
||||||
ImGui.Text("Visible");
|
var drawPair = new DrawGroupPair(
|
||||||
ImGui.Separator();
|
groupDto.GID + pair.UserData.UID, pair,
|
||||||
foreach (var entry in visibleUsers)
|
ApiController, _mainUi.Mediator, groupDto,
|
||||||
{
|
pair.GroupPair.Single(
|
||||||
using (ImRaii.PushId(groupDto.GID + entry.UID)) entry.DrawPairedClient();
|
g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)
|
||||||
}
|
).Value,
|
||||||
|
_uidDisplayHandler);
|
||||||
|
|
||||||
|
if (pair.IsVisible)
|
||||||
|
visibleUsers.Add(drawPair);
|
||||||
|
else if (pair.IsOnline)
|
||||||
|
onlineUsers.Add(drawPair);
|
||||||
|
else
|
||||||
|
offlineUsers.Add(drawPair);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onlineUsers.Any())
|
if (visibleUsers.Count > 0)
|
||||||
{
|
{
|
||||||
ImGui.Text("Online");
|
ImGui.TextUnformatted("Visible");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
foreach (var entry in onlineUsers)
|
_uidDisplayHandler.RenderPairList(visibleUsers);
|
||||||
{
|
|
||||||
using (ImRaii.PushId(groupDto.GID + entry.UID)) entry.DrawPairedClient();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offlineUsers.Any())
|
if (onlineUsers.Count > 0)
|
||||||
{
|
{
|
||||||
ImGui.Text("Offline/Unknown");
|
ImGui.TextUnformatted("Online");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
foreach (var entry in offlineUsers)
|
_uidDisplayHandler.RenderPairList(onlineUsers);
|
||||||
{
|
}
|
||||||
using (ImRaii.PushId(groupDto.GID + entry.UID)) entry.DrawPairedClient();
|
|
||||||
}
|
if (offlineUsers.Count > 0)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Offline/Unknown");
|
||||||
|
ImGui.Separator();
|
||||||
|
_uidDisplayHandler.RenderPairList(offlineUsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.Unindent(ImGui.GetStyle().ItemSpacing.X / 2);
|
|
||||||
}
|
}
|
||||||
ImGui.Unindent(20);
|
ImGui.Unindent(20);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ public class PairGroupsUi
|
|||||||
private readonly MareConfigService _mareConfig;
|
private readonly MareConfigService _mareConfig;
|
||||||
private readonly SelectPairForGroupUi _selectGroupForPairUi;
|
private readonly SelectPairForGroupUi _selectGroupForPairUi;
|
||||||
private readonly TagHandler _tagHandler;
|
private readonly TagHandler _tagHandler;
|
||||||
|
private readonly UidDisplayHandler _uidDisplayHandler;
|
||||||
|
|
||||||
public PairGroupsUi(MareConfigService mareConfig, TagHandler tagHandler, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
|
public PairGroupsUi(MareConfigService mareConfig, TagHandler tagHandler, UidDisplayHandler uidDisplayHandler, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
|
||||||
{
|
{
|
||||||
_mareConfig = mareConfig;
|
_mareConfig = mareConfig;
|
||||||
_tagHandler = tagHandler;
|
_tagHandler = tagHandler;
|
||||||
|
_uidDisplayHandler = uidDisplayHandler;
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_selectGroupForPairUi = selectGroupForPairUi;
|
_selectGroupForPairUi = selectGroupForPairUi;
|
||||||
}
|
}
|
||||||
@@ -182,10 +184,7 @@ public class PairGroupsUi
|
|||||||
private void DrawPairs(string tag, IEnumerable<DrawPairBase> availablePairsInThisCategory)
|
private void DrawPairs(string tag, IEnumerable<DrawPairBase> availablePairsInThisCategory)
|
||||||
{
|
{
|
||||||
// These are all the OtherUIDs that are tagged with this tag
|
// These are all the OtherUIDs that are tagged with this tag
|
||||||
foreach (var pair in availablePairsInThisCategory)
|
_uidDisplayHandler.RenderPairList(availablePairsInThisCategory);
|
||||||
{
|
|
||||||
using (ImRaii.PushId($"tag-{tag}-pair-${pair.UID}")) pair.DrawPairedClient();
|
|
||||||
}
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using MareSynchronos.Services.ServerConfiguration;
|
|||||||
using MareSynchronos.MareConfiguration;
|
using MareSynchronos.MareConfiguration;
|
||||||
using ImGuiScene;
|
using ImGuiScene;
|
||||||
using MareSynchronos.Services.Mediator;
|
using MareSynchronos.Services.Mediator;
|
||||||
|
using MareSynchronos.UI.Components;
|
||||||
|
|
||||||
namespace MareSynchronos.UI.Handlers;
|
namespace MareSynchronos.UI.Handlers;
|
||||||
|
|
||||||
@@ -32,6 +33,31 @@ public class UidDisplayHandler
|
|||||||
_mareConfigService = mareConfigService;
|
_mareConfigService = mareConfigService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RenderPairList(IEnumerable<DrawPairBase> pairs)
|
||||||
|
{
|
||||||
|
var textHeight = ImGui.GetFontSize();
|
||||||
|
var style = ImGui.GetStyle();
|
||||||
|
var framePadding = style.FramePadding;
|
||||||
|
var spacing = style.ItemSpacing;
|
||||||
|
var lineHeight = textHeight + framePadding.Y * 2 + spacing.Y;
|
||||||
|
var startY = ImGui.GetCursorStartPos().Y;
|
||||||
|
var cursorY = ImGui.GetCursorPosY();
|
||||||
|
var contentHeight = UiSharedService.GetWindowContentRegionHeight();
|
||||||
|
|
||||||
|
foreach (var entry in pairs)
|
||||||
|
{
|
||||||
|
if ((startY + cursorY) < -lineHeight || (startY + cursorY) > contentHeight)
|
||||||
|
{
|
||||||
|
cursorY += lineHeight;
|
||||||
|
ImGui.SetCursorPosY(cursorY);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (ImRaii.PushId(entry.ImGuiID)) entry.DrawPairedClient();
|
||||||
|
cursorY += lineHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawPairText(string id, Pair pair, float textPosX, float originalY, Func<float> editBoxWidth)
|
public void DrawPairText(string id, Pair pair, float textPosX, float originalY, Func<float> editBoxWidth)
|
||||||
{
|
{
|
||||||
ImGui.SameLine(textPosX);
|
ImGui.SameLine(textPosX);
|
||||||
|
|||||||
@@ -326,6 +326,11 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float GetWindowContentRegionHeight()
|
||||||
|
{
|
||||||
|
return ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y;
|
||||||
|
}
|
||||||
|
|
||||||
public static Vector2 GetNormalizedIconTextButtonSize(FontAwesomeIcon icon, string text, float? width = null, bool isInPopup = false)
|
public static Vector2 GetNormalizedIconTextButtonSize(FontAwesomeIcon icon, string text, float? width = null, bool isInPopup = false)
|
||||||
{
|
{
|
||||||
var iconData = GetIconData(icon);
|
var iconData = GetIconData(icon);
|
||||||
|
|||||||
Reference in New Issue
Block a user