Skip to content

Commit

Permalink
Merge branch 'feat.more-keybinds' of https://github.com/zacharied/Ong…
Browse files Browse the repository at this point in the history
…ekiFumenEditor into batch_mode

# Conflicts:
#	OngekiFumenEditor/Properties/Resources.Designer.cs
  • Loading branch information
MikiraSora committed Feb 17, 2025
2 parents df066b2 + 702f2d1 commit ada7e56
Show file tree
Hide file tree
Showing 24 changed files with 226 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
using Caliburn.Micro;
using Microsoft.Xaml.Behaviors;
using OngekiFumenEditor.Base;
using OngekiFumenEditor.Kernel.KeyBinding;
using OngekiFumenEditor.Modules.FumenObjectPropertyBrowser;
using OngekiFumenEditor.Modules.FumenVisualEditor.Base;
using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel;
using OngekiFumenEditor.Modules.FumenVisualEditor.ViewModels;
Expand All @@ -26,25 +24,25 @@ namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode;

public class BatchModeBehavior : Behavior<FumenVisualEditorView>
{
private static readonly ImmutableDictionary<KeyBindingDefinition, BatchModeSubmode> CommandDefinitions =
new Dictionary<KeyBindingDefinition, Type>
public static readonly ImmutableList<BatchModeSubmode> Submodes =
new List<BatchModeSubmode>
{
[KeyBindingDefinitions.KBD_Batch_ModeWallLeft] = typeof(BatchModeInputWallLeft),
[KeyBindingDefinitions.KBD_Batch_ModeLaneLeft] = typeof(BatchModeInputLaneLeft),
[KeyBindingDefinitions.KBD_Batch_ModeLaneCenter] = typeof(BatchModeInputLaneCenter),
[KeyBindingDefinitions.KBD_Batch_ModeLaneRight] = typeof(BatchModeInputLaneRight),
[KeyBindingDefinitions.KBD_Batch_ModeWallRight] = typeof(BatchModeInputWallRight),
[KeyBindingDefinitions.KBD_Batch_ModeLaneColorful] = typeof(BatchModeInputLaneColorful),
[KeyBindingDefinitions.KBD_Batch_ModeTap] = typeof(BatchModeInputTap),
[KeyBindingDefinitions.KBD_Batch_ModeHold] = typeof(BatchModeInputHold),
[KeyBindingDefinitions.KBD_Batch_ModeFlick] = typeof(BatchModeInputFlick),
[KeyBindingDefinitions.KBD_Batch_ModeLaneBlock] = typeof(BatchModeInputLaneBlock),
[KeyBindingDefinitions.KBD_Batch_ModeNormalBell] = typeof(BatchModeInputNormalBell),
[KeyBindingDefinitions.KBD_Batch_ModeClipboard] = typeof(BatchModeInputClipboard),
[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));
new BatchModeInputClipboard(),
new BatchModeInputWallLeft(),
new BatchModeInputLaneLeft(),
new BatchModeInputLaneCenter(),
new BatchModeInputLaneRight(),
new BatchModeInputWallRight(),
new BatchModeInputLaneColorful(),
new BatchModeInputTap(),
new BatchModeInputHold(),
new BatchModeInputFlick(),
new BatchModeInputLaneBlock(),
new BatchModeInputNormalBell(),
new BatchModeFilterLanes(),
new BatchModeFilterDockableObjects(),
new BatchModeFilterFloatingObjects(),
}.ToImmutableList();

private static readonly ImmutableDictionary<string, Func<BatchModeBehavior, TriggerAction>> ClickTriggers =
new Dictionary<string, Func<BatchModeBehavior, TriggerAction>>()
Expand All @@ -63,10 +61,6 @@ public BatchModeSubmode CurrentSubmode
private readonly List<TriggerBase> OldKeyTriggers = new();
private readonly List<TriggerBase> NewKeyTriggers = new();

public BatchModeBehavior()
{
}

protected override void OnAttached()
{
if (AssociatedObject.DataContext is not FumenVisualEditorViewModel editor)
Expand All @@ -76,11 +70,11 @@ protected override void OnAttached()

// Create brush key triggers on the FumenVisualEditorView.
// Temporarily delete existing ones that clash with brush keys.
var allCommands = CommandDefinitions.SelectMany
<KeyValuePair<KeyBindingDefinition, BatchModeSubmode>, ((Key, ModifierKeys), BatchModeSubmode)>(kv =>
var allCommands = Submodes.SelectMany
<BatchModeSubmode, ((Key, ModifierKeys), BatchModeSubmode)>(submode =>
[
((kv.Key.Key, kv.Key.Modifiers), kv.Value),
((kv.Key.Key, kv.Key.Modifiers | ModifierKeys.Shift), kv.Value)
((submode.KeyBinding.Key, submode.KeyBinding.Modifiers), submode),
((submode.KeyBinding.Key, submode.KeyBinding.Modifiers | ModifierKeys.Shift), submode)
]);

foreach (var ((key, modifiers), submodeType) in allCommands) {
Expand Down Expand Up @@ -128,7 +122,7 @@ protected override void OnDetaching()

NewKeyTriggers.Clear();
OldKeyTriggers.Clear();

var glTriggers = Interaction.GetTriggers(AssociatedObject.glView);
foreach (var (eventName, action) in GeneratedClickTriggerActions) {
var glTrigger = glTriggers.First(t => t is EventTrigger et && et.EventName == eventName);
Expand Down Expand Up @@ -357,7 +351,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(CommandDefinitions[KeyBindingDefinitions.KBD_Batch_ModeClipboard]));
public static readonly DependencyProperty CurrentSubmodeProperty = DependencyProperty.RegisterAttached(nameof(CurrentSubmode), typeof(BatchModeSubmode), typeof(BatchModeBehavior), new(Submodes.First()));

#endregion

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;
using System.Windows.Input;
using Caliburn.Micro;
using Gemini.Framework.Commands;
using OngekiFumenEditor.Kernel.KeyBinding;
using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel;
using OngekiFumenEditor.Utils;

namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode;

public abstract class BatchModeSubmodeCommandHandler<TCommandDefinition> : CommandHandlerBase<TCommandDefinition>
where TCommandDefinition : BatchModeSubmode
{
private IEditorDocumentManager Editor;
private BatchModeSubmode Submode;

public BatchModeSubmodeCommandHandler()
{
Editor = IoC.Get<IEditorDocumentManager>();
Submode = BatchModeBehavior.Submodes.OfType<TCommandDefinition>().Single();
}

public override void Update(Command command)
{
base.Update(command);

if (Editor.CurrentActivatedEditor is not null && Editor.CurrentActivatedEditor.IsBatchMode) {
command.Enabled = true;
command.Checked = Editor.CurrentActivatedEditor.BatchModeBehavior.CurrentSubmode == Submode;
}
else {
command.Enabled = false;
command.Checked = false;
}
}

public override Task Run(Command command)
{
Editor.CurrentActivatedEditor.BatchModeBehavior.CurrentSubmode = Submode;
return Task.CompletedTask;
}
}

[CommandHandler] public class BatchModeLaneLeftCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputLaneLeft>;
[CommandHandler] public class BatchModeLaneCenterCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputLaneCenter>;
[CommandHandler] public class BatchModeLaneRightCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputLaneRight>;
[CommandHandler] public class BatchModeWallLeftCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputWallLeft>;
[CommandHandler] public class BatchModeWallRightCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputWallRight>;
[CommandHandler] public class BatchModeLaneColorfulCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputLaneColorful>;
[CommandHandler] public class BatchModeTapCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputTap>;
[CommandHandler] public class BatchModeHoldCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputHold>;
[CommandHandler] public class BatchModeFlickCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputFlick>;
[CommandHandler] public class BatchModeBellCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputNormalBell>;
[CommandHandler] public class BatchModeLaneBlockCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputLaneBlock>;
[CommandHandler] public class BatchModeClipboardCommandHandler : BatchModeSubmodeCommandHandler<BatchModeInputClipboard>;
[CommandHandler] public class BatchModeFilterLanesCommandHandler : BatchModeSubmodeCommandHandler<BatchModeFilterLanes>;
[CommandHandler] public class BatchModeFilterDockableObjectsCommandHandler : BatchModeSubmodeCommandHandler<BatchModeFilterDockableObjects>;
[CommandHandler] public class BatchModeFilterFloatingObjectsCommandHandler : BatchModeSubmodeCommandHandler<BatchModeFilterFloatingObjects>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using Gemini.Framework.Commands;
using Gemini.Framework.Services;
using OngekiFumenEditor.Base;
using OngekiFumenEditor.Base.OngekiObjects;
using OngekiFumenEditor.Base.OngekiObjects.Lane;
using OngekiFumenEditor.Base.OngekiObjects.Lane.Base;
using OngekiFumenEditor.Base.OngekiObjects.Wall;
using OngekiFumenEditor.Kernel.KeyBinding;
using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;

namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode;

Expand All @@ -19,21 +23,34 @@ namespace OngekiFumenEditor.Modules.FumenVisualEditor.Behaviors.BatchMode;
/// Sub-modes are selected via Batch Mode shortcuts.
/// Only one sub-mode can be active at a time.
/// </summary>
public abstract class BatchModeSubmode
public abstract class BatchModeSubmode : CommandDefinition
{
public abstract string DisplayName { get; }
public abstract KeyBindingDefinition KeyBinding { get; }
public abstract string ResourceKey { get; }

public string HelperText => $"{DisplayName} ({KeyBindingDefinition.FormatToExpression(KeyBinding)})";
public string DisplayName => Resources.ResourceManager.GetString(ResourceKey)!;

public override string Name => $"BatchMode.{GetType().Name}";
public override Uri IconSource =>
new Uri($"pack://application:,,,/OngekiFumenEditor;component/Resources/Icons/Batch/{ResourceKey}.png");

public override string Text => DisplayName;
}

/// <summary>
/// A sub-mode that controls what the user is able to select.
/// </summary>
public abstract class BatchModeFilterSubmode : BatchModeSubmode
{
public sealed override string ToolTip => Resources.BatchModeFilterTooltipFormat.Format(HelperText);
public abstract Func<OngekiObjectBase, bool> FilterFunction { get; }
}

public abstract class BatchModeInputSubmode : BatchModeSubmode
{
public override string ToolTip => HelperText;

public abstract IEnumerable<OngekiTimelineObjectBase> GenerateObject();
public virtual bool AutoSelect => false;
public virtual BatchModeObjectModificationAction? ModifyObjectCtrl { get; } = null;
Expand All @@ -43,6 +60,7 @@ public abstract class BatchModeInputSubmode : BatchModeSubmode
: null;
}

[CommandDefinition]
public class BatchModeInputClipboard : BatchModeInputSubmode
{
private IFumenEditorClipboard Clipboard;
Expand All @@ -52,7 +70,8 @@ public BatchModeInputClipboard()
Clipboard = IoC.Get<IFumenEditorClipboard>();
}

public override string DisplayName => Resources.Clipboard;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeClipboard;
public override string ResourceKey => nameof(Resources.Clipboard);
public override IEnumerable<OngekiTimelineObjectBase> GenerateObject()
{
return Clipboard.CurrentCopiedObjects.Select(obj => (OngekiTimelineObjectBase)obj.CopyNew());
Expand All @@ -61,7 +80,7 @@ public override IEnumerable<OngekiTimelineObjectBase> GenerateObject()

public abstract class BatchModeSingleInputSubmode : BatchModeInputSubmode
{
public abstract Type ObjectType { get;}
public abstract Type ObjectType { get; }
}

public abstract class BatchModeInputSubmode<T> : BatchModeSingleInputSubmode
Expand All @@ -81,34 +100,46 @@ public abstract class BatchModeInputLane<T> : BatchModeInputSubmode<T>
public override bool AutoSelect => true;
}

[CommandDefinition]
public class BatchModeInputLaneLeft : BatchModeInputLane<LaneLeftStart>
{
public override string DisplayName => Resources.LaneLeft;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeLaneLeft;
public override string ResourceKey => nameof(Resources.LaneLeft);
}

[CommandDefinition]
public class BatchModeInputLaneCenter : BatchModeInputLane<LaneCenterStart>
{
public override string DisplayName => Resources.LaneCenter;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeLaneCenter;
public override string ResourceKey => nameof(Resources.LaneCenter);
}

[CommandDefinition]
public class BatchModeInputLaneRight : BatchModeInputLane<LaneRightStart>
{
public override string DisplayName => Resources.LaneRight;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeLaneRight;
public override string ResourceKey => nameof(Resources.LaneRight);
}

[CommandDefinition]
public class BatchModeInputWallRight : BatchModeInputLane<WallRightStart>
{
public override string DisplayName => Resources.WallRight;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeWallRight;
public override string ResourceKey => nameof(Resources.WallRight);
}

[CommandDefinition]
public class BatchModeInputWallLeft : BatchModeInputLane<WallLeftStart>
{
public override string DisplayName => Resources.WallLeft;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeWallLeft;
public override string ResourceKey => nameof(Resources.WallLeft);
}

[CommandDefinition]
public class BatchModeInputLaneColorful : BatchModeInputLane<ColorfulLaneStart>
{
public override string DisplayName => Resources.LaneColorful;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeLaneColorful;
public override string ResourceKey => nameof(Resources.LaneColorful);
}

public abstract class BatchModeInputHitSubmode<T> : BatchModeInputSubmode<T>
Expand All @@ -122,31 +153,39 @@ private static void CritObject(OngekiObjectBase baseObject)
}
}

[CommandDefinition]
public class BatchModeInputTap : BatchModeInputHitSubmode<Tap>
{
public override string DisplayName => Resources.Tap;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeTap;
public override string ResourceKey => nameof(Resources.Tap);
}

[CommandDefinition]
public class BatchModeInputHold : BatchModeInputHitSubmode<Hold>
{
public override string DisplayName => Resources.Hold;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeHold;
public override string ResourceKey => nameof(Resources.Hold);
public override bool AutoSelect => true;
}

[CommandDefinition]
public class BatchModeInputFlick : BatchModeInputHitSubmode<Flick>
{
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeFlick;
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 => Resources.Flick;
public override string ResourceKey => nameof(Resources.Flick);
}

[CommandDefinition]
public class BatchModeInputLaneBlock : BatchModeInputSubmode<LaneBlockArea>
{
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeLaneBlock;
public override BatchModeObjectModificationAction ModifyObjectCtrl { get; } =
new BatchModeObjectModificationAction(SwitchDirection, Resources.BatchModeModifierSwitchDirection);

Expand All @@ -155,29 +194,37 @@ private static void SwitchDirection(OngekiObjectBase baseObject)
((LaneBlockArea)baseObject).Direction = LaneBlockArea.BlockDirection.Right;
}

public override string DisplayName => Resources.LaneBlock;
public override string ResourceKey => nameof(Resources.LaneBlock);
}

[CommandDefinition]
public class BatchModeInputNormalBell : BatchModeInputSubmode<Bell>
{
public override string DisplayName => Resources.Bell;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeNormalBell;
public override string ResourceKey => nameof(Resources.Bell);
}

[CommandDefinition]
public class BatchModeFilterLanes : BatchModeFilterSubmode
{
public override string DisplayName => Resources.ObjectFilterLanes;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeFilterLanes;
public override string ResourceKey => nameof(Resources.ObjectFilterLanes);
public override Func<OngekiObjectBase, bool> FilterFunction => obj => obj is LaneStartBase or LaneNextBase;
}

[CommandDefinition]
public class BatchModeFilterDockableObjects : BatchModeFilterSubmode
{
public override string DisplayName => Resources.ObjectFilterDockables;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeFilterDockableObjects;
public override string ResourceKey => nameof(Resources.ObjectFilterDockables);
public override Func<OngekiObjectBase, bool> FilterFunction => obj => obj is Tap or Hold or HoldEnd;
}

[CommandDefinition]
public class BatchModeFilterFloatingObjects : BatchModeFilterSubmode
{
public override string DisplayName => Resources.ObjectFilterFloating;
public override KeyBindingDefinition KeyBinding => KeyBindingDefinitions.KBD_Batch_ModeFilterFloatingObjects;
public override string ResourceKey => nameof(Resources.ObjectFilterFloating);
public override Func<OngekiObjectBase, bool> FilterFunction => obj => obj is Bell or Bullet or Flick;
}

Expand Down
Loading

0 comments on commit ada7e56

Please sign in to comment.