feat: add arbitrary grouping

This commit is contained in:
Anna 2024-02-18 15:00:27 -05:00
parent 4c575d622a
commit 14f96ff6ba
Signed by: anna
GPG Key ID: D0943384CD9F87D1
2 changed files with 133 additions and 11 deletions

View File

@ -1,4 +1,8 @@
using System.Data;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using ImGuiNET;
using Newtonsoft.Json;
using Screenie.Util;
@ -10,9 +14,22 @@ internal class DatabaseTab : ITab {
private Plugin Plugin { get; }
private List<SavedMetadata> Screenshots { get; } = [];
private LinkedList<GroupBy> GroupBys { get; } = new();
private GroupBy _selectedGroupBy = GroupBy.Character;
private enum GroupBy {
Character,
World,
Year,
Month,
Day,
Location,
}
internal DatabaseTab(Plugin plugin) {
this.Plugin = plugin;
this.GroupBys.AddLast(GroupBy.Character);
this.Update();
}
@ -25,23 +42,114 @@ internal class DatabaseTab : ITab {
this.Update();
}
var byChara = this.Screenshots.GroupBy(shot => {
var chara = shot.Metadata.ActiveCharacter;
if (chara == null) {
return default;
var first = true;
foreach (var groupBy in this.GroupBys) {
if (first) {
ImGui.TextUnformatted($"Group by {Enum.GetName(groupBy)}");
} else {
ImGui.TextUnformatted($"then by {Enum.GetName(groupBy)}");
}
first = false;
}
return (chara.Name, chara.HomeWorld);
});
Vector2 buttonSize;
ImGui.PushFont(UiBuilder.IconFont);
using (new OnDispose(ImGui.PopFont)) {
buttonSize = ImGuiHelpers.GetButtonSize(FontAwesomeIcon.Plus.ToIconString());
}
foreach (var group in byChara) {
var (name, homeWorld) = group.Key;
if (ImGui.CollapsingHeader($"{name} ({homeWorld})")) {
foreach (var shot in group) {
ImGui.TextUnformatted(shot.Path);
var comboSize = ImGui.GetContentRegionAvail().X
- buttonSize.X
- ImGui.GetStyle().ItemSpacing.X;
ImGui.SetNextItemWidth(comboSize);
if (ImGui.BeginCombo("##then-by", Enum.GetName(this._selectedGroupBy))) {
using var endCombo = new OnDispose(ImGui.EndCombo);
foreach (var groupBy in Enum.GetValues<GroupBy>()) {
var contained = this.GroupBys.Contains(groupBy);
using (ImGuiHelper.WithDisabled(contained)) {
if (ImGui.Selectable(Enum.GetName(groupBy), this._selectedGroupBy == groupBy)) {
this._selectedGroupBy = groupBy;
}
}
}
}
ImGui.SameLine();
var contains = this.GroupBys.Contains(this._selectedGroupBy);
using (ImGuiHelper.WithDisabled(contains)) {
if (ImGuiComponents.IconButton("add-group-by", FontAwesomeIcon.Plus) && !contains) {
this.GroupBys.AddLast(this._selectedGroupBy);
}
}
if (this.GroupBys.First == null) {
this.DrawShots(this.Screenshots);
} else {
this.DrawGroup(this.GroupBys.First, this.Screenshots);
}
}
private void DrawGroup(LinkedListNode<GroupBy> groupBy, IEnumerable<SavedMetadata> shots) {
var grouped = shots.GroupBy(shot => {
switch (groupBy.Value) {
case GroupBy.Character: {
var chara = shot.Metadata.ActiveCharacter;
if (chara == null) {
return null;
}
return $"{chara.Name} ({chara.HomeWorld})";
}
case GroupBy.World: {
return shot.Metadata.World;
}
case GroupBy.Year: {
return shot.Metadata
.CapturedAtUtc
.ToLocalTime()
.ToString("yyyy");
}
case GroupBy.Month: {
return shot.Metadata
.CapturedAtUtc
.ToLocalTime()
.ToString("MMMM");
}
case GroupBy.Day: {
return shot.Metadata
.CapturedAtUtc
.ToLocalTime()
.ToString("dd");
}
case GroupBy.Location: {
return shot.Metadata.Location;
}
default: {
return null;
}
}
});
foreach (var grouping in grouped) {
var label = grouping.Key;
if (groupBy.Next == null) {
this.DrawShots(grouping);
} else {
this.DrawGroup(groupBy.Next, grouping);
}
}
}
private void DrawShots(IEnumerable<SavedMetadata> shots) {
foreach (var shot in shots) {
this.DrawShot(shot);
}
}
private void DrawShot(SavedMetadata shot) {
ImGui.TextUnformatted(shot.Path);
}
private void Update() {

14
Util/ImGuiHelper.cs Normal file
View File

@ -0,0 +1,14 @@
using ImGuiNET;
namespace Screenie.Util;
internal static class ImGuiHelper {
internal static OnDispose? WithDisabled(bool disabled) {
if (disabled) {
ImGui.BeginDisabled();
return new OnDispose(ImGui.EndDisabled);
}
return null;
}
}