Skip to content

Commit

Permalink
Merge pull request #892 from maiko3tattun/1020_ShowWaitMessage
Browse files Browse the repository at this point in the history
Show loading dialog / Set try-catch
  • Loading branch information
stakira authored Nov 25, 2023
2 parents 7e2c5a1 + 615e928 commit f4cb188
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 62 deletions.
18 changes: 18 additions & 0 deletions OpenUtau.Core/Commands/Notifications.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ public ErrorMessageNotification(string message, Exception e) {
public override string ToString() => $"Error message: {message} {e}";
}

public class LoadingNotification : UNotification {
public readonly Type window;
public readonly bool startLoading;
public readonly string loadObject;
public LoadingNotification(Type window, bool startLoading, string loadObject) {
this.window = window;
this.startLoading = startLoading;
this.loadObject = loadObject;
}
public override string ToString() {
if (startLoading) {
return $"Start loading {loadObject}";
} else {
return $"Finish loading {loadObject}";
}
}
}

public class LoadPartNotification : UNotification {
public readonly int tick;
public LoadPartNotification(UPart part, UProject project, int tick) {
Expand Down
21 changes: 12 additions & 9 deletions OpenUtau/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Avalonia.Threading;
using DynamicData.Binding;
using OpenUtau.App.Views;
using OpenUtau.Core;
using OpenUtau.Core.Ustx;
using ReactiveUI;
Expand Down Expand Up @@ -59,8 +60,7 @@ public MainWindowViewModel() {
try {
OpenProject(new[] { file });
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(
"failed to open recent.", e));
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("failed to open recent.", e));
}
});
OpenTemplateCommand = ReactiveCommand.Create<string>(file => {
Expand All @@ -69,8 +69,7 @@ public MainWindowViewModel() {
DocManager.Inst.Project.Saved = false;
DocManager.Inst.Project.FilePath = string.Empty;
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(
"failed to open template.", e));
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("failed to open template.", e));
}
});
PartDeleteCommand = ReactiveCommand.Create<UPart>(part => {
Expand Down Expand Up @@ -109,8 +108,7 @@ public void NewProject() {
DocManager.Inst.Project.FilePath = string.Empty;
return;
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(
"failed to load default template.", e));
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("failed to load default template.", e));
}
}
DocManager.Inst.ExecuteCmd(new LoadProjectNotification(Core.Format.Ustx.Create()));
Expand All @@ -120,9 +118,14 @@ public void OpenProject(string[] files) {
if (files == null) {
return;
}
Core.Format.Formats.LoadProject(files);
DocManager.Inst.ExecuteCmd(new VoiceColorRemappingNotification(-1, true));
this.RaisePropertyChanged(nameof(Title));
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), true, "project"));
try {
Core.Format.Formats.LoadProject(files);
DocManager.Inst.ExecuteCmd(new VoiceColorRemappingNotification(-1, true));
this.RaisePropertyChanged(nameof(Title));
} finally {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), false, "project"));
}
}

public void SaveProject(string file = "") {
Expand Down
34 changes: 21 additions & 13 deletions OpenUtau/ViewModels/PianoRollViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Avalonia.Input;
using Avalonia.Threading;
using DynamicData.Binding;
using OpenUtau.App.Views;
using OpenUtau.Classic;
using OpenUtau.Core;
using OpenUtau.Core.Editing;
Expand Down Expand Up @@ -120,27 +121,34 @@ public PianoRollViewModel() {
if (NotesViewModel.Part == null || NotesViewModel.Part.notes.Count == 0) {
return;
}
var part = NotesViewModel.Part;
UNote? first;
UNote? last;
if (NotesViewModel.Selection.IsEmpty) {
first = part.notes.First();
last = part.notes.Last();
} else {
first = NotesViewModel.Selection.FirstOrDefault();
last = NotesViewModel.Selection.LastOrDefault();
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(PianoRollWindow), true, "legacy plugin"));
try {
var part = NotesViewModel.Part;
UNote? first;
UNote? last;
if (NotesViewModel.Selection.IsEmpty) {
first = part.notes.First();
last = part.notes.Last();
} else {
first = NotesViewModel.Selection.FirstOrDefault();
last = NotesViewModel.Selection.LastOrDefault();
}
var runner = PluginRunner.from(PathManager.Inst, DocManager.Inst);
runner.Execute(NotesViewModel.Project, part, first, last, plugin);
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(e));
} finally {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(PianoRollWindow), false, "legacy plugin"));
}
var runner = PluginRunner.from(PathManager.Inst, DocManager.Inst);
runner.Execute(NotesViewModel.Project, part, first, last, plugin);
});
LoadLegacyPlugins();

noteBatchEditCommand = ReactiveCommand.Create<BatchEdit>(edit => {
if (NotesViewModel.Part != null) {
try{
edit.Run(NotesViewModel.Project, NotesViewModel.Part, NotesViewModel.Selection.ToList(), DocManager.Inst);
}catch(System.Exception e){
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("Failed to run editing macro",e));
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("Failed to run editing macro", e));
}
}
});
Expand Down
65 changes: 46 additions & 19 deletions OpenUtau/ViewModels/SingersViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using DynamicData.Binding;
using NAudio.Wave;
using NWaves.Signals;
using OpenUtau.App.Views;
using OpenUtau.Classic;
using OpenUtau.Core;
using OpenUtau.Core.Ustx;
Expand Down Expand Up @@ -56,17 +57,36 @@ public SingersViewModel() {
this.WhenAnyValue(vm => vm.Singer)
.WhereNotNull()
.Subscribe(singer => {
singer.EnsureLoaded();
Avatar = LoadAvatar(singer);
Otos.Clear();
Otos.AddRange(singer.Otos);
DisplayedOtos.Clear();
DisplayedOtos.AddRange(singer.Otos);
Info = $"Author: {singer.Author}\nVoice: {singer.Voice}\nWeb: {singer.Web}\nVersion: {singer.Version}\n{singer.OtherInfo}\n\n{string.Join("\n", singer.Errors)}";
HasWebsite = !string.IsNullOrEmpty(singer.Web);
LoadSubbanks();
DocManager.Inst.ExecuteCmd(new OtoChangedNotification());
this.RaisePropertyChanged(nameof(IsClassic));
if (MessageBox.LoadingIsActive()) {
try {
AttachSinger();
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(e));
}
} else {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(SingersDialog), true, "singer"));
try {
AttachSinger();
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(e));
} finally {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(SingersDialog), false, "singer"));
}
}
void AttachSinger() {
singer.EnsureLoaded();
Avatar = LoadAvatar(singer);
Otos.Clear();
Otos.AddRange(singer.Otos);
DisplayedOtos.Clear();
DisplayedOtos.AddRange(singer.Otos);
Info = $"Author: {singer.Author}\nVoice: {singer.Voice}\nWeb: {singer.Web}\nVersion: {singer.Version}\n{singer.OtherInfo}\n\n{string.Join("\n", singer.Errors)}";
HasWebsite = !string.IsNullOrEmpty(singer.Web);
LoadSubbanks();
DocManager.Inst.ExecuteCmd(new OtoChangedNotification());
this.RaisePropertyChanged(nameof(IsClassic));
this.RaisePropertyChanged(nameof(UseSearchAlias));
}
});
this.WhenAnyValue(vm => vm.SearchAlias)
.Subscribe(alias => {
Expand Down Expand Up @@ -195,15 +215,22 @@ public void Refresh() {
if (Singer == null) {
return;
}
var singerId = Singer.Id;
SingerManager.Inst.SearchAllSingers();
this.RaisePropertyChanged(nameof(Singers));
if (SingerManager.Inst.Singers.TryGetValue(singerId, out var singer)) {
Singer = singer;
} else {
Singer = Singers.FirstOrDefault();
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(SingersDialog), true, "singer"));
try {
var singerId = Singer.Id;
SingerManager.Inst.SearchAllSingers();
this.RaisePropertyChanged(nameof(Singers));
if (SingerManager.Inst.Singers.TryGetValue(singerId, out var singer)) {
Singer = singer;
} else {
Singer = Singers.FirstOrDefault();
}
DocManager.Inst.ExecuteCmd(new SingersRefreshedNotification());
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(e));
} finally {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(SingersDialog), false, "singer"));
}
DocManager.Inst.ExecuteCmd(new SingersRefreshedNotification());
}

Bitmap? LoadAvatar(USinger singer) {
Expand Down
53 changes: 34 additions & 19 deletions OpenUtau/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@
using OpenUtau.App.ViewModels;
using OpenUtau.Classic;
using OpenUtau.Core;
using OpenUtau.Core.DiffSinger;
using OpenUtau.Core.Format;
using OpenUtau.Core.Ustx;
using OpenUtau.Core.Util;
using ReactiveUI;
using Serilog;
using Point = Avalonia.Point;

using OpenUtau.Core.DiffSinger;

namespace OpenUtau.App.Views {
public partial class MainWindow : Window, ICmdSubscriber {
private readonly KeyModifiers cmdKey =
Expand Down Expand Up @@ -475,25 +474,33 @@ public void OpenSingersWindow() {
if (lifetime == null) {
return;
}
var dialog = lifetime.Windows.FirstOrDefault(w => w is SingersDialog);
if (dialog == null) {
USinger? singer = null;
if (viewModel.TracksViewModel.SelectedParts.Count > 0) {
singer = viewModel.TracksViewModel.Tracks[viewModel.TracksViewModel.SelectedParts.First().trackNo].Singer;
}
if (singer == null && viewModel.TracksViewModel.Tracks.Count > 0) {
singer = viewModel.TracksViewModel.Tracks.First().Singer;

DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), true, "singers window"));
try {
var dialog = lifetime.Windows.FirstOrDefault(w => w is SingersDialog);
if (dialog == null) {
USinger? singer = null;
if (viewModel.TracksViewModel.SelectedParts.Count > 0) {
singer = viewModel.TracksViewModel.Tracks[viewModel.TracksViewModel.SelectedParts.First().trackNo].Singer;
}
if (singer == null && viewModel.TracksViewModel.Tracks.Count > 0) {
singer = viewModel.TracksViewModel.Tracks.First().Singer;
}
var vm = new SingersViewModel();
if (singer != null) {
vm.Singer = singer;
}
dialog = new SingersDialog() { DataContext = vm };
dialog.Show();
}
var vm = new SingersViewModel();
if (singer != null) {
vm.Singer = singer;
dialog.Activate();
if (dialog.Position.Y < 0) {
dialog.Position = dialog.Position.WithY(0);
}
dialog = new SingersDialog() { DataContext = vm };
dialog.Show();
}
dialog.Activate();
if (dialog.Position.Y < 0) {
dialog.Position = dialog.Position.WithY(0);
} catch (Exception e) {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(e));
} finally {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), false, "singers window"));
}
}

Expand Down Expand Up @@ -973,10 +980,12 @@ public void PartsCanvasDoubleTapped(object sender, TappedEventArgs args) {
var control = canvas.InputHitTest(args.GetPosition(canvas));
if (control is PartControl partControl && partControl.part is UVoicePart) {
if (pianoRollWindow == null) {
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), true, "pianoroll window"));
pianoRollWindow = new PianoRollWindow() {
MainWindow = this,
};
pianoRollWindow.ViewModel.PlaybackViewModel = viewModel.PlaybackViewModel;
DocManager.Inst.ExecuteCmd(new LoadingNotification(typeof(MainWindow), false, "pianoroll window"));
}
// Workaround for new window losing focus.
openPianoRollWindow = true;
Expand Down Expand Up @@ -1161,6 +1170,12 @@ private async Task<bool> AskIfSaveAndContinue() {
public void OnNext(UCommand cmd, bool isUndo) {
if (cmd is ErrorMessageNotification notif) {
MessageBox.ShowError(this, notif.message, notif.e);
} else if (cmd is LoadingNotification loadingNotif && loadingNotif.window == typeof(MainWindow)) {
if (loadingNotif.startLoading) {
MessageBox.ShowLoading(this);
} else {
MessageBox.CloseLoading();
}
} else if (cmd is VoiceColorRemappingNotification voicecolorNotif) {
if(voicecolorNotif.TrackNo < 0 || DocManager.Inst.Project.tracks.Count <= voicecolorNotif.TrackNo) {
ValidateTracksVoiceColor();
Expand Down
20 changes: 20 additions & 0 deletions OpenUtau/Views/MessageBox.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public partial class MessageBox : Window {
public enum MessageBoxButtons { Ok, OkCancel, YesNo, YesNoCancel, OkCopy }
public enum MessageBoxResult { Ok, Cancel, Yes, No }

private static MessageBox? loadingDialog;

public MessageBox() {
InitializeComponent();
}
Expand Down Expand Up @@ -102,5 +104,23 @@ public static MessageBox ShowModal(Window parent, string text, string title) {
msgbox.ShowDialog(parent);
return msgbox;
}

public static void ShowLoading(Window parent) {
loadingDialog = new MessageBox() {
Title = "Loading"
};
loadingDialog.Text.Text = "Please wait...";
loadingDialog.Show(parent);
}

public static void CloseLoading() {
if (loadingDialog != null) {
loadingDialog.Close();
}
}

public static bool LoadingIsActive() {
return loadingDialog != null && loadingDialog.IsActive;
}
}
}
14 changes: 13 additions & 1 deletion OpenUtau/Views/PianoRollWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface IValueTip {
void UpdateValueTip(string text);
}

public partial class PianoRollWindow : Window, IValueTip {
public partial class PianoRollWindow : Window, IValueTip, ICmdSubscriber {
public MainWindow? MainWindow { get; set; }
public readonly PianoRollViewModel ViewModel;

Expand Down Expand Up @@ -58,6 +58,8 @@ public PianoRollWindow() {
noteDefaultsCommand = ReactiveCommand.Create(() => {
EditNoteDefaults();
});

DocManager.Inst.AddSubscriber(this);
}

public void WindowDeactivated(object sender, EventArgs args) {
Expand Down Expand Up @@ -1376,5 +1378,15 @@ public void AttachExpressions() {
exps[DocManager.Inst.Project.expSecondary].SelectExp();
exps[DocManager.Inst.Project.expPrimary].SelectExp();
}

public void OnNext(UCommand cmd, bool isUndo) {
if (cmd is LoadingNotification loadingNotif && loadingNotif.window == typeof(PianoRollWindow)) {
if (loadingNotif.startLoading) {
MessageBox.ShowLoading(this);
} else {
MessageBox.CloseLoading();
}
}
}
}
}
8 changes: 7 additions & 1 deletion OpenUtau/Views/SingersDialog.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,13 @@ void OnKeyDown(object sender, KeyEventArgs args) {
#region ICmdSubscriber

public void OnNext(UCommand cmd, bool isUndo) {
if (cmd is OtoChangedNotification otoChanged) {
if (cmd is LoadingNotification loadingNotif && loadingNotif.window == typeof(SingersDialog)) {
if (loadingNotif.startLoading) {
MessageBox.ShowLoading(this);
} else {
MessageBox.CloseLoading();
}
} else if (cmd is OtoChangedNotification otoChanged) {
var viewModel = DataContext as SingersViewModel;
if (viewModel == null) {
return;
Expand Down

0 comments on commit f4cb188

Please sign in to comment.