Skip to content

Commit

Permalink
要素の分割をショートカットで行えるようにした
Browse files Browse the repository at this point in the history
  • Loading branch information
yuto-trd committed Sep 12, 2023
1 parent 3247442 commit eda2a87
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 9 deletions.
9 changes: 9 additions & 0 deletions src/Beutl.Language/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Beutl.Language/Strings.ja.resx
Original file line number Diff line number Diff line change
Expand Up @@ -949,4 +949,7 @@ b-editorがダウンロードURLを管理します。</value>
<data name="ChangeToOriginalLength" xml:space="preserve">
<value>オリジナルの長さに変更</value>
</data>
<data name="SplitByCurrentFrame" xml:space="preserve">
<value>現在のフレームで分割</value>
</data>
</root>
3 changes: 3 additions & 0 deletions src/Beutl.Language/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -949,4 +949,7 @@ and b-editor maintains the download URL.</value>
<data name="ChangeToOriginalLength" xml:space="preserve">
<value>Change to original length</value>
</data>
<data name="SplitByCurrentFrame" xml:space="preserve">
<value>Split by current frame</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/Beutl/App.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<KeyGesture x:Key="CutKeyGesture">Ctrl+X</KeyGesture>
<KeyGesture x:Key="CopyKeyGesture">Ctrl+C</KeyGesture>
<KeyGesture x:Key="PasteKeyGesture">Ctrl+V</KeyGesture>
<KeyGesture x:Key="SplitKeyGesture">Ctrl+K</KeyGesture>
<KeyGesture x:Key="PlayPauseKeyGesture">Space</KeyGesture>
<KeyGesture x:Key="NextKeyGesture">Right</KeyGesture>
<KeyGesture x:Key="PreviousKeyGesture">Left</KeyGesture>
Expand Down
22 changes: 18 additions & 4 deletions src/Beutl/ViewModels/ElementViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ public ElementViewModel(Element element, TimelineViewModel timeline)
.AddTo(_disposables);

// コマンドを構成
Split.Where(func => func != null)
.Subscribe(func => OnSplit(func!()))
Split.Where(_ => GetClickedTime != null)
.Subscribe(_ => OnSplit(GetClickedTime!()))
.AddTo(_disposables);

SplitByCurrentFrame
.Subscribe(_ => OnSplit(Scene.CurrentFrame))
.AddTo(_disposables);

Cut.Subscribe(OnCut)
Expand Down Expand Up @@ -130,6 +134,8 @@ public ElementViewModel(Element element, TimelineViewModel timeline)

public Func<(Thickness Margin, Thickness BorderMargin, double Width), CancellationToken, Task> AnimationRequested { get; set; } = (_, _) => Task.CompletedTask;

public Func<TimeSpan>? GetClickedTime { get; set; }

public TimelineViewModel Timeline { get; private set; }

public Element Model { get; private set; }
Expand Down Expand Up @@ -160,7 +166,9 @@ public ElementViewModel(Element element, TimelineViewModel timeline)

public ReadOnlyReactivePropertySlim<Avalonia.Media.Color> TextColor { get; }

public ReactiveCommand<Func<TimeSpan>?> Split { get; } = new();
public ReactiveCommand Split { get; } = new();

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

public AsyncReactiveCommand Cut { get; } = new();

Expand Down Expand Up @@ -189,6 +197,7 @@ public void Dispose()
Model = null!;
Scope = null!;
AnimationRequested = (_, _) => Task.CompletedTask;
GetClickedTime = null;
GC.SuppressFinalize(this);
}

Expand Down Expand Up @@ -339,10 +348,14 @@ private async Task OnCut()
private void OnSplit(TimeSpan timeSpan)
{
int rate = Scene.FindHierarchicalParent<Project>() is { } proj ? proj.GetFrameRate() : 30;
TimeSpan minLength = TimeSpan.FromSeconds(1d / rate);
TimeSpan absTime = timeSpan.RoundToRate(rate);
TimeSpan forwardLength = absTime - Model.Start;
TimeSpan backwardLength = Model.Length - forwardLength;

if (forwardLength < minLength || backwardLength < minLength)
return;

CoreObjectReborn.Reborn(Model, out Element backwardLayer);

IRecordableCommand command1 = Scene.MoveChild(Model.ZIndex, Model.Start, forwardLength, Model);
Expand Down Expand Up @@ -391,7 +404,8 @@ private List<KeyBinding> CreateKeyBinding()
var list = new List<KeyBinding>
{
new KeyBinding { Gesture = new(Key.Delete), Command = Exclude },
new KeyBinding { Gesture = new(Key.Delete, modifier), Command = Delete }
new KeyBinding { Gesture = new(Key.Delete, modifier), Command = Delete },
new KeyBinding { Gesture = new(Key.K, modifier), Command = SplitByCurrentFrame }
};

if (config != null)
Expand Down
8 changes: 5 additions & 3 deletions src/Beutl/Views/ElementView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@
</Border.Resources>
<Border.ContextFlyout>
<ui:FAMenuFlyout>
<ui:MenuFlyoutItem Command="{Binding Split}"
CommandParameter="{Binding #root.GetClickedTime, Mode=OneTime}"
Text="{x:Static lang:Strings.Split}">
<ui:MenuFlyoutItem Command="{Binding Split}" Text="{x:Static lang:Strings.Split}">
<ui:MenuFlyoutItem.IconSource>
<icons:SymbolIconSource Symbol="SplitVertical" />
</ui:MenuFlyoutItem.IconSource>
</ui:MenuFlyoutItem>
<ui:MenuFlyoutItem x:Name="splitByCurrent"
Command="{Binding SplitByCurrentFrame}"
InputGesture="{DynamicResource SplitKeyGesture}"
Text="{x:Static lang:Strings.SplitByCurrentFrame}" />
<ui:MenuFlyoutItem Command="{Binding Cut}"
InputGesture="{DynamicResource CutKeyGesture}"
Text="{x:Static lang:Strings.Cut}">
Expand Down
5 changes: 3 additions & 2 deletions src/Beutl/Views/ElementView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ public ElementView()
this.SubscribeDataContextChange<ElementViewModel>(OnDataContextAttached, OnDataContextDetached);
}

public Func<TimeSpan> GetClickedTime => () => _pointerPosition;

private ElementViewModel ViewModel => (ElementViewModel)DataContext!;

protected override void OnKeyDown(KeyEventArgs e)
Expand Down Expand Up @@ -82,12 +80,14 @@ private void OnContextFlyoutOpening(object? sender, EventArgs e)
if (DataContext is ElementViewModel viewModel)
{
change2OriginalLength.IsEnabled = viewModel.HasOriginalLength();
splitByCurrent.IsEnabled = viewModel.Model.Range.Contains(viewModel.Scene.CurrentFrame);
}
}

private void OnDataContextDetached(ElementViewModel obj)
{
obj.AnimationRequested = (_, _) => Task.CompletedTask;
obj.GetClickedTime = null;
_disposables.Clear();
}

Expand Down Expand Up @@ -155,6 +155,7 @@ await Dispatcher.UIThread.InvokeAsync(async () =>
await Task.WhenAll(task1, task2);
});
};
obj.GetClickedTime = () => _pointerPosition;

obj.Model.GetObservable(Element.IsEnabledProperty)
.ObserveOnUIDispatcher()
Expand Down

0 comments on commit eda2a87

Please sign in to comment.