Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Lock editing of unselected notes" menu #1063

Merged
merged 3 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions OpenUtau.Core/Util/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ public class SerializablePreferences {
public string PhoneticAssistant = string.Empty;
public string RecentOpenSingerDirectory = string.Empty;
public string RecentOpenProjectDirectory = string.Empty;
public bool LockUnselectedNotesPitch = true;
public bool LockUnselectedNotesVibrato = true;
public bool LockUnselectedNotesExpressions = true;

public bool VoicebankPublishUseIgnore = true;
public string VoicebankPublishIgnores = "#Adobe Audition\n*.pkf\n\n#UTAU Engines\n*.ctspec\n*.d4c\n*.dio\n*.frc\n*.frt\n*.frq\n*.harvest\n*.lessaudio\n*.llsm\n*.mrq\n*.pitchtier\n*.pkf\n*.platinum\n*.pmk\n*.star\n*.uspec\n*.vs4ufrq\n\n#UTAU related tools\n$read\n*.setParam-Scache\n*.lbp\n*.lbp.caches/*\n\n#OpenUtau\nerrors.txt";
Expand Down
4 changes: 4 additions & 0 deletions OpenUtau/Strings/Strings.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
<system:String x:Key="menu.edit.copy">Copy</system:String>
<system:String x:Key="menu.edit.cut">Cut</system:String>
<system:String x:Key="menu.edit.delete">Delete</system:String>
<system:String x:Key="menu.edit.lockunselectednotes">Lock editing of unselected notes</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.pitchpoints">Pitch Points</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.vibrato">Vibrato</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.expressions">Expressions</system:String>
<system:String x:Key="menu.edit.paste">Paste</system:String>
<system:String x:Key="menu.edit.redo">Redo</system:String>
<system:String x:Key="menu.edit.selectall">Select All</system:String>
Expand Down
6 changes: 5 additions & 1 deletion OpenUtau/Strings/Strings.ja-JP.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,14 @@
<system:String x:Key="menu.edit.copy">コピー</system:String>
<system:String x:Key="menu.edit.cut">切り取り</system:String>
<system:String x:Key="menu.edit.delete">削除</system:String>
<system:String x:Key="menu.edit.lockunselectednotes">選択されていないノートの編集をロック</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.pitchpoints">ピッチ点</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.vibrato">ビブラート</system:String>
<system:String x:Key="menu.edit.lockunselectednotes.expressions">表情</system:String>
<system:String x:Key="menu.edit.paste">貼り付け</system:String>
<system:String x:Key="menu.edit.redo">やり直す</system:String>
<system:String x:Key="menu.edit.selectall">全て選択</system:String>
<system:String x:Key="menu.edit.undo">元に戻る</system:String>
<system:String x:Key="menu.edit.undo">元に戻す</system:String>
<system:String x:Key="menu.file">ファイル</system:String>
<system:String x:Key="menu.file.exit">OpenUTAUを終了</system:String>
<system:String x:Key="menu.file.exportaudio">音声をエクスポート</system:String>
Expand Down
3 changes: 3 additions & 0 deletions OpenUtau/ViewModels/PianoRollViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public class PianoRollViewModel : ViewModelBase, ICmdSubscriber {
[Reactive] public NotesViewModel NotesViewModel { get; set; }
[Reactive] public PlaybackViewModel? PlaybackViewModel { get; set; }

public bool LockPitchPoints { get => Preferences.Default.LockUnselectedNotesPitch; }
public bool LockVibrato { get => Preferences.Default.LockUnselectedNotesVibrato; }
public bool LockExpressions { get => Preferences.Default.LockUnselectedNotesExpressions; }
public bool ShowPortrait { get => Preferences.Default.ShowPortrait; }
public bool ShowIcon { get => Preferences.Default.ShowIcon; }
public bool ShowGhostNotes { get => Preferences.Default.ShowGhostNotes; }
Expand Down
4 changes: 2 additions & 2 deletions OpenUtau/Views/NoteEditStates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ private void UpdatePhonemeExp(IPointer pointer, Point point, bool shiftHeld) {
startValue = Math.Max(descriptor.min, Math.Min(descriptor.max, startValue));
}
foreach (var hit in hits) {
if (notesVm.Selection.Count > 0 && !notesVm.Selection.Contains(hit.phoneme.Parent)) {
if (Preferences.Default.LockUnselectedNotesExpressions && notesVm.Selection.Count > 0 && !notesVm.Selection.Contains(hit.phoneme.Parent)) {
continue;
}
var valuePoint = notesVm.TickToneToPoint(hit.note.position + hit.phoneme.position, 0);
Expand Down Expand Up @@ -758,7 +758,7 @@ private void ResetPhonemeExp(IPointer pointer, Point point) {
return;
}
foreach (var hit in hits) {
if (notesVm.Selection.Count > 0 && !notesVm.Selection.Contains(hit.phoneme.Parent)) {
if (Preferences.Default.LockUnselectedNotesExpressions && notesVm.Selection.Count > 0 && !notesVm.Selection.Contains(hit.phoneme.Parent)) {
continue;
}
if (!hit.phoneme.GetExpression(notesVm.Project, track, key).Item2) {
Expand Down
18 changes: 18 additions & 0 deletions OpenUtau/Views/PianoRollWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,25 @@
<MenuItem Header="{DynamicResource menu.edit.selectall}" InputGesture="Ctrl+A" Command="{Binding SelectAll}"/>
<MenuItem Header="-" Height="1"/>
<MenuItem Header="{DynamicResource pianoroll.menu.part.singer}" Click="OnMenuSingers"/>
<MenuItem Header="{DynamicResource menu.edit.lockunselectednotes}">
<MenuItem Header="{DynamicResource menu.edit.lockunselectednotes.pitchpoints}" Click="OnMenuLockPitchPoints">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding LockPitchPoints}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="{DynamicResource menu.edit.lockunselectednotes.vibrato}" Click="OnMenuLockVibrato">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding LockVibrato}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="{DynamicResource menu.edit.lockunselectednotes.expressions}" Click="OnMenuLockExpressions">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding LockExpressions}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</MenuItem>

<MenuItem Header="{DynamicResource menu.view}">
<MenuItem Header="{DynamicResource prefs.appearance.showportrait}" Click="OnMenuShowPortrait">
<MenuItem.Icon>
Expand Down
31 changes: 26 additions & 5 deletions OpenUtau/Views/PianoRollWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@ void OnMenuPointerLeave(object sender, PointerEventArgs args) {
Focus(); // Force unfocus menu for key down events.
}

// Edit menu
void OnMenuLockPitchPoints(object sender, RoutedEventArgs args) {
Preferences.Default.LockUnselectedNotesPitch = !Preferences.Default.LockUnselectedNotesPitch;
Preferences.Save();
ViewModel.RaisePropertyChanged(nameof(ViewModel.LockPitchPoints));
}
void OnMenuLockVibrato(object sender, RoutedEventArgs args) {
Preferences.Default.LockUnselectedNotesVibrato = !Preferences.Default.LockUnselectedNotesVibrato;
Preferences.Save();
ViewModel.RaisePropertyChanged(nameof(ViewModel.LockVibrato));
}
void OnMenuLockExpressions(object sender, RoutedEventArgs args) {
Preferences.Default.LockUnselectedNotesExpressions = !Preferences.Default.LockUnselectedNotesExpressions;
Preferences.Save();
ViewModel.RaisePropertyChanged(nameof(ViewModel.LockExpressions));
}

// View menu
void OnMenuShowPortrait(object sender, RoutedEventArgs args) {
Preferences.Default.ShowPortrait = !Preferences.Default.ShowPortrait;
Expand Down Expand Up @@ -396,13 +413,13 @@ private void NotesCanvasLeftPointerPressed(Control control, PointerPoint point,
return;
}
var pitHitInfo = ViewModel.NotesViewModel.HitTest.HitTestPitchPoint(point.Position);
if (pitHitInfo.Note != null) {
if (pitHitInfo.Note != null && !IsLockedEdit(ViewModel.LockPitchPoints, pitHitInfo.Note)) {
editState = new PitchPointEditState(control, ViewModel, this,
pitHitInfo.Note, pitHitInfo.Index, pitHitInfo.OnPoint, pitHitInfo.X, pitHitInfo.Y);
return;
}
var vbrHitInfo = ViewModel.NotesViewModel.HitTest.HitTestVibrato(point.Position);
if (vbrHitInfo.hit) {
if (vbrHitInfo.hit && !IsLockedEdit(ViewModel.LockVibrato, vbrHitInfo.note)) {
if (vbrHitInfo.hitToggle) {
ViewModel.NotesViewModel.ToggleVibrato(vbrHitInfo.note);
return;
Expand Down Expand Up @@ -491,7 +508,7 @@ private void NotesCanvasRightPointerPressed(Control control, PointerPoint point,
}
if (ViewModel.NotesViewModel.ShowPitch) {
var pitHitInfo = ViewModel.NotesViewModel.HitTest.HitTestPitchPoint(point.Position);
if (pitHitInfo.Note != null) {
if (pitHitInfo.Note != null && !IsLockedEdit(ViewModel.LockPitchPoints, pitHitInfo.Note)) {
ViewModel.NotesContextMenuItems.Add(new MenuItemViewModel() {
Header = ThemeManager.GetString("context.pitch.easeinout"),
Command = ViewModel.PitEaseInOutCommand,
Expand Down Expand Up @@ -608,12 +625,12 @@ public void NotesCanvasPointerMoved(object sender, PointerEventArgs args) {
return;
}
var pitHitInfo = ViewModel.NotesViewModel.HitTest.HitTestPitchPoint(point.Position);
if (pitHitInfo.Note != null) {
if (pitHitInfo.Note != null && !IsLockedEdit(ViewModel.LockPitchPoints, pitHitInfo.Note)) {
Cursor = ViewConstants.cursorHand;
return;
}
var vbrHitInfo = ViewModel.NotesViewModel.HitTest.HitTestVibrato(point.Position);
if (vbrHitInfo.hit) {
if (vbrHitInfo.hit && !IsLockedEdit(ViewModel.LockVibrato, vbrHitInfo.note)) {
if (vbrHitInfo.hitDepth) {
Cursor = ViewConstants.cursorSizeNS;
} else if (vbrHitInfo.hitPeriod) {
Expand Down Expand Up @@ -872,6 +889,10 @@ public void PhonemeCanvasPointerReleased(object sender, PointerReleasedEventArgs
Cursor = null;
}

private bool IsLockedEdit(bool locked, UNote note) {
return locked && ViewModel.NotesViewModel.Selection.Count > 0 && !ViewModel.NotesViewModel.Selection.Contains(note);
}

public void OnSnapDivMenuButton(object sender, RoutedEventArgs args) {
SnapDivMenu.PlacementTarget = sender as Button;
SnapDivMenu.Open();
Expand Down