From f4af00672e60d9b2d739d26296c1ae3b516da514 Mon Sep 17 00:00:00 2001 From: William Date: Mon, 29 Jan 2024 23:15:39 +0000 Subject: [PATCH] Improve save editing UI (#339) --- .../SaveFile/SaveFilePreview.cs | 154 +++ src/SerialLoops/Controls/HomePanel.cs | 10 +- .../Dialogs/ProjectSettingsDialog.cs | 2 +- src/SerialLoops/Dialogs/SaveEditorDialog.cs | 147 ++- .../Dialogs/SaveSlotEditorDialog.cs | 919 ++++++++++++------ src/SerialLoops/Icons/Edit_Save.png | Bin 0 -> 63871 bytes src/SerialLoops/Icons/Next_Page.png | Bin 0 -> 31151 bytes src/SerialLoops/Icons/Previous_Page.png | Bin 0 -> 31920 bytes src/SerialLoops/MainForm.eto.cs | 81 +- src/SerialLoops/Utility/ControlGenerator.cs | 99 ++ 10 files changed, 1037 insertions(+), 375 deletions(-) create mode 100644 src/SerialLoops.Lib/SaveFile/SaveFilePreview.cs create mode 100644 src/SerialLoops/Icons/Edit_Save.png create mode 100644 src/SerialLoops/Icons/Next_Page.png create mode 100644 src/SerialLoops/Icons/Previous_Page.png diff --git a/src/SerialLoops.Lib/SaveFile/SaveFilePreview.cs b/src/SerialLoops.Lib/SaveFile/SaveFilePreview.cs new file mode 100644 index 00000000..82c0546a --- /dev/null +++ b/src/SerialLoops.Lib/SaveFile/SaveFilePreview.cs @@ -0,0 +1,154 @@ +using System; +using HaruhiChokuretsuLib.Save; +using SerialLoops.Lib.Items; +using SerialLoops.Lib.Script.Parameters; +using SerialLoops.Lib.Util; +using SkiaSharp; + +namespace SerialLoops.Lib.SaveFile { + public class SaveFilePreview { + + private const int WIDTH = 250; + private const int HEIGHT = 42; + private const float SCALE = 2f; + + private SaveSlotData _slotData; + private Project _project; + + public SaveFilePreview(SaveSlotData slotData, Project project) + { + _slotData = slotData; + _project = project; + } + + public SKBitmap DrawPreview() + { + SKBitmap bitmap = new(WIDTH, HEIGHT); + + using SKCanvas canvas = new(bitmap); + DrawBox(canvas); + if (_slotData.EpisodeNumber == 0) + { + DrawText(canvas, _project.UiText.Messages[27]); + } + else + { + DrawEpisodeNumber(canvas, _slotData.EpisodeNumber); + DrawText(canvas, GetEpisodeTitle(_slotData.EpisodeNumber), 90); + DrawSaveTime(canvas, _slotData.SaveTime); + } + + canvas.Flush(); + return bitmap.Resize( + new SKImageInfo( + (int) (WIDTH * SCALE), + (int) (HEIGHT * SCALE) + ), + SKFilterQuality.None + ); + } + + private void DrawText(SKCanvas canvas, string text, int x = 10, int y = 5, SKPaint paint = null) + { + canvas.DrawHaroohieText( + _project.LangCode != "ja" ? text.GetOriginalString(_project) : text, + paint ?? DialogueScriptParameter.Paint00, + _project, + x, + y + ); + } + + private void DrawBox(SKCanvas canvas) + { + // Draw outer dark gray outline + canvas.Clear(new(93, 93, 93)); + SKRect textArea = new(3, 2, WIDTH - 3, HEIGHT - 2); + + // Draw inner green fill + using SKPaint paint = new(); + paint.Color = new(12, 36, 20); + paint.Style = SKPaintStyle.Fill; + canvas.DrawRect(textArea, paint); + + // Draw inner light grey outline + paint.Color = new(150, 150, 150); + paint.Style = SKPaintStyle.Stroke; + paint.StrokeWidth = 1; + canvas.DrawRect(textArea, paint); + } + + private void DrawEpisodeNumber(SKCanvas canvas, int number) + { + if (_project.Items.Find(item => item.Type == ItemDescription.ItemType.System_Texture + && item.Name == "SYSTEX_SYS_CMN_B38") is not SystemTextureItem graphic) + { + DrawText(canvas, $"EPISODE: {number}"); + return; + } + + // Draw the top half of the image onto the canvas, treating (0, 255, 0) as transparent + var bitmap = graphic.Grp.GetImage(transparentIndex: 0); + SKBitmap episodeNumber = new(bitmap.Width + 8, bitmap.Height / 2); + SKCanvas episodeCanvas = new(episodeNumber); + + // Draw "EPISODE: (number)" + var numberXOffSet = 8 * (number - 1); + episodeCanvas.DrawBitmap(bitmap, 0, 0); + episodeCanvas.DrawBitmap( + bitmap, + new SKRectI(numberXOffSet, bitmap.Height / 2, numberXOffSet + 8, bitmap.Height), + new SKRectI(bitmap.Width - 8, 0, bitmap.Width, bitmap.Height / 2) + ); + episodeCanvas.Flush(); + + canvas.DrawBitmap(episodeNumber, 10, 5); + } + + private void DrawSaveTime(SKCanvas canvas, DateTimeOffset saveTime) + { + string date = saveTime.ToString("yyyy/MM/dd"); + string time = saveTime.ToString("HH:mm:ss"); + if (_project.Items.Find(item => item.Type == ItemDescription.ItemType.System_Texture + && item.Name == "SYSTEX_SYS_MNU_B00") is not SystemTextureItem graphic) + { + DrawText(canvas, date, 60, 25, DialogueScriptParameter.Paint01); + DrawText(canvas, time, 180, 25, DialogueScriptParameter.Paint01); + return; + } + SKBitmap bitmap = graphic.Grp.GetImage(transparentIndex: 0); + SKBitmap timeBitmap = new(WIDTH, 16); + SKCanvas timeCanvas = new(timeBitmap); + // Draw date, for each char + for (int i = 0; i < date.Length; i++) + { + DrawLargeGlyph(date[i], timeCanvas, bitmap, 30 + i * 8); + } + for (int i = 0; i < time.Length; i++) + { + DrawLargeGlyph(time[i], timeCanvas, bitmap, 160 + i * 8); + } + timeCanvas.Flush(); + canvas.DrawBitmap(timeBitmap, 0, 23); + } + + private void DrawLargeGlyph(char glyph, SKCanvas canvas, SKBitmap bitmap, int x, int y = 0) + { + int offset = glyph switch + { + '0' => 0, '1' => 8, '2' => 16, '3' => 24, '4' => 32, '5' => 40, '6' => 48, + '7' => 56, '8' => 64, '9' => 72, ':' => 80, '/' => 88, '%' => 96, _ => 104 + }; + canvas.DrawBitmap( + bitmap, + new SKRectI(offset, 0, offset + 8, bitmap.Height), + new SKRectI(x, y, x + 8, y + bitmap.Height) + ); + } + + private string GetEpisodeTitle(int number) + { + return _project.UiText.Messages[16 + number]; + } + } +} \ No newline at end of file diff --git a/src/SerialLoops/Controls/HomePanel.cs b/src/SerialLoops/Controls/HomePanel.cs index 5ca38771..84505e07 100644 --- a/src/SerialLoops/Controls/HomePanel.cs +++ b/src/SerialLoops/Controls/HomePanel.cs @@ -41,6 +41,12 @@ private void InitializeComponents() LinkButton openProjectLink = new() { Text = "Open Project" }; openProjectLink.Click += _mainForm.OpenProject_Executed; + + LinkButton editSaveLink = new() { Text = "Edit Save File" }; + editSaveLink.Click += _mainForm.EditSaveFileCommand_Executed; + + LinkButton aboutLink = new() { Text = "About" }; + aboutLink.Click += _mainForm.AboutCommand_Executed; LinkButton preferencesLink = new() { Text = "Preferences" }; preferencesLink.Click += _mainForm.PreferencesCommand_Executed; @@ -55,7 +61,9 @@ private void InitializeComponents() ControlGenerator.GetTextHeader("Start"), ControlGenerator.GetControlWithIcon(newProjectLink, "New", _log), ControlGenerator.GetControlWithIcon(openProjectLink, "Open", _log), - ControlGenerator.GetControlWithIcon(preferencesLink, "Options", _log) + ControlGenerator.GetControlWithIcon(editSaveLink, "Edit_Save", _log), + ControlGenerator.GetControlWithIcon(preferencesLink, "Options", _log), + ControlGenerator.GetControlWithIcon(aboutLink, "Help", _log), } }; diff --git a/src/SerialLoops/Dialogs/ProjectSettingsDialog.cs b/src/SerialLoops/Dialogs/ProjectSettingsDialog.cs index 4ee5134a..fccda09d 100644 --- a/src/SerialLoops/Dialogs/ProjectSettingsDialog.cs +++ b/src/SerialLoops/Dialogs/ProjectSettingsDialog.cs @@ -34,7 +34,7 @@ private void InitializeComponent() applyButton.Click += ApplyButton_OnClick; Button cancelButton = new() { Text = "Cancel" }; - cancelButton.Click += (sender, e) => { Close(); }; + cancelButton.Click += (sender, e) => Close(); Content = new TableLayout( new TableRow( diff --git a/src/SerialLoops/Dialogs/SaveEditorDialog.cs b/src/SerialLoops/Dialogs/SaveEditorDialog.cs index a56f5506..ef0f3d32 100644 --- a/src/SerialLoops/Dialogs/SaveEditorDialog.cs +++ b/src/SerialLoops/Dialogs/SaveEditorDialog.cs @@ -5,6 +5,8 @@ using SerialLoops.Lib; using System; using System.IO; +using SerialLoops.Lib.SaveFile; +using SerialLoops.Utility; namespace SerialLoops.Dialogs { @@ -41,16 +43,17 @@ public SaveEditorDialog(ILogger log, Project project, EditorTabsPanel tabs, stri void InitializeComponent() { - Title = $"Save Editor - {Path.GetFileName(_saveLoc)}"; - Width = 400; - Height = 400; - Button saveCommonButton = new() { Text = "Common Save Data", Height = 64 }; - saveCommonButton.Click += (sender, args) => - { - SaveSlotEditorDialog saveSlotEditorDialog = new(_log, _save.CommonData, _project, _tabs); - saveSlotEditorDialog.Show(); - }; + Title = $"Edit Save File - {Path.GetFileName(_saveLoc)}"; + Width = 600; + Height = 390; + Resizable = false; + Padding = 10; + + UpdateContent(); + } + private void UpdateContent() + { Button saveButton = new() { Text = "Save" }; saveButton.Click += (sender, args) => { @@ -67,15 +70,12 @@ void InitializeComponent() }; Button cancelButton = new() { Text = "Cancel" }; - cancelButton.Click += (sender, args) => - { - Close(); - }; - + cancelButton.Click += (sender, args) => Close(); + StackLayout buttonsLayout = new() { Orientation = Orientation.Horizontal, - Spacing = 3, + Spacing = 5, HorizontalContentAlignment = HorizontalAlignment.Right, Items = { @@ -86,36 +86,131 @@ void InitializeComponent() Content = new TableLayout { - Spacing = new(5, 5), Rows = { - new(saveCommonButton), - new(GetSaveSlotPreviewButton(_save.CheckpointSaveSlots[0])), - new(GetSaveSlotPreviewButton(_save.CheckpointSaveSlots[1])), - new(GetSaveSlotPreviewButton(_save.QuickSaveSlot)), - new(), - new(buttonsLayout), + GetSaveFiles(), + buttonsLayout }, + Spacing = new(0, 20) }; } - private Button GetSaveSlotPreviewButton(SaveSlotData slot) + private Control GetSaveFiles() { - Button slotButton = new() { Text = slot.EpisodeNumber == 0 ? "New Save" : $"EPISODE: {slot.EpisodeNumber}\n\n{slot.SaveTime:yyyy/MM/dd H:mm:ss}", Height = 64 }; + Button saveCommonButton = new() + { + Text = "Common Save Data...", + Image = ControlGenerator.GetIcon("Edit_Save", _log) + }; + saveCommonButton.Click += (sender, args) => + { + SaveSlotEditorDialog saveSlotEditorDialog = new( + _log, + _save.CommonData, + Path.GetFileName(_saveLoc), + "Common Save Data", + _project, + _tabs, + UpdateContent + ); + saveSlotEditorDialog.Show(); + }; + StackLayout commonDataRow = new(saveCommonButton) { HorizontalContentAlignment = HorizontalAlignment.Center }; + + return new TableLayout + { + Rows = + { + new GroupBox + { + Text = "Save Files", + Padding = 5, + Content = new TableLayout + { + Spacing = new(0, 10), + Rows = + { + GetSaveSlotPreview(_save.CheckpointSaveSlots[0], 1), + GetSaveSlotPreview(_save.CheckpointSaveSlots[1], 2), + GetSaveSlotPreview(_save.QuickSaveSlot, 3), + }, + } + }, + commonDataRow, + }, + Spacing = new(0, 15) + }; + } + + private TableRow GetSaveSlotPreview(SaveSlotData data, int slotNum) + { + return new TableLayout + { + Size = new(430, 64), + Spacing = new(6, 6), + Rows = + { + new TableRow( + new SKGuiImage( + new SaveFilePreview(data, _project).DrawPreview() + ), + new StackLayout( + slotNum == 3 ? "Quick Save" : $"File {slotNum}", + new StackLayout + { + Orientation = Orientation.Horizontal, + Spacing = 5, + Items = + { + GetSlotEditButton(data, Path.GetFileName(_saveLoc), slotNum), + // GetSlotClearButton(data, Path.GetFileName(_saveLoc), slotNum) TODO + }, + } + ) + { + Orientation = Orientation.Vertical, + HorizontalContentAlignment = HorizontalAlignment.Center, + VerticalContentAlignment = VerticalAlignment.Center, + Spacing = 5, + } + ) + } + }; + } + + private Button GetSlotEditButton(SaveSlotData slot, string fileName, int slotNumber) + { + Button slotButton = new() { Width = 22, Image = ControlGenerator.GetIcon("Edit_Save", _log) }; slotButton.Click += (sender, args) => { SaveSlotEditorDialog saveSlotEditorDialog; if (slot is QuickSaveSlotData quickSave) { - saveSlotEditorDialog = new(_log, quickSave, _project, _tabs); + saveSlotEditorDialog = new(_log, quickSave, fileName, "Quick Save Data", _project, _tabs, UpdateContent); } else { - saveSlotEditorDialog = new(_log, slot, _project, _tabs); + saveSlotEditorDialog = new(_log, slot, fileName, $"File {slotNumber}", _project, _tabs, UpdateContent); } saveSlotEditorDialog.Show(); }; return slotButton; } + + private Button GetSlotClearButton(SaveSlotData slot, string fileName, int slotNumber) + { + Button slotButton = new() + { + Width = 22, + Image = ControlGenerator.GetIcon("Clear", _log), + Enabled = slot.EpisodeNumber > 0 + }; + slotButton.Click += (sender, args) => + { + slot.EpisodeNumber = 0; + _log.Log($"Cleared Save File {slotNumber}."); + }; + return slotButton; + } } } diff --git a/src/SerialLoops/Dialogs/SaveSlotEditorDialog.cs b/src/SerialLoops/Dialogs/SaveSlotEditorDialog.cs index f9600162..bfb435b4 100644 --- a/src/SerialLoops/Dialogs/SaveSlotEditorDialog.cs +++ b/src/SerialLoops/Dialogs/SaveSlotEditorDialog.cs @@ -1,5 +1,4 @@ using Eto.Forms; -using HaruhiChokuretsuLib.Archive.Data; using HaruhiChokuretsuLib.Archive.Event; using HaruhiChokuretsuLib.Save; using HaruhiChokuretsuLib.Util; @@ -23,360 +22,74 @@ public class SaveSlotEditorDialog : FloatingForm { private readonly ILogger _log; private readonly SaveSection _saveSection; + private readonly string _fileName; + private readonly string _slotName; private readonly Project _project; private readonly EditorTabsPanel _tabs; + private readonly Action _callback; private readonly Dictionary _flagModifications = []; private readonly List _modifierControls = []; private ScriptItem _quickSaveScript; private ScriptPreview _quickSaveScriptPreview; - public SaveSlotEditorDialog(ILogger log, SaveSection saveSection, Project project, EditorTabsPanel tabs) + private const int FLAGS_PER_PAGE = 12; + private StackLayout _checkBoxContainer = new(); + private int _flagPage = 1; + private List _flags = new(); + + public SaveSlotEditorDialog(ILogger log, SaveSection saveSection, string fileName, string slotName, + Project project, EditorTabsPanel tabs, Action callback) { _log = log; _saveSection = saveSection; + _fileName = fileName; + _slotName = slotName; _project = project; _tabs = tabs; - + _callback = callback; + _flags = GetFilteredFlags(); + InitializeComponent(); } private void InitializeComponent() { - Title = "Save Slot Editor"; - Width = 500; - Height = 800; - - StackLayout flagsLayout = new() - { - Orientation = Orientation.Vertical, - Padding = 4, - Spacing = 4, - Width = 500, - }; - for (int i = 0; i < 5120; i++) - { - int flagId = i; - CheckBox flagCheckBox = new() { Checked = _saveSection.IsFlagSet(flagId) }; - flagCheckBox.CheckedChanged += (sender, args) => - { - if (_flagModifications.ContainsKey(flagId)) - { - _flagModifications[flagId] = flagCheckBox.Checked ?? true; - } - else - { - _flagModifications.Add(flagId, flagCheckBox.Checked ?? true); - } - }; - StackLayout checkboxLayout = new() - { - Orientation = Orientation.Horizontal, - Spacing = 2, - Items = - { - flagCheckBox, - Flags.GetFlagNickname(flagId, _project), - } - }; - - flagsLayout.Items.Add(checkboxLayout); - } + Title = $"Edit Save File - {_fileName} - {_slotName}"; + Width = 550; + Height = 560; + Padding = 10; + TabControl menuTabs = new(); TableLayout layout = new() { - Spacing = new(5, 5), + Spacing = new(5, 10), + Height = 500, Rows = { - new TableRow(new Scrollable { Content = flagsLayout, Height = 400 }), + ControlGenerator.GetTextHeader($"{_slotName}"), + menuTabs, } }; if (_saveSection is CommonSaveData commonSave) { - NumericStepper numSavesStepper = new() { Value = commonSave.NumSaves, Increment = 1, MaximumDecimalPlaces = 0, ID = "NumSaves" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Number of Saves: ", numSavesStepper)); - _modifierControls.Add(numSavesStepper); - - NumericStepper bgmVolumeStepper = new() { Value = commonSave.Options.BgmVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "BgmVolume" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("BGM Volume: ", bgmVolumeStepper)); - _modifierControls.Add(bgmVolumeStepper); - - NumericStepper sfxVolumeStepper = new() { Value = commonSave.Options.SfxVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "SfxVolume" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("SFX Volume: ", sfxVolumeStepper)); - _modifierControls.Add(sfxVolumeStepper); - - NumericStepper wordsVolumeStepper = new() { Value = commonSave.Options.WordsVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "WordsVolume" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Words Volume: ", wordsVolumeStepper)); - _modifierControls.Add(wordsVolumeStepper); - - NumericStepper voiceVolumeStepper = new() { Value = commonSave.Options.VoiceVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "VoiceVolume" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Voice Volume: ", voiceVolumeStepper)); - _modifierControls.Add(voiceVolumeStepper); - - CheckBox kyonVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KYON), ID = "KyonVoiceToggle" }; - CheckBox haruhiVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.HARUHI), ID = "HaruhiVoiceToggle" }; - CheckBox mikuruVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.MIKURU), ID = "MikuruVoiceToggle" }; - CheckBox nagatoVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.NAGATO), ID = "NagatoVoiceToggle" }; - CheckBox koizumiVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KOIZUMI), ID = "KoizumiVoiceToggle" }; - CheckBox sisterVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.SISTER), ID = "SisterVoiceToggle" }; - CheckBox tsuruyaVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.TSURUYA), ID = "TsuruyaVoiceToggle" }; - CheckBox taniguchiVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.TANIGUCHI), ID = "TaniguchiVoiceToggle" }; - CheckBox kunikidaVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KUNIKIDA), ID = "KunikidaVoiceToggle" }; - CheckBox mysteryGirlVoiceCheckBox = new() { Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.MYSTERY_GIRL), ID = "MysteryGirlVoiceToggle" }; - TableLayout voiceToggleLayout = new() - { - Spacing = new(3, 3), - Rows = - { - new(ControlGenerator.GetControlWithLabel("Kyon", kyonVoiceCheckBox), ControlGenerator.GetControlWithLabel("Haruhi", haruhiVoiceCheckBox), - ControlGenerator.GetControlWithLabel("Mikuru", mikuruVoiceCheckBox), ControlGenerator.GetControlWithLabel("Nagato", nagatoVoiceCheckBox), - ControlGenerator.GetControlWithLabel("Koizumi", koizumiVoiceCheckBox)), - new(ControlGenerator.GetControlWithLabel("Kyon's Sister", sisterVoiceCheckBox), ControlGenerator.GetControlWithLabel("Tsuruya", tsuruyaVoiceCheckBox), - ControlGenerator.GetControlWithLabel("Taniguchi", taniguchiVoiceCheckBox), ControlGenerator.GetControlWithLabel("Kunikida", kunikidaVoiceCheckBox), - ControlGenerator.GetControlWithLabel("Mystery Girl", mysteryGirlVoiceCheckBox)) - } - }; - layout.Rows.Add("Voice Toggles"); - layout.Rows.Add(voiceToggleLayout); - _modifierControls.AddRange( - [kyonVoiceCheckBox, - haruhiVoiceCheckBox, - mikuruVoiceCheckBox, - nagatoVoiceCheckBox, - koizumiVoiceCheckBox, - sisterVoiceCheckBox, - tsuruyaVoiceCheckBox, - taniguchiVoiceCheckBox, - kunikidaVoiceCheckBox, - mysteryGirlVoiceCheckBox]); - - RadioButtonList batchDialogueDisplay = new() - { - Items = - { - "Off", - "On" - }, - SelectedValue = commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.BATCH_DIALOGUE_DISPLAY_ON) ? "On" : "Off", - Orientation = Orientation.Horizontal, - ID = "BatchDialogueDisplay", - }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Batch Dialogue Display", batchDialogueDisplay)); - _modifierControls.Add(batchDialogueDisplay); - - RadioButtonList puzzleInterruptScenes = new() - { - Items = - { - "Off", - "Unseen Only", - "On" - }, - SelectedValue = commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.PUZZLE_INTERRUPTE_SCENES_ON) ? "On" : - (commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.PUZZLE_INTERRUPT_SCENES_UNSEEN_ONLY) ? "Unseen Only" : "Off"), - Orientation = Orientation.Horizontal, - ID = "PuzzleInterruptScenes", - }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Puzzle Interrupt Scenes", puzzleInterruptScenes)); - _modifierControls.Add(puzzleInterruptScenes); - - RadioButtonList topicStockMode = new() - { - Items = - { - "Off", - "On" - }, - SelectedValue = commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.TOPIC_STOCK_MODE_ON) ? "On" : "Off", - Orientation = Orientation.Horizontal, - ID = "TopicStockMode", - }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Topic Stock Mode", topicStockMode)); - _modifierControls.Add(topicStockMode); - - RadioButtonList dialogueSkipping = new() - { - Items = - { - "Fast Forward", - "Skip Already Read" - }, - SelectedValue = commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.DIALOGUE_SKIPPING_SKIP_ALREADY_READ) ? "Skip Already Read" : "Fast Forward", - Orientation = Orientation.Horizontal, - ID = "DialogueSkipping", - }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Dialogue Skipping", dialogueSkipping)); - _modifierControls.Add(dialogueSkipping); + menuTabs.Pages.Add(new TabPage { Content = GetCommonDataBox(commonSave), Text = "Config Data"}); } else { SaveSlotData slotSave = (SaveSlotData)_saveSection; - - DateTimePicker dateTimePicker = new() { Mode = DateTimePickerMode.DateTime, Value = slotSave.SaveTime.DateTime, ID = "DateTime", MinDate = new DateTime(2000, 1, 1, 0, 0, 0) }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Save Time: ", dateTimePicker)); - _modifierControls.Add(dateTimePicker); - - NumericStepper scenarioPositionStepper = new() { Value = slotSave.ScenarioPosition, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = _project.Scenario.Commands.Count, ID = "ScenarioPosition" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Scenario Command Index: ", scenarioPositionStepper)); - _modifierControls.Add(scenarioPositionStepper); - - NumericStepper episodeNumberStepper = new() { Value = slotSave.EpisodeNumber, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 5, ID = "EpisodeNumber" }; - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Episode: ", episodeNumberStepper)); - _modifierControls.Add(episodeNumberStepper); - - NumericStepper hflStepper = new() { Value = slotSave.HaruhiFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "HFL" }; - _modifierControls.Add(hflStepper); - NumericStepper mflStepper = new() { Value = slotSave.MikuruFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "MFL" }; - _modifierControls.Add(mflStepper); - NumericStepper nflStepper = new() { Value = slotSave.NagatoFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "NFL" }; - _modifierControls.Add(nflStepper); - NumericStepper kflStepper = new() { Value = slotSave.KoizumiFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "KFL" }; - _modifierControls.Add(kflStepper); - NumericStepper uflStepper = new() { Value = slotSave.UnknownFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "UFL" }; - _modifierControls.Add(uflStepper); - NumericStepper tflStepper = new() { Value = slotSave.TsuruyaFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "TFL" }; - _modifierControls.Add(tflStepper); - GroupBox friendshipLevelSteppersGroupBox = new() - { - Text = "Friendship Levels", - Content = new TableLayout - { - Spacing = new(5, 5), - Rows = - { - new(ControlGenerator.GetControlWithLabel("Haruhi", hflStepper), ControlGenerator.GetControlWithLabel("Mikuru", mflStepper), ControlGenerator.GetControlWithLabel("Nagato", nflStepper)), - new(ControlGenerator.GetControlWithLabel("Koizumi", kflStepper), ControlGenerator.GetControlWithLabel("Unknown", uflStepper), ControlGenerator.GetControlWithLabel("Tsuruya", tflStepper)), - } - } - }; - layout.Rows.Add(friendshipLevelSteppersGroupBox); - + menuTabs.Pages.Add(new TabPage { Content = GetSlotDataBox(slotSave), Text = "Save Data"}); + if (slotSave is QuickSaveSlotData quickSave) { - StackLayout previewLayout = new(); - - NumericMaskedTextBox scriptCommandIndexBox = new() { ID = "ScriptCommandIndex", Value = quickSave.CurrentScriptCommand }; - - _quickSaveScript = (ScriptItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Script && ((ScriptItem)i).Event.Index == quickSave.CurrentScript); - Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); - _quickSaveScript.CalculateGraphEdges(commands, _log); - - DropDown scriptBlockSelector = new() { ID = "CurrentScriptBlock" }; - scriptBlockSelector.Items.AddRange(_quickSaveScript.Event.ScriptSections.Select(s => new ListItem { Key = s.Name, Text = s.Name })); - scriptBlockSelector.SelectedIndex = quickSave.CurrentScriptBlock; - scriptBlockSelector.SelectedIndexChanged += (sender, args) => - { - scriptCommandIndexBox.Value = 0; - }; - _modifierControls.Add(scriptBlockSelector); - - DropDown scriptSelector = new() { ID = "CurrentScript" }; - scriptSelector.Items.AddRange(_project.Items.Where(i => i.Type == ItemDescription.ItemType.Script).Select(s => new ListItem { Text = s.DisplayName, Key = ((ScriptItem)s).Event.Index.ToString() })); - scriptSelector.SelectedKey = quickSave.CurrentScript.ToString(); - StackLayout scriptSelectorWithLink = new() - { - Orientation = Orientation.Horizontal, - Spacing = 2, - Items = - { - ControlGenerator.GetControlWithLabel("Current Script: ", scriptSelector), - ControlGenerator.GetFileLink(_quickSaveScript, _tabs, _log), - } - }; - scriptSelector.SelectedKeyChanged += (sender, args) => - { - _quickSaveScript = (ScriptItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Script && ((ScriptItem)i).Event.Index == int.Parse(scriptSelector.SelectedKey)); - Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); - _quickSaveScript.CalculateGraphEdges(commands, _log); - scriptBlockSelector.Items.Clear(); - scriptBlockSelector.Items.AddRange(_quickSaveScript.Event.ScriptSections.Select(s => new ListItem { Key = s.Name, Text = s.Name })); - scriptBlockSelector.SelectedIndex = 0; - scriptSelectorWithLink.Items.RemoveAt(1); - scriptSelectorWithLink.Items.Add(ControlGenerator.GetFileLink(_quickSaveScript, _tabs, _log)); - }; - _modifierControls.Add(scriptSelector); - - - scriptCommandIndexBox.ValueChanged += (sender, args) => - { - previewLayout.Items.Clear(); - Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); - _quickSaveScriptPreview = _quickSaveScript.GetScriptPreview(commands, commands[_quickSaveScript.Event.ScriptSections[scriptBlockSelector.SelectedIndex < 0 ? 0 : scriptBlockSelector.SelectedIndex]][scriptCommandIndexBox.Value], _project, _log); - (SKBitmap scriptPreviewImage, string errorImage) = ScriptItem.GeneratePreviewImage(_quickSaveScriptPreview, _project); - if (scriptPreviewImage is null) - { - scriptPreviewImage = new(256, 384); - SKCanvas canvas = new(scriptPreviewImage); - canvas.DrawColor(SKColors.Black); - using Stream noPreviewStream = Assembly.GetCallingAssembly().GetManifestResourceStream(errorImage); - canvas.DrawImage(SKImage.FromEncodedData(noPreviewStream), new SKPoint(0, 0)); - canvas.Flush(); - previewLayout.Items.Add(new SKGuiImage(scriptPreviewImage)); - } - previewLayout.Items.Add(new SKGuiImage(scriptPreviewImage)); - }; - _modifierControls.Add(scriptCommandIndexBox); - - layout.Rows.Add(scriptSelectorWithLink); - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Current Script Block: ", scriptBlockSelector)); - layout.Rows.Add(ControlGenerator.GetControlWithLabel("Current Script Command Index: ", scriptCommandIndexBox)); - - List<(ChibiItem Chibi, int X, int Y)> topScreenChibis = []; - int chibiCurrentX = 80; - int chibiY = 100; - for (int i = 1; i <= 5; i++) - { - if (quickSave.TopScreenChibis.HasFlag((CharacterMask)(1 << i))) - { - ChibiItem chibi = (ChibiItem)_project.Items.First(it => it.Type == ItemType.Chibi && ((ChibiItem)it).ChibiIndex == i); - topScreenChibis.Add((chibi, chibiCurrentX, chibiY)); - chibiCurrentX += chibi.ChibiAnimations.First().Value.ElementAt(0).Frame.Width - 16; - } - } - - _quickSaveScriptPreview = new() - { - Background = (BackgroundItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Background && ((BackgroundItem)i).Id == (quickSave.CgIndex != 0 ? quickSave.CgIndex : quickSave.BgIndex)), - BgPalEffect = (PaletteEffectScriptParameter.PaletteEffect)quickSave.BgPalEffect, - EpisodeHeader = quickSave.EpisodeHeader, - Kbg = (BackgroundItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Background && ((BackgroundItem)i).Id == quickSave.KbgIndex), - Place = (PlaceItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Place && ((PlaceItem)i).Index == quickSave.Place), - TopScreenChibis = topScreenChibis, - Sprites = - [ - new() - { - Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.FirstCharacterSprite), - Positioning = new() { X = quickSave.Sprite1XOffset, Layer = 2 } - }, - new() - { - Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.SecondCharacterSprite), - Positioning = new() { X = quickSave.Sprite2XOffset, Layer = 1 } - }, - new() - { - Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.ThirdCharacterSprite), - Positioning = new() { X = quickSave.Sprite3XOffset, Layer = 0 } - }, - ], - }; - (SKBitmap previewBitmap, string previewErrorImage) = ScriptItem.GeneratePreviewImage(_quickSaveScriptPreview, _project); - if (previewBitmap is null) - { - previewBitmap = new(256, 384); - SKCanvas canvas = new(previewBitmap); - canvas.DrawColor(SKColors.Black); - using Stream noPreviewStream = Assembly.GetCallingAssembly().GetManifestResourceStream(previewErrorImage); - canvas.DrawImage(SKImage.FromEncodedData(noPreviewStream), new SKPoint(0, 0)); - canvas.Flush(); - previewLayout.Items.Add(new SKGuiImage(previewBitmap)); - } - previewLayout.Items.Add(new SKGuiImage(previewBitmap)); - layout.Rows.Add(previewLayout); + menuTabs.Pages.Add(new TabPage { Content = GetQuickSaveDataBox(quickSave), Text = "Script Position"}); } } + TabPage flagsTab = new TabPage {Content = GetFlagsBox(), Text = "Flags" }; + flagsTab.Shown += (sender, args) => UpdateFlagList(_flagPage); + menuTabs.Pages.Add(flagsTab); + Button saveButton = new() { Text = "Save" }; saveButton.Click += (sender, args) => @@ -476,7 +189,7 @@ private void InitializeComponent() quickSave.CurrentScriptCommand = ((NumericMaskedTextBox)_modifierControls.First(c => c.ID == "ScriptCommandIndex")).Value; } } - + Close(); }; @@ -489,7 +202,7 @@ private void InitializeComponent() StackLayout buttonsLayout = new() { Orientation = Orientation.Horizontal, - Spacing = 3, + Spacing = 5, HorizontalContentAlignment = HorizontalAlignment.Right, Items = { @@ -499,8 +212,570 @@ private void InitializeComponent() }; layout.Rows.Add(buttonsLayout); + Content = layout; + Closed += (sender, args) => _callback(); + } + + private TableLayout GetFlagsBox() + { + // Add page buttons + int totalPages = (_flags.Count / FLAGS_PER_PAGE) + 1; + NumericMaskedTextBox flagPageBox = new() + { + Value = _flagPage, + Width = 30, + }; + Button lastPageButton = new() { Image = ControlGenerator.GetIcon("Previous_Page", _log), Width = 22, Enabled = _flagPage > 1, }; + lastPageButton.Click += (sender, args) => + { + flagPageBox.Value = _flagPage - 1; + }; + Button nextPageButton = new() { Image = ControlGenerator.GetIcon("Next_Page", _log), Width = 22, Enabled = _flagPage < totalPages, }; + nextPageButton.Click += (sender, args) => + { + flagPageBox.Value = _flagPage + 1; + }; + flagPageBox.ValueChanged += (sender, args) => + { + _flagPage = flagPageBox.Value = Math.Max(1, Math.Min(totalPages, flagPageBox.Value)); + lastPageButton.Enabled = _flagPage > 1; + nextPageButton.Enabled = _flagPage < totalPages; + UpdateFlagList(_flagPage); + }; + + SearchBox filterBox = new() { PlaceholderText = "Filter by Name", Width = 200 }; + CheckBox showSetFlagsCheckbox = new() { Text = "Hide Unset Flags", Checked = false }; + Button applyFiltersButton = new() { Image = ControlGenerator.GetIcon("Search", _log), Text = "Filter"}; + Label totalPagesLabel = new() { Text = $" / {totalPages}" }; + Label totalResultsLabel = new() { Text = $"{_flags.Count} results" }; + filterBox.KeyDown += (sender, args) => + { + if (args.Key == Keys.Enter) + { + applyFiltersButton.PerformClick(); + } + }; + applyFiltersButton.Click += ((sender, args) => { + _flags = GetFilteredFlags(filterBox.Text, showSetFlagsCheckbox.Checked ?? true); + flagPageBox.Value = _flagPage = 1; + totalPages = (_flags.Count / FLAGS_PER_PAGE) + 1; + totalPagesLabel.Text = $" / {totalPages}"; + totalResultsLabel.Text = $"{_flags.Count} results"; + UpdateFlagList(_flagPage); + }); + + return new() + { + Height = 400, + Spacing = new(0, 10), + Padding = 10, + Rows = + { + GetCenteredLayout([ + showSetFlagsCheckbox, + filterBox, + applyFiltersButton, + ]), + _checkBoxContainer, + GetCenteredLayout([totalResultsLabel]), + GetCenteredLayout([ + lastPageButton, + flagPageBox, + totalPagesLabel, + nextPageButton + ]) + } + }; + } + + private StackLayout GetCenteredLayout(StackLayoutItem[] items) + { + return new StackLayout + { + Orientation = Orientation.Vertical, + HorizontalContentAlignment = HorizontalAlignment.Center, + Items = + { + new StackLayout(items) + { + Orientation = Orientation.Horizontal, + VerticalContentAlignment = VerticalAlignment.Center, + Spacing = 5 + } + } + }; + } + + private void UpdateFlagList(int page) + { + TableLayout rows = new TableLayout { Spacing = new(15, 5)}; + if (_flags.Count > 0) + { + rows.Rows.Add(new TableRow { + Cells = + { + ControlGenerator.GetTextHeader("Value", 10), + ControlGenerator.GetTextHeader("Flag Description", 10) + } + }); + } + GetFlagBoxes((page - 1) * FLAGS_PER_PAGE, page * FLAGS_PER_PAGE).ToList().ForEach(c => rows.Rows.Add(c)); + _checkBoxContainer.Content = rows; + } + + private IEnumerable GetFlagBoxes(int start, int end) + { + List flagBoxes = new(); + foreach (int flag in _flags.GetRange(start, Math.Min(end - start, _flags.Count - start))) + { + CheckBox flagCheckBox = new() { Checked = _saveSection.IsFlagSet(flag) }; + flagCheckBox.CheckedChanged += (sender, args) => { _flagModifications[flag] = flagCheckBox.Checked ?? true; }; + TableRow checkboxLayout = new() + { + Cells = + { + flagCheckBox, + Flags.GetFlagNickname(flag, _project), + } + }; + flagBoxes.Add(checkboxLayout); + } + return flagBoxes; + } + + private List GetFilteredFlags(string term = null, bool onlyShowSet = false) + { + List filtered = new(); + for (int i = 0; i < 5120; i++) + { + if (onlyShowSet && !(_flagModifications.TryGetValue(i, out var set) ? set : _saveSection.IsFlagSet(i))) + { + continue; + } + + if (!string.IsNullOrWhiteSpace(term) && !Flags.GetFlagNickname(i, _project).ToLower().Contains(term.ToLower().Trim())) + { + continue; + } + + filtered.Add(i); + } + return filtered; + } + + private Container GetQuickSaveDataBox(QuickSaveSlotData quickSave) + { + StackLayout previewLayout = new(); + + NumericMaskedTextBox scriptCommandIndexBox = new() { ID = "ScriptCommandIndex", Value = quickSave.CurrentScriptCommand, Width = 30 }; + _quickSaveScript = (ScriptItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Script && ((ScriptItem)i).Event.Index == quickSave.CurrentScript); + Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); + _quickSaveScript.CalculateGraphEdges(commands, _log); + + DropDown scriptBlockSelector = new() { ID = "CurrentScriptBlock" }; + scriptBlockSelector.Items.AddRange(_quickSaveScript.Event.ScriptSections.Select(s => new ListItem { Key = s.Name, Text = s.Name })); + scriptBlockSelector.SelectedIndex = quickSave.CurrentScriptBlock; + scriptBlockSelector.SelectedIndexChanged += (sender, args) => + { + scriptCommandIndexBox.Value = 0; + }; + _modifierControls.Add(scriptBlockSelector); + + DropDown scriptSelector = new() { ID = "CurrentScript" }; + scriptSelector.Items.AddRange(_project.Items.Where(i => i.Type == ItemDescription.ItemType.Script).Select(s => new ListItem { Text = s.DisplayName, Key = ((ScriptItem)s).Event.Index.ToString() })); + scriptSelector.SelectedKey = quickSave.CurrentScript.ToString(); + StackLayout scriptSelectorWithLink = new() + { + Orientation = Orientation.Horizontal, + Spacing = 2, + Items = + { + ControlGenerator.GetControlWithLabel("Script: ", scriptSelector), + ControlGenerator.GetFileLink(_quickSaveScript, _tabs, _log), + } + }; + scriptSelector.SelectedKeyChanged += (sender, args) => + { + _quickSaveScript = (ScriptItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Script && ((ScriptItem)i).Event.Index == int.Parse(scriptSelector.SelectedKey)); + Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); + _quickSaveScript.CalculateGraphEdges(commands, _log); + scriptBlockSelector.Items.Clear(); + scriptBlockSelector.Items.AddRange(_quickSaveScript.Event.ScriptSections.Select(s => new ListItem { Key = s.Name, Text = s.Name })); + scriptBlockSelector.SelectedIndex = 0; + scriptSelectorWithLink.Items.RemoveAt(1); + scriptSelectorWithLink.Items.Add(ControlGenerator.GetFileLink(_quickSaveScript, _tabs, _log)); + }; + _modifierControls.Add(scriptSelector); + + + scriptCommandIndexBox.ValueChanged += (sender, args) => + { + previewLayout.Items.Clear(); + Dictionary> commands = _quickSaveScript.GetScriptCommandTree(_project, _log); + List block = commands[_quickSaveScript.Event.ScriptSections[scriptBlockSelector.SelectedIndex < 0 ? 0 : scriptBlockSelector.SelectedIndex]]; + int index = Math.Max(0, Math.Min(block.Count - 1, scriptCommandIndexBox.Value)); + _quickSaveScriptPreview = _quickSaveScript.GetScriptPreview(commands, block[index], _project, _log); + (SKBitmap scriptPreviewImage, string errorImage) = ScriptItem.GeneratePreviewImage(_quickSaveScriptPreview, _project); + if (scriptPreviewImage is null) + { + scriptPreviewImage = new(256, 384); + SKCanvas canvas = new(scriptPreviewImage); + canvas.DrawColor(SKColors.Black); + using Stream noPreviewStream = Assembly.GetCallingAssembly().GetManifestResourceStream(errorImage); + canvas.DrawImage(SKImage.FromEncodedData(noPreviewStream), new SKPoint(0, 0)); + canvas.Flush(); + previewLayout.Items.Add(new SKGuiImage(scriptPreviewImage)); + } + previewLayout.Items.Add(new SKGuiImage(scriptPreviewImage)); + }; + _modifierControls.Add(scriptCommandIndexBox); + + List<(ChibiItem Chibi, int X, int Y)> topScreenChibis = []; + int chibiCurrentX = 80; + int chibiY = 100; + for (int i = 1; i <= 5; i++) + { + if (quickSave.TopScreenChibis.HasFlag((CharacterMask)(1 << i))) + { + ChibiItem chibi = (ChibiItem)_project.Items.First(it => it.Type == ItemType.Chibi && ((ChibiItem)it).ChibiIndex == i); + topScreenChibis.Add((chibi, chibiCurrentX, chibiY)); + chibiCurrentX += chibi.ChibiAnimations.First().Value.ElementAt(0).Frame.Width - 16; + } + } + + _quickSaveScriptPreview = new() + { + Background = (BackgroundItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Background && ((BackgroundItem)i).Id == (quickSave.CgIndex != 0 ? quickSave.CgIndex : quickSave.BgIndex)), + BgPalEffect = (PaletteEffectScriptParameter.PaletteEffect)quickSave.BgPalEffect, + EpisodeHeader = quickSave.EpisodeHeader, + Kbg = (BackgroundItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Background && ((BackgroundItem)i).Id == quickSave.KbgIndex), + Place = (PlaceItem)_project.Items.First(i => i.Type == ItemDescription.ItemType.Place && ((PlaceItem)i).Index == quickSave.Place), + TopScreenChibis = topScreenChibis, + Sprites = + [ + new() + { + Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.FirstCharacterSprite), + Positioning = new() { X = quickSave.Sprite1XOffset, Layer = 2 } + }, + new() + { + Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.SecondCharacterSprite), + Positioning = new() { X = quickSave.Sprite2XOffset, Layer = 1 } + }, + new() + { + Sprite = (CharacterSpriteItem)_project.Items.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Character_Sprite && ((CharacterSpriteItem)i).Index == quickSave.ThirdCharacterSprite), + Positioning = new() { X = quickSave.Sprite3XOffset, Layer = 0 } + }, + ], + }; + (SKBitmap previewBitmap, string previewErrorImage) = ScriptItem.GeneratePreviewImage(_quickSaveScriptPreview, _project); + if (previewBitmap is null) + { + previewBitmap = new(256, 384); + SKCanvas canvas = new(previewBitmap); + canvas.DrawColor(SKColors.Black); + using Stream noPreviewStream = Assembly.GetCallingAssembly().GetManifestResourceStream(previewErrorImage); + canvas.DrawImage(SKImage.FromEncodedData(noPreviewStream), new SKPoint(0, 0)); + canvas.Flush(); + previewLayout.Items.Add(new SKGuiImage(previewBitmap)); + } + previewLayout.Items.Add(new SKGuiImage(previewBitmap)); + + return new TableLayout + { + Height = 400, + Spacing = new (10, 0), + Padding = 10, + Rows = + { + new TableRow( + new StackLayout() + { + Orientation = Orientation.Vertical, + Spacing = 10, + Items = + { + scriptSelectorWithLink, + ControlGenerator.GetControlWithLabel("Block: ", scriptBlockSelector), + ControlGenerator.GetControlWithLabel("Command Index: ", scriptCommandIndexBox) + } + }, + previewLayout + ) + }, + }; + } + + private Container GetSlotDataBox(SaveSlotData slotSave) + { + TableLayout layout = new() + { + Height = 400, + Spacing = new(5, 5), + Padding = 10 + }; + DateTimePicker dateTimePicker = new() { Mode = DateTimePickerMode.DateTime, Value = slotSave.SaveTime.DateTime, ID = "DateTime", MinDate = new DateTime(2000, 1, 1, 0, 0, 0) }; + layout.Rows.Add(ControlGenerator.GetControlWithLabel("Save Time: ", dateTimePicker)); + _modifierControls.Add(dateTimePicker); + + NumericStepper scenarioPositionStepper = new() { Value = slotSave.ScenarioPosition, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = _project.Scenario.Commands.Count, ID = "ScenarioPosition" }; + layout.Rows.Add(ControlGenerator.GetControlWithLabel("Scenario Command Index: ", scenarioPositionStepper)); + _modifierControls.Add(scenarioPositionStepper); + + NumericStepper episodeNumberStepper = new() { Value = slotSave.EpisodeNumber, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 5, ID = "EpisodeNumber" }; + layout.Rows.Add(ControlGenerator.GetControlWithLabel("Episode: ", episodeNumberStepper)); + _modifierControls.Add(episodeNumberStepper); + + NumericStepper hflStepper = new() { Value = slotSave.HaruhiFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "HFL" }; + _modifierControls.Add(hflStepper); + NumericStepper mflStepper = new() { Value = slotSave.MikuruFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "MFL" }; + _modifierControls.Add(mflStepper); + NumericStepper nflStepper = new() { Value = slotSave.NagatoFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "NFL" }; + _modifierControls.Add(nflStepper); + NumericStepper kflStepper = new() { Value = slotSave.KoizumiFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "KFL" }; + _modifierControls.Add(kflStepper); + NumericStepper uflStepper = new() { Value = slotSave.UnknownFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "UFL" }; + _modifierControls.Add(uflStepper); + NumericStepper tflStepper = new() { Value = slotSave.TsuruyaFriendshipLevel, Increment = 1, MaximumDecimalPlaces = 0, MinValue = 1, MaxValue = 64, ID = "TFL" }; + _modifierControls.Add(tflStepper); + GroupBox friendshipLevelSteppersGroupBox = new() + { + Text = "Friendship Levels", + Content = new TableLayout + { + Spacing = new(5, 5), + Padding = 10, + Rows = + { + new( + ControlGenerator.GetCharacterProgressControl(hflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Haruhi), + ControlGenerator.GetCharacterProgressControl(mflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Mikuru) + ), + new( + ControlGenerator.GetCharacterProgressControl(nflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Nagato), + ControlGenerator.GetCharacterProgressControl(kflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Koizumi) + ), + new TableRow( + ControlGenerator.GetCharacterProgressControl(tflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Tsuruya), + ControlGenerator.GetCharacterProgressControl(uflStepper, _project, _log, ControlGenerator.ProgressPortraitCharacter.Unknown) + ) + } + } + }; + layout.Rows.Add(new StackLayout(friendshipLevelSteppersGroupBox)); + return layout; + } + + private Container GetCommonDataBox(CommonSaveData commonSave) + { + TableLayout layout = new() + { + Height = 400, + Spacing = new(5, 5), + Padding = 10 + }; + + NumericStepper numSavesStepper = new() + {Value = commonSave.NumSaves, Increment = 1, MaximumDecimalPlaces = 0, ID = "NumSaves"}; + layout.Rows.Add(ControlGenerator.GetControlWithLabel("Number of Saves: ", numSavesStepper)); + _modifierControls.Add(numSavesStepper); + + TableLayout volumeLayout = new() {Spacing = new(5, 5), Padding = 10}; + NumericStepper bgmVolumeStepper = new() + { + Value = commonSave.Options.BgmVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "BgmVolume" + }; + volumeLayout.Rows.Add(ControlGenerator.GetControlWithLabel("Music: ", bgmVolumeStepper)); + _modifierControls.Add(bgmVolumeStepper); + + NumericStepper sfxVolumeStepper = new() + { + Value = commonSave.Options.SfxVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, ID = "SfxVolume" + }; + volumeLayout.Rows.Add(ControlGenerator.GetControlWithLabel("Sound Effects: ", sfxVolumeStepper)); + _modifierControls.Add(sfxVolumeStepper); + + NumericStepper wordsVolumeStepper = new() + { + Value = commonSave.Options.WordsVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, + ID = "WordsVolume" + }; + volumeLayout.Rows.Add(ControlGenerator.GetControlWithLabel("Dialogue: ", wordsVolumeStepper)); + _modifierControls.Add(wordsVolumeStepper); + + NumericStepper voiceVolumeStepper = new() + { + Value = commonSave.Options.VoiceVolume / 10, MinValue = 0, MaxValue = 100, MaximumDecimalPlaces = 0, + ID = "VoiceVolume" + }; + volumeLayout.Rows.Add(ControlGenerator.GetControlWithLabel("Voices: ", voiceVolumeStepper)); + _modifierControls.Add(voiceVolumeStepper); + + CheckBox kyonVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KYON), ID = "KyonVoiceToggle"}; + CheckBox haruhiVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.HARUHI), ID = "HaruhiVoiceToggle"}; + CheckBox mikuruVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.MIKURU), ID = "MikuruVoiceToggle"}; + CheckBox nagatoVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.NAGATO), ID = "NagatoVoiceToggle"}; + CheckBox koizumiVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KOIZUMI), ID = "KoizumiVoiceToggle"}; + CheckBox sisterVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.SISTER), ID = "SisterVoiceToggle"}; + CheckBox tsuruyaVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.TSURUYA), ID = "TsuruyaVoiceToggle"}; + CheckBox taniguchiVoiceCheckBox = new() + { + Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.TANIGUCHI), ID = "TaniguchiVoiceToggle" + }; + CheckBox kunikidaVoiceCheckBox = new() + {Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.KUNIKIDA), ID = "KunikidaVoiceToggle"}; + CheckBox mysteryGirlVoiceCheckBox = new() + { + Checked = commonSave.Options.VoiceToggles.HasFlag(SaveOptions.VoiceOptions.MYSTERY_GIRL), + ID = "MysteryGirlVoiceToggle" + }; + TableLayout voiceToggleLayout = new TableLayout + { + Spacing = new(5, 5), + Padding = 10, + Rows = + { + new( + ControlGenerator.GetCharacterVoiceControl(kyonVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Kyon), + ControlGenerator.GetCharacterVoiceControl(haruhiVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Haruhi) + ), + new( + ControlGenerator.GetCharacterVoiceControl(mikuruVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Mikuru), + ControlGenerator.GetCharacterVoiceControl(nagatoVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Nagato) + ), + new( + ControlGenerator.GetCharacterVoiceControl(tsuruyaVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Tsuruya), + ControlGenerator.GetCharacterVoiceControl(koizumiVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Koizumi) + ), + new( + ControlGenerator.GetCharacterVoiceControl(taniguchiVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Taniguchi), + ControlGenerator.GetCharacterVoiceControl(sisterVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Sister) + ), + new( + ControlGenerator.GetCharacterVoiceControl(kunikidaVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Kunikida), + ControlGenerator.GetCharacterVoiceControl(mysteryGirlVoiceCheckBox, _project, _log, ControlGenerator.VoicePortraitCharacter.Mystery_Girl) + ) + } + }; + + _modifierControls.AddRange( + [ + kyonVoiceCheckBox, + haruhiVoiceCheckBox, + mikuruVoiceCheckBox, + nagatoVoiceCheckBox, + koizumiVoiceCheckBox, + sisterVoiceCheckBox, + tsuruyaVoiceCheckBox, + taniguchiVoiceCheckBox, + kunikidaVoiceCheckBox, + mysteryGirlVoiceCheckBox + ]); + + RadioButtonList dialogueSkipping = new() + { + Items = + { + "Fast Forward", + "Skip Already Read" + }, + SelectedValue = + commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions + .DIALOGUE_SKIPPING_SKIP_ALREADY_READ) + ? "Skip Already Read" + : "Fast Forward", + Orientation = Orientation.Vertical, + Padding = 10, + Spacing = new(0, 5), + ID = "DialogueSkipping", + }; + _modifierControls.Add(dialogueSkipping); + + RadioButtonList batchDialogueDisplay = new() + { + Items = + { + "Off", + "On" + }, + SelectedValue = + commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.BATCH_DIALOGUE_DISPLAY_ON) + ? "On" + : "Off", + Orientation = Orientation.Vertical, + Padding = 10, + Spacing = new(0, 5), + ID = "BatchDialogueDisplay", + }; + _modifierControls.Add(batchDialogueDisplay); - Content = new Scrollable { Content = layout }; + RadioButtonList puzzleInterruptScenes = new() + { + Items = + { + "Off", + "Unseen Only", + "On" + }, + SelectedValue = + commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.PUZZLE_INTERRUPTE_SCENES_ON) + ? "On" + : (commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions + .PUZZLE_INTERRUPT_SCENES_UNSEEN_ONLY) + ? "Unseen Only" + : "Off"), + Orientation = Orientation.Vertical, + Padding = 10, + Spacing = new(0, 5), + ID = "PuzzleInterruptScenes", + }; + _modifierControls.Add(puzzleInterruptScenes); + + RadioButtonList topicStockMode = new() + { + Items = + { + "Off", + "On" + }, + SelectedValue = commonSave.Options.StoryOptions.HasFlag(SaveOptions.PuzzleInvestigationOptions.TOPIC_STOCK_MODE_ON) + ? "On" + : "Off", + Orientation = Orientation.Vertical, + Padding = 10, + Spacing = new(0, 5), + ID = "TopicStockMode", + }; + _modifierControls.Add(topicStockMode); + + + layout.Rows.Add(new TableLayout( + new TableRow( + new GroupBox { Text = "Volume Config", Content = volumeLayout }, + new GroupBox { Text = "Voices Config", Content = voiceToggleLayout } + ), + new TableRow( + new GroupBox { Text = "Puzzle Interrupt Scenes", Content = puzzleInterruptScenes}, + new GroupBox { Text = "Topic Stock Mode", Content = topicStockMode} + ), + new TableRow( + new GroupBox { Text = "Dialogue Skipping", Content = dialogueSkipping}, + new GroupBox { Text = "Batch Dialogue Display", Content = batchDialogueDisplay} + ), + new TableRow() + ) { Spacing = new(10, 0) }); + + return layout; } } + } diff --git a/src/SerialLoops/Icons/Edit_Save.png b/src/SerialLoops/Icons/Edit_Save.png new file mode 100644 index 0000000000000000000000000000000000000000..56e2449ab353f5b9fa0535e66322578ea3159a97 GIT binary patch literal 63871 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 literal 0 HcmV?d00001 diff --git a/src/SerialLoops/Icons/Next_Page.png b/src/SerialLoops/Icons/Next_Page.png new file mode 100644 index 0000000000000000000000000000000000000000..22256e1fd05b70050ff1e8e904745546b568257c GIT binary patch literal 31151 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%0AeK8zK6++NtWM z$T#)jarsCj%Db76wVM);X1||E<@C#DSLw!ac%@U}h}PCVJS+d~Pkc7^6eBZ#6OLTL{LY+uJjmEz{GZLK(jmg;=qiu{Zq5k-)Q>|Z56m@|?p(kIDW z`i#rb2FZ$&+}}UvYItp;#ILZ;D~}6e7!TPAUb@qX6l?g>>N!+o=Y2VTxnHI`3vJ~F zwu8q$WEwEBf+>)&C%5_@7W5W#sJ8}-Bj=y3fzcEAvRvtBHL3Eb%Dgu$*xAJaG?$3# zY4cwNI{PoqrIGTm6J(>)+nU-6=(hEIzv*Miaejbx zx>b2eojZ-#xy}9gSvJS$^m7fxB);DQqoRJrS*}SZaa7}n_H!hfw4OTiA<_OY2lQAM zV*{}+;Uwrt%-ZR?;#Xir$SlM6HCKAvU?FRRZ!^EQc$r*U&q7+KxNOzpCt2}wI!F(l zaN3z|)6}#Kw!&a0HlSHFTaC!Sgo7EiuEw{ex2xZnN)_ol{W|Bkv&566C(`jEZvTGF z4%q5&^Xh+j?We>hPD^us*Pe+T5mxJ4Jx_FaI7ak?U5VH^oyk(yVzUhuu}^jUXObG( z7&dkLuzfs~&3dzlC)9S_N=}^;8)IJM3wphXs?(yb*vdet%{SPUZ$G?F5mC!KfCwrv zVrW0HrP}*UDz_bFvobVfqp3hRo#od){oIi{x!5{jB!{H^y#!Jd+t3vhCC38Hf;5dZ zZK?>UzAYT*Qz{6TbIXA+J-fD?w2T! zok_J~-r58gkwi^=^ytx?RX<7}2j46j*%{@638M>Q0ia zC*ogddc;7!ZKnx1LFT*k`wSA8f zg`H3AGds{5B^JZYW~_)2h9h?%1zM<4U*E$f?nzTk1kzdJ`g~DkkDM-5 z3DvQ~_rReIh0sS|sXRyaAr57;sqg6p`zWynU44Rjag(Y_tuN@f9tOn)^X6usXOj0X z5SK593wBZBiEJWR9Z}W$RirJe){&w@0=usokl4+uZ&zbxN<8(9%kS$PR>d|yt$NRK zY|h6{Jo@9;%yY!x!A(a!u5Zy25DTcg+^Tr;&VWLgY)p~p<*mHNO#g|_Jy zOL%z*wr|i2?RLfxZUIMX$>SsJY$w<7mDt5+i-a*E0SjDUO`E7)ItipRt{Wa;NMZN~ z6?AE5B2eTKzYy3mMH@Eff)xVMqC9mrXBu%$q;%s?rVUwVxRaqpQZ=Z^xLr>r?J?D? z4Vbm2Ljuh0SeR8(wh=qxu=4!p7&1lHLn>0~6h!29qeLQ}q?=sI?&E~^+kDrg*+?5` zCT*~WcnOQ!zGNilDt5c_#ejBD%zx~bh`iiGsp=ck^mz2NwrSl6E8(&!xyu%rG0d$+ zI8Y(4%Gmk{sG#&+9xw!A{5s5kw~4m71#DdVC80#=N=eOUt%j~Zq@W$nmC7M2;_J}c zja@?_zTKepaVO>v?IU(Tq-)MzJfk(K

4=9~9ZMJPWY|C(?DY=g@QTa1(T zVz0d|tr($J!gP@BIEXGB^{^3d#EO@ax-Ewn;)z^(2#P?-peU{FvqR#5uQtSFZ6c?m z!r5Hb;IJ+iQ8hZY%g1n}dUD%f0td4c9=SKnO7GVf#?j5G3O^H`=vN0fd+`_yH|C*x zA8{LebrI1in==p=RM*b>S|=KS21ygTkjuL06uH z3B=B^;^J%QCqiJR9@Hv+)rWn#NJPa_3k%e4R!@V;aLKbh^2dk}m^v_lX&}-9?eDpjAja8gf(cKNaiMCp@8Z^lFW^; z1wL?B%1v(Lqb_@V>mnGRbhvZdOC30akiq+BkJV&+BEF}{_Z$mzKHHOb?>?tJB-tQ6 zV}c1(l12pdhiPA!z|R=*=?t&Uf!>VmnZF{$%NcUaVc8LIgh!36Zgr)Sv!SwXM ztj*<_n?b7RmSFl5{4y0`lzlS?(NlKE=YsYN0#6*~1 zzpsVFP{{d-xe_15XaoN$*e@7OW+W#5dtt8k>ZOh(y3C;%2RH~8#{Z<&j!{BK)UvkKr<%4RRb@MS;Wzj0PO)rB zY8o_>y~(5ywee-nbDUNfHggVKyvt@&ce`Blp^C_OM$+Z;6@^W%%0 zv51ebcpocrzHoW|aMyW3D-5@zh;1b3KK{X4WKR?3!2+FBAz3@~&5hIn85Pu@ML9=G5N@mR!Q$!&YiMa$qWvNxHhFLZEq1;xp zD*T!v){k&E!sgM; zrkQ4T6tud1;mn&jLg^+-(hI94

OkP)0GNs`3Wkvm27pYe=B6H3^2|SN9>3(Gh`y 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 W=CpY>y~-*4XX+&Ti7D3J8~zUj^DEE* literal 0 HcmV?d00001 diff --git a/src/SerialLoops/MainForm.eto.cs b/src/SerialLoops/MainForm.eto.cs index 1cc63412..74e9ac27 100644 --- a/src/SerialLoops/MainForm.eto.cs +++ b/src/SerialLoops/MainForm.eto.cs @@ -143,6 +143,14 @@ private void InitializeBaseMenu() }; openProjectCommand.Executed += OpenProject_Executed; + Command editSaveFileCommand = new() + { + MenuText = "Edit Save File...", + ToolBarText = "Edit Save File", + Image = ControlGenerator.GetIcon("Edit_Save", Log) + }; + editSaveFileCommand.Executed += EditSaveFileCommand_Executed; + // Application Items Command preferencesCommand = new(); preferencesCommand.Executed += PreferencesCommand_Executed; @@ -175,15 +183,7 @@ private void InitializeBaseMenu() // About Command aboutCommand = new() { MenuText = "About...", Image = ControlGenerator.GetIcon("Help", Log) }; - aboutCommand.Executed += (sender, e) => new AboutDialog - { - ProgramName = "Serial Loops", - Developers = new[] { "Jonko", "William278" }, - Copyright = "© Haroohie Translation Club, 2023", - Website = new Uri("https://haroohie.club"), - Version = Assembly.GetExecutingAssembly().GetCustomAttribute() - .InformationalVersion, - }.ShowDialog(this); + aboutCommand.Executed += AboutCommand_Executed; // Create Menu _recentProjectsCommand = new() { Text = "Recent Projects" }; @@ -199,7 +199,9 @@ private void InitializeBaseMenu() { newProjectCommand, openProjectCommand, - _recentProjectsCommand + _recentProjectsCommand, + new SeparatorMenuItem(), + editSaveFileCommand } } }, @@ -295,9 +297,6 @@ private void InitializeProjectMenu() Command findOrphanedItemsCommand = new() { MenuText = "Find Orphaned Items...", Image = ControlGenerator.GetIcon("Orphan_Search", Log) }; findOrphanedItemsCommand.Executed += FindOrphanedItems_Executed; - Command editSaveFileCommand = new() { MenuText = "Edit Save File..." }; - editSaveFileCommand.Executed += EditSaveFileCommand_Executed; - // Build Command buildIterativeProjectCommand = new() { @@ -339,14 +338,17 @@ private void InitializeProjectMenu() // Add project items to existing File menu if (Menu.Items.FirstOrDefault(x => x.Text.Contains("File")) is SubMenuItem fileMenu) { - fileMenu.Items.AddRange(new[] + foreach (var command in new[] + { + saveProjectCommand, + projectSettingsCommand, + migrateProjectCommand, + exportPatchCommand, + closeProjectCommand + }) { - saveProjectCommand, - projectSettingsCommand, - migrateProjectCommand, - exportPatchCommand, - closeProjectCommand - }); + fileMenu.Items.Insert(3, command); + } } Menu.Items.Add(new SubMenuItem @@ -360,8 +362,6 @@ private void InitializeProjectMenu() editTutorialMappingsCommand, searchProjectCommand, findOrphanedItemsCommand, - new SeparatorMenuItem(), - editSaveFileCommand, } }); Menu.Items.Add(new SubMenuItem @@ -481,6 +481,19 @@ private void UpdateRecentProjects() }); ProjectsCache.Save(Log); } + + public void AboutCommand_Executed(object sender, EventArgs e) + { + new AboutDialog + { + ProgramName = "Serial Loops", + Developers = new[] { "Jonko", "William278" }, + Copyright = "© Haroohie Translation Club, 2023", + Website = new Uri("https://haroohie.club"), + Version = Assembly.GetExecutingAssembly().GetCustomAttribute() + .InformationalVersion, + }.ShowDialog(this); + } public void NewProjectCommand_Executed(object sender, EventArgs e) { @@ -821,11 +834,11 @@ private void FindOrphanedItems_Executed(object sender, EventArgs e) } } - private void EditSaveFileCommand_Executed(object sender, EventArgs e) + public void EditSaveFileCommand_Executed(object sender, EventArgs e) { - if (OpenProject is not null) + var openEditor = () => { - OpenFileDialog openFileDialog = new() { Title = "Open Chokuretsu save file" }; + OpenFileDialog openFileDialog = new() {Title = "Open Chokuretsu Save File"}; openFileDialog.Filters.Add(new("Chokuretsu Save File", ["*.sav"])); if (openFileDialog.ShowAndReportIfFileSelected(this)) { @@ -835,6 +848,24 @@ private void EditSaveFileCommand_Executed(object sender, EventArgs e) saveEditorDialog.Show(); } } + }; + if (OpenProject is not null) + { + openEditor.Invoke(); + return; + } + + // Ask user if they wish to create a project + if (MessageBox.Show("To edit Save Files, you need to have a project open.\n" + + "No project is currently open. Would you like to create a new project?", + "No Project Open", MessageBoxButtons.YesNo, MessageBoxType.Question, + MessageBoxDefaultButton.Yes) == DialogResult.Yes) + { + NewProjectCommand_Executed(sender, e); + if (OpenProject is not null) + { + openEditor.Invoke(); + } } } diff --git a/src/SerialLoops/Utility/ControlGenerator.cs b/src/SerialLoops/Utility/ControlGenerator.cs index 939a5377..b791c09f 100644 --- a/src/SerialLoops/Utility/ControlGenerator.cs +++ b/src/SerialLoops/Utility/ControlGenerator.cs @@ -4,6 +4,8 @@ using SerialLoops.Controls; using SerialLoops.Lib.Items; using System; +using SerialLoops.Lib; +using SkiaSharp; namespace SerialLoops.Utility { @@ -82,6 +84,103 @@ public static Icon GetIcon(string iconName, ILogger log, int size = 16) } } + public static ImageView GetCharacterVoicePortrait(Project project, ILogger log, VoicePortraitCharacter character) + { + ItemDescription id = project.Items.Find(i => i.Name.Equals("SYSTEX_SYS_CMN_B46")); + if (id is not SystemTextureItem tex) + { + log.LogError($"Failed to load character progress voice for {character}."); + return null; + } + SKBitmap bitmap = tex.Grp.GetImage(transparentIndex: 0); + + // Crop a 16x16 bitmap portrait + SKBitmap portrait = new(16, 16); + int charNum = (int) character - 1; + int x = (charNum % 4) * 32; + int z = (charNum / 4) * 32; + + SKRectI cropRect = new(x + 8, z + 4, x + 24, z + 20); + bitmap.ExtractSubset(portrait, cropRect); + return new ImageView { Image = new SKGuiImage(portrait) }; + } + + public enum VoicePortraitCharacter + { + Kyon = 1, + Haruhi = 2, + Mikuru = 3, + Nagato = 4, + Koizumi = 5, + Sister = 6, + Tsuruya = 7, + Taniguchi = 8, + Kunikida = 9, + Mystery_Girl = 10, + } + public static StackLayout GetCharacterVoiceControl(Control control, Project project, ILogger log, VoicePortraitCharacter character) + { + return new StackLayout + { + Orientation = Orientation.Horizontal, + HorizontalContentAlignment = HorizontalAlignment.Left, + VerticalContentAlignment = VerticalAlignment.Center, + Spacing = 5, + Items = + { + GetCharacterVoicePortrait(project, log, character), + character.ToString().Replace("_", " "), + control + } + }; + } + + public static ImageView GetCharacterProgressPortrait(Project project, ILogger log, ProgressPortraitCharacter character) + { + ItemDescription id = project.Items.Find(i => i.Name.Equals("SYSTEX_XTR_PRG_T08")); + if (id is not SystemTextureItem tex) + { + log.LogError($"Failed to load character progress portrait for {character}."); + return null; + } + SKBitmap bitmap = tex.Grp.GetImage(transparentIndex: 0, width: 16); + + // Crop a 16x16 bitmap portrait + SKBitmap portrait = new(16, 16); + int z = (4 + (int) character) * 16; + + SKRectI cropRect = new(0, z, 16, z + 16); + bitmap.ExtractSubset(portrait, cropRect); + return new ImageView { Image = new SKGuiImage(portrait) }; + } + + public enum ProgressPortraitCharacter + { + Haruhi = 1, + Mikuru = 2, + Nagato = 3, + Koizumi = 4, + Tsuruya = 5, + Unknown = 6, + } + + public static StackLayout GetCharacterProgressControl(Control control, Project project, ILogger log, ProgressPortraitCharacter character) + { + return new StackLayout + { + Orientation = Orientation.Horizontal, + HorizontalContentAlignment = HorizontalAlignment.Left, + VerticalContentAlignment = VerticalAlignment.Center, + Spacing = 5, + Items = + { + GetCharacterProgressPortrait(project, log, character), + character.ToString(), + control + } + }; + } + public static StackLayout GetControlWithIcon(Control control, string iconName, ILogger log) { return new StackLayout