using QuikDawEditor.VST; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; using System.Windows.Media; using static QuikDawEditor.EDITING.VstMethods; namespace QuikDawEditor; public partial class VstiWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private string _TitleText = "Track -"; public string TitleText { get { return _TitleText; } set { _TitleText = value; NotifyPropertyChanged(nameof(TitleText)); } } public ObservableCollection VstInstrumentReferences { get; set; } public VstiWindow() { InitializeComponent(); VstInstrumentReferences = new ObservableCollection(ScannedVstInstrumentReferences); VstInstrumentsLV.ItemsSource = VstInstrumentReferences; VstiFavoritesTV.ItemsSource = VstiFavorites; } private void Window_LocationChanged(object sender, EventArgs e) { Track thisTrack = (Track)this.DataContext; thisTrack.FxWinLocation = new IntPair() { int1 = (int)this.Left, int2 = (int)this.Top }; editingProject.NeedsSaving = true; } public bool receivingAdjustment = false; private void OpenVstBut_Click(object sender, RoutedEventArgs e) { try { ActiveVstPlugin thisactivevst = (ActiveVstPlugin)((Button)e.OriginalSource).DataContext; if (thisactivevst.IsEditorOpen) thisactivevst.edHostWin.Activate(); else thisactivevst.OpenEditor(this); editingProject.NeedsSaving = true; } catch (Exception ex) { MessageBox.Show("Error opening Vst window:\n" + ex.Message); } } private void ActiveCheckBox_Checked(object sender, RoutedEventArgs e) { CheckBox thisCB = (CheckBox)sender; ActiveVstPlugin thisVSTPlugin = (ActiveVstPlugin)thisCB.DataContext; thisVSTPlugin.IsActive = true; editingProject.NeedsSaving = true; } private void ActiveCheckBox_Unchecked(object sender, RoutedEventArgs e) { CheckBox thisCB = (CheckBox)sender; ActiveVstPlugin thisVSTPlugin = (ActiveVstPlugin)thisCB.DataContext; thisVSTPlugin.IsActive = false; editingProject.NeedsSaving = true; } private void SelectedVstsLV_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (movingLVItem) return; if (SelectedVstsLV.SelectedIndex == -1) { detailsLV.ItemsSource = null; detailsLV.Visibility = Visibility.Collapsed; return; } Track thisTrack = (Track)this.DataContext; ActiveVstPlugin thisActivevst = thisTrack.TrackInstrumentVsts[SelectedVstsLV.SelectedIndex]; if (!thisActivevst.ReturnedWithoutError) { detailsLV.ItemsSource = null; return; } int progcount = thisActivevst.myContext.PluginInfo.ProgramCount; int paramcount = thisActivevst.myContext.PluginInfo.ParameterCount; //Debug.WriteLine ("program mnam=" + thisActivevst.myContext.PluginCommandStub.Commands.GetProgramName()); if (thisActivevst.IsGeneralMidi) { //GeneralMidiDetailsLV.Visibility = Visibility.Visible; //detailsLV.Visibility = Visibility.Collapsed; //GeneralMidiDetailsLV.ItemsSource = thisActivevst.VstPluginChannels; detailsLV.ItemsSource = thisActivevst.ActiveVstPrograms; detailsLV.SelectedIndex = thisActivevst.SelectedVstProgramIndex; detailsLV.ScrollIntoView(thisActivevst.ActiveVstPrograms[Math.Max(0, thisActivevst.SelectedVstProgramIndex)]); } else { //GeneralMidiDetailsLV.Visibility = Visibility.Collapsed; //detailsLV.Visibility = Visibility.Visible; if (paramcount == 0) { if (progcount > 0) { for (int progno = 0; progno < progcount; progno++) thisActivevst.ActiveVstPrograms.Add(new VstProgram() { ProgramName = thisActivevst.myContext.PluginCommandStub.Commands.GetProgramNameIndexed(progno) }); } detailsLV.ItemsSource = thisActivevst.ActiveVstPrograms; detailsLV.SelectedIndex = thisActivevst.SelectedVstProgramIndex; if (thisActivevst.ActiveVstPrograms.Count > 0) detailsLV.ScrollIntoView(thisActivevst.ActiveVstPrograms[Math.Max(0, thisActivevst.SelectedVstProgramIndex)]); } else detailsLV.ItemsSource = thisActivevst.VstParameters; } } private void CloseButton_Click(object sender, RoutedEventArgs e) { this.Close(); } private void vstiWin_PreviewKeyDown(object sender, KeyEventArgs e) { if (VstFavoriteFolderEditing) return; if (e.Key == Key.Escape) this.Close(); if (Keyboard.IsKeyDown(Key.LeftCtrl) && e.Key == Key.S) editingProject.Save(); if (e.Key == Key.Space) projPlayer.TogglePlayPauseCurrentProject(); } private void programsLV_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (detailsLV.SelectedIndex == -1) return; Track thisTrack = (Track)this.DataContext; ActiveVstPlugin thisvst = thisTrack.TrackInstrumentVsts[SelectedVstsLV.SelectedIndex]; if (detailsLV.ItemsSource != thisvst.ActiveVstPrograms) return; thisvst.SelectedVstProgramIndex = detailsLV.SelectedIndex; if (thisvst.IsGeneralMidi) { //Set program thisvst.Channel = thisvst.SelectedVstProgramIndex == 128 ? 10 : 1; byte[] chunkbytes = thisvst.myContext.PluginCommandStub.Commands.GetChunk(true); if (thisvst.SelectedVstProgramIndex == 128) { int offset = 9 * 0x28; //channel 10 Array.Copy(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, chunkbytes, 0xA70 + offset, 4); //prog Array.Copy(new byte[] { 0x64 }, 0, chunkbytes, 0xA83 + offset, 1); //vol Array.Copy(new byte[] { 0x20 }, 0, chunkbytes, 0xA78 + offset, 1); //pitchbend(0) Array.Copy(new byte[] { 0x40 }, 0, chunkbytes, 0xA87 + offset, 1); //pan } else Array.Copy(new byte[] { 0x00, 0x00, 0x00, (byte)detailsLV.SelectedIndex }, 0, chunkbytes, 0xA70, 4); thisvst.myContext.PluginCommandStub.Commands.SetChunk(chunkbytes, true); thisvst.PluginChunk = chunkbytes; } else { thisvst.Channel = 1; thisvst.myContext.PluginCommandStub.Commands.SetProgram(thisvst.SelectedVstProgramIndex); } VstProgram thisvProg = thisTrack.TrackInstrumentVsts[SelectedVstsLV.SelectedIndex].ActiveVstPrograms[detailsLV.SelectedIndex]; int selIdx = detailsLV.SelectedIndex; foreach (VstProgram vstp in thisvst.ActiveVstPrograms) vstp.IsSelected = false; thisvProg.IsSelected = true; thisTrack.TrackInstrumentVsts[SelectedVstsLV.SelectedIndex].SelectedProgramChanged(); editingProject.NeedsSaving = true; } private void RemoveVstBut_Click(object sender, RoutedEventArgs e) { Track thisTrack = (Track)this.DataContext; Button thisBut = (Button)sender; ActiveVstPlugin thisVSTRef = (ActiveVstPlugin)thisBut.DataContext; if (thisVSTRef.isNotifying) return; thisVSTRef.Close(); thisTrack.TrackInstrumentVsts.Remove(thisVSTRef); thisVSTRef.IsSelected = false; editingProject.NeedsSaving = true; } //private void AddVstInstrumentBut_Clicked(object sender, RoutedEventArgs e) //{ // Button thisBut = (Button)sender; // VstPluginReference thisVSTRef = (VstPluginReference)thisBut.DataContext; // if (thisVSTRef.isNotifying) return; // Track thisTrack = (Track)this.DataContext; // AddVSTInstrument(thisTrack, thisVSTRef); // editingProject.NeedsSaving = true; //} private void vstiWin_Activated(object sender, EventArgs e) { //this.Topmost = true; } private void DisplayNameTextBox_PreviewKeyDown(object sender, KeyEventArgs e) { TextBox thisTB = (TextBox)sender; VstFavorite thisVF = (VstFavorite)thisTB.DataContext; if (e.Key == Key.Enter) { if (thisTB.Text == "") { MessageBox.Show("Cannot have empty folder name"); return; } thisVF.FolderName = thisTB.Text; SaveVstiFavorites(); } if (e.Key == Key.Escape | e.Key == Key.Enter) { thisTB.BorderThickness = new Thickness(0); thisTB.Background = Brushes.Transparent; thisTB.IsReadOnly = true; VstFavoriteFolderEditing = false; thisTB.Focusable = false; } if (e.Key == Key.Escape) thisTB.Text = thisVF.FolderName; } private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e) { if (VstFavoriteFolderEditing) ((VstFavorite)((TreeViewItem)e.OriginalSource).DataContext).IsExpanded = true; } private bool FolderContainsFolder(VstFavorite vf1, VstFavorite vf2) { bool contains = false; ObservableCollection vfavs = VstiFavorites; VstFavorite vfav = vf2; while (vfav != null && !VstiFavorites.Contains(vfav)) { vfavs = GetParentFavoriteCollection(VstiFavorites, vfav); vfav = GetAllNestedFavorites(VstiFavorites).FirstOrDefault(vf => vf.VstFavorites == vfavs); if (vfav == vf1) { contains = true; break; } } return contains; } private int GetNestedFavoriteLevel(VstFavorite vfav) { int level = 0; ObservableCollection vfavs = VstiFavorites; while (vfav != null && !VstiFavorites.Contains(vfav)) { vfavs = GetParentFavoriteCollection(VstiFavorites, vfav); vfav = GetAllNestedFavorites(VstiFavorites).FirstOrDefault(vf => vf.VstFavorites == vfavs); level += 1; } return level; } private List GetAllNestedFavorites (IEnumerable vsfs) { List favorites = new List(); favorites.AddRange(vsfs); foreach (VstFavorite vf in vsfs) favorites.AddRange(GetAllNestedFavorites(vf.VstFavorites)); return favorites; } private ObservableCollection GetParentFavoriteCollection (ObservableCollection VSFs, VstFavorite vsf) { if (VSFs.Contains(vsf)) return VSFs; else { ObservableCollection foundCollection = null; foreach (VstFavorite subvsf in VSFs) { foundCollection = GetParentFavoriteCollection(subvsf.VstFavorites, vsf); if (foundCollection?.Count > 0) break; } return foundCollection; } } private void VstTVITextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e) { TextBox thisTB = (TextBox)sender; VstFavorite vstf = (VstFavorite)thisTB.DataContext; if (vstf != null) { switch (vstf.ItemType) { case "Plugin": ((MenuItem)thisTB.ContextMenu.Items[0]).Visibility = Visibility.Collapsed; ((MenuItem)thisTB.ContextMenu.Items[1]).Visibility = Visibility.Collapsed; break; case "Folder": ((MenuItem)thisTB.ContextMenu.Items[2]).Visibility = Visibility.Collapsed; ((MenuItem)thisTB.ContextMenu.Items[1]).Visibility = vstf.VstFavorites.Count == 0 ? Visibility.Visible : Visibility.Collapsed; break; } } } private void ContextMenu_Opened(object sender, RoutedEventArgs e) { if (MouseOverVstItem) { VstiFavoritesTV.ContextMenu.IsOpen = false; } MouseOverVstItem = false; } private void vstiWin_Loaded(object sender, RoutedEventArgs e) { Track thisTrack = (Track)this.DataContext; TitleText = "Track: " + thisTrack.TrackName + " - Virtual instruments"; } private void AddFavoritesFolderBut_Click(object sender, RoutedEventArgs e) { VstiFavorites.Add(new VstFavorite("Folder")); SaveVstiFavorites(); } private void ShowDetailsRB_Click(object sender, RoutedEventArgs e) { CheckBox cbox = (CheckBox)sender; detailsLV.Visibility = (bool)cbox.IsChecked ? Visibility.Visible : Visibility.Collapsed; } }