Skip to content

Commit

Permalink
Merge pull request #682 from b-editor/fix-keybinding
Browse files Browse the repository at this point in the history
ショートカットの動作を修正
  • Loading branch information
yuto-trd authored Aug 28, 2023
2 parents 3448065 + 49db05a commit 246b787
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 28 deletions.
10 changes: 10 additions & 0 deletions src/Beutl.Controls/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class Player : RangeBase
private Button _endButton;
private Button _startButton;
private Image _image;
private Slider _slider;
private ICommand _playButtonCommand;
private ICommand _nextButtonCommand;
private ICommand _previousButtonCommand;
Expand Down Expand Up @@ -126,6 +127,14 @@ public Image GetImage()
return _image;
}

public void SetSeekBarOpacity(double opacity)
{
if (_slider != null)
{
_slider.Opacity = opacity;
}
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand All @@ -135,6 +144,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_endButton = e.NameScope.Find<Button>("PART_EndButton");
_startButton = e.NameScope.Find<Button>("PART_StartButton");
_image = e.NameScope.Find<Image>("PART_Image");
_slider = e.NameScope.Find<Slider>("PART_Slider");

_playButton.Click += (s, e) => PlayButtonCommand?.Execute(null);
_nextButton.Click += (s, e) => NextButtonCommand?.Execute(null);
Expand Down
36 changes: 36 additions & 0 deletions src/Beutl/ViewModels/EditViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using System.Numerics;
using System.Text.Json.Nodes;
using System.Windows.Input;

using Avalonia;
using Avalonia.Input;
using Avalonia.Input.Platform;

using Beutl.Animation;
using Beutl.Api.Services;
Expand Down Expand Up @@ -64,6 +69,8 @@ public EditViewModel(Scene scene)
newHierarchical.DetachedFromHierarchy += OnSelectedObjectDetachedFromHierarchy;
})
.DisposeWith(_disposables);

KeyBindings = CreateKeyBindings();
}

private void OnSelectedObjectDetachedFromHierarchy(object? sender, HierarchyAttachmentEventArgs e)
Expand Down Expand Up @@ -99,6 +106,8 @@ private void OnSelectedObjectDetachedFromHierarchy(object? sender, HierarchyAtta

IReactiveProperty<bool> IEditorContext.IsEnabled => IsEnabled;

public List<KeyBinding> KeyBindings { get; }

public void Dispose()
{
SaveState();
Expand Down Expand Up @@ -448,6 +457,33 @@ void ISupportCloseAnimation.Close(object obj)
}
}

// Todo: 設定からショートカットを変更できるようにする。
private List<KeyBinding> CreateKeyBindings()
{
static KeyBinding KeyBinding(Key key, KeyModifiers modifiers, ICommand command)
{
return new KeyBinding
{
Gesture = new KeyGesture(key, modifiers),
Command = command
};
}

return new List<KeyBinding>
{
// PlayPause: Space
KeyBinding(Key.Space, KeyModifiers.None, Player.PlayPause),
// Next: Right
KeyBinding(Key.Right, KeyModifiers.None, Player.Next),
// Previous: Left
KeyBinding(Key.Left, KeyModifiers.None, Player.Previous),
// Start: Home
KeyBinding(Key.Home, KeyModifiers.None, Player.Start),
// End: End
KeyBinding(Key.End, KeyModifiers.None, Player.End),
};
}

private sealed class KnownCommandsImpl : IKnownEditorCommands
{
private readonly Scene _scene;
Expand Down
28 changes: 28 additions & 0 deletions src/Beutl/ViewModels/ElementViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ public ElementViewModel(Element element, TimelineViewModel timeline)
LayerHeader.Value = newLH;
})
.AddTo(_disposables);

KeyBindings = CreateKeyBinding();
}

~ElementViewModel()
Expand Down Expand Up @@ -159,6 +161,8 @@ public ElementViewModel(Element element, TimelineViewModel timeline)

public ReactiveCommand BringAnimationToTop { get; } = new();

public List<KeyBinding> KeyBindings { get; }

public void SetClipboard(IClipboard? clipboard)
{
_clipboard = clipboard;
Expand Down Expand Up @@ -333,6 +337,30 @@ private void OnSplit(TimeSpan timeSpan)
Scene.AddChild(backwardLayer).DoAndRecord(CommandRecorder.Default);
}

private List<KeyBinding> CreateKeyBinding()
{
PlatformHotkeyConfiguration? config = Application.Current?.PlatformSettings?.HotkeyConfiguration;
KeyModifiers modifier = config?.CommandModifiers ?? KeyModifiers.Control;
var list = new List<KeyBinding>
{
new KeyBinding { Gesture = new(Key.Delete), Command = Exclude },
new KeyBinding { Gesture = new(Key.Delete, modifier), Command = Delete }
};

if (config != null)
{
list.AddRange(config.Cut.Select(x => new KeyBinding { Gesture = x, Command = Cut }));
list.AddRange(config.Copy.Select(x => new KeyBinding { Gesture = x, Command = Copy }));
}
else
{
list.Add(new KeyBinding { Gesture = new(Key.X, modifier), Command = Cut });
list.Add(new KeyBinding { Gesture = new(Key.C, modifier), Command = Copy });
}

return list;
}

// https://github.com/google/skia/blob/0d39172f35d259b6ab888974177bc4e6d839d44c/src/effects/SkHighContrastFilter.cpp
private Avalonia.Media.Color GetTextColor(Avalonia.Media.Color color)
{
Expand Down
54 changes: 54 additions & 0 deletions src/Beutl/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#pragma warning disable CS0436

using System.CodeDom.Compiler;
using System.Windows.Input;

using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Threading;

using Beutl.Api;
Expand Down Expand Up @@ -213,6 +217,8 @@ public MainViewModel()
NotificationService.ShowInformation("", Message.CouldNotOpenProject);
}
});

KeyBindings = CreateKeyBindings();
}

public bool IsDebuggerAttached { get; } = Debugger.IsAttached;
Expand Down Expand Up @@ -299,6 +305,8 @@ public MainViewModel()

public CoreList<NavItemViewModel> Pages { get; }

public List<KeyBinding> KeyBindings { get; }

public ReactiveProperty<NavItemViewModel?> SelectedPage { get; } = new();

public IReadOnlyReactiveProperty<bool> IsProjectOpened { get; }
Expand Down Expand Up @@ -546,4 +554,50 @@ private void OnExit(object? sender, ControlledApplicationLifetimeExitEventArgs e
Process.Start(startInfo);
}
}

// Todo: 設定からショートカットを変更できるようにする。
private List<KeyBinding> CreateKeyBindings()
{
static KeyBinding KeyBinding(Key key, KeyModifiers modifiers, ICommand command)
{
return new KeyBinding
{
Gesture = new KeyGesture(key, modifiers),
Command = command
};
}

PlatformHotkeyConfiguration? config = Application.Current?.PlatformSettings?.HotkeyConfiguration;
KeyModifiers modifier = config?.CommandModifiers ?? KeyModifiers.Control;
var list = new List<KeyBinding>
{
// CreateNewProject: Ctrl+Shift+N
KeyBinding(Key.N, modifier | KeyModifiers.Shift, CreateNewProject),
// CreateNew: Ctrl+N
KeyBinding(Key.N, modifier, CreateNew),
// OpenProject: Ctrl+Shift+O
KeyBinding(Key.O, modifier | KeyModifiers.Shift, OpenProject),
// OpenFile: Ctrl+O
KeyBinding(Key.O, modifier, OpenFile),
// Save: Ctrl+S
KeyBinding(Key.S, modifier, Save),
// SaveAll: Ctrl+Shift+S
KeyBinding(Key.S, modifier | KeyModifiers.Shift, SaveAll),
// Exit: Alt+F4
KeyBinding(Key.F4, KeyModifiers.Alt, Exit),
};

if (config != null)
{
list.AddRange(config.Undo.Select(x => KeyBinding(x.Key, x.KeyModifiers, Undo)));
list.AddRange(config.Redo.Select(x => KeyBinding(x.Key, x.KeyModifiers, Redo)));
}
else
{
list.Add(KeyBinding(Key.Z, modifier, Undo));
list.Add(KeyBinding(Key.R, modifier, Redo));
}

return list;
}
}
24 changes: 24 additions & 0 deletions src/Beutl/ViewModels/TimelineViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Text.Json.Nodes;

using Avalonia;
using Avalonia.Input;
using Avalonia.Input.Platform;

using Beutl.Animation;
using Beutl.Models;
Expand Down Expand Up @@ -121,6 +123,26 @@ public TimelineViewModel(EditViewModel editViewModel)
editViewModel.Options.Select(x => x.MaxLayerCount)
.DistinctUntilChanged()
.Subscribe(TryApplyLayerCount);

// Todo: 設定からショートカットを変更できるようにする。
KeyBindings = new List<KeyBinding>();
PlatformHotkeyConfiguration? keyConf = Application.Current?.PlatformSettings?.HotkeyConfiguration;
if (keyConf != null)
{
KeyBindings.AddRange(keyConf.Paste.Select(i => new KeyBinding
{
Command = Paste,
Gesture = i
}));
}
else
{
KeyBindings.Add(new KeyBinding
{
Command = Paste,
Gesture = new KeyGesture(Key.V, keyConf?.CommandModifiers ?? KeyModifiers.Control)
});
}
}

public Scene Scene { get; private set; }
Expand Down Expand Up @@ -163,6 +185,8 @@ public TimelineViewModel(EditViewModel editViewModel)

public string Header => Strings.Timeline;

public List<KeyBinding> KeyBindings { get; }

public void Dispose()
{
_disposables.Dispose();
Expand Down
1 change: 1 addition & 0 deletions src/Beutl/Views/EditView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
d:DesignHeight="720"
d:DesignWidth="1280"
x:DataType="vm:EditViewModel"
Focusable="True"
IsEnabled="{CompiledBinding IsEnabled.Value}"
mc:Ignorable="d">
<UserControl.Styles>
Expand Down
28 changes: 27 additions & 1 deletion src/Beutl/Views/EditView.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Collections.Specialized;

using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Threading;

using Beutl.Controls;
Expand Down Expand Up @@ -33,10 +35,34 @@ public EditView()
// 右側のタブ
RightTabView.ItemsSource = _rightTabItems;
_rightTabItems.CollectionChanged += TabItems_CollectionChanged;

this.GetObservable(IsKeyboardFocusWithinProperty)
.Subscribe(v => Player.SetSeekBarOpacity(v ? 1 : 0.8));
}

private Image Image => _image ??= Player.GetImage();

protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (DataContext is EditViewModel viewModel)
{
// TextBox.OnKeyDown で e.Handled が True に設定されないので
if (e.Key == Key.Space && e.Source is TextBox)
{
return;
}

// KeyBindingsは変更してはならない。
foreach (KeyBinding binding in viewModel.KeyBindings)
{
if (e.Handled)
break;
binding.TryHandle(e);
}
}
}

private void TabItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
static void OnAdded(NotifyCollectionChangedEventArgs e, AvaloniaList<BcTabItem> tabItems)
Expand Down Expand Up @@ -87,7 +113,7 @@ static void OnRemoved(NotifyCollectionChangedEventArgs e, AvaloniaList<BcTabItem
}
}

protected override void OnDetachedFromVisualTree(Avalonia.VisualTreeAttachmentEventArgs e)
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
if (DataContext is EditViewModel viewModel && viewModel.Player.IsPlaying.Value)
Expand Down
6 changes: 0 additions & 6 deletions src/Beutl/Views/ElementView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@
Focusable="True"
IsEnabled="{CompiledBinding IsEnabled.Value}"
mc:Ignorable="d">
<UserControl.KeyBindings>
<KeyBinding Command="{Binding Cut}" Gesture="{DynamicResource CutKeyGesture}" />
<KeyBinding Command="{Binding Copy}" Gesture="{DynamicResource CopyKeyGesture}" />
<KeyBinding Command="{Binding Delete}" Gesture="{DynamicResource LayerDeleteKeyGesture}" />
<KeyBinding Command="{Binding Exclude}" Gesture="{DynamicResource DeleteKeyGesture}" />
</UserControl.KeyBindings>
<Border x:Name="border"
Width="{Binding Width.Value}"
Margin="{Binding BorderMargin.Value}"
Expand Down
21 changes: 21 additions & 0 deletions src/Beutl/Views/ElementView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,27 @@ public ElementView()

private ElementViewModel ViewModel => (ElementViewModel)DataContext!;

protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (DataContext is ElementViewModel viewModel)
{
if(e.Key== Key.F2)
{
Rename_Click(null, null!);
return;
}

// KeyBindingsは変更してはならない。
foreach (KeyBinding binding in viewModel.KeyBindings)
{
if (e.Handled)
break;
binding.TryHandle(e);
}
}
}

private void OnDataContextDetached(ElementViewModel obj)
{
obj.AnimationRequested = (_, _) => Task.CompletedTask;
Expand Down
12 changes: 0 additions & 12 deletions src/Beutl/Views/MainView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@
<vm:MainViewModel />
</Design.DataContext>

<UserControl.KeyBindings>
<KeyBinding Command="{CompiledBinding CreateNewProject}" Gesture="{DynamicResource CreateNewProjectKeyGesture}" />
<KeyBinding Command="{CompiledBinding CreateNew}" Gesture="{DynamicResource CreateNewKeyGesture}" />
<KeyBinding Command="{CompiledBinding OpenProject}" Gesture="{DynamicResource OpenProjectKeyGesture}" />
<KeyBinding Command="{CompiledBinding OpenFile}" Gesture="{DynamicResource OpenKeyGesture}" />
<KeyBinding Command="{CompiledBinding Save}" Gesture="{DynamicResource SaveKeyGesture}" />
<KeyBinding Command="{CompiledBinding SaveAll}" Gesture="{DynamicResource SaveAllKeyGesture}" />
<KeyBinding Command="{CompiledBinding Exit}" Gesture="{DynamicResource ExitKeyGesture}" />
<KeyBinding Command="{CompiledBinding Undo}" Gesture="{DynamicResource UndoKeyGesture}" />
<KeyBinding Command="{CompiledBinding Redo}" Gesture="{DynamicResource RedoKeyGesture}" />
</UserControl.KeyBindings>

<UserControl.Styles>
<Style Selector="FlyoutPresenter.HiddenNotificationPadding0">
<Setter Property="Padding" Value="0" />
Expand Down
Loading

0 comments on commit 246b787

Please sign in to comment.