mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-23 00:27:50 +03:00
* Большое обновление книжек * Remove dotnet tool cache artifacts * Remove dotnet tool cache artifacts 2 * All comments on English * Add all validation * All localization, code reduction, named bookmarks system * Add "try catch" because coderabbitai asked * Add base check content length * Fix "\\n" * the "BookRandomStory" system has been fix and translate * little fix "BookRandomStory" system * 2 little fix "BookRandomStory" system * 3 little fix "BookRandomStory" system * 4 little fix "BookRandomStory" system * 5 little fix "BookRandomStory" system * Improved handling of UTF-8 character truncation * 2 Improved validation and handling of UTF-8 character truncation * Mini-up for author_books * add new author book for botany * Smaller long of text on one page * translation of the new janitor's book * Spelling lesson * Make TODO notes * Translate TODO notes... * little fix "Check the status of the dialog before using it." * DONE: Create new pages to transfer text, not replace old ones * DONE: Make it visible when the text limit per page is exceeded * DONE: Make it possible to delete unnecessary pages * Fall protection on incorrect markings * fix ".ftl" * Text length limit for SplitContentIntoPages * change limits * Add sound * Add placeholder to loadouts and new symbol for CreateNewPage * Apply some suggestions from code review All changes, except moving files into White folders Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * Apply some suggestions from code review 2 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * Transfering into "_White" folder * Remove dublicate code * Added the necessary code * Add method * BookSystem has been transfered into "Shared" folder * Add attributions for ".ogg" * changes for tools have been canceled * Apply some suggestions from code review 3 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * content have been transfered into "_White" folder 2 * Little fix locales * Apply some suggestions from code review 4 Add comments in "Resources/Prototypes/Entities/Objects/Misc/books_author.yml" Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * content have been transfered into "_White" folder and translate * English spelling lesson Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * Add BookRandomeStorySystem * Apply some suggestions from code review 5 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * rolling back some changes from "code review 5" * Spelling lesson 2 * tweak BookSystem. (Apply suggestion from code review) Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * Little fix bookmark-default-title * Apply some suggestions from code review 6 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * fix code review changes and transfer "BookRandomStorySystem.cs" into "Content.System" * Half of good locales * full good locales of RandomStorySystem * Spelling lesson 3 * Removed unnecessary StoryGen file * Fixed bookmarks pos after del any page * Transd files into _White folder * Fixed the constant activity of the add page button * Correction at the request of coderabbitai * Transfered at the request of code review * Transfered at the request of code review 2 * Fix transfer * Apply suggestions from code review 7 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> * Apply suggestions from code review 8 Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Apply and fix all suggestions from code review of file "BookWindow.xaml.cs" * Fix formated * Apply some suggestions from code review 9 maybe last... Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add try catch on texture loading * Add Dispose method * Correct display of blank pages * Little fix eng locale * Unnecessary code removed * A Little Defense Against NRE/KeyNotFound. * Highlighting the current page in the bookmarks drop-down list. * Added fallback for the save button when there is no hotkey. * Correct unsubscribing from events. * Little fix save button * Little fix formated * Locales transfered fix --------- Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
458 lines
16 KiB
C#
458 lines
16 KiB
C#
using System.Linq;
|
|
using System.Numerics;
|
|
using Content.Client.UserInterface.Controls;
|
|
using Content.Shared._White.Book;
|
|
using Content.Shared.Administration;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Input;
|
|
using Robust.Client.ResourceManagement;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Input;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client._White.Book.UI;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class BookWindow : FancyWindow
|
|
{
|
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
|
[Dependency] private readonly ILogManager _logManager = default!;
|
|
|
|
private List<string> _pages = new();
|
|
private int _currentPageIndex = 0;
|
|
private Dictionary<int, string> _bookmarks = new();
|
|
private int _maxBookmarks;
|
|
private DialogWindow? _bookmarkDialog;
|
|
private int _maxCharactersPerPage;
|
|
private int _maxPages;
|
|
private Label? _characterCountLabel;
|
|
private ISawmill _sawmill = default!;
|
|
private Action? _bookmarkDialogOnClose;
|
|
|
|
private void OnPrevPressed(BaseButton.ButtonEventArgs _) => NavigateToPage(_currentPageIndex - 1);
|
|
private void OnNextPressed(BaseButton.ButtonEventArgs _) => NavigateToPage(_currentPageIndex + 1);
|
|
private void OnAddPagePressed(BaseButton.ButtonEventArgs _) => OnAddPage?.Invoke();
|
|
private void OnSavePressed(BaseButton.ButtonEventArgs _) => SaveCurrentPage();
|
|
private void OnDeletePressed(BaseButton.ButtonEventArgs _) => DeleteCurrentPage();
|
|
private void OnToggleBookmarkPressed(BaseButton.ButtonEventArgs _) => ToggleBookmarkForCurrentPage();
|
|
private void OnBookmarksTogglePressed(BaseButton.ButtonEventArgs _) => ToggleBookmarksVisibility();
|
|
|
|
public event Action<int>? OnPageChanged;
|
|
public event Action<string>? OnTextSaved;
|
|
public event Action? OnAddPage;
|
|
public event Action<int, string>? OnBookmarkAdded;
|
|
public event Action<int>? OnBookmarkRemoved;
|
|
public event Action<int>? OnPageDeleted;
|
|
|
|
public BookWindow()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
|
|
_sawmill = _logManager.GetSawmill("book.ui");
|
|
|
|
var resCache = IoCManager.Resolve<IResourceCache>();
|
|
|
|
try
|
|
{
|
|
var customTexture = resCache.GetResource<TextureResource>("/Textures/_White/Interface/Book/rounded_book_background.png");
|
|
var paperSheetTexture = resCache.GetResource<TextureResource>("/Textures/_White/Interface/Book/paper_sheet_curled_edges.png");
|
|
|
|
var paperBackground = new StyleBoxTexture
|
|
{
|
|
Texture = customTexture,
|
|
Mode = StyleBoxTexture.StretchMode.Stretch
|
|
};
|
|
var paperSheetBackground = new StyleBoxTexture
|
|
{
|
|
Texture = paperSheetTexture,
|
|
Mode = StyleBoxTexture.StretchMode.Stretch,
|
|
Modulate = Color.FromHex("#f8f8f8") // Paper color
|
|
};
|
|
|
|
paperBackground.SetPatchMargin(StyleBox.Margin.All, 24.0f);
|
|
paperSheetBackground.SetPatchMargin(StyleBox.Margin.All, 20.0f);
|
|
|
|
WindowsPanelBackground.PanelOverride = paperBackground;
|
|
WindowsPanelBackground.ModulateSelfOverride = Color.FromHex("#636363ff"); // Book color
|
|
|
|
PaperBackground.Margin = new Thickness(0, 8, 5, 0);
|
|
PaperBackground.MinSize = new Vector2(400, 500);
|
|
PaperBackground.PanelOverride = paperSheetBackground;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Fallback to default styling if texture loading fails
|
|
_sawmill.Error($"Failed to load book textures: {ex}");
|
|
}
|
|
|
|
WindowsHeadingBackground.Visible = false;
|
|
|
|
var floatingCloseButton = new PanelContainer
|
|
{
|
|
StyleClasses = { "AngleRect", },
|
|
VerticalAlignment = VAlignment.Top,
|
|
HorizontalAlignment = HAlignment.Right,
|
|
Margin = new Thickness(0, -50, 10, 0),
|
|
SetSize = new Vector2(42, 42),
|
|
VerticalExpand = false,
|
|
HorizontalExpand = false
|
|
};
|
|
|
|
CloseButton.Parent?.RemoveChild(CloseButton);
|
|
floatingCloseButton.AddChild(CloseButton);
|
|
|
|
AddChild(floatingCloseButton);
|
|
|
|
PrevPageButton.OnPressed += OnPrevPressed;
|
|
NextPageButton.OnPressed += OnNextPressed;
|
|
AddPageButton.OnPressed += OnAddPagePressed;
|
|
|
|
Input.OnKeyBindDown += args =>
|
|
{
|
|
if (args.Function == EngineKeyFunctions.MultilineTextSubmit)
|
|
{
|
|
SaveCurrentPage();
|
|
args.Handle();
|
|
}
|
|
};
|
|
|
|
SaveButton.OnPressed += OnSavePressed;
|
|
var key = _inputManager.GetKeyFunctionButtonString(EngineKeyFunctions.MultilineTextSubmit);
|
|
SaveButton.Text = Loc.GetString(
|
|
string.IsNullOrEmpty(key)
|
|
? "book-ui-save-button-no-keybind"
|
|
: "book-ui-save-button",
|
|
("keybind", key)
|
|
);
|
|
|
|
PageNumberInput.OnTextChanged += args =>
|
|
{
|
|
const int maxLength = 3;
|
|
|
|
if (args.Text.Length > maxLength)
|
|
PageNumberInput.Text = args.Text[..maxLength];
|
|
|
|
var newText = string.Concat(args.Text.Where(char.IsDigit));
|
|
if (newText != args.Text)
|
|
PageNumberInput.Text = newText;
|
|
};
|
|
PageNumberInput.OnTextEntered += OnPageNumberEntered;
|
|
PageNumberInput.OnFocusExit += OnPageNumberEntered;
|
|
InitializeBookmarks();
|
|
|
|
Input.OnTextChanged += _ => UpdateCharacterCount();
|
|
|
|
DeletePageButton.OnPressed += OnDeletePressed;
|
|
}
|
|
|
|
public void ShowBook(BookBoundUserInterfaceState state, bool isEditing)
|
|
{
|
|
_pages = state.Pages;
|
|
_bookmarks = state.Bookmarks;
|
|
_maxBookmarks = state.MaxBookmarks;
|
|
_maxCharactersPerPage = state.MaxCharactersPerPage;
|
|
_maxPages = state.MaxPages;
|
|
|
|
_currentPageIndex = Math.Max(0, Math.Min(state.CurrentPage, _pages.Count - 1));
|
|
|
|
UpdatePageDisplay();
|
|
UpdateNavigationButtons();
|
|
SetEditMode(isEditing);
|
|
UpdateBookmarksDisplay();
|
|
}
|
|
|
|
private void SetEditMode(bool isEditing)
|
|
{
|
|
InputContainer.Visible = isEditing;
|
|
EditButtons.Visible = isEditing;
|
|
PageContainer.Visible = !isEditing;
|
|
|
|
if (!isEditing)
|
|
return;
|
|
if (_currentPageIndex >= 0 && _currentPageIndex < _pages.Count && _pages.Count > 0)
|
|
{
|
|
Input.TextRope = new Rope.Leaf(_pages[_currentPageIndex]);
|
|
Input.CursorPosition = new TextEdit.CursorPos(Rope.Collapse(Input.TextRope).Length, TextEdit.LineBreakBias.Top);
|
|
}
|
|
else
|
|
{
|
|
Input.TextRope = new Rope.Leaf("");
|
|
Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top);
|
|
}
|
|
UpdateCharacterCount();
|
|
}
|
|
|
|
private void SaveCurrentPage()
|
|
{
|
|
OnTextSaved?.Invoke(Rope.Collapse(Input.TextRope));
|
|
}
|
|
|
|
private void UpdatePageDisplay()
|
|
{
|
|
PageContainer.RemoveAllChildren();
|
|
if (_pages.Count == 0)
|
|
{
|
|
var blankPageLabel = new RichTextLabel();
|
|
blankPageLabel.SetMessage(Loc.GetString("paper-ui-blank-page-message"), null, Color.Gray);
|
|
PageContainer.AddChild(blankPageLabel);
|
|
}
|
|
else if (_currentPageIndex < _pages.Count)
|
|
{
|
|
var pageText = _pages[_currentPageIndex];
|
|
if (string.IsNullOrWhiteSpace(pageText))
|
|
{
|
|
var blankPageLabel = new RichTextLabel();
|
|
blankPageLabel.SetMessage(Loc.GetString("paper-ui-blank-page-message"), null, Color.Gray);
|
|
PageContainer.AddChild(blankPageLabel);
|
|
}
|
|
else
|
|
{
|
|
var label = new RichTextLabel();
|
|
var formattedMessage = new FormattedMessage();
|
|
formattedMessage.PushColor(Color.Black);
|
|
if (!formattedMessage.TryAddMarkup(pageText, out _))
|
|
formattedMessage.AddText(pageText);
|
|
formattedMessage.Pop();
|
|
label.SetMessage(formattedMessage);
|
|
PageContainer.AddChild(label);
|
|
}
|
|
}
|
|
PageInfo.Text = Loc.GetString("book-page-info", ("total", _pages.Count));
|
|
}
|
|
|
|
private void UpdatePageNumberDisplay()
|
|
{
|
|
PageNumberInput.Text = Math.Min(_pages.Count, _currentPageIndex + 1).ToString();
|
|
}
|
|
|
|
private void NavigateToPage(int pageIndex)
|
|
{
|
|
if (pageIndex >= 0 && pageIndex < _pages.Count)
|
|
{
|
|
_currentPageIndex = pageIndex;
|
|
OnPageChanged?.Invoke(pageIndex);
|
|
UpdatePageDisplay();
|
|
UpdateNavigationButtons();
|
|
UpdateBookmarksDisplay();
|
|
if (InputContainer.Visible)
|
|
SetEditMode(true);
|
|
}
|
|
else
|
|
{
|
|
UpdatePageNumberDisplay();
|
|
}
|
|
}
|
|
|
|
private void ToggleBookmarksVisibility()
|
|
{
|
|
BookmarksPanel.Visible = !BookmarksPanel.Visible;
|
|
BookmarksToggleButton.Text = BookmarksPanel.Visible ? Loc.GetString("book-bookmarks-hide") : Loc.GetString("book-bookmarks-show");
|
|
}
|
|
|
|
private void ToggleBookmarkForCurrentPage()
|
|
{
|
|
if (_currentPageIndex < 0 || _currentPageIndex >= _pages.Count)
|
|
return;
|
|
if (_bookmarks.Remove(_currentPageIndex))
|
|
{
|
|
OnBookmarkRemoved?.Invoke(_currentPageIndex);
|
|
}
|
|
else if (_bookmarks.Count < _maxBookmarks)
|
|
{
|
|
var defaultTitle = Loc.GetString("book-bookmark-default-title", ("page", _currentPageIndex + 1));
|
|
ShowBookmarkDialog(defaultTitle);
|
|
}
|
|
|
|
UpdateBookmarksDisplay();
|
|
}
|
|
|
|
private void UpdateNavigationButtons()
|
|
{
|
|
if (_pages == null)
|
|
{
|
|
PrevPageButton.Disabled = true;
|
|
NextPageButton.Disabled = true;
|
|
DeletePageButton.Disabled = true;
|
|
AddPageButton.Disabled = true;
|
|
return;
|
|
}
|
|
PrevPageButton.Disabled = _currentPageIndex <= 0;
|
|
NextPageButton.Disabled = _currentPageIndex >= _pages.Count - 1;
|
|
DeletePageButton.Disabled = _pages.Count <= 1;
|
|
AddPageButton.Disabled = _pages.Count >= _maxPages;
|
|
UpdatePageNumberDisplay();
|
|
}
|
|
|
|
private void OnPageNumberEntered(LineEdit.LineEditEventArgs args)
|
|
{
|
|
if (int.TryParse(args.Text, out var pageNumber) && pageNumber > 0)
|
|
{
|
|
NavigateToPage(pageNumber - 1);
|
|
}
|
|
else
|
|
{
|
|
UpdatePageNumberDisplay();
|
|
}
|
|
}
|
|
|
|
private void InitializeBookmarks()
|
|
{
|
|
ToggleBookmarkButton.OnPressed += OnToggleBookmarkPressed;
|
|
BookmarkDropdown.OnItemSelected += OnBookmarkSelected;
|
|
BookmarksToggleButton.OnPressed += OnBookmarksTogglePressed;
|
|
}
|
|
|
|
private void ShowBookmarkDialog(string defaultTitle)
|
|
{
|
|
if (_bookmarkDialog != null)
|
|
{
|
|
if (_bookmarkDialog.IsOpen)
|
|
{
|
|
_bookmarkDialog.MoveToFront();
|
|
return;
|
|
}
|
|
_bookmarkDialog = null;
|
|
}
|
|
var field = "title";
|
|
var prompt = Loc.GetString("book-bookmark-title-prompt");
|
|
var entry = new QuickDialogEntry(field, QuickDialogEntryType.ShortText, prompt, defaultTitle);
|
|
var entries = new List<QuickDialogEntry> { entry, };
|
|
_bookmarkDialog = new DialogWindow(Loc.GetString("book-bookmark-title-dialog"), entries);
|
|
_bookmarkDialog.OnConfirmed += responses =>
|
|
{
|
|
if (!responses.TryGetValue(field, out var title))
|
|
title = defaultTitle;
|
|
title = title.Trim();
|
|
if (string.IsNullOrEmpty(title))
|
|
title = defaultTitle;
|
|
|
|
const int maxLength = 50;
|
|
if (title.Length > maxLength)
|
|
title = title[..maxLength];
|
|
|
|
_bookmarks[_currentPageIndex] = title;
|
|
OnBookmarkAdded?.Invoke(_currentPageIndex, title);
|
|
UpdateBookmarksDisplay();
|
|
};
|
|
_bookmarkDialogOnClose ??= () => _bookmarkDialog = null;
|
|
_bookmarkDialog.OnClose += _bookmarkDialogOnClose;
|
|
}
|
|
|
|
private void OnBookmarkSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
switch (args.Id)
|
|
{
|
|
case -1:
|
|
return;
|
|
case var pageIndex:
|
|
NavigateToPage(pageIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UpdateBookmarksDisplay()
|
|
{
|
|
BookmarkDropdown.Clear();
|
|
|
|
if (_bookmarks.Count == 0)
|
|
{
|
|
BookmarkDropdown.Disabled = true;
|
|
BookmarkCountLabel.Text = Loc.GetString("book-no-bookmarks");
|
|
}
|
|
else
|
|
{
|
|
BookmarkDropdown.Disabled = false;
|
|
BookmarkDropdown.AddItem(Loc.GetString("book-select-bookmark"), -1);
|
|
|
|
var sortedBookmarks = _bookmarks.OrderBy(kvp => kvp.Key);
|
|
foreach (var bookmark in sortedBookmarks)
|
|
{
|
|
var displayText = bookmark.Value;
|
|
BookmarkDropdown.AddItem(displayText, bookmark.Key);
|
|
}
|
|
|
|
BookmarkCountLabel.Text = Loc.GetString("book-bookmarks-count", ("count", _bookmarks.Count), ("max", _maxBookmarks));
|
|
if (_bookmarks.ContainsKey(_currentPageIndex))
|
|
BookmarkDropdown.SelectId(_currentPageIndex);
|
|
else
|
|
BookmarkDropdown.SelectId(-1);
|
|
}
|
|
|
|
if (_bookmarks.ContainsKey(_currentPageIndex))
|
|
{
|
|
ToggleBookmarkButton.Text = "-";
|
|
ToggleBookmarkButton.Disabled = false;
|
|
}
|
|
else if (_bookmarks.Count >= _maxBookmarks)
|
|
{
|
|
ToggleBookmarkButton.Text = "+";
|
|
ToggleBookmarkButton.Disabled = true;
|
|
}
|
|
else
|
|
{
|
|
ToggleBookmarkButton.Text = "+";
|
|
ToggleBookmarkButton.Disabled = false;
|
|
}
|
|
}
|
|
|
|
private void UpdateCharacterCount()
|
|
{
|
|
if (CharacterCountLabel == null || !InputContainer.Visible)
|
|
return;
|
|
var currentLength = Rope.Collapse(Input.TextRope).Length;
|
|
var isOverLimit = currentLength > _maxCharactersPerPage;
|
|
CharacterCountLabel.Text = Loc.GetString("book-character-count",
|
|
("current", currentLength),
|
|
("max", _maxCharactersPerPage));
|
|
if (isOverLimit)
|
|
{
|
|
CharacterCountLabel.StyleClasses.Clear();
|
|
CharacterCountLabel.StyleClasses.Add("LabelDanger");
|
|
}
|
|
else
|
|
{
|
|
CharacterCountLabel.StyleClasses.Clear();
|
|
CharacterCountLabel.StyleClasses.Add("LabelSubText");
|
|
}
|
|
}
|
|
|
|
private void DeleteCurrentPage()
|
|
{
|
|
if (_pages.Count <= 1 || _currentPageIndex < 0 || _currentPageIndex >= _pages.Count)
|
|
return;
|
|
|
|
OnPageDeleted?.Invoke(_currentPageIndex);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
base.Dispose(disposing);
|
|
if (!disposing)
|
|
return;
|
|
|
|
PrevPageButton.OnPressed -= OnPrevPressed;
|
|
NextPageButton.OnPressed -= OnNextPressed;
|
|
AddPageButton.OnPressed -= OnAddPagePressed;
|
|
SaveButton.OnPressed -= OnSavePressed;
|
|
DeletePageButton.OnPressed -= OnDeletePressed;
|
|
|
|
PageNumberInput.OnTextEntered -= OnPageNumberEntered;
|
|
PageNumberInput.OnFocusExit -= OnPageNumberEntered;
|
|
|
|
ToggleBookmarkButton.OnPressed -= OnToggleBookmarkPressed;
|
|
BookmarkDropdown.OnItemSelected -= OnBookmarkSelected;
|
|
BookmarksToggleButton.OnPressed -= OnBookmarksTogglePressed;
|
|
|
|
if (_bookmarkDialog != null)
|
|
{
|
|
if (_bookmarkDialogOnClose != null)
|
|
_bookmarkDialog.OnClose -= _bookmarkDialogOnClose;
|
|
_bookmarkDialog = null;
|
|
_bookmarkDialogOnClose = null;
|
|
}
|
|
}
|
|
}
|