diff --git a/src/SerialLoops.Lib/Items/ChibiItem.cs b/src/SerialLoops.Lib/Items/ChibiItem.cs index d826bdab..08032272 100644 --- a/src/SerialLoops.Lib/Items/ChibiItem.cs +++ b/src/SerialLoops.Lib/Items/ChibiItem.cs @@ -26,11 +26,11 @@ public ChibiItem(Chibi chibi, int chibiIndex, Project project) : base($"CHIBI{ch Chibi = chibi; ChibiIndex = chibiIndex + 1; string firstAnimationName = project.Grp.GetFileByIndex(Chibi.ChibiEntries[0].Animation).Name; - Name = $"CHIBI_{firstAnimationName[0..firstAnimationName.IndexOf('_')]}"; - DisplayName = $"CHIBI_{firstAnimationName[0..firstAnimationName.IndexOf('_')]}"; - TopScreenIndex = chibiIndices.IndexOf(firstAnimationName[0..3]); + Name = $"CHIBI_{firstAnimationName[..firstAnimationName.IndexOf('_')]}"; + DisplayName = $"CHIBI_{firstAnimationName[..firstAnimationName.IndexOf('_')]}"; + TopScreenIndex = chibiIndices.IndexOf(firstAnimationName[..3]); ChibiEntries.AddRange(Chibi.ChibiEntries.Where(c => c.Animation > 0) - .Select(c => (project.Grp.GetFileByIndex(c.Animation).Name[0..^3], new ChibiGraphics(c, project)))); + .Select(c => (project.Grp.GetFileByIndex(c.Animation).Name[..^3], new ChibiGraphics(c, project)))); ChibiEntries.ForEach(e => ChibiEntryModifications.Add(e.Name, false)); ChibiEntries.ForEach(e => ChibiAnimations.Add(e.Name, GetChibiAnimation(e.Name, project.Grp))); } diff --git a/src/SerialLoops.Lib/Items/ItemDescription.cs b/src/SerialLoops.Lib/Items/ItemDescription.cs index 396ea849..af982d86 100644 --- a/src/SerialLoops.Lib/Items/ItemDescription.cs +++ b/src/SerialLoops.Lib/Items/ItemDescription.cs @@ -80,7 +80,7 @@ public List GetReferencesTo(Project project) ]; (string ScriptName, ScriptCommandInvocation command)[] bgScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => bgCommands.Contains(c.Command.Mnemonic)).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => bgCommands.Contains(c.Command.Mnemonic)).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == bg.Id || t.c.Command.Mnemonic == EventFile.CommandVerb.BG_FADE.ToString() && t.c.Parameters[1] == bg.Id).ToArray(); return project.Items.Where(i => bgScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); @@ -88,7 +88,7 @@ public List GetReferencesTo(Project project) BackgroundMusicItem bgm = (BackgroundMusicItem)this; (string ScriptName, ScriptCommandInvocation comamnd)[] bgmScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.BGM_PLAY.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.BGM_PLAY.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == bgm.Index).ToArray(); return project.Items.Where(i => bgmScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); @@ -100,17 +100,25 @@ public List GetReferencesTo(Project project) CharacterSpriteItem sprite = (CharacterSpriteItem)this; (string ScriptName, ScriptCommandInvocation command)[] spriteScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.DIALOGUE.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.DIALOGUE.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[1] == sprite.Index).ToArray(); return project.Items.Where(i => spriteScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); + case ItemType.Chess_Puzzle: + ChessPuzzleItem chessPuzzle = (ChessPuzzleItem)this; + (string ScriptName, ScriptCommandInvocation command)[] chessPuzzleScriptUses = project.Evt.Files.AsParallel().SelectMany(e => + e.ScriptSections.SelectMany((sec => + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.CHESS_LOAD.ToString()).Select(c => (e.Name[..^1], c))))) + .Where(t => t.c.Parameters[0] == chessPuzzle.ChessPuzzle.Index).ToArray(); + return project.Items.Where(i => chessPuzzleScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); + case ItemType.Chibi: ChibiItem chibi = (ChibiItem)this; references.AddRange(project.Items.Where(i => i.Type == ItemType.Script && project.Evt.Files.Where(e => e.MapCharactersSection?.Objects?.Any(t => t.CharacterIndex == chibi.ChibiIndex) ?? false).Select(e => e.Index).Contains(((ScriptItem)i).Event.Index))); (string ScriptName, ScriptCommandInvocation command)[] chibiScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.CHIBI_ENTEREXIT.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.CHIBI_ENTEREXIT.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == chibi.TopScreenIndex).ToArray(); references.AddRange(project.Items.Where(i => chibiScriptUses.Select(s => s.ScriptName).Contains(i.Name))); return references.Distinct().ToList(); @@ -127,7 +135,7 @@ public List GetReferencesTo(Project project) MapItem map = (MapItem)this; (string ScriptName, ScriptCommandInvocation command)[] mapScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.LOAD_ISOMAP.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.LOAD_ISOMAP.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == map.Map.Index).ToArray(); return project.Items.Where(i => i.Type == ItemType.Puzzle && ((PuzzleItem)i).Puzzle.Settings.MapId == map.QmapIndex) .Concat(project.Items.Where(i => mapScriptUses.Select(s => s.ScriptName).Contains(i.Name))).ToList(); @@ -136,7 +144,7 @@ public List GetReferencesTo(Project project) PlaceItem place = (PlaceItem)this; (string ScriptName, ScriptCommandInvocation command)[] placeScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.SET_PLACE.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.SET_PLACE.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[1] == place.Index).ToArray(); return project.Items.Where(i => placeScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); @@ -165,7 +173,7 @@ public List GetReferencesTo(Project project) SfxItem sfx = (SfxItem)this; (string ScriptName, ScriptCommandInvocation command)[] sfxScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.SND_PLAY.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.SND_PLAY.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == sfx.Index).ToArray(); references.AddRange(project.Items.Where(i => sfxScriptUses.Select(s => s.ScriptName).Contains(i.Name))); references.AddRange(project.Items.Where(c => c.Type == ItemType.Character && ((CharacterItem)c).MessageInfo.VoiceFont == sfx.Index)); @@ -175,7 +183,7 @@ public List GetReferencesTo(Project project) TopicItem topic = (TopicItem)this; (string ScriptName, ScriptCommandInvocation command)[] topicScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.TOPIC_GET.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.TOPIC_GET.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == topic.TopicEntry.Id).ToArray(); return project.Items.Where(i => topicScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); @@ -183,11 +191,11 @@ public List GetReferencesTo(Project project) VoicedLineItem voicedLine = (VoicedLineItem)this; (string ScriptName, ScriptCommandInvocation command)[] vceScriptUses = project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.DIALOGUE.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.DIALOGUE.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[5] == voicedLine.Index) .Concat(project.Evt.Files.AsParallel().SelectMany(e => e.ScriptSections.SelectMany(sec => - sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.VCE_PLAY.ToString()).Select(c => (e.Name[0..^1], c)))) + sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.VCE_PLAY.ToString()).Select(c => (e.Name[..^1], c)))) .Where(t => t.c.Parameters[0] == voicedLine.Index)) .ToArray(); return project.Items.Where(i => vceScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList(); @@ -196,4 +204,4 @@ public List GetReferencesTo(Project project) return references; } } -} \ No newline at end of file +} diff --git a/src/SerialLoops.Lib/Items/MapItem.cs b/src/SerialLoops.Lib/Items/MapItem.cs index 36955d65..88fcc2e4 100644 --- a/src/SerialLoops.Lib/Items/MapItem.cs +++ b/src/SerialLoops.Lib/Items/MapItem.cs @@ -14,7 +14,7 @@ public class MapItem : Item public MapItem(string name) : base(name, ItemType.Map) { } - public MapItem(MapFile map, int qmapIndex, Project project) : base(map.Name[0..^1], ItemType.Map) + public MapItem(MapFile map, int qmapIndex, Project project) : base(map.Name[..^1], ItemType.Map) { Map = map; QmapIndex = qmapIndex; diff --git a/src/SerialLoops.Lib/Items/PlaceItem.cs b/src/SerialLoops.Lib/Items/PlaceItem.cs index c87fbb02..9754d53c 100644 --- a/src/SerialLoops.Lib/Items/PlaceItem.cs +++ b/src/SerialLoops.Lib/Items/PlaceItem.cs @@ -12,7 +12,7 @@ public class PlaceItem : Item, IPreviewableGraphic public GraphicsFile PlaceGraphic { get; set; } public string PlaceName { get; set; } - public PlaceItem(int index, GraphicsFile placeGrp) : base(placeGrp.Name[0..^3], ItemType.Place) + public PlaceItem(int index, GraphicsFile placeGrp) : base(placeGrp.Name[..^3], ItemType.Place) { Index = index; CanRename = false; diff --git a/src/SerialLoops.Lib/Items/PuzzleItem.cs b/src/SerialLoops.Lib/Items/PuzzleItem.cs index d8b25fc5..5baeddb0 100644 --- a/src/SerialLoops.Lib/Items/PuzzleItem.cs +++ b/src/SerialLoops.Lib/Items/PuzzleItem.cs @@ -11,7 +11,7 @@ public class PuzzleItem : Item public PuzzleFile Puzzle { get; set; } public SKBitmap SingularityImage { get; set; } - public PuzzleItem(PuzzleFile puzzleFile, Project project, ILogger log) : base(puzzleFile.Name[0..^1], ItemType.Puzzle) + public PuzzleItem(PuzzleFile puzzleFile, Project project, ILogger log) : base(puzzleFile.Name[..^1], ItemType.Puzzle) { Puzzle = puzzleFile; Refresh(project, log); diff --git a/src/SerialLoops.Lib/Items/ScriptItem.cs b/src/SerialLoops.Lib/Items/ScriptItem.cs index 7bc21eeb..4324f7f2 100644 --- a/src/SerialLoops.Lib/Items/ScriptItem.cs +++ b/src/SerialLoops.Lib/Items/ScriptItem.cs @@ -27,7 +27,7 @@ public ScriptItem(string name) : base(name, ItemType.Script) } public ScriptItem(EventFile evt, EventTable evtTbl, Func localize, ILogger log) : base( - evt.Name[0..^1], ItemType.Script) + evt.Name[..^1], ItemType.Script) { Event = evt; _localize = localize; diff --git a/src/SerialLoops.Lib/Project.cs b/src/SerialLoops.Lib/Project.cs index ee35e5ca..763cfe7c 100644 --- a/src/SerialLoops.Lib/Project.cs +++ b/src/SerialLoops.Lib/Project.cs @@ -518,7 +518,7 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker) if (entry.BgIndex1 > 0) { GraphicsFile nameGraphic = Grp.GetFileByIndex(entry.BgIndex1); - string name = $"BG_{nameGraphic.Name[0..nameGraphic.Name.LastIndexOf('_')]}"; + string name = $"BG_{nameGraphic.Name[..nameGraphic.Name.LastIndexOf('_')]}"; string bgNameBackup = name; for (int j = 1; names.Contains(name); j++) { @@ -820,21 +820,21 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker) tracker.Finished++; foreach (SystemTexture extraSysTex in systemTextureFile.SystemTextures.Where(s => Grp.Files.AsParallel().Where(g => g.Name.StartsWith("XTR")).Distinct().Select(g => g.Index).Contains(s.GrpIndex))) { - Items.Add(new SystemTextureItem(extraSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(extraSysTex.GrpIndex).Name[0..^3]}")); + Items.Add(new SystemTextureItem(extraSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(extraSysTex.GrpIndex).Name[..^3]}")); tracker.Finished++; } // Exclude B12 as that's the nameplates we replace in the character items and PPT_001 as that's the puzzle phase singularity we'll be replacing in the puzzle items // We also exclude the "special" graphics as they do not include all of them in the SYSTEX file (should be made to be edited manually) foreach (SystemTexture sysSysTex in systemTextureFile.SystemTextures.Where(s => Grp.Files.AsParallel().Where(g => g.Name.StartsWith("SYS") && !g.Name.Contains("_SPC_") && g.Name != "SYS_CMN_B12DNX" && g.Name != "SYS_PPT_001DNX").Select(g => g.Index).Contains(s.GrpIndex)).DistinctBy(s => s.GrpIndex)) { - if (Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[0..^4].EndsWith("T6")) + if (Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[..^4].EndsWith("T6")) { // special case the ep headers - Items.Add(new SystemTextureItem(sysSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[0..^3]}", height: 192)); + Items.Add(new SystemTextureItem(sysSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[..^3]}", height: 192)); } else { - Items.Add(new SystemTextureItem(sysSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[0..^3]}")); + Items.Add(new SystemTextureItem(sysSysTex, this, $"SYSTEX_{Grp.GetFileByIndex(sysSysTex.GrpIndex).Name[..^3]}")); } tracker.Finished++; } diff --git a/src/SerialLoops.Lib/Script/ScriptItemCommand.cs b/src/SerialLoops.Lib/Script/ScriptItemCommand.cs index 047acf79..75b1d3dc 100644 --- a/src/SerialLoops.Lib/Script/ScriptItemCommand.cs +++ b/src/SerialLoops.Lib/Script/ScriptItemCommand.cs @@ -713,7 +713,7 @@ public override string ToString() switch (Verb) { case CommandVerb.DIALOGUE: - str += $" {((DialogueScriptParameter)Parameters[0]).Line.Text.GetSubstitutedString(Project)[0..Math.Min(((DialogueScriptParameter)Parameters[0]).Line.Text.Length, 10)]}..."; + str += $" {((DialogueScriptParameter)Parameters[0]).Line.Text.GetSubstitutedString(Project)[..Math.Min(((DialogueScriptParameter)Parameters[0]).Line.Text.Length, 10)]}..."; break; case CommandVerb.GOTO: str += $" {((ScriptSectionScriptParameter)Parameters[0]).Section.Name}"; diff --git a/src/SerialLoops.Lib/Util/Extensions.cs b/src/SerialLoops.Lib/Util/Extensions.cs index d4f050b3..1554a7ec 100644 --- a/src/SerialLoops.Lib/Util/Extensions.cs +++ b/src/SerialLoops.Lib/Util/Extensions.cs @@ -431,7 +431,7 @@ public override SKColor Read(ref Utf8JsonReader reader, Type typeToConvert, Json byte.Parse(html[2..4], NumberStyles.HexNumber), byte.Parse(html[4..6], NumberStyles.HexNumber), byte.Parse(html[6..8], NumberStyles.HexNumber), - byte.Parse(html[0..2], NumberStyles.HexNumber) + byte.Parse(html[..2], NumberStyles.HexNumber) ); } diff --git a/src/SerialLoops/Assets/Strings.Designer.cs b/src/SerialLoops/Assets/Strings.Designer.cs index 81000eb3..fc95bcf7 100644 --- a/src/SerialLoops/Assets/Strings.Designer.cs +++ b/src/SerialLoops/Assets/Strings.Designer.cs @@ -1693,8 +1693,8 @@ public static string devkitARM_Docker_Tag { /// public static string devkitARM_is_not_detected_at_the_default_or_specified_install_location__Please_set_devkitARM_path_ { get { - return ResourceManager.GetString("devkitARM is not detected at the default or specified install location. Please se" + - "t devkitARM path.", resourceCulture); + return ResourceManager.GetString(("devkitARM is not detected at the default or specified install location. Please se" + + "t devkitARM path."), resourceCulture); } } @@ -2360,8 +2360,8 @@ public static string ERROR___0_ { /// public static string Error__duplicate_hack_detected__A_file_with_the_same_name_as_a_file_in_this_hack_has_already_been_imported_ { get { - return ResourceManager.GetString("Error: duplicate hack detected! A file with the same name as a file in this hack " + - "has already been imported.", resourceCulture); + return ResourceManager.GetString(("Error: duplicate hack detected! A file with the same name as a file in this hack " + + "has already been imported."), resourceCulture); } } @@ -2370,8 +2370,8 @@ public static string Error__duplicate_hack_detected__A_file_with_the_same_name_a /// public static string Error__duplicate_hack_detected__A_hack_with_the_same_name_has_already_been_imported_ { get { - return ResourceManager.GetString("Error: duplicate hack detected! A hack with the same name has already been import" + - "ed.", resourceCulture); + return ResourceManager.GetString(("Error: duplicate hack detected! A hack with the same name has already been import" + + "ed."), resourceCulture); } } @@ -2799,8 +2799,8 @@ public static string Failed_to_add_parameters_for_hack_file__0__in_hack__1_ { /// public static string Failed_to_apply_the_following_hacks_to_the_ROM__n_0__n_nPlease_check_the_log_file_for_more_information__n_nIn_order_to_preserve_state__no_hacks_were_applied_ { get { - return ResourceManager.GetString("Failed to apply the following hacks to the ROM:\\n{0}\\n\\nPlease check the log file" + - " for more information.\\n\\nIn order to preserve state, no hacks were applied.", resourceCulture); + return ResourceManager.GetString(("Failed to apply the following hacks to the ROM:\\n{0}\\n\\nPlease check the log file" + + " for more information.\\n\\nIn order to preserve state, no hacks were applied."), resourceCulture); } } @@ -2872,8 +2872,8 @@ public static string Failed_to_delete_file___0__ { /// public static string Failed_to_delete_files_for_hack___0______this_hack_is_likely_applied_in_the_ROM_base_and_can_t_be_disabled_ { get { - return ResourceManager.GetString("Failed to delete files for hack \'{0}\' -- this hack is likely applied in the ROM b" + - "ase and can\'t be disabled.", resourceCulture); + return ResourceManager.GetString(("Failed to delete files for hack \'{0}\' -- this hack is likely applied in the ROM b" + + "ase and can\'t be disabled."), resourceCulture); } } @@ -2963,8 +2963,8 @@ public static string Failed_to_export_system_texture__0__to_file__1_ { /// public static string Failed_to_find_character_item____have_you_saved_all_of_your_changes_to_character_names_ { get { - return ResourceManager.GetString("Failed to find character item -- have you saved all of your changes to character " + - "names?", resourceCulture); + return ResourceManager.GetString(("Failed to find character item -- have you saved all of your changes to character " + + "names?"), resourceCulture); } } @@ -3126,8 +3126,8 @@ public static string Failed_to_replace_item__0__with_file__1_ { /// public static string Failed_to_replace_screen_image__image_too_complex__generated_more_than_255_tiles___please_use_a_simpler_image { get { - return ResourceManager.GetString("Failed to replace screen image: image too complex (generated more than 255 tiles)" + - "; please use a simpler image", resourceCulture); + return ResourceManager.GetString(("Failed to replace screen image: image too complex (generated more than 255 tiles)" + + "; please use a simpler image"), resourceCulture); } } @@ -4460,8 +4460,8 @@ public static string No_Emulator_Path { /// public static string No_emulator_path_has_been_set__nPlease_set_the_path_to_a_Nintendo_DS_emulator_in_Preferences_to_use_Build___Run_ { get { - return ResourceManager.GetString("No emulator path has been set.\\nPlease set the path to a Nintendo DS emulator in " + - "Preferences to use Build & Run.", resourceCulture); + return ResourceManager.GetString(("No emulator path has been set.\\nPlease set the path to a Nintendo DS emulator in " + + "Preferences to use Build & Run."), resourceCulture); } } @@ -4749,7 +4749,7 @@ public static string Option_4 { /// public static string Orphaned_Items { get { - return ResourceManager.GetString("Orphaned Items", resourceCulture); + return ResourceManager.GetString("Orphaned_Items", resourceCulture); } } @@ -5883,9 +5883,9 @@ public static string Save_voiced_line_as_WAV { /// public static string Saved_but_unbuilt_files_were_detected_in_the_project_directory__Would_you_like_to_build_before_loading_the_project__Not_building_could_result_in_these_files_being_overwritten_ { get { - return ResourceManager.GetString("Saved but unbuilt files were detected in the project directory. Would you like to" + + return ResourceManager.GetString(("Saved but unbuilt files were detected in the project directory. Would you like to" + " build before loading the project? Not building could result in these files bein" + - "g overwritten.", resourceCulture); + "g overwritten."), resourceCulture); } } @@ -7020,8 +7020,8 @@ public static string Text_Voice_Font { /// public static string The_base_ROM_hash_does_not_match_the_expected_hash__Please_check_the___Ignore_Hash___checkbox_if_you_wish_to_override_this_ { get { - return ResourceManager.GetString("The base ROM hash does not match the expected hash! Please check the \\\"Ignore Has" + - "h\\\" checkbox if you wish to override this.", resourceCulture); + return ResourceManager.GetString(("The base ROM hash does not match the expected hash! Please check the \\\"Ignore Has" + + "h\\\" checkbox if you wish to override this."), resourceCulture); } } @@ -7050,9 +7050,9 @@ public static string The_root_section_cannot_be_deleted_ { /// public static string The_selected_ROM_s_hash_does_not_match_the_expected_ROM_hash__Please_ensure_you_are_using_the_correct_base_ROM__n_nIf_you_wish_to_ignore_this__please_check_the___Ignore_Hash___checkbox_ { get { - return ResourceManager.GetString("The selected ROM\'s hash does not match the expected ROM hash. Please ensure you a" + + return ResourceManager.GetString(("The selected ROM\'s hash does not match the expected ROM hash. Please ensure you a" + "re using the correct base ROM.\\n\\nIf you wish to ignore this, please check the \\" + - "\"Ignore Hash\\\" checkbox.", resourceCulture); + "\"Ignore Hash\\\" checkbox."), resourceCulture); } } @@ -7061,8 +7061,8 @@ public static string The_selected_ROM_s_hash_does_not_match_the_expected_ROM_has /// public static string There_is_already_a_template_with_that_name__Please_choose_a_different_name_for_your_template_ { get { - return ResourceManager.GetString("There is already a template with that name. Please choose a different name for yo" + - "ur template.", resourceCulture); + return ResourceManager.GetString(("There is already a template with that name. Please choose a different name for yo" + + "ur template."), resourceCulture); } } @@ -7071,9 +7071,9 @@ public static string There_is_already_a_template_with_that_name__Please_choose_a /// public static string There_is_no_recorded_base_ROM_hash_for_this_project__This_is_likely_because_this_project_was_created_with_an_older_version_of_Serial_Loops__Please_select_the_base_ROM_used_for_this_project_so_the_hash_can_be_recorded_now_ { get { - return ResourceManager.GetString("There is no recorded base ROM hash for this project. This is likely because this " + + return ResourceManager.GetString(("There is no recorded base ROM hash for this project. This is likely because this " + "project was created with an older version of Serial Loops. Please select the bas" + - "e ROM used for this project so the hash can be recorded now.", resourceCulture); + "e ROM used for this project so the hash can be recorded now."), resourceCulture); } } @@ -7091,8 +7091,8 @@ public static string This_script_is_not_included_in_the_event_table_ { /// public static string This_system_texture_uses_a_common_palette__so_palette_replacement_has_been_disabled { get { - return ResourceManager.GetString("This system texture uses a common palette, so palette replacement has been disabl" + - "ed", resourceCulture); + return ResourceManager.GetString(("This system texture uses a common palette, so palette replacement has been disabl" + + "ed"), resourceCulture); } } @@ -7183,8 +7183,8 @@ public static string Title_screen_return_unsaved_progress_lost_prompt_message_bo /// public static string To_edit_Save_Files__you_need_to_have_a_project_open__nNo_project_is_currently_open__Would_you_like_to_create_a_new_project_ { get { - return ResourceManager.GetString("To edit Save Files, you need to have a project open.\\nNo project is currently ope" + - "n. Would you like to create a new project?", resourceCulture); + return ResourceManager.GetString(("To edit Save Files, you need to have a project open.\\nNo project is currently ope" + + "n. Would you like to create a new project?"), resourceCulture); } } @@ -7868,8 +7868,8 @@ public static string Yes { /// public static string You_have_unsaved_changes_in__0__item_s___Would_you_like_to_save_before_closing_the_project_ { get { - return ResourceManager.GetString("You have unsaved changes in {0} item(s). Would you like to save before closing th" + - "e project?", resourceCulture); + return ResourceManager.GetString(("You have unsaved changes in {0} item(s). Would you like to save before closing th" + + "e project?"), resourceCulture); } } diff --git a/src/SerialLoops/Assets/Strings.en-GB.resx b/src/SerialLoops/Assets/Strings.en-GB.resx index da278b9e..683c215a 100644 --- a/src/SerialLoops/Assets/Strings.en-GB.resx +++ b/src/SerialLoops/Assets/Strings.en-GB.resx @@ -1423,7 +1423,7 @@ Option 4 - + Orphaned Items diff --git a/src/SerialLoops/Assets/Strings.it.resx b/src/SerialLoops/Assets/Strings.it.resx index 94f83aff..967a9e66 100644 --- a/src/SerialLoops/Assets/Strings.it.resx +++ b/src/SerialLoops/Assets/Strings.it.resx @@ -1735,7 +1735,7 @@ file FLAC - + Oggetti senza collegamenti diff --git a/src/SerialLoops/Assets/Strings.resx b/src/SerialLoops/Assets/Strings.resx index 8c2c081f..7c084f0d 100644 --- a/src/SerialLoops/Assets/Strings.resx +++ b/src/SerialLoops/Assets/Strings.resx @@ -1608,7 +1608,7 @@ Please set the path to a Nintendo DS emulator or specify a Nintendo DS emulator Option 4 - + Orphaned Items diff --git a/src/SerialLoops/Assets/Strings.zh-Hans.resx b/src/SerialLoops/Assets/Strings.zh-Hans.resx index 9d23db14..881cbf9a 100644 --- a/src/SerialLoops/Assets/Strings.zh-Hans.resx +++ b/src/SerialLoops/Assets/Strings.zh-Hans.resx @@ -1522,7 +1522,7 @@ 选项 4 - + 未使用的项目 diff --git a/src/SerialLoops/SerialLoops.csproj b/src/SerialLoops/SerialLoops.csproj index 838b363d..ff11492d 100644 --- a/src/SerialLoops/SerialLoops.csproj +++ b/src/SerialLoops/SerialLoops.csproj @@ -55,6 +55,7 @@ + diff --git a/src/SerialLoops/Utility/ControlGenerator.cs b/src/SerialLoops/Utility/ControlGenerator.cs index 1c3dd92e..70a33aec 100644 --- a/src/SerialLoops/Utility/ControlGenerator.cs +++ b/src/SerialLoops/Utility/ControlGenerator.cs @@ -7,9 +7,7 @@ using Avalonia.Svg; using HaruhiChokuretsuLib.Util; using SerialLoops.Assets; -using SerialLoops.Lib; using SerialLoops.Lib.Items; -using SerialLoops.ViewModels.Dialogs; namespace SerialLoops.Utility; @@ -93,25 +91,6 @@ public static string LocalizeItemTypes(ItemDescription.ItemType type) }; } - public static string LocalizeSearchScopes(SearchQuery.DataHolder scope) - { - return scope switch - { - SearchQuery.DataHolder.Title => Strings.Title, - SearchQuery.DataHolder.Background_ID => Strings.Background_ID, - - SearchQuery.DataHolder.Dialogue_Text => Strings.Dialogue_Text, - SearchQuery.DataHolder.Flag => Strings.Flag, - SearchQuery.DataHolder.Speaker_Name => Strings.Speaker_Name, - SearchQuery.DataHolder.Conditional => Strings.Conditional, - SearchQuery.DataHolder.Background_Type => Strings.Background_Type, - SearchQuery.DataHolder.Episode_Number => Strings.Episode_Number, - SearchQuery.DataHolder.Episode_Unique => Strings.Episode_Unique, - SearchQuery.DataHolder.Orphaned_Items => Strings.Orphaned_Items, - _ => "UNKNOWN SCOPE", - }; - } - public static StackPanel GetControlWithIcon(Control control, string iconName, ILogger log) { StackPanel panel = new() diff --git a/src/SerialLoops/ViewModels/Dialogs/SearchDialogViewModel.cs b/src/SerialLoops/ViewModels/Dialogs/SearchDialogViewModel.cs index b4f36da2..420525ea 100644 --- a/src/SerialLoops/ViewModels/Dialogs/SearchDialogViewModel.cs +++ b/src/SerialLoops/ViewModels/Dialogs/SearchDialogViewModel.cs @@ -2,13 +2,12 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Threading.Tasks; using System.Windows.Input; -using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Models.TreeDataGrid; using Avalonia.Controls.Templates; using Avalonia.Input; -using Avalonia.Layout; using HaruhiChokuretsuLib.Util; using MsBox.Avalonia.Enums; using ReactiveUI; @@ -21,7 +20,6 @@ using SerialLoops.Utility; using SerialLoops.ViewModels.Panels; using SerialLoops.Views.Dialogs; -using Tabalonia; namespace SerialLoops.ViewModels.Dialogs; @@ -31,30 +29,39 @@ public class SearchDialogViewModel : ViewModelBase public int MinHeight => 700; public int Width { get; set; } = 900; public int Height { get; set; } = 750; - public ICommand OpenItemCommand { get; private set; } - public ICommand SearchCommand { get; private set; } - public ICommand DeepSearchCommand { get; private set; } - public ICommand CloseCommand { get; private set; } + public ICommand OpenItemCommand { get; } + public ICommand SearchCommand { get; } + public ICommand DeepSearchCommand { get; } + public ICommand ToggleItemScopesCommand { get; } + public ICommand CloseCommand { get; } [Reactive] public string SearchStatusLabel { get; private set; } = Strings.Search_Project; [Reactive] - public KeyGesture CloseKeyGesture { get; private set; } + public KeyGesture CloseHotKey { get; private set; } [Reactive] - public KeyGesture DeepSearchGesture { get; private set; } + public KeyGesture DeepSearchHotKey { get; private set; } [Reactive] public HierarchicalTreeDataGridSource Source { get; private set; } - private ILogger _log; - private Project _project; - private EditorTabsPanelViewModel _tabs; - private SearchDialog _searchDialog; + private readonly ILogger _log; + private readonly Project _project; + private readonly EditorTabsPanelViewModel _tabs; - private List _itemFilterCheckBoxes = []; - private HashSet _checkedSearchScopes = [SearchQuery.DataHolder.Title]; - private HashSet _checkedItemScopes = Enum.GetValues().ToHashSet(); + [Reactive] + public string SearchText { get; set; } + + [Reactive] + public string ToggleText { get; set; } + + private bool _toggleScopesTo = false; - private ObservableCollection _items = new(); + public ObservableCollection SearchScopes { get; } = + new(Enum.GetValues().Select(h => new LocalizedSearchScope(h))); + public ObservableCollection ItemScopes { get; } = + new(Enum.GetValues().Select(i => new LocalizedItemScope(i))); + + private ObservableCollection _items = []; public ObservableCollection Items { get => _items; @@ -71,8 +78,8 @@ public ObservableCollection Items new FuncDataTemplate((val, _) => val?.GetDisplay()), cellEditingTemplate: null, options: null ), i => i.Children - ) - } + ), + }, }; Source.ExpandAll(); @@ -81,7 +88,7 @@ public ObservableCollection Items private ObservableCollection GetSections() { - return new ObservableCollection(Items.GroupBy(i => i.Type) + return new(Items.GroupBy(i => i.Type) .OrderBy(g => ControlGenerator.LocalizeItemTypes(g.Key)) .Select(g => new SectionTreeItem( ControlGenerator.LocalizeItemTypes(g.Key), @@ -92,56 +99,62 @@ private ObservableCollection GetSections() private SearchQuery GetQuery(string query) { - return new SearchQuery + return new() { Term = query, - Scopes = _checkedSearchScopes, - Types = _checkedItemScopes, + Scopes = SearchScopes.Where(s => s.IsActive).Select(s => s.Scope).ToHashSet(), + Types = ItemScopes.Where(i => i.IsActive).Select(i => i.Type).ToHashSet(), }; } - - public void Initialize(SearchDialog searchDialog, Project project, EditorTabsPanelViewModel tabs, ILogger log) + public SearchDialogViewModel(Project project, EditorTabsPanelViewModel tabs, ILogger log) { - _searchDialog = searchDialog; _project = project; _tabs = tabs; _log = log; - SearchCommand = ReactiveCommand.Create(Search); - DeepSearchCommand = ReactiveCommand.Create(() => Search(_searchDialog.Search.Text, true)); - ReactiveCommand.Create(box => box.Focus()); + SearchCommand = ReactiveCommand.CreateFromTask(Search); + DeepSearchCommand = ReactiveCommand.CreateFromTask(DeepSearch); OpenItemCommand = ReactiveCommand.Create(OpenItem); - CloseCommand = ReactiveCommand.Create(_searchDialog.Close); - CloseKeyGesture = new KeyGesture(Key.Escape); - DeepSearchGesture = new KeyGesture(Key.Enter); + CloseCommand = ReactiveCommand.Create(dialog => dialog.Close()); + ToggleItemScopesCommand = ReactiveCommand.Create(() => + { + foreach (LocalizedItemScope scope in ItemScopes) + { + scope.IsActive = _toggleScopesTo; + } + _toggleScopesTo = !_toggleScopesTo; + ToggleText = _toggleScopesTo ? Strings.All_On : Strings.All_Off; + }); + CloseHotKey = new(Key.Escape); + DeepSearchHotKey = new(Key.Enter); - PopulateSearchScopeFilters(); - PopulateSearchItemFilters(); + SearchScopes[0].IsActive = true; + ToggleText = Strings.All_Off; } - public void DeepSearch(string text) => Search(text, true); - public void Search(string text) => Search(text, false); + public async Task DeepSearch(SearchDialog dialog) => await Search(dialog, true); + public async Task Search(SearchDialog dialog) => await Search(dialog, false); - public async void Search(string text, bool force) + public async Task Search(SearchDialog dialog, bool force) { - SearchQuery query = GetQuery(text ?? string.Empty); + SearchQuery query = GetQuery(SearchText ?? string.Empty); switch (query.QuickSearch) { case false when !force: SearchStatusLabel = Strings.Press_ENTER_to_execute_search; return; - case true when string.IsNullOrWhiteSpace(text): + case true when string.IsNullOrWhiteSpace(SearchText): { SearchStatusLabel = Strings.Search_Project; - Items = new ObservableCollection(); + Items = []; break; } case true: { var results = _project.GetSearchResults(query, _log); - Items = new (results); + Items = new(results); SearchStatusLabel = string.Format(Strings._0__results_found, _items.Count); break; } @@ -150,9 +163,11 @@ public async void Search(string text, bool force) SearchStatusLabel = Strings.Press_ENTER_to_execute_search; if (query.Scopes.Count is 0 || query.Types.Count is 0) { - await _searchDialog.ShowMessageBoxAsync(Strings.Please_select_at_least_one_search_scope_and_item_filter_, Strings.Invalid_search_terms, ButtonEnum.Ok, Icon.Error, _log); + await dialog.ShowMessageBoxAsync(Strings.Please_select_at_least_one_search_scope_and_item_filter_, + Strings.Invalid_search_terms, ButtonEnum.Ok, Icon.Error, _log); return; } + LoopyProgressTracker tracker = new(Strings.Searching); List results = []; await new ProgressDialog(() => results = _project.GetSearchResults(query, _log, tracker), @@ -160,7 +175,7 @@ public async void Search(string text, bool force) { Items = new(results); SearchStatusLabel = string.Format(Strings._0__results_found, _items.Count); - }, tracker, string.Format(Strings.Searching__0____, _project.Name)).ShowDialog(_searchDialog);; + }, tracker, string.Format(Strings.Searching__0____, _project.Name)).ShowDialog(dialog); break; } } @@ -168,125 +183,29 @@ public async void Search(string text, bool force) public void OpenItem(TreeDataGrid viewer) { - ItemDescription item = _project.FindItem(((ITreeItem)viewer.RowSelection.SelectedItem)?.Text); + ItemDescription item = _project.FindItem(((ITreeItem)viewer.RowSelection?.SelectedItem)?.Text); if (item is null) { return; } - _searchDialog.Close(); _tabs.OpenTab(item); } +} - private void PopulateSearchScopeFilters() - { - int col = 0; - int row = 0; - foreach (SearchQuery.DataHolder scope in Enum.GetValues()) - { - var label = new TextBlock { - Text = ControlGenerator.LocalizeSearchScopes(scope), - FontSize = 16, - VerticalAlignment = VerticalAlignment.Center - }; - label.SetValue(Grid.ColumnProperty, col); - label.SetValue(Grid.RowProperty, row); - - var box = new CheckBox { - IsChecked = _checkedSearchScopes.Contains(scope), - Margin = new Thickness(10, 0) - }; - box.SetValue(Grid.ColumnProperty, col + 1); - box.SetValue(Grid.RowProperty, row); - box.IsCheckedChanged += (_, _) => - { - if (_checkedSearchScopes.Contains(scope)) - { - _checkedSearchScopes.Remove(scope); - return; - } - _checkedSearchScopes.Add(scope); - }; - - _searchDialog.ScopeFiltersGrid.Children.Add(label); - _searchDialog.ScopeFiltersGrid.Children.Add(box); - - row++; - if (row > 6) - { - row = 0; - col += 2; - } - } - } - - private void PopulateSearchItemFilters() - { - int col = 0; - int row = 0; - foreach (ItemDescription.ItemType type in Enum.GetValues()) - { - var label = ControlGenerator.GetControlWithIcon( - new TextBlock { - Text = ControlGenerator.LocalizeItemTypes(type), - FontSize = 16, - VerticalAlignment = VerticalAlignment.Center - }, - type.ToString(), _log - ); - label.SetValue(Grid.ColumnProperty, col); - label.SetValue(Grid.RowProperty, row); - - var box = new CheckBox { - IsChecked = _checkedItemScopes.Contains(type), - Margin = new Thickness(10, 0) - }; - box.SetValue(Grid.ColumnProperty, col + 1); - box.SetValue(Grid.RowProperty, row); - box.IsCheckedChanged += (_, _) => - { - if (_checkedItemScopes.Contains(type)) - { - _checkedItemScopes.Remove(type); - return; - } - _checkedItemScopes.Add(type); - }; - _itemFilterCheckBoxes.Add(box); - - _searchDialog.TypeFiltersGrid.Children.Add(label); - _searchDialog.TypeFiltersGrid.Children.Add(box); - - // Span across 3 cols - row++; - if (row > 6) - { - row = 0; - col += 2; - } - } - - LinkButton toggleButton = new() { Text = Strings.All_Off, FontSize = 16 }; - toggleButton.Command = new SimpleActionCommand(() => - { - bool allOn = _checkedItemScopes.Count == 0; - _itemFilterCheckBoxes.ForEach(cb => cb.IsChecked = allOn); - _checkedItemScopes = allOn ? Enum.GetValues().ToHashSet() : []; - toggleButton.Text = allOn ? Strings.All_Off : Strings.All_On; - }); - StackPanel toggleStack = new() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Margin = new Thickness(0, 5), - Children = { toggleButton } - }; - toggleStack.SetValue(Grid.ColumnProperty, col); - toggleStack.SetValue(Grid.RowProperty, row); - toggleStack.SetValue(Grid.ColumnSpanProperty, 2); - - _searchDialog.TypeFiltersGrid.Children.Add(toggleStack); - } +public class LocalizedSearchScope(SearchQuery.DataHolder scope) : ReactiveObject +{ + public SearchQuery.DataHolder Scope { get; } = scope; + public string DisplayText { get; } = Strings.ResourceManager.GetString(scope.ToString()); + [Reactive] + public bool IsActive { get; set; } +} +public class LocalizedItemScope(ItemDescription.ItemType type) : ReactiveObject +{ + public ItemDescription.ItemType Type { get; } = type; + public string Icon => $"avares://SerialLoops/Assets/Icons/{Type.ToString()}.svg"; + public string DisplayText { get; } = Strings.ResourceManager.GetString($"{type.ToString()}s"); + [Reactive] + public bool IsActive { get; set; } = true; } diff --git a/src/SerialLoops/ViewModels/MainWindowViewModel.cs b/src/SerialLoops/ViewModels/MainWindowViewModel.cs index 5414e2ae..7641ec90 100644 --- a/src/SerialLoops/ViewModels/MainWindowViewModel.cs +++ b/src/SerialLoops/ViewModels/MainWindowViewModel.cs @@ -618,12 +618,8 @@ public void SearchProject_Executed() { return; } - - SearchDialogViewModel searchDialogViewModel = new(); - SearchDialog searchDialog = new(); - searchDialogViewModel.Initialize(searchDialog, OpenProject, EditorTabs, Log); - searchDialog.DataContext = searchDialogViewModel; - searchDialog.ShowDialog(Window); + SearchDialog searchDialog = new() { DataContext = new SearchDialogViewModel(OpenProject, EditorTabs, Log) }; + searchDialog.Show(Window); } public async Task BuildIterative_Executed() diff --git a/src/SerialLoops/Views/Dialogs/SearchDialog.axaml b/src/SerialLoops/Views/Dialogs/SearchDialog.axaml index 0bb243ff..6df35d92 100644 --- a/src/SerialLoops/Views/Dialogs/SearchDialog.axaml +++ b/src/SerialLoops/Views/Dialogs/SearchDialog.axaml @@ -1,33 +1,34 @@ + x:DataType="vm:SearchDialogViewModel" + x:Class="SerialLoops.Views.Dialogs.SearchDialog" + Title="{x:Static assets:Strings.Search_Project}" + Name="Dialog"> - - + + - + CommandParameter="{Binding #Dialog}"/> @@ -36,12 +37,40 @@ - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + +