mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 22:39:22 +00:00
Stickers: added some code
This commit is contained in:
parent
07d6dff0a9
commit
58079d9390
36 changed files with 2092 additions and 1651 deletions
270
Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs
Normal file
270
Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs
Normal file
|
@ -0,0 +1,270 @@
|
|||
using BTKUILib;
|
||||
using BTKUILib.UIObjects;
|
||||
using BTKUILib.UIObjects.Components;
|
||||
using MTJobSystem;
|
||||
using NAK.Stickers.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Stickers.Integrations;
|
||||
|
||||
public static partial class BTKUIAddon
|
||||
{
|
||||
#region Constants and Fields
|
||||
|
||||
private static readonly HashSet<string> SUPPORTED_IMAGE_EXTENSIONS = new() { ".png", ".jpg", ".jpeg" };
|
||||
|
||||
private static Page _ourDirectoryBrowserPage;
|
||||
|
||||
private static Category _fileCategory;
|
||||
private static Category _folderCategory;
|
||||
|
||||
private static Button[] _fileButtons = new Button[80]; // 100 files, will resize if needed
|
||||
private static Button[] _folderButtons = new Button[20]; // 20 folders, will resize if needed
|
||||
|
||||
private static readonly Button[] _stickerSelectionButtons = new Button[4];
|
||||
private static float _stickerSelectionButtonDoubleClickTime;
|
||||
|
||||
private static DirectoryInfo _curDirectoryInfo;
|
||||
private static string _initialDirectory;
|
||||
private static int _curSelectedSticker;
|
||||
|
||||
private static readonly object _isPopulatingLock = new();
|
||||
private static bool _isPopulating;
|
||||
internal static bool IsPopulatingPage {
|
||||
get { lock (_isPopulatingLock) return _isPopulating; }
|
||||
private set { lock (_isPopulatingLock) _isPopulating = value; }
|
||||
}
|
||||
|
||||
#endregion Constants and Fields
|
||||
|
||||
#region Page Setup
|
||||
|
||||
private static void Setup_StickerSelectionCategory()
|
||||
{
|
||||
_initialDirectory = StickerSystem.GetStickersFolderPath();
|
||||
_curDirectoryInfo = new DirectoryInfo(_initialDirectory);
|
||||
|
||||
// Create page
|
||||
_ourDirectoryBrowserPage = Page.GetOrCreatePage(ModSettings.ModName, "Directory Browser");
|
||||
QuickMenuAPI.AddRootPage(_ourDirectoryBrowserPage);
|
||||
|
||||
// Setup categories
|
||||
_folderCategory = _ourDirectoryBrowserPage.AddCategory("Subdirectories");
|
||||
_fileCategory = _ourDirectoryBrowserPage.AddCategory("Images");
|
||||
|
||||
SetupFolderButtons();
|
||||
SetupFileButtons();
|
||||
SetupStickerSelectionButtons();
|
||||
|
||||
_ourDirectoryBrowserPage.OnPageOpen += OnPageOpen;
|
||||
_ourDirectoryBrowserPage.OnPageClosed += OnPageClosed;
|
||||
}
|
||||
|
||||
private static void SetupFolderButtons(int startIndex = 0)
|
||||
{
|
||||
for (int i = startIndex; i < _folderButtons.Length; i++)
|
||||
{
|
||||
Button button = _folderCategory.AddButton("A", "Stickers-folder", "A");
|
||||
button.OnPress += () =>
|
||||
{
|
||||
if (IsPopulatingPage) return;
|
||||
_curDirectoryInfo = new DirectoryInfo(Path.Combine(_curDirectoryInfo.FullName, button.ButtonTooltip[5..]));
|
||||
_ourDirectoryBrowserPage.OpenPage(false, true);
|
||||
};
|
||||
_folderButtons[i] = button;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupFileButtons(int startIndex = 0)
|
||||
{
|
||||
for (int i = startIndex; i < _fileButtons.Length; i++)
|
||||
{
|
||||
Button button = _fileCategory.AddButton(string.Empty, "Stickers-folder", "A", ButtonStyle.FullSizeImage);
|
||||
button.Hidden = true;
|
||||
button.OnPress += () =>
|
||||
{
|
||||
string absolutePath = Path.Combine(_curDirectoryInfo.FullName, button.ButtonTooltip[5..]);
|
||||
string relativePath = Path.GetRelativePath(_initialDirectory, absolutePath);
|
||||
StickerSystem.Instance.LoadImage(relativePath, _curSelectedSticker);
|
||||
};
|
||||
_fileButtons[i] = button;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupStickerSelectionButtons()
|
||||
{
|
||||
Category stickerSelection = _rootPage.AddMelonCategory(ModSettings.Hidden_Foldout_SelectionCategory);
|
||||
|
||||
for (int i = 0; i < _stickerSelectionButtons.Length; i++)
|
||||
{
|
||||
Button button = stickerSelection.AddButton(string.Empty, "Stickers-puzzle", "Click to select sticker for placement. Double-click or hold to select from Stickers folder.", ButtonStyle.FullSizeImage);
|
||||
var curIndex = i;
|
||||
button.OnPress += () => SelectStickerAtSlot(curIndex);
|
||||
button.OnHeld += () => OpenStickerSelectionForSlot(curIndex);
|
||||
_stickerSelectionButtons[i] = button;
|
||||
|
||||
// initial setup
|
||||
button.ButtonIcon = StickerCache.GetBtkUiIconName(ModSettings.Hidden_SelectedStickerNames.Value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Page Setup
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private static void OnPageOpen()
|
||||
{
|
||||
if (IsPopulatingPage) return; // btkui bug, page open is called twice when using OnHeld
|
||||
IsPopulatingPage = true;
|
||||
|
||||
_ourDirectoryBrowserPage.PageDisplayName = _curDirectoryInfo.Name;
|
||||
|
||||
HideAllButtons(_folderButtons);
|
||||
HideAllButtons(_fileButtons);
|
||||
|
||||
// Populate the page
|
||||
Task.Run(PopulateMenuItems);
|
||||
}
|
||||
|
||||
private static void OnPageClosed()
|
||||
{
|
||||
if (_curDirectoryInfo.FullName != _initialDirectory)
|
||||
_curDirectoryInfo = new DirectoryInfo(Path.Combine(_curDirectoryInfo.FullName, @"..\"));
|
||||
}
|
||||
|
||||
private static void HideAllButtons(Button[] buttons)
|
||||
{
|
||||
foreach (Button button in buttons)
|
||||
{
|
||||
if (button == null) break; // Array resized, excess buttons are generating
|
||||
//if (button.Hidden) break; // Reached the end of the visible buttons
|
||||
button.Hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SelectStickerAtSlot(int index)
|
||||
{
|
||||
if (_curSelectedSticker != index)
|
||||
{
|
||||
_curSelectedSticker = index;
|
||||
_stickerSelectionButtonDoubleClickTime = 0f;
|
||||
}
|
||||
|
||||
StickerSystem.Instance.SelectedStickerSlot = index;
|
||||
|
||||
// double-click to open (otherwise just hold)
|
||||
if (Time.time - _stickerSelectionButtonDoubleClickTime < 0.5f)
|
||||
{
|
||||
OpenStickerSelectionForSlot(index);
|
||||
_stickerSelectionButtonDoubleClickTime = 0f;
|
||||
return;
|
||||
}
|
||||
_stickerSelectionButtonDoubleClickTime = Time.time;
|
||||
}
|
||||
|
||||
private static void OpenStickerSelectionForSlot(int index)
|
||||
{
|
||||
if (IsPopulatingPage) return;
|
||||
_curSelectedSticker = index;
|
||||
_curDirectoryInfo = new DirectoryInfo(_initialDirectory);
|
||||
_ourDirectoryBrowserPage.OpenPage(false, true);
|
||||
}
|
||||
|
||||
private static void PopulateMenuItems()
|
||||
{
|
||||
// StickerMod.Logger.Msg("Populating menu items.");
|
||||
try
|
||||
{
|
||||
var directories = _curDirectoryInfo.GetDirectories();
|
||||
var files = _curDirectoryInfo.GetFiles();
|
||||
|
||||
MTJobManager.RunOnMainThread("PopulateMenuItems", () =>
|
||||
{
|
||||
// resize the arrays to the max amount of buttons
|
||||
int difference = directories.Length - _folderButtons.Length;
|
||||
if (difference > 0)
|
||||
{
|
||||
Array.Resize(ref _folderButtons, directories.Length);
|
||||
SetupFolderButtons(difference);
|
||||
StickerMod.Logger.Msg($"Resized folder buttons to {directories.Length}");
|
||||
}
|
||||
|
||||
difference = files.Length - _fileButtons.Length;
|
||||
if (difference > 0)
|
||||
{
|
||||
Array.Resize(ref _fileButtons, files.Length);
|
||||
SetupFileButtons(difference);
|
||||
StickerMod.Logger.Msg($"Resized file buttons to {files.Length}");
|
||||
}
|
||||
|
||||
_folderCategory.Hidden = directories.Length == 0;
|
||||
_folderCategory.CategoryName = $"Subdirectories ({directories.Length})";
|
||||
_fileCategory.Hidden = files.Length == 0;
|
||||
_fileCategory.CategoryName = $"Images ({files.Length})";
|
||||
});
|
||||
|
||||
PopulateFolders(directories);
|
||||
PopulateFiles(files);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
StickerMod.Logger.Error($"Failed to populate menu items: {e.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsPopulatingPage = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void PopulateFolders(IReadOnlyList<DirectoryInfo> directories)
|
||||
{
|
||||
for (int i = 0; i < _folderButtons.Length; i++)
|
||||
{
|
||||
Button button = _folderButtons[i];
|
||||
if (i >= directories.Count)
|
||||
break;
|
||||
|
||||
button.ButtonText = directories[i].Name;
|
||||
button.ButtonTooltip = $"Open {directories[i].Name}";
|
||||
MTJobManager.RunOnMainThread("PopulateMenuItems", () => button.Hidden = false);
|
||||
|
||||
if (i <= 16) Thread.Sleep(10); // For the pop-in effect
|
||||
}
|
||||
}
|
||||
|
||||
private static void PopulateFiles(IReadOnlyList<FileInfo> files)
|
||||
{
|
||||
for (int i = 0; i < _fileButtons.Length; i++)
|
||||
{
|
||||
Button button = _fileButtons[i];
|
||||
if (i >= files.Count)
|
||||
break;
|
||||
|
||||
FileInfo fileInfo = files[i];
|
||||
|
||||
if (!SUPPORTED_IMAGE_EXTENSIONS.Contains(fileInfo.Extension.ToLower()))
|
||||
continue;
|
||||
|
||||
string relativePath = Path.GetRelativePath(_initialDirectory, fileInfo.FullName);
|
||||
string relativePathWithoutExtension = relativePath[..^fileInfo.Extension.Length];
|
||||
|
||||
button.ButtonTooltip = $"Load {fileInfo.Name}"; // Do not change "Load " prefix, we extract file name
|
||||
|
||||
if (StickerCache.IsThumbnailAvailable(relativePathWithoutExtension))
|
||||
{
|
||||
button.ButtonIcon = StickerCache.GetBtkUiIconName(relativePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.ButtonIcon = string.Empty;
|
||||
StickerCache.EnqueueThumbnailGeneration(fileInfo, button);
|
||||
}
|
||||
|
||||
MTJobManager.RunOnMainThread("PopulateMenuItems", () => button.Hidden = false);
|
||||
|
||||
if (i <= 16) Thread.Sleep(10); // For the pop-in effect
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Icon Utils
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue