* Fix some bugs in stations and do a little cleanup. * Begin backporting the guidebook. * wow that's a lot of work. * More work, gives the monkey some more interactions. * disco monkye. * monky * jobs entry. * more writing. * disco * im being harassed * fix spacing. * i hate writing. * Update Resources/Prototypes/Entities/Mobs/NPCs/animals.yml Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> * builds again * a * pilfer changes from AL * fix and remove unused code * pilfer actual guide changes from AL * localization * more error logs & safety checks * replace controls button with command * add test * todos * pidgin parsing * remove old parser * Move files and change tree sorting * add localization and public methods. * Add help component/verb * rename ITag to IDocumentTag * Fix yml and tweak tooltips * autoclose tooltip * Split container * Fancier-tree * Hover color * txt to xml * oops * Curse you hidden merge conflicts * Rename parsing manager * Stricter arg parsing tag args must now be of the form key="value" * Change default args * Moar tests * nullable enable * Even fancier tree * extremely fancy trees * better indent icons * stricter xml and subheadings * tweak embed margin * Fix parsing bugs * quick fixes. * spain. * ogh * hn bmvdsyc Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
143 lines
4.2 KiB
C#
143 lines
4.2 KiB
C#
using System.Linq;
|
|
using Content.Client.UserInterface.Controls;
|
|
using Content.Client.UserInterface.Controls.FancyTree;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.ContentPack;
|
|
|
|
namespace Content.Client.Guidebook.Controls;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class GuidebookWindow : FancyWindow
|
|
{
|
|
[Dependency] private readonly IResourceManager _resourceManager = default!;
|
|
[Dependency] private readonly DocumentParsingManager _parsingMan = default!;
|
|
|
|
private Dictionary<string, GuideEntry> _entries = new();
|
|
|
|
public GuidebookWindow()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
|
|
Tree.OnSelectedItemChanged += OnSelectionChanged;
|
|
}
|
|
|
|
private void OnSelectionChanged(TreeItem? item)
|
|
{
|
|
if (item != null && item.Metadata is GuideEntry entry)
|
|
ShowGuide(entry);
|
|
else
|
|
ClearSelectedGuide();
|
|
}
|
|
|
|
public void ClearSelectedGuide()
|
|
{
|
|
Placeholder.Visible = true;
|
|
EntryContainer.Visible = false;
|
|
EntryContainer.RemoveAllChildren();
|
|
}
|
|
|
|
private void ShowGuide(GuideEntry entry)
|
|
{
|
|
Scroll.SetScrollValue(default);
|
|
Placeholder.Visible = false;
|
|
EntryContainer.Visible = true;
|
|
EntryContainer.RemoveAllChildren();
|
|
using var file = _resourceManager.ContentFileReadText(entry.Text);
|
|
|
|
if (!_parsingMan.TryAddMarkup(EntryContainer, file.ReadToEnd()))
|
|
{
|
|
EntryContainer.AddChild(new Label() { Text = "ERROR: Failed to parse document." });
|
|
Logger.Error($"Failed to parse contents of guide document {entry.Id}.");
|
|
}
|
|
}
|
|
|
|
public void UpdateGuides(
|
|
Dictionary<string, GuideEntry> entries,
|
|
List<string>? rootEntries = null,
|
|
string? forceRoot = null,
|
|
string? selected = null)
|
|
{
|
|
_entries = entries;
|
|
RepopulateTree(rootEntries, forceRoot);
|
|
ClearSelectedGuide();
|
|
|
|
Split.State = SplitContainer.SplitState.Auto;
|
|
if (entries.Count == 1)
|
|
{
|
|
TreeBox.Visible = false;
|
|
Split.ResizeMode = SplitContainer.SplitResizeMode.NotResizable;
|
|
selected = entries.Keys.First();
|
|
}
|
|
else
|
|
{
|
|
TreeBox.Visible = true;
|
|
Split.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize;
|
|
}
|
|
|
|
if (selected != null)
|
|
{
|
|
var item = Tree.Items.FirstOrDefault(x => x.Metadata is GuideEntry entry && entry.Id == selected);
|
|
Tree.SetSelectedIndex(item?.Index);
|
|
}
|
|
}
|
|
|
|
private IEnumerable<GuideEntry> GetSortedRootEntries(List<string>? rootEntries)
|
|
{
|
|
if (rootEntries == null)
|
|
{
|
|
HashSet<string> entries = new(_entries.Keys);
|
|
foreach (var entry in _entries.Values)
|
|
{
|
|
entries.ExceptWith(entry.Children);
|
|
}
|
|
rootEntries = entries.ToList();
|
|
}
|
|
|
|
return rootEntries
|
|
.Select(x => _entries[x])
|
|
.OrderBy(x => x.Priority)
|
|
.ThenBy(x => Loc.GetString(x.Name));
|
|
}
|
|
|
|
private void RepopulateTree(List<string>? roots = null, string? forcedRoot = null)
|
|
{
|
|
Tree.Clear();
|
|
|
|
HashSet<string> addedEntries = new();
|
|
|
|
TreeItem? parent = forcedRoot == null ? null : AddEntry(forcedRoot, null, addedEntries);
|
|
foreach (var entry in GetSortedRootEntries(roots))
|
|
{
|
|
AddEntry(entry.Id, parent, addedEntries);
|
|
}
|
|
Tree.SetAllExpanded(true);
|
|
}
|
|
|
|
private TreeItem? AddEntry(string id, TreeItem? parent, HashSet<string> addedEntries)
|
|
{
|
|
if (!_entries.TryGetValue(id, out var entry))
|
|
return null;
|
|
|
|
if (!addedEntries.Add(id))
|
|
{
|
|
Logger.Error($"Adding duplicate guide entry: {id}");
|
|
return null;
|
|
}
|
|
|
|
var item = Tree.AddItem(parent);
|
|
item.Metadata = entry;
|
|
var name = Loc.GetString(entry.Name);
|
|
item.Label.Text = name;
|
|
|
|
foreach (var child in entry.Children)
|
|
{
|
|
AddEntry(child, item, addedEntries);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
}
|