Files
SnowcloakClient/MareSynchronos/UI/EventViewerUI.cs

239 lines
9.1 KiB
C#
Raw Normal View History

2025-08-22 02:19:48 +01:00
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using MareSynchronos.MareConfiguration;
using MareSynchronos.Services;
using MareSynchronos.Services.Events;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
namespace MareSynchronos.UI;
internal class EventViewerUI : WindowMediatorSubscriberBase
{
private readonly EventAggregator _eventAggregator;
private readonly UiSharedService _uiSharedService;
private readonly MareConfigService _configService;
private List<Event> _currentEvents = new();
private Lazy<List<Event>> _filteredEvents;
private string _filterFreeText = string.Empty;
private bool _isPaused = false;
private List<Event> CurrentEvents
{
get
{
return _currentEvents;
}
set
{
_currentEvents = value;
_filteredEvents = RecreateFilter();
}
}
public EventViewerUI(ILogger<EventViewerUI> logger, MareMediator mediator,
EventAggregator eventAggregator, UiSharedService uiSharedService, MareConfigService configService,
PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Event Viewer", performanceCollectorService)
{
_eventAggregator = eventAggregator;
_uiSharedService = uiSharedService;
_configService = configService;
SizeConstraints = new()
{
MinimumSize = new(700, 400)
};
_filteredEvents = RecreateFilter();
}
private Lazy<List<Event>> RecreateFilter()
{
return new(() =>
CurrentEvents.Where(f =>
string.IsNullOrEmpty(_filterFreeText)
|| (f.EventSource.Contains(_filterFreeText, StringComparison.OrdinalIgnoreCase)
|| f.Character.Contains(_filterFreeText, StringComparison.OrdinalIgnoreCase)
|| f.UID.Contains(_filterFreeText, StringComparison.OrdinalIgnoreCase)
|| f.Message.Contains(_filterFreeText, StringComparison.OrdinalIgnoreCase)
)
).ToList());
}
private void ClearFilters()
{
_filterFreeText = string.Empty;
_filteredEvents = RecreateFilter();
}
public override void OnOpen()
{
CurrentEvents = _eventAggregator.EventList.Value.OrderByDescending(f => f.EventTime).ToList();
ClearFilters();
}
protected override void DrawInternal()
{
var newEventsAvailable = _eventAggregator.NewEventsAvailable;
var freezeSize = _uiSharedService.GetIconTextButtonSize(FontAwesomeIcon.PlayCircle, "Unfreeze View");
if (_isPaused)
{
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow, newEventsAvailable))
{
if (_uiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, "Unfreeze View"))
_isPaused = false;
if (newEventsAvailable)
UiSharedService.AttachToolTip("New events are available. Click to resume updating.");
}
}
else
{
if (_uiSharedService.IconTextButton(FontAwesomeIcon.PauseCircle, "Freeze View"))
_isPaused = true;
}
if (newEventsAvailable && !_isPaused)
CurrentEvents = _eventAggregator.EventList.Value.OrderByDescending(f => f.EventTime).ToList();
ImGui.SameLine(freezeSize + ImGui.GetStyle().ItemSpacing.X * 2);
bool changedFilter = false;
ImGui.SetNextItemWidth(200);
changedFilter |= ImGui.InputText("Filter lines", ref _filterFreeText, 50);
if (changedFilter) _filteredEvents = RecreateFilter();
using (ImRaii.Disabled(_filterFreeText.IsNullOrEmpty()))
{
ImGui.SameLine();
if (_uiSharedService.IconButton(FontAwesomeIcon.Ban))
{
_filterFreeText = string.Empty;
_filteredEvents = RecreateFilter();
}
}
if (_configService.Current.LogEvents)
{
var buttonSize = _uiSharedService.GetIconTextButtonSize(FontAwesomeIcon.FolderOpen, "Open EventLog Folder");
var dist = ImGui.GetWindowContentRegionMax().X - buttonSize;
ImGui.SameLine(dist);
if (_uiSharedService.IconTextButton(FontAwesomeIcon.FolderOpen, "Open EventLog folder"))
{
ProcessStartInfo ps = new()
{
FileName = _eventAggregator.EventLogFolder,
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Normal
};
Process.Start(ps);
}
}
var cursorPos = ImGui.GetCursorPosY();
var max = ImGui.GetWindowContentRegionMax();
var min = ImGui.GetWindowContentRegionMin();
var width = max.X - min.X;
var height = max.Y - cursorPos;
using var table = ImRaii.Table("eventTable", 6, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg,
new Vector2(width, height));
float timeColWidth = ImGui.CalcTextSize("88:88:88 PM").X;
float sourceColWidth = ImGui.CalcTextSize("PairManager").X;
float uidColWidth = ImGui.CalcTextSize("WWWWWWW").X;
float characterColWidth = ImGui.CalcTextSize("Wwwwww Wwwwww").X;
if (table)
{
ImGui.TableSetupScrollFreeze(0, 1);
ImGui.TableSetupColumn(string.Empty, ImGuiTableColumnFlags.NoSort);
ImGui.TableSetupColumn("Time", ImGuiTableColumnFlags.None, timeColWidth);
ImGui.TableSetupColumn("Source", ImGuiTableColumnFlags.None, sourceColWidth);
ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, uidColWidth);
ImGui.TableSetupColumn("Character", ImGuiTableColumnFlags.None, characterColWidth);
ImGui.TableSetupColumn("Event", ImGuiTableColumnFlags.None);
ImGui.TableHeadersRow();
int i = 0;
foreach (var ev in _filteredEvents.Value)
{
++i;
var icon = ev.EventSeverity switch
{
EventSeverity.Informational => FontAwesomeIcon.InfoCircle,
EventSeverity.Warning => FontAwesomeIcon.ExclamationTriangle,
EventSeverity.Error => FontAwesomeIcon.Cross,
_ => FontAwesomeIcon.QuestionCircle
};
var iconColor = ev.EventSeverity switch
{
EventSeverity.Informational => new Vector4(),
EventSeverity.Warning => ImGuiColors.DalamudYellow,
EventSeverity.Error => ImGuiColors.DalamudRed,
_ => new Vector4()
};
ImGui.TableNextColumn();
_uiSharedService.IconText(icon, iconColor == new Vector4() ? null : iconColor);
UiSharedService.AttachToolTip(ev.EventSeverity.ToString());
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(ev.EventTime.ToString("T", CultureInfo.CurrentCulture));
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(ev.EventSource);
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
if (!string.IsNullOrEmpty(ev.UID))
{
if (ImGui.Selectable(ev.UID + $"##{i}"))
{
_filterFreeText = ev.UID;
_filteredEvents = RecreateFilter();
}
}
else
{
ImGui.TextUnformatted("--");
}
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
if (!string.IsNullOrEmpty(ev.Character))
{
if (ImGui.Selectable(ev.Character + $"##{i}"))
{
_filterFreeText = ev.Character;
_filteredEvents = RecreateFilter();
}
}
else
{
ImGui.TextUnformatted("--");
}
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
var posX = ImGui.GetCursorPosX();
var maxTextLength = ImGui.GetWindowContentRegionMax().X - posX;
var textSize = ImGui.CalcTextSize(ev.Message).X;
var msg = ev.Message;
while (textSize > maxTextLength)
{
msg = msg[..^5] + "...";
textSize = ImGui.CalcTextSize(msg).X;
}
ImGui.TextUnformatted(msg);
if (!string.Equals(msg, ev.Message, StringComparison.Ordinal))
{
UiSharedService.AttachToolTip(ev.Message);
}
}
}
}
}