From 625d5e25fc3a5de2d448c8b9e29febef46262341 Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 02:41:00 -0400 Subject: [PATCH 1/6] Fix Right Click behavior --- .../Behaviors/BatchMode/BatchModeBehavior.cs | 36 ++++++++++++++++--- ...lEditorViewModel.UserInteractionActions.cs | 3 -- .../ViewModels/FumenVisualEditorViewModel.cs | 3 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs index 5ec8d08a..518b72ff 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs @@ -19,6 +19,7 @@ using OngekiFumenEditor.Properties; using OngekiFumenEditor.UI.KeyBinding.Input; using OngekiFumenEditor.Utils; +using Xceed.Wpf.Toolkit.Core.Input; using EventTrigger = Microsoft.Xaml.Behaviors.EventTrigger; using TriggerAction = Microsoft.Xaml.Behaviors.TriggerAction; using TriggerBase = Microsoft.Xaml.Behaviors.TriggerBase; @@ -178,6 +179,7 @@ private void MouseDown(MouseButtonEventArgs args) editor.SelectionStartPosition = cursor.ToSystemNumericsVector2(); if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) { editor.SelectRegionType = SelectRegionType.SelectFiltered; + editor.SelectionVisibility = Visibility.Visible; } return; } @@ -211,14 +213,34 @@ private void MouseUp(MouseButtonEventArgs args) return; if (args.ChangedButton == MouseButton.Left) { + if (editor.IsRangeSelecting) { + // Selection mode + Func filterFunc = null; + if (editor.SelectRegionType == SelectRegionType.SelectFiltered && CurrentSubmode is BatchModeFilterSubmode filterSubmode) { + filterFunc = filterSubmode.FilterFunction; + } else if (editor.SelectRegionType == SelectRegionType.SelectFiltered && CurrentSubmode is BatchModeSingleInputSubmode singleInputSubmode) { + filterFunc = o => o.GetType() == singleInputSubmode.ObjectType || o.GetType().IsSubclassOf(singleInputSubmode.ObjectType); + } + + if (filterFunc != null) { + editor.SelectionVisibility = Visibility.Hidden; + PerformFilterSelect(filterFunc); + args.Handled = true; + } + + editor.SelectRegionType = SelectRegionType.Select; + // otherwise fall through to FumenVisualEditorViewModel click handler + } + if (!lastLeftClickWasAltClick) { // Can hold alt while releasing to "cancel" the left click if ((Keyboard.Modifiers & ModifierKeys.Alt) == 0) { - if (CurrentSubmode is BatchModeInputSubmode inputSubmode) + if (CurrentSubmode is BatchModeInputSubmode inputSubmode) { PerformBrush(inputSubmode); + } else if (CurrentSubmode is BatchModeFilterSubmode filterSubmode && editor.IsRangeSelecting) { editor.SelectionVisibility = Visibility.Hidden; - PerformFilterSelect(filterSubmode); + PerformFilterSelect(filterSubmode.FilterFunction); } } args.Handled = true; @@ -243,7 +265,6 @@ private void MouseUp(MouseButtonEventArgs args) } } - editor.SelectRegionType = SelectRegionType.Select; editor.SelectionVisibility = Visibility.Hidden; } else { @@ -318,10 +339,15 @@ void Undo() } } - private void PerformFilterSelect(BatchModeFilterSubmode submode) + // TODO Refactor into `SelectionBox` class or something + private void PerformFilterSelect(Func filterFunction) { var editor = (FumenVisualEditorViewModel)AssociatedObject.DataContext; - var hits = editor.GetRangeObjects().Where(o => submode.FilterFunction(o)).ToList(); + var hits = editor.GetRangeObjects().Where(filterFunction).ToList(); + + if (!Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)) { + editor.ClearSelection(); + } foreach (var hit in hits) { if (hit is OngekiMovableObjectBase selectable) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs index 02ba5ac9..65355007 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs @@ -157,7 +157,6 @@ public Point? CurrentCursorPosition private double startXOffset; private double startScrollOffset; private bool isCanvasDragging; - private bool isLeftMouseDown; private bool isMiddleMouseDown; private MouseButtonState prevRightButtonState; private Point contextMenuPosition; @@ -1103,7 +1102,6 @@ public void OnMouseUp(ActionExecutionContext e) } } - isLeftMouseDown = false; isSelectRangeDragging = false; SelectionVisibility = Visibility.Collapsed; currentDraggingActionId = int.MaxValue; @@ -1146,7 +1144,6 @@ public void OnMouseDown(ActionExecutionContext e) { position.Y = Math.Max(0, Rect.MaxY - position.Y); - isLeftMouseDown = true; isSelectRangeDragging = false; var hitResult = hits.AsParallel().Where(x => x.Value.Contains(position)).Select(x => x.Key).OrderBy(x => x.Id).ToList(); diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs index 39914734..ecdfdc32 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs @@ -149,7 +149,8 @@ public void RecalculateTotalDurationHeight() } } - public bool EnableDragging => !IsBatchMode || (Keyboard.Modifiers & ModifierKeys.Alt) != 0; + public bool EnableDragging => !IsBatchMode || (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt) && + !Keyboard.Modifiers.HasFlag(ModifierKeys.Control)); private bool isSelectRangeDragging; private bool isShowCurveControlAlways = false; From e054f924b64df2954f4d36aa5795a918f4dafaaa Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 03:24:37 -0400 Subject: [PATCH 2/6] Select object when same type as Input Object is clicked --- .../Behaviors/BatchMode/BatchModeBehavior.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs index 518b72ff..1142ea04 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs @@ -236,7 +236,16 @@ private void MouseUp(MouseButtonEventArgs args) // Can hold alt while releasing to "cancel" the left click if ((Keyboard.Modifiers & ModifierKeys.Alt) == 0) { if (CurrentSubmode is BatchModeInputSubmode inputSubmode) { - PerformBrush(inputSubmode); + if (inputSubmode is BatchModeSingleInputSubmode singleInputSubmode + && editor.GetHits().Where(kv => + kv.Value.Contains(editor.CurrentCursorPosition!.Value) && + singleInputSubmode.ObjectType.IsInstanceOfType(kv.Key)).Select(kv => kv.Key) + .FirstOrDefault() is { } hit) { + editor.NotifyObjectClicked(hit); + } + else { + PerformBrush(inputSubmode); + } } else if (CurrentSubmode is BatchModeFilterSubmode filterSubmode && editor.IsRangeSelecting) { editor.SelectionVisibility = Visibility.Hidden; From ab461cdb3c61ffeff9f990234394b9f24b3f3576 Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 19:24:18 -0400 Subject: [PATCH 3/6] Localize --- .../Behaviors/BatchMode/BatchModeSubmode.cs | 39 +++-- ...lEditorViewModel.UserInteractionActions.cs | 1 + .../Properties/Resources.Designer.cs | 162 ++++++++++++++++++ OngekiFumenEditor/Properties/Resources.resx | 54 ++++++ 4 files changed, 237 insertions(+), 19 deletions(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeSubmode.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeSubmode.cs index 25bcbc1b..024ec7e1 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeSubmode.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeSubmode.cs @@ -9,6 +9,7 @@ using OngekiFumenEditor.Base.OngekiObjects.Lane.Base; using OngekiFumenEditor.Base.OngekiObjects.Wall; using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel; +using OngekiFumenEditor.Properties; namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode; @@ -38,7 +39,7 @@ public abstract class BatchModeInputSubmode : BatchModeSubmode public virtual BatchModeObjectModificationAction? ModifyObjectCtrl { get; } = null; public virtual BatchModeObjectModificationAction? ModifyObjectShift => AutoSelect - ? new BatchModeObjectModificationAction(null, "Add to selection") + ? new BatchModeObjectModificationAction(null, Resources.BatchModeModifierAddToSelection) : null; } @@ -52,7 +53,7 @@ public BatchModeInputClipboard() .Select(obj => (OngekiTimelineObjectBase)obj.CopyNew()).ToList(); } - public override string DisplayName => "Clipboard"; + public override string DisplayName => Resources.Clipboard; public override IEnumerable GenerateObject() { return ClipboardContents.Select(obj => (OngekiTimelineObjectBase)obj.CopyNew()); @@ -83,38 +84,38 @@ public abstract class BatchModeInputLane : BatchModeInputSubmode public class BatchModeInputLaneLeft : BatchModeInputLane { - public override string DisplayName => "LaneLeft"; + public override string DisplayName => Resources.LaneLeft; } public class BatchModeInputLaneCenter : BatchModeInputLane { - public override string DisplayName => "LaneCenter"; + public override string DisplayName => Resources.LaneCenter; } public class BatchModeInputLaneRight : BatchModeInputLane { - public override string DisplayName => "LaneRight"; + public override string DisplayName => Resources.LaneRight; } public class BatchModeInputWallRight : BatchModeInputLane { - public override string DisplayName => "WallRight"; + public override string DisplayName => Resources.WallRight; } public class BatchModeInputWallLeft : BatchModeInputLane { - public override string DisplayName => "WallLeft"; + public override string DisplayName => Resources.WallLeft; } public class BatchModeInputLaneColorful : BatchModeInputLane { - public override string DisplayName => "LaneColorful"; + public override string DisplayName => Resources.LaneColorful; } public abstract class BatchModeInputHitSubmode : BatchModeInputSubmode where T : OngekiTimelineObjectBase, ICriticalableObject { - public override BatchModeObjectModificationAction ModifyObjectCtrl { get; } = new(CritObject, "Set critical"); + public override BatchModeObjectModificationAction ModifyObjectCtrl { get; } = new(CritObject, Resources.BatchModeModifierSetCritical); private static void CritObject(OngekiObjectBase baseObject) { @@ -124,60 +125,60 @@ private static void CritObject(OngekiObjectBase baseObject) public class BatchModeInputTap : BatchModeInputHitSubmode { - public override string DisplayName => "Tap"; + public override string DisplayName => Resources.Tap; } public class BatchModeInputHold : BatchModeInputHitSubmode { - public override string DisplayName => "Hold"; + public override string DisplayName => Resources.Hold; public override bool AutoSelect => true; } public class BatchModeInputFlick : BatchModeInputHitSubmode { - public override BatchModeObjectModificationAction ModifyObjectShift { get; } = new(SwitchFlick, "Switch direction"); + public override BatchModeObjectModificationAction ModifyObjectShift { get; } = new(SwitchFlick, Resources.BatchModeModifierSwitchDirection); private static void SwitchFlick(OngekiObjectBase baseObject) { ((Flick)baseObject).Direction = Flick.FlickDirection.Right; } - public override string DisplayName => "Flick"; + public override string DisplayName => Resources.Flick; } public class BatchModeInputLaneBlock : BatchModeInputSubmode { public override BatchModeObjectModificationAction ModifyObjectCtrl { get; } = - new BatchModeObjectModificationAction(SwitchDirection, "Switch direction"); + new BatchModeObjectModificationAction(SwitchDirection, Resources.BatchModeModifierSwitchDirection); private static void SwitchDirection(OngekiObjectBase baseObject) { ((LaneBlockArea)baseObject).Direction = LaneBlockArea.BlockDirection.Right; } - public override string DisplayName => "LaneBlock"; + public override string DisplayName => Resources.LaneBlock; } public class BatchModeInputNormalBell : BatchModeInputSubmode { - public override string DisplayName => "Bell"; + public override string DisplayName => Resources.Bell; } public class BatchModeFilterLanes : BatchModeFilterSubmode { - public override string DisplayName => "Lanes"; + public override string DisplayName => Resources.ObjectFilterLanes; public override Func FilterFunction => obj => obj is LaneStartBase or LaneNextBase; } public class BatchModeFilterDockableObjects : BatchModeFilterSubmode { - public override string DisplayName => "Dockable objects"; + public override string DisplayName => Resources.ObjectFilterDockables; public override Func FilterFunction => obj => obj is Tap or Hold or HoldEnd; } public class BatchModeFilterFloatingObjects : BatchModeFilterSubmode { - public override string DisplayName => "Floating objects"; + public override string DisplayName => Resources.ObjectFilterFloating; public override Func FilterFunction => obj => obj is Bell or Bullet or Flick; } diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs index 65355007..62f362fa 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs @@ -1184,6 +1184,7 @@ public void OnMouseDown(ActionExecutionContext e) SelectionStartPosition = new Vector2((float)position.X, (float)position.Y); SelectionCurrentCursorPosition = SelectionStartPosition; SelectionVisibility = Visibility.Visible; + SelectRegionType = SelectRegionType.Select; } else { diff --git a/OngekiFumenEditor/Properties/Resources.Designer.cs b/OngekiFumenEditor/Properties/Resources.Designer.cs index 3d454cbf..990a2212 100644 --- a/OngekiFumenEditor/Properties/Resources.Designer.cs +++ b/OngekiFumenEditor/Properties/Resources.Designer.cs @@ -383,6 +383,33 @@ public static string BatchModeDeleteRangeOfObjectType { } } + /// + /// 查找类似 Add to selection 的本地化字符串。 + /// + public static string BatchModeModifierAddToSelection { + get { + return ResourceManager.GetString("BatchModeModifierAddToSelection", resourceCulture); + } + } + + /// + /// 查找类似 Set critical 的本地化字符串。 + /// + public static string BatchModeModifierSetCritical { + get { + return ResourceManager.GetString("BatchModeModifierSetCritical", resourceCulture); + } + } + + /// + /// 查找类似 Switch direction 的本地化字符串。 + /// + public static string BatchModeModifierSwitchDirection { + get { + return ResourceManager.GetString("BatchModeModifierSwitchDirection", resourceCulture); + } + } + /// /// 查找类似 Toggle batch mode 的本地化字符串。 /// @@ -428,6 +455,15 @@ public static string BeatSplit { } } + /// + /// 查找类似 Bell 的本地化字符串。 + /// + public static string Bell { + get { + return ResourceManager.GetString("Bell", resourceCulture); + } + } + /// /// 查找类似 In preview mode, if the total number of Bells/Bullets exceeds 的本地化字符串。 /// @@ -896,6 +932,15 @@ public static string CliInputErrorHeader { } } + /// + /// 查找类似 Clipboard 的本地化字符串。 + /// + public static string Clipboard { + get { + return ResourceManager.GetString("Clipboard", resourceCulture); + } + } + /// /// 查找类似 Clone 的本地化字符串。 /// @@ -2138,6 +2183,15 @@ public static string FirstBpm { } } + /// + /// 查找类似 Flick 的本地化字符串。 + /// + public static string Flick { + get { + return ResourceManager.GetString("Flick", resourceCulture); + } + } + /// /// 查找类似 Snap objects to grid 的本地化字符串。 /// @@ -2561,6 +2615,15 @@ public static string HeaderConstMismatch4 { } } + /// + /// 查找类似 Hold 的本地化字符串。 + /// + public static string Hold { + get { + return ResourceManager.GetString("Hold", resourceCulture); + } + } + /// /// 查找类似 Image file: 的本地化字符串。 /// @@ -3047,6 +3110,33 @@ public static string KeywordSortFilter { } } + /// + /// 查找类似 Lane Block 的本地化字符串。 + /// + public static string LaneBlock { + get { + return ResourceManager.GetString("LaneBlock", resourceCulture); + } + } + + /// + /// 查找类似 Lane Center 的本地化字符串。 + /// + public static string LaneCenter { + get { + return ResourceManager.GetString("LaneCenter", resourceCulture); + } + } + + /// + /// 查找类似 Lane Colorful 的本地化字符串。 + /// + public static string LaneColorful { + get { + return ResourceManager.GetString("LaneColorful", resourceCulture); + } + } + /// /// 查找类似 This lane contains an illegal segment 的本地化字符串。 /// @@ -3056,6 +3146,24 @@ public static string LaneContainInvalidPath { } } + /// + /// 查找类似 Lane Left 的本地化字符串。 + /// + public static string LaneLeft { + get { + return ResourceManager.GetString("LaneLeft", resourceCulture); + } + } + + /// + /// 查找类似 Lane Right 的本地化字符串。 + /// + public static string LaneRight { + get { + return ResourceManager.GetString("LaneRight", resourceCulture); + } + } + /// /// 查找类似 Languages: 的本地化字符串。 /// @@ -3488,6 +3596,33 @@ public static string ObjectBatchBrush { } } + /// + /// 查找类似 Dockable Objects 的本地化字符串。 + /// + public static string ObjectFilterDockables { + get { + return ResourceManager.GetString("ObjectFilterDockables", resourceCulture); + } + } + + /// + /// 查找类似 Floating Objects 的本地化字符串。 + /// + public static string ObjectFilterFloating { + get { + return ResourceManager.GetString("ObjectFilterFloating", resourceCulture); + } + } + + /// + /// 查找类似 Lanes 的本地化字符串。 + /// + public static string ObjectFilterLanes { + get { + return ResourceManager.GetString("ObjectFilterLanes", resourceCulture); + } + } + /// /// 查找类似 ID 的本地化字符串。 /// @@ -5027,6 +5162,15 @@ public static string TabSound { } } + /// + /// 查找类似 Tap 的本地化字符串。 + /// + public static string Tap { + get { + return ResourceManager.GetString("Tap", resourceCulture); + } + } + /// /// 查找类似 Throw an error and see 的本地化字符串。 /// @@ -5369,6 +5513,24 @@ public static string WallConflict3 { } } + /// + /// 查找类似 Wall Left 的本地化字符串。 + /// + public static string WallLeft { + get { + return ResourceManager.GetString("WallLeft", resourceCulture); + } + } + + /// + /// 查找类似 Wall Right 的本地化字符串。 + /// + public static string WallRight { + get { + return ResourceManager.GetString("WallRight", resourceCulture); + } + } + /// /// 查找类似 Warning 的本地化字符串。 /// diff --git a/OngekiFumenEditor/Properties/Resources.resx b/OngekiFumenEditor/Properties/Resources.resx index 7e3ba1fc..a449b88c 100644 --- a/OngekiFumenEditor/Properties/Resources.resx +++ b/OngekiFumenEditor/Properties/Resources.resx @@ -1914,4 +1914,58 @@ Batch: Select Floating + + Add to selection + + + Lane Left + + + Lane Center + + + Lane Right + + + Wall Left + + + Wall Right + + + Tap + + + Hold + + + Flick + + + Lane Block + + + Lane Colorful + + + Set critical + + + Switch direction + + + Lanes + + + Dockable Objects + + + Floating Objects + + + Bell + + + Clipboard + \ No newline at end of file From f98dff144c9498ed4cc0177a58bdd154d6aeb452 Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 20:36:52 -0400 Subject: [PATCH 4/6] Fix clipboard behavior --- .../Behaviors/BatchMode/BatchModeBehavior.cs | 28 ++++++++++-------- .../Properties/Resources.Designer.cs | 29 ++++++++++++++++++- OngekiFumenEditor/Properties/Resources.resx | 11 ++++++- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs index 1142ea04..54af7d57 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs @@ -28,7 +28,7 @@ namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode; public class BatchModeBehavior : Behavior { - private static readonly ImmutableDictionary CommandDefinitions = + private static readonly ImmutableDictionary CommandDefinitions = new Dictionary { [KeyBindingDefinitions.KBD_Batch_ModeWallLeft] = typeof(BatchModeInputWallLeft), @@ -46,7 +46,7 @@ public class BatchModeBehavior : Behavior [KeyBindingDefinitions.KBD_Batch_ModeFilterLanes] = typeof(BatchModeFilterLanes), [KeyBindingDefinitions.KBD_Batch_ModeFilterDockableObjects] = typeof(BatchModeFilterDockableObjects), [KeyBindingDefinitions.KBD_Batch_ModeFilterFloatingObjects] = typeof(BatchModeFilterFloatingObjects), - }.ToImmutableDictionary(kv => kv.Key, kv => (BatchModeSubmode)Activator.CreateInstance(kv.Value)); + }.ToImmutableDictionary(); private static readonly ImmutableDictionary> ClickTriggers = new Dictionary>() @@ -82,7 +82,7 @@ protected override void OnAttached() // Create brush key triggers on the FumenVisualEditorView. // Temporarily delete existing ones that clash with brush keys. - foreach (var (key, submode) in CommandDefinitions) { + foreach (var (key, submodeType) in CommandDefinitions) { var existingTriggers = triggerCollection.Where(t => t is ActionMessageKeyBinding am && am.Definition.Key == key.Key && am.Definition.Modifiers == key.Modifiers); @@ -92,7 +92,7 @@ protected override void OnAttached() foreach (var mod in new[] { ModifierKeys.None, ModifierKeys.Shift }) { // It's useful to hold down shift as we place multiple lanes, so bind everything to Shift+ as well. var newTrigger = new KeyTrigger() { Key = key.Key, Modifiers = mod }; - newTrigger.Actions.Add(new ChangePropertyAction() { TargetObject = this, PropertyName = nameof(CurrentSubmode), Value = submode }); + newTrigger.Actions.Add(new ChangePropertyAction() { TargetObject = this, PropertyName = nameof(CurrentSubmode), Value = Activator.CreateInstance(submodeType) }); triggerCollection.Add(newTrigger); NewKeyTriggers.Add(newTrigger); } @@ -174,10 +174,10 @@ private void MouseDown(MouseButtonEventArgs args) if (args.ChangedButton == MouseButton.Left) { // In all sub-modes, Alt forces normal mouse behavior - if ((Keyboard.Modifiers & ModifierKeys.Alt) > 0) { + if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) { lastLeftClickWasAltClick = true; editor.SelectionStartPosition = cursor.ToSystemNumericsVector2(); - if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) { + if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control)) { editor.SelectRegionType = SelectRegionType.SelectFiltered; editor.SelectionVisibility = Visibility.Visible; } @@ -194,13 +194,13 @@ private void MouseDown(MouseButtonEventArgs args) args.Handled = true; } else if (args.ChangedButton == MouseButton.Right) { editor.SelectionStartPosition = cursor.ToSystemNumericsVector2(); - if ((Keyboard.Modifiers & ModifierKeys.Alt) == 0) { - editor.SelectRegionType = SelectRegionType.DeleteFiltered; - } - else { + if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) { lastRightClickWasAltClick = true; editor.SelectRegionType = SelectRegionType.Delete; } + else { + editor.SelectRegionType = SelectRegionType.DeleteFiltered; + } args.Handled = true; } @@ -279,7 +279,7 @@ private void MouseUp(MouseButtonEventArgs args) else { lastRightClickWasAltClick = false; if (editor.IsRangeSelecting) { - PerformRemoveGroup(null, "objects"); + PerformRemoveGroup(null, Resources.Objects); } } @@ -306,10 +306,14 @@ private void PerformBrush(BatchModeInputSubmode submode) ongekiObjects = submode.GenerateObject().ToImmutableList(); if (ongekiObjects.Count == 0) { + if (submode is BatchModeInputClipboard) + editor.ToastNotify(Resources.CannotBatchInputClipboardEmpty); return; } if (ongekiObjects.Count > 1) { + if (submode is BatchModeInputClipboard) + editor.ToastNotify(Resources.CannotBatchInputClipboardNotBrushable); Log.LogWarn("Multiple object placement is currently not supported"); return; } @@ -438,7 +442,7 @@ private static void ConsumeAlt(object sender, KeyEventArgs e) #region Dependency property - public static readonly DependencyProperty CurrentSubmodeProperty = DependencyProperty.RegisterAttached(nameof(CurrentSubmode), typeof(BatchModeSubmode), typeof(BatchModeBehavior), new PropertyMetadata(CommandDefinitions[KeyBindingDefinitions.KBD_Batch_ModeClipboard])); + public static readonly DependencyProperty CurrentSubmodeProperty = DependencyProperty.RegisterAttached(nameof(CurrentSubmode), typeof(BatchModeSubmode), typeof(BatchModeBehavior), new PropertyMetadata(Activator.CreateInstance(CommandDefinitions[KeyBindingDefinitions.KBD_Batch_ModeClipboard]))); #endregion diff --git a/OngekiFumenEditor/Properties/Resources.Designer.cs b/OngekiFumenEditor/Properties/Resources.Designer.cs index 990a2212..ba49425a 100644 --- a/OngekiFumenEditor/Properties/Resources.Designer.cs +++ b/OngekiFumenEditor/Properties/Resources.Designer.cs @@ -375,7 +375,7 @@ public static string BatchModeAddObject { } /// - /// 查找类似 Batch delete {0} 的本地化字符串。 + /// 查找类似 Batch delete {0} (x{1}) 的本地化字符串。 /// public static string BatchModeDeleteRangeOfObjectType { get { @@ -680,6 +680,24 @@ public static string CancelSelected { } } + /// + /// 查找类似 The clipboard is empty 的本地化字符串。 + /// + public static string CannotBatchInputClipboardEmpty { + get { + return ResourceManager.GetString("CannotBatchInputClipboardEmpty", resourceCulture); + } + } + + /// + /// 查找类似 The clipboard contents are not brushable 的本地化字符串。 + /// + public static string CannotBatchInputClipboardNotBrushable { + get { + return ResourceManager.GetString("CannotBatchInputClipboardNotBrushable", resourceCulture); + } + } + /// /// 查找类似 Unable to create a new project: 的本地化字符串。 /// @@ -3695,6 +3713,15 @@ public static string ObjectPropertyChanged { } } + /// + /// 查找类似 Objects 的本地化字符串。 + /// + public static string Objects { + get { + return ResourceManager.GetString("Objects", resourceCulture); + } + } + /// /// 查找类似 Represents a user-defined label, typically used for script differentiation 的本地化字符串。 /// diff --git a/OngekiFumenEditor/Properties/Resources.resx b/OngekiFumenEditor/Properties/Resources.resx index a449b88c..1ef90617 100644 --- a/OngekiFumenEditor/Properties/Resources.resx +++ b/OngekiFumenEditor/Properties/Resources.resx @@ -259,7 +259,7 @@ Shape - Batch delete {0} + Batch delete {0} (x{1}) AcbGeneratorFuck.Generator.Generate() failed @@ -1968,4 +1968,13 @@ Clipboard + + Objects + + + The clipboard is empty + + + The clipboard contents are not brushable + \ No newline at end of file From 81f40bc92bad285cd2e49f0d25b587477940ab02 Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 20:52:28 -0400 Subject: [PATCH 5/6] Fix selection color and Shift + Alt drag behavior --- .../Behaviors/BatchMode/BatchModeBehavior.cs | 5 +++++ .../FumenVisualEditorViewModel.UserInteractionActions.cs | 1 - .../ViewModels/FumenVisualEditorViewModel.cs | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs index 54af7d57..c78f5252 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Behaviors/BatchMode/BatchModeBehavior.cs @@ -141,6 +141,10 @@ protected override void OnDetaching() GeneratedClickTriggerActions.Clear(); AssociatedObject.KeyDown -= ConsumeAlt; + + if (AssociatedObject.DataContext is FumenVisualEditorViewModel edtior) { + edtior.SelectRegionType = SelectRegionType.Select; + } } #region Mouse handling @@ -175,6 +179,7 @@ private void MouseDown(MouseButtonEventArgs args) if (args.ChangedButton == MouseButton.Left) { // In all sub-modes, Alt forces normal mouse behavior if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) { + editor.SelectRegionType = SelectRegionType.Select; lastLeftClickWasAltClick = true; editor.SelectionStartPosition = cursor.ToSystemNumericsVector2(); if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control)) { diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs index 62f362fa..65355007 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs @@ -1184,7 +1184,6 @@ public void OnMouseDown(ActionExecutionContext e) SelectionStartPosition = new Vector2((float)position.X, (float)position.Y); SelectionCurrentCursorPosition = SelectionStartPosition; SelectionVisibility = Visibility.Visible; - SelectRegionType = SelectRegionType.Select; } else { diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs index ecdfdc32..bdd8d280 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.cs @@ -150,7 +150,8 @@ public void RecalculateTotalDurationHeight() } public bool EnableDragging => !IsBatchMode || (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt) && - !Keyboard.Modifiers.HasFlag(ModifierKeys.Control)); + !Keyboard.Modifiers.HasFlag(ModifierKeys.Control) && + !Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)); private bool isSelectRangeDragging; private bool isShowCurveControlAlways = false; From 910b4b6de4820942b116054eb22ffb1ec969b147 Mon Sep 17 00:00:00 2001 From: Zach Day Date: Fri, 25 Oct 2024 21:04:36 -0400 Subject: [PATCH 6/6] Fix abnormal shift-drag behavior in normal mode --- .../FumenVisualEditorViewModel.UserInteractionActions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs index 65355007..3ce50e6a 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/ViewModels/FumenVisualEditorViewModel.UserInteractionActions.cs @@ -1354,7 +1354,7 @@ public async void OnMouseMove(Point pos) ScrollTo(audioTime); } - if (EnableDragging) + if (EnableDragging && !IsRangeSelecting) { //拖动已选物件 var cp = pos;