using Microsoft.Win32; using NAudio.Midi; using NAudio.Wave; using NLayer.NAudioSupport; using QuikDawEditor.EditingClasses; using QuikDawEditor.Properties; using QuikDawEditor.Undo; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; using static QuikDawEditor.EDITING.MiscMethods; using static QuikDawEditor.EDITING.StaticProperties; using static QuikDawEditor.EDITING.VstMethods; using static QuikDawEditor.EDITING.MidiMethods; using static QuikDawEditor.EDITING.AudioMethods; using Windows.ApplicationModel.Contacts; using QuikDawEditor.VST; namespace QuikDawEditor; public partial class EditorWindow : Window, INotifyPropertyChanged { public string RelRes() { ReleaseResources(); return "Resources released"; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private string _DisplayInfoText = "Ready"; public string DisplayInfoText { get { return _DisplayInfoText; } set { _DisplayInfoText = value; NotifyPropertyChanged(nameof(DisplayInfoText)); } } public ObservableCollection UndoActions { get { return undoActions; } } private string _ProcessingMessage = ""; public string ProcessingMessage { get { return _ProcessingMessage; } set { _ProcessingMessage = value; NotifyPropertyChanged(nameof(ProcessingMessage)); NotifyPropertyChanged(nameof(ProcessingMessageVisible)); } } public bool ProcessingMessageVisible { get { return _ProcessingMessage != ""; } } public void ShowProcessingMessage(string message) { ProcessingMessage = message; this.IsEnabled = false; } public void HideProcessingMessage() { ProcessingMessage = ""; this.IsEnabled = true; } public EditorWindow() { InitializeComponent(); MainMenu.DataContext = this; splashWindow.InfoTB2.Text = "Version: " + GetAppVersion(); splashWindow.Show(); if (Process.GetProcessesByName("QuikDawEditor").Length > 1) { MessageBox.Show((Process.GetProcessesByName("QuikDawEditor").Length - 1).ToString() + " QuikDaw already running!"); foreach (Process p in Process.GetProcessesByName("QuikDawEditor")) if (p.Id != Process.GetCurrentProcess().Id) p.Kill(); } SetupWindowInitializing = true; while (Settings.Default.DataDirectory == "") { if (MessageBox.Show("Data directory not set yet - will open Setup Dialog", "Set directory", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { splashWindow.Hide(); setupInfoWin.ShowDialog(); } else Environment.Exit(0); } if (!Directory.Exists(Settings.Default.DataDirectory)) { MessageBox.Show("Data directory doesn't exist! Maybe deleted. Please set again", "Set directory"); splashWindow.Hide(); setupInfoWin.ShowDialog(); } if (Settings.Default.ScanVstDirectories == null) Settings.Default.ScanVstDirectories = new System.Collections.Specialized.StringCollection(); while (!CheckAudio()) { if (MessageBox.Show("Audio devices not selected yet - will open Setup Dialog", "Setup audio", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { splashWindow.Hide(); setupInfoWin.ShowDialog(); } else Environment.Exit(0); } SetupWindowInitializing = false; EnsureGlobalDirectories(); EQPresets = new ObservableCollection(new List(File.ReadAllLines(GlobalSettingsDirectory + "\\EQPresets.txt")).ConvertAll(gs => new EQPreset(gs))); } private bool CheckAudio() { bool audioInOk = false; bool audioOutOk = false; if (Settings.Default.AsioInRadioButtonChecked) { SelectedAudioOutIndex = setupInfoWin.asioOutputs.IndexOf(Settings.Default.SoundOutputDeviceName); audioOutOk = SelectedAudioOutIndex > -1; SelectedAudioInIndex = setupInfoWin.asioInputs.IndexOf(Settings.Default.SoundInputDeviceName); audioInOk = SelectedAudioInIndex > -1; } else { SelectedAudioOutIndex = setupInfoWin.waveOutputs.IndexOf(Settings.Default.SoundOutputDeviceName); audioOutOk = SelectedAudioOutIndex > -1; SelectedAudioInIndex = setupInfoWin.waveInputs.IndexOf(Settings.Default.SoundInputDeviceName); audioInOk = SelectedAudioInIndex > -1; } return audioInOk & audioOutOk; } public void EnsureGlobalDirectories() { if (!Directory.Exists(Settings.Default.DataDirectory)) Directory.CreateDirectory(Settings.Default.DataDirectory); if (!Directory.Exists(ProjectsDirectory)) Directory.CreateDirectory(ProjectsDirectory); if (!Directory.Exists(GlobalSettingsDirectory)) Directory.CreateDirectory(GlobalSettingsDirectory); if (!File.Exists(EQPresetsFile)) File.Create(EQPresetsFile).Close(); //if (!File.Exists(CompPresetsFile)) File.Create(CompPresetsFile).Close(); if (!File.Exists(VstiFavoritesFilePath)) File.Create(VstiFavoritesFilePath).Close(); if (!File.Exists(VstFxFavoritesFilePath)) File.Create(VstFxFavoritesFilePath).Close(); } private void EnsureProjectDirectories() { if (!Directory.Exists(EditingProjectPath)) Directory.CreateDirectory(EditingProjectPath); if (!Directory.Exists(EditingProjectClipsDirectory)) Directory.CreateDirectory(EditingProjectClipsDirectory); if (!Directory.Exists(ProjectBackupsDirectory)) Directory.CreateDirectory(ProjectBackupsDirectory); if (!Directory.Exists(ProjectMixdownDirectory)) Directory.CreateDirectory(ProjectMixdownDirectory); if (!Directory.Exists(ProjectWaveformImagesDirectory)) Directory.CreateDirectory(ProjectWaveformImagesDirectory); if (!Directory.Exists(ProjectRecordingDirectory)) Directory.CreateDirectory(ProjectRecordingDirectory); } private void ProjectPlayer_UpdateProjectEndPoint() { double currendPoint = editingProject.projectEndPointMs; double checkEnd = 0; Clip rightmostclip = editingProject.GetProjectRightMostClip(editingProject.Tracks); checkEnd = rightmostclip == null ? 0 : rightmostclip.ClipRightMs; editingProject.projectEndPointMs = (checkEnd == 0) ? PixelsToMsec(MainEditor.TracksContentSV.ActualWidth) : Math.Max(checkEnd, MainEditor.TracksContentSV.ActualWidth) + 20000; //Adjust scale grid here if (editingProject.projectEndPointMs > currendPoint) { bool CoverMessageWasVisible = CoverMessageLabel.IsVisible; if (!CoverMessageWasVisible) Dispatcher.Invoke(() => { CoverMessageShow("Updating end point . . ."); }, System.Windows.Threading.DispatcherPriority.Send); if (!CoverMessageWasVisible) CoverMessageHide(); } } private void CoverMessageShow(string message) { CoverMessageTB.Text = message; CoverMessageLabel.Visibility = Visibility.Visible; } private void CoverMessageHide() { CoverMessageTB.Text = ""; CoverMessageLabel.Visibility = Visibility.Hidden; } public string myQKey { get; set; } = "Q"; private void edWin_ContentRendered(object sender, EventArgs e) { SetUserMenuCommandBindings(); //LoadContentIntoEditor(); } private void LoadContentIntoEditor() { if (Environment.GetCommandLineArgs().Length > 1) { string firstCommandLineArg = Environment.GetCommandLineArgs()[1]; if (firstCommandLineArg.EndsWith(".qdd")) if (File.Exists(firstCommandLineArg)) LoadProject(firstCommandLineArg); else { MessageBox.Show("Not a QuikDaw file"); Application.Current.Shutdown(); } } else { int addno = 1; string newProjName = "New project"; while (Directory.Exists(ProjectsDirectory + "\\" + newProjName)) { newProjName = "New project" + addno.ToString(); addno += 1; } //For release***************** CreateNewProject(newProjName); //************************** } } private void GetJsonForProject_Click(object sender, RoutedEventArgs e) { GetProjectJson(); } private void Window_Closing(object sender, CancelEventArgs e) { if (CloseProject()) Application.Current.Shutdown(); else e.Cancel = true; } public void CloseAudioResources() { try { if (projPlayer != null) { projPlayer.SendProcessMessage -= ProjPlayer_SendProcessMessage; projPlayer.UpdateProjectEndPoint -= ProjectPlayer_UpdateProjectEndPoint; projPlayer.ScrollTracksContentSVForward -= ProjPlayer_ScrollTracksContentSVForward; projPlayer.ScaleGridToggled -= ProjPlayer_ScaleGridToggled; projPlayer.IsProjectPlaying = false; projPlayer.StopPlayTimer(); projPlayer.AudioPlayerStop(); // MessageBox.Show("stoppped"); projPlayer.Dispose(); } } catch (Exception ex) { MessageBox.Show("Error closing resources:\n" + ex.Message); } } internal void ShowLocalMessage(string message) { Dispatcher.Invoke(() => { MessTB.Text += message + "\n"; MessTB.ScrollToEnd(); }); } private void MarkersCB_DropDownClosed(object sender, EventArgs e) { if (MarkersCB.SelectedIndex == -1) return; MainEditor.TracksContentSV.ScrollToHorizontalOffset(MsecToPixels(editingProject.Markers[MarkersCB.SelectedIndex].timePosMs) * editingProject.ViewXZoomFac - 500); MainEditor.TrackContentControlsIC.Focus(); } private void MessTB_TextChanged(object sender, TextChangedEventArgs e) { //MessTBOverlayGrid.Visibility = Visibility.Visible; MessTB.ScrollToEnd(); } private void edWin_PreviewMouseDown(object sender, MouseButtonEventArgs e) { //MessTBOverlayGrid.Visibility = Visibility.Hidden; } private void MainEditor_CoverMessageInvoked(string messageText) { switch (messageText) { case "": CoverMessageHide(); break; default: CoverMessageShow(messageText); break; } } private void MainEditor_MarkersCBSelectionChanged(int selindex) { MarkersCB.SelectedIndex = selindex; } public void GetProjectJson() { if (!File.Exists(EditingProjectDataFileName)) return; if (File.Exists(@"D:\PROG\Visual C#\JsonViewer\JsonViewer\bin\Debug\net6.0-windows\JsonViewer.exe")) Process.Start(@"D:\PROG\Visual C#\JsonViewer\JsonViewer\bin\Debug\net6.0-windows\JsonViewer.exe", "\"" + EditingProjectDataFileName + "\""); else { string jsonString = File.ReadAllText(EditingProjectDataFileName); ViewJsonWindow vpm = new ViewJsonWindow(jsonString) { Owner = this }; vpm.Show(); } } Mp3FileReaderBase.FrameDecompressorBuilder builder = new Mp3FileReaderBase.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf)); private void PlayBut_Click(object sender, RoutedEventArgs e) { projPlayer.TogglePlayPauseCurrentProject(); } private void StopBut_Click(object sender, RoutedEventArgs e) { if (projPlayer.IsProjectRecording) { RecordBut.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); return; } if (editingProject.pianoRoll.clipPlaying) editingProject.pianoRoll.StopPlay(); projPlayer.CurrentPlayingPosMS = 0; projPlayer.ChangePlayPos(0); MainEditor.TracksContentSV.ScrollToHorizontalOffset(0); projPlayer.IsProjectPlaying = false; projPlayer.UpdatePlayPosDisplay(); } private void RecordBut_Click(object sender, RoutedEventArgs e) { switch (projPlayer.IsProjectRecording) { case false: if (editingProject.GetRecordingTrack == null && editingProject.GetAutomationRecordingTrack == null) { MessageBox.Show("No track is armed for recording", "No recording track", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); return; } Clip firstClipRight = editingProject.GetRecordingTrack.Clips.FirstOrDefault(clp => clp.ClipLeftMs >= projPlayer.CurrentPlayingPosMS); if (firstClipRight != null && firstClipRight.ClipLeftMs - projPlayer.CurrentPlayingPosMS < 1000D) { MessageBox.Show("Not enough room to record", "Not enough recording room", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); return; } if (MessageBox.Show("Begin recording?", "RECORD", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes, MessageBoxOptions.DefaultDesktopOnly) == MessageBoxResult.No) return; break; case true: StopAllNotes(); break; } projPlayer.IsProjectRecording = !projPlayer.IsProjectRecording; MainEditor.IsEnabled = !projPlayer.IsProjectRecording; MarkersCB.IsEnabled = !projPlayer.IsProjectRecording; ShowMenuBut.IsEnabled = !projPlayer.IsProjectRecording; } private void ShowMenuBut_MouseEnter(object sender, MouseEventArgs e) { if (menuShown) return; if (MainMenu.IsVisible) return; MainMenu.Visibility = Visibility.Visible; TotalDP.IsEnabled = false; if (!FileMenuItem.IsSubmenuOpen) FileMenuItem.IsSubmenuOpen = true; FileMenuItem.Focus(); } bool menuShown = false; private void ShowMenuBut_PreviewMouseDown(object sender, MouseButtonEventArgs e) { e.Handled = true; } private void ShowMenuBut_MouseLeave(object sender, MouseEventArgs e) { menuShown = false; } private void ShowMenuBut_PreviewMouseUp(object sender, MouseButtonEventArgs e) { e.Handled = true; menuShown = true; MainMenu.Visibility = Visibility.Visible; if (MainMenu.IsVisible) FileMenuItem.IsSubmenuOpen = true; } private void MainMenu_MouseEnter(object sender, MouseEventArgs e) { MainMenu.Focus(); } private void MainMenu_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { menuShown = MainMenu.IsVisible; TotalDP.IsEnabled = !MainMenu.IsVisible; } private void MainMenu_MouseLeave(object sender, MouseEventArgs e) { ShowMenuBut.Focus(); } private void TotalDP_PreviewMouseDown(object sender, MouseButtonEventArgs e) { MainMenu.Visibility = Visibility.Hidden; } private void MenuItem_PreviewMouseUp(object sender, MouseButtonEventArgs e) { MainMenu.Visibility = Visibility.Hidden; } private void ShowMenuBut_Click(object sender, RoutedEventArgs e) { e.Handled = true; if (MainMenu.IsVisible) FileMenuItem.IsSubmenuOpen = true; } private void MainMenu_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { MainMenu.Visibility = Visibility.Hidden; TotalDP.IsEnabled = true; } } private void MainMenu_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { MainMenu.Visibility = Visibility.Hidden; TotalDP.IsEnabled = true; } } private void ContinueWithoutAudioBut_Click(object sender, RoutedEventArgs e) { AudioNotAvailableBanner.Visibility = Visibility.Hidden; //breaks binding but ok since app needs to restart anyway MainEditor.TrackControlsSV.Focus(); } private void AudioNotAvailableBanner_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { TotalDP.IsEnabled = !AudioNotAvailableBanner.IsVisible; } private void AddAudioFilesMenuItem_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog() { InitialDirectory = Settings.Default.LastOpenFileDialogDirectory, Filter = "mp3 files|*.mp3|wave files|*.wav", Multiselect = true }; if ((bool)ofd.ShowDialog()) { foreach (string f in ofd.FileNames) AddNewAudioClipToTrack(f, null, 0, -1, false, false); } } internal SplashWindow splashWindow = new SplashWindow(); private void ShowAboutMenuItem_Click(object sender, RoutedEventArgs e) { //splashWindow.CurrOperation = "Ver. " + Assembly.GetEntryAssembly().GetName().Version.ToString(); Assembly assembly = Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); splashWindow.CurrOperation = "Ver. " + fvi.FileVersion; splashWindow.InfoTB2.Text = "(Build version:" + Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion + ")"; splashWindow.Show(); } BackgroundWorker scanVstsBW; private void MainEditor_Loaded(object sender, RoutedEventArgs e) { scanVstsBW = new BackgroundWorker() { WorkerReportsProgress = true }; scanVstsBW.DoWork += ScanVstsBW_DoWork; scanVstsBW.ProgressChanged += ScanVstsBW_ProgressChanged; scanVstsBW.RunWorkerCompleted += ScanVstsBW_RunWorkerCompleted; scanVstsBW.RunWorkerAsync(); if (!IsDebugging) UndosLV.ItemsSource = null; } private void ScanVstsBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { LoadContentIntoEditor(); GetVstiFavorites(); GetVstFxFavorites(); } private void ScanVstsBW_ProgressChanged(object sender, ProgressChangedEventArgs e) { splashWindow.CurrOperation = (e.ProgressPercentage == 0) ? "Scanning for Vsts . . ." + (e.UserState == null ? "" : "\n" + e.UserState.ToString()) : "Loading content ..."; } private void ScanVstsBW_DoWork(object sender, DoWorkEventArgs e) { try { scanVstsBW.ReportProgress(0); //Report on previous error of unloadable Vst if (File.Exists(VSTLoadLogFileName)) { List VstLogLines = new List(File.ReadAllLines(VSTLoadLogFileName)); if (VstLogLines.Count > 0 && !VstLogLines.Last().EndsWith("***OK")) { Settings.Default.ErrorProducingVsts.Add(VstLogLines.Last()); Settings.Default.Save(); //MessageBox.Show("unable to load last time:\n" + VstLogLines.Last()); } } File.Create(VSTLoadLogFileName).Close(); // recreate empty new log AddBassMidiDefaultVst(); //Scan for VSTs foreach (string vstdir in Settings.Default.ScanVstDirectories) { scanVstsBW.ReportProgress(0, Path.GetPathRoot(vstdir) + ".../" + Path.GetFileName(vstdir) + "/"); ScanVsts(vstdir, true); } scanVstsBW.ReportProgress(1); ReturnedWithErrorVstReferencesOther.AddRange(ScannedVstEffectReferences.Where(svst => !svst.ReturnedWithoutError)); ReturnedWithErrorVstReferencesOther.AddRange(ScannedVstInstrumentReferences.Where(svst => !svst.ReturnedWithoutError)); ReturnedWithErrorVstReferencesOther.Sort((rw1, rw2) => rw1.PluginCategory.CompareTo(rw2.PluginCategory)); ScannedVstEffectReferences.RemoveAll(svpr => !svpr.ReturnedWithoutError); ScannedVstInstrumentReferences.RemoveAll(svpr => !svpr.ReturnedWithoutError); } catch(Exception ex) { MessageBox.Show("Error scanning vst directories...\n" + ex.Message); } } private void AddBassMidiDefaultVst() { string BassMidiGeneralMidiVstPath = AppDomain.CurrentDomain.BaseDirectory + @"\GeneralMidiVst\BassMidi\BassMidiVsti.dll"; VstPluginReference newVSTpir = new VstPluginReference() { VstDllFileFullPath = BassMidiGeneralMidiVstPath, PluginName = "Reality GM Instruments" }; ScannedVstInstrumentReferences.Add(newVSTpir); GeneralMidiPrograms = new ObservableCollection(); foreach (VstProgram vprog in File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + @"\GeneralMidiVst\GeneralMidiList.txt").ToList().ConvertAll(rl => new VstProgram() { ProgramName = rl })) GeneralMidiPrograms.Add(vprog); } private void ProjectNameLabel_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { RenameProject(); } private void MessTBOverlayGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e) { ViewJsonMI.IsEnabled = File.Exists(EditingProjectDataFileName); } private void PlayScaleToggleBut_Click(object sender, RoutedEventArgs e) { editingProject.ToggleTimeBeatsView(); undoActions.Add(new TimeBeatsViewToggleUndo()); MainEditor.playGridHeader.UpdateGridVisual(); } private void PlayScaleBut_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { if (editingProject.IsTimePlayScale) return; editingProject.ToggleBeatsPerMeasure(); editingProject.UpdateProjectGridLines(); undoActions.Add(new BeatsPerMeasureToggleUndo()); MainEditor.playGridHeader.UpdateGridVisual(); } private void SnapToCB_DropDownClosed(object sender, EventArgs e) { ComboBox snaptocb = (ComboBox)sender; if (snaptocb.SelectedIndex < 1) editingProject.CurrentSnapTo = 2; else { //MessageBox.Show(snaptocb.SelectedIndex.ToString() + Math.Pow(2, snaptocb.SelectedIndex - 1).ToString()); decimal div = (decimal)Math.Pow(2, snaptocb.SelectedIndex - 1); editingProject.CurrentSnapTo = 1M / div; } editingProject.NeedsSaving = true; } private void BeatsMinNS_ValueChanged(double value) { if (oldBPMvalue == 0) return; if (!IsUndoing && oldBPMvalue != value) undoActions.Add(new BPMChangeUndo(oldBPMvalue)); editingProject.UpdateProjectGridLines(); if (MainEditor != null) MainEditor.playGridHeader.UpdateGridVisual(); editingProject.ResetAllClipsToBPM(); } private void LoopToggleBut_Click(object sender, RoutedEventArgs e) { ToggleLoopPlayOn_Execute(); } private void ToggleMixerViewMI_Click(object sender, RoutedEventArgs e) { ToggleMixerView_Execute(); ((MenuItem)sender).IsChecked = editingProject.IsMixerVisible; } private void TogglePianoRollViewMI_Click(object sender, RoutedEventArgs e) { TogglePianoRollView_Execute(); ((MenuItem)sender).IsChecked = editingProject.pianoRoll.IsVisible; } public string ToggleMixerHotKeyString { get { return ToggleMixerViewUCKP == null ? "" : ToggleMixerViewUCKP.KeyGestureString; } } public string TogglePianoRollHotKeyString { get { return TogglePianoRollViewUCKP == null ? "" : TogglePianoRollViewUCKP.KeyGestureString; } } public string ToggleRangeSelectionHotKeyString { get { return ToggleShowSelectionRangeUCKP == null ? "" : ToggleShowSelectionRangeUCKP.KeyGestureString; } } public string SetBookmarkHotKeyString { get { return SetBookmarkUCKP == null ? "" : SetBookmarkUCKP.KeyGestureString; } } public string GoToBookmarkHotKeyString { get { return GoToBookmarkUCKP == null ? "" : GoToBookmarkUCKP.KeyGestureString; } } public string PlayingImageSource { get { return projPlayer.PlayButImageSource; } } private void ViewMenu_SubmenuOpened(object sender, RoutedEventArgs e) { if (editingProject == null) return; ToggleMixerMI.IsChecked = editingProject.IsMixerVisible; NotifyPropertyChanged(nameof(ToggleMixerHotKeyString)); NotifyPropertyChanged(nameof(TogglePianoRollHotKeyString)); NotifyPropertyChanged(nameof(ToggleRangeSelectionHotKeyString)); TogglePianoRollMI.IsChecked = editingProject.pianoRoll.IsVisible; ToggleLyricLineMI.IsChecked = editingProject.IsLyricBarVisible; ToggleRangeSelectionMI.IsChecked = editingProject.LoopRangeSelected; } private void UndoMenuItem_Click(object sender, RoutedEventArgs e) { MainEditor.PerformUndo(); } private void AddMidiFileMenuItem_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog() { InitialDirectory = Settings.Default.LastOpenFileDialogDirectory, Filter = "midi files|*.mid|midi files|*.midi", Multiselect = false }; if ((bool)ofd.ShowDialog()) { MidiFile mfile = new MidiFile(ofd.FileName); AddMidiTracks(mfile.Events, -1, 0, 0, Double.MaxValue); } } private void WaveLoopsBut_Click(object sender, RoutedEventArgs e) { editingProject.ProjectSnapshot = GetControlAsBitmapSource(MainEditor.TracksContentSV); MainEditor.WaveLoopDropForm.Visibility = MainEditor.WaveLoopDropForm.IsVisible ? Visibility.Collapsed : Visibility.Visible; DragWaveLoopsModeBut.Background = MainEditor.WaveLoopDropForm.IsVisible ? Brushes.Coral : Brushes.Azure; DragWaveLoopsModeBut.Content = MainEditor.WaveLoopDropForm.IsVisible ? "Close drop window" : "Drag wave loops"; MainEditor.LeftDP.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; MainEditor.TracksContentSV.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; MainEditor.ScaleBarSV.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; ControlsDP.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; MarkersCB.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; MenuDP.IsEnabled = !MainEditor.WaveLoopDropForm.IsVisible; } private void ToggleLyricLaneMI_Click(object sender, RoutedEventArgs e) { editingProject.IsLyricBarVisible = !editingProject.IsLyricBarVisible; ((MenuItem)sender).IsChecked = editingProject.IsLyricBarVisible; editingProject.NeedsSaving = true; } private void ToggleRangeSelectionMI_Click(object sender, RoutedEventArgs e) { editingProject.LoopRangeSelected = !editingProject.LoopRangeSelected; ((MenuItem)sender).IsChecked = editingProject.LoopRangeSelected; editingProject.NeedsSaving = true; } private void SetBookmarkMenuItem_Click(object sender, RoutedEventArgs e) { SetBookmark_Execute(); } private void GoToBookmarkMenuItem_Click(object sender, RoutedEventArgs e) { GoToBookmark_Execute(); } private void TransportMenu_SubmenuOpened(object sender, RoutedEventArgs e) { NotifyPropertyChanged(nameof(SetBookmarkHotKeyString)); NotifyPropertyChanged(nameof(GoToBookmarkHotKeyString)); } private void PlayMenuItem_Click(object sender, RoutedEventArgs e) { PlayBut.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); } }