// Every button on the button grid uses this as its click handler. private void btnProgramChange_Click(object sender, EventArgs e) { // Get the patchNo from within the button that was clicked MidiProgram midiProgram = (MidiProgram)(((Button)sender).Tag); // And switch to it. if (midiProgram != null && midiProgram.myPatchNumber >= 0) { // Override the default intput device in the mapping to be the on for this tab LogicalInputDevice deviceForThisMidiProgram = mapper.configuration.primaryInputDevice; if (tabControl1.SelectedTab.Tag != null && tabControl1.SelectedTab.Tag is LogicalInputDevice) { deviceForThisMidiProgram = (LogicalInputDevice)tabControl1.SelectedTab.Tag; } // Rebind it to make the device override take effect midiProgram.bind(mapper.configuration.logicalInputDeviceDict, mapper.configuration.soundGenerators, mapper.configuration.mappings, deviceForThisMidiProgram); // Fire the program change mapper.ProgramChange((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber); mapper.masterTranspose = 0; } // Select (only) this button unselectAllRandomAccessButtons(); ((Button)sender).BackColor = SystemColors.Highlight; }
private void midiProgramActivatedNotification(MidiProgram midiProgram) { unselectAllRandomAccessButtons(); if (midiProgram.activationButton != null) { midiProgram.activationButton.BackColor = SystemColors.Highlight; } }
public MidiProgram(MidiProgram orig) { myBankNumber = orig.myBankNumber; myPatchNumber = orig.myPatchNumber; bSingle = orig.bSingle; SingleSoundGeneratorName = orig.SingleSoundGeneratorName; SinglePatchName = orig.SinglePatchName; MappingName = orig.MappingName; }
//public String getCurrentMappingName() //{ // if (m_currentMapping != null) // { // return m_currentPatchNo + ": " + m_currentMapping.name; // } // else // { // return ""; // } //} public void selectFirstMidiProgram() { if (configuration.midiPrograms.Count > 0) { int firstMidiProgramKey = configuration.midiPrograms.Keys.Min(); MidiProgram firstMidiProgram = configuration.midiPrograms[firstMidiProgramKey]; this.ProgramChange(firstMidiProgram.myPatchNumber); } }
//-------------------------------------------------------------------------- // Program Button Context Menu Handler: deletion. //-------------------------------------------------------------------------- private void toolStripMenuItem1_Click(object sender, EventArgs e) { // Find the Button being Deleted and its position. ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; ContextMenuStrip cms = (ContextMenuStrip)tsmi.Owner; if (cms.SourceControl is Button) { // Request to delete a Random Access Button Button buttonToBeDeleted = (Button)cms.SourceControl; TableLayoutPanelCellPosition tlpcp = tlpRandomAccess.GetCellPosition(buttonToBeDeleted); // Remove it from the table layout panel tlpRandomAccess.Controls.Remove(buttonToBeDeleted); // And remove the midiProgram that underlies it MidiProgram midiProgram = (MidiProgram)buttonToBeDeleted.Tag; mapper.configuration.midiPrograms.Remove(midiProgram.key); // Iterate through the buttons below it in it's column of the table layout panel and shift them each up one row for (int row = tlpcp.Row; row < (N_RANDOMACCESS_ROWS + FIRST_RANDOMACCESS_BTN_ROW); ++row) { Button buttonToShift = (Button)tlpRandomAccess.GetControlFromPosition(tlpcp.Column, row + 1); if (buttonToShift == null) { break; // All out of buttons in this col... } // Remove the button from its original position and add it back into its new position tlpRandomAccess.Controls.Remove(buttonToShift); tlpRandomAccess.Controls.Add(buttonToShift, tlpcp.Column, row); // Adjust the patch number of the midi program that underlies it. Since that's part of its dict key, remove and re-add it to the midi programs dictionary. midiProgram = (MidiProgram)buttonToShift.Tag; if (midiProgram.myPatchNumber > N_RANDOMACCESS_COLS) { mapper.configuration.midiPrograms.Remove(midiProgram.key); midiProgram.myPatchNumber -= (N_RANDOMACCESS_COLS); mapper.configuration.midiPrograms.Add(midiProgram.key, midiProgram); } } mapper.configuration.dirty = true; } else if (cms.SourceControl is ListBox) { // Request to delete a Mapping Patch on one of the Mapping Patch List Boxes ListBox listBox = (ListBox)cms.SourceControl; if (listBox.SelectedItem != null && listBox.SelectedItem is SimpleMapping.SimpleMappingDefinition) { listBox.Items.Remove(listBox.SelectedItem); } } }
//-------------------------------------------------------------------------- // Delete a button from the grid, rippling up the ones below it in its column. //-------------------------------------------------------------------------- private void removeControlFromTableLayoutPanelProgramButtons(TableLayoutPanelCellPosition tlpcp) { // Remove the control in question System.Windows.Forms.Control ctl = tlpRandomAccess.GetControlFromPosition(tlpcp.Column, tlpcp.Row); tlpRandomAccess.Controls.Remove(ctl); // And its associated MidiProgram (Button's tag will still reference it, though, which may be used to insert it back in its new home) Object o = ctl.Tag; if (o is MidiProgram) { MidiProgram midiProgram = (MidiProgram)o; midiProgram.activationButton = null; mapper.configuration.midiPrograms.Remove(midiProgram.key); mapper.configuration.dirty = true; } // Ripple up to fill the gap. for (int r = tlpcp.Row; r < (N_RANDOMACCESS_ROWS + FIRST_RANDOMACCESS_BTN_ROW) - 1; ++r) { // Get the control in the next row of this col ctl = tlpRandomAccess.GetControlFromPosition(tlpcp.Column, r + 1); // If there isn't one, we're done if (ctl == null) { break; } // Remove it tlpRandomAccess.Controls.Remove(ctl); // Add it back in, up one row tlpRandomAccess.Controls.Add(ctl, tlpcp.Column, r); // If it's pointing to a midiProgram (and it should be) then fix up its program number to reflect the button's new pos o = ctl.Tag; if (o is MidiProgram) { MidiProgram midiProgram = (MidiProgram)o; if (midiProgram.myPatchNumber > (N_RANDOMACCESS_COLS)) { mapper.configuration.midiPrograms.Remove(midiProgram.key); midiProgram.myPatchNumber -= (N_RANDOMACCESS_COLS); mapper.configuration.midiPrograms.Add(midiProgram.key, midiProgram); mapper.configuration.dirty = true; } } } }
public static void createTrialConfiguration(Dictionary <int, MidiProgram> midiProgramDict) { MidiProgram midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 0; midiProgram.bSingle = true; midiProgram.SingleSoundGeneratorName = "Proteus VX"; midiProgram.SinglePatchName = "Dynamic Grand"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 1; midiProgram.bSingle = true; midiProgram.SingleSoundGeneratorName = "Proteus VX"; midiProgram.SinglePatchName = "EP-3"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 9; midiProgram.bSingle = true; midiProgram.SingleSoundGeneratorName = "Proteus VX"; midiProgram.SinglePatchName = "EP-2"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 17; midiProgram.bSingle = true; midiProgram.SingleSoundGeneratorName = "Proteus VX"; midiProgram.SinglePatchName = "Clavinetti"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 2; midiProgram.bSingle = false; midiProgram.MappingName = "Rock Organ 1"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); midiProgram = new MidiProgram(); midiProgram.myBankNumber = 0; midiProgram.myPatchNumber = 3; midiProgram.bSingle = false; midiProgram.MappingName = "Vintage Vince"; midiProgramDict.Add((midiProgram.myBankNumber * 128) + midiProgram.myPatchNumber, midiProgram); }
public void ProgramChange(int programNoToSwitchTo) { // Select the mapping that matches the requested bank/program# if (configuration.midiPrograms.ContainsKey(programNoToSwitchTo)) { MidiProgram midiProgramToActivate = configuration.midiPrograms[programNoToSwitchTo]; SetMapping(midiProgramToActivate.mapping); if (midiProgramActivatedNotification != null) { midiProgramActivatedNotification(midiProgramToActivate); } } }
public void createTrialConfiguration() { dirty = true; try { Mapping.PerDeviceChannelMapping globalPerInputDeviceChannelMapping = new Mapping.PerDeviceChannelMapping(); globalPerInputDeviceChannelMapping.logicalInputDeviceName = "Input Device 1"; globalPerInputDeviceChannelMapping.inputDeviceChannel = 0; ControlMapping globalControlMapping = new ControlMapping(); globalControlMapping.soundGeneratorName = "Reaper"; globalControlMapping.soundGeneratorRelativeChannel = 0; globalControlMapping.sourceControlNumber = 75; // Top Left Rotary Knob on Oxygen globalControlMapping.mappedControlNumber = 9; // I've got Reaper Master Volume mapped to this. globalControlMapping.min = 30; // This provides a nice workable vol range globalControlMapping.max = 91; globalPerInputDeviceChannelMapping.controlMappings.Add(globalControlMapping); globalControlMappings.Add(globalPerInputDeviceChannelMapping); primaryInputDeviceName = "Input Device 1"; LogicalInputDevice.createTrialConfiguration(logicalInputDeviceDict); LogicalOutputDevice.createTrialConfiguration(logicalOutputDeviceDict); SoundGenerator.createTrialConfiguration(soundGenerators); Mapping.createTrialConfiguration(mappings); MidiProgram.createTrialConfiguration(midiPrograms); Setlist.createTrialConfiguration(songDict, setlists); } catch (Exception e) { MessageBox.Show("Exception creating trial configurations: " + e); } }
//-------------------------------------------------------------------------------- // When you click on a program in the Programs treeview that program is activated. //-------------------------------------------------------------------------------- private void tvProgramPatches_Click(object sender, EventArgs e) { TreeNode node = tvProgramPatches.SelectedNode; if (node != null) { if (node.Tag is SoundGenerator) { // Route out to this SG, but send no program change... // Allows user to select an SG and then set sound directly from it. Useful during configuration. } else if (node.Tag is SoundGeneratorPatch) { // Create an MidiProgram that won't be assigned to any buttons. Use it to formulate a Mapping and make that the current Mapping. SoundGeneratorPatch soundGeneratorPatch = (SoundGeneratorPatch)node.Tag; MidiProgram midiProgram = new MidiProgram(); midiProgram.bSingle = true; midiProgram.SingleSoundGeneratorName = soundGeneratorPatch.soundGenerator.name; midiProgram.SinglePatchName = soundGeneratorPatch.name; // Determine the input device for this midiProgram: the tab's currently selected input device LogicalInputDevice deviceForThisMidiProgram = mapper.configuration.primaryInputDevice; if (tabControl1.SelectedTab.Tag != null && tabControl1.SelectedTab.Tag is LogicalInputDevice) { deviceForThisMidiProgram = (LogicalInputDevice)tabControl1.SelectedTab.Tag; } // Have the midiProgram flesh out its inner details midiProgram.bind(mapper.configuration.logicalInputDeviceDict, mapper.configuration.soundGenerators, mapper.configuration.mappings, deviceForThisMidiProgram); mapper.SetMapping(midiProgram.mapping); } else if (node.Tag is Mapping) { Mapping mapping = (Mapping)node.Tag; mapper.SetMapping(mapping); } } }
public bool bind() { foreach (String key in logicalInputDeviceDict.Keys) { LogicalInputDevice device = logicalInputDeviceDict[key]; if (device.bind() == false) { return(false); } } // Resolve the Primary Input Device. (If non defined, pick the first on in the dict.) if (primaryInputDeviceName == null && logicalInputDeviceDict.Count > 0) { primaryInputDeviceName = logicalInputDeviceDict.Keys.First <String>(); dirty = true; } if (logicalInputDeviceDict.ContainsKey(primaryInputDeviceName)) { primaryInputDevice = logicalInputDeviceDict[primaryInputDeviceName]; } else { MessageBox.Show("Cannot find primary logical input device by configured name " + primaryInputDeviceName); return(false); } foreach (String key in logicalOutputDeviceDict.Keys) { LogicalOutputDevice device = logicalOutputDeviceDict[key]; if (device.bind() == false) { return(false); } } foreach (String key in soundGenerators.Keys) { SoundGenerator soundGenerator = soundGenerators[key]; if (soundGenerator.bind(logicalOutputDeviceDict) == false) { return(false); } } foreach (Mapping.PerDeviceChannelMapping perDeviceChannelMapping in globalControlMappings) { perDeviceChannelMapping.bind(logicalInputDeviceDict, soundGenerators); } foreach (String key in mappings.Keys) { Mapping mapping = mappings[key]; if (mapping.bind(logicalInputDeviceDict, soundGenerators) == false) { return(false); } } foreach (int bankAndProgram in midiPrograms.Keys) { MidiProgram midiProgram = midiPrograms[bankAndProgram]; midiProgram.bind(logicalInputDeviceDict, soundGenerators, mappings, primaryInputDevice); } // Drop up any non-bound midiPrograms (ie, that point to mappings or SoundGeneratorPatches that no longer exist) List <MidiProgram> midiProgramListClone = midiPrograms.Values.ToList <MidiProgram>(); foreach (MidiProgram midiProgram in midiProgramListClone) { if (midiProgram.mapping == null) { midiPrograms.Remove(midiProgram.key); } } foreach (String songTitle in songDict.Keys) { Song song = songDict[songTitle]; song.bind(logicalInputDeviceDict, soundGenerators, mappings, primaryInputDevice); } foreach (Setlist setlist in setlists) { setlist.bind(songDict, logicalInputDeviceDict, soundGenerators, mappings, primaryInputDevice); } if (primaryControllerButtonProgramNumbers.Count == 0) { int[] casioPx3Buttons = new int[8] { 0x0, 0x4, 0x5, 0x7, 0x12, 0x30, 0x19, 0x3D }; primaryControllerButtonProgramNumbers.Add("CASIO USB-MIDI", casioPx3Buttons); } if (primaryControllerButtonProgramNumbers.ContainsKey(primaryInputDevice.device.Name)) { currentPrimaryControllerButtonProgramNumbers = primaryControllerButtonProgramNumbers[primaryInputDevice.device.Name]; } else { currentPrimaryControllerButtonProgramNumbers = new int[8] { -1, -1, -1, -1, -1, -1, -1, -1 }; } return(true); }
//-------------------------------------------------------------------------- // Insert a button into the grid, rippling down the ones below it in its column. //-------------------------------------------------------------------------- private void insertButtonIntoTableLayoutPanelProgramButtons(Button btn, TableLayoutPanelCellPosition tlpcp) { // See if there's a control there already System.Windows.Forms.Control ctl = tlpRandomAccess.GetControlFromPosition(tlpcp.Column, tlpcp.Row); // If the requested position isn't empty, we gotta make room for it first if (ctl != null) { // Remove the control in the last row (if there is one). ctl = tlpRandomAccess.GetControlFromPosition(tlpcp.Column, N_RANDOMACCESS_ROWS + FIRST_RANDOMACCESS_BTN_ROW - 1); if (ctl != null) { tlpRandomAccess.Controls.Remove(ctl); if (ctl.Tag is MidiProgram) { MidiProgram midiProgram = (MidiProgram)ctl.Tag; mapper.configuration.midiPrograms.Remove(midiProgram.key); } } // Ripple buttons down, bottom up to top for (int r = (N_RANDOMACCESS_ROWS + FIRST_RANDOMACCESS_BTN_ROW) - 1; r > tlpcp.Row; --r) { // Get the control in the row above this one ctl = tlpRandomAccess.GetControlFromPosition(tlpcp.Column, r - 1); // If there isn't one, skip it if (ctl == null) { continue; } // Remove it tlpRandomAccess.Controls.Remove(ctl); // Add it back in, down one row tlpRandomAccess.Controls.Add(ctl, tlpcp.Column, r); // If it's pointing to a midiProgram (and it should be) then fix up its program number to reflect the button's new pos Object o = ctl.Tag; if (o is MidiProgram) { MidiProgram midiProgram = (MidiProgram)o; mapper.configuration.midiPrograms.Remove(midiProgram.key); midiProgram.myPatchNumber += N_RANDOMACCESS_COLS; mapper.configuration.midiPrograms.Add(midiProgram.key, midiProgram); mapper.configuration.dirty = true; } } } // Now we can add it into the open slot tlpRandomAccess.Controls.Add(btn, tlpcp.Column, tlpcp.Row); // If it's pointing to a midiProgram (and it should be) then fix up its program number to reflect the button's new pos Object o2 = btn.Tag; if (o2 is MidiProgram) { MidiProgram midiProgram = (MidiProgram)o2; midiProgram.myPatchNumber = ((tlpcp.Row - FIRST_RANDOMACCESS_BTN_ROW) * N_RANDOMACCESS_COLS) + (tlpcp.Column - 1); mapper.configuration.midiPrograms.Add(midiProgram.key, midiProgram); } }
private void btnRandAccessCol_DragDrop(object sender, DragEventArgs e) { Console.WriteLine("btnRandAccessCol DragDrop: " + e); if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false)) { // Figure out the table layout panel column of heading button that this TreeNode got dropped onto int col = tlpRandomAccess.GetColumn((System.Windows.Forms.Control)sender); // Find the first unoccupied row in that column int row; for (row = 0; row < N_RANDOMACCESS_ROWS; ++row) { if (tlpRandomAccess.GetControlFromPosition(col, row + FIRST_RANDOMACCESS_BTN_ROW) == null) { break; } } if (row == N_RANDOMACCESS_ROWS) { MessageBox.Show("No room in this column"); return; } // Get the dropped node TreeNode droppedNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode"); // Get the SoundGeneratorPatch or Mapping that it points to Object o = droppedNode.Tag; // Create a new midiProgram to capture the action of the random access button we're about to create MidiProgram midiProgram; // Initialize the midiProgram appropriately, depending on whether there was a SoundGeneratorPatch or a Mapping in the droppped TreeNode if (o is SoundGeneratorPatch) { midiProgram = new MidiProgram((SoundGeneratorPatch)o); } else if (o is Mapping) { midiProgram = new MidiProgram((Mapping)o); } else { return; } // Determine the input device for this midiProgram: the tab's currently selected input device LogicalInputDevice deviceForThisMidiProgram = mapper.configuration.primaryInputDevice; if (tabControl1.SelectedTab.Tag != null && tabControl1.SelectedTab.Tag is LogicalInputDevice) { deviceForThisMidiProgram = (LogicalInputDevice)tabControl1.SelectedTab.Tag; } // Have the midiProgram flesh out its inner details midiProgram.bind(mapper.configuration.logicalInputDeviceDict, mapper.configuration.soundGenerators, mapper.configuration.mappings, deviceForThisMidiProgram); // Assign this Midi Program a patch number based on where it was dropped in the button matrix. midiProgram.myPatchNumber = (row * N_RANDOMACCESS_COLS) + col - FIRST_RANDOMACCESS_BTN_COL; // Assign it a bank number based on which Random Access page it's dropped on (which is captured in currentRandomAccessBank) midiProgram.myBankNumber = currentRandomAccessBank; // Add the newly created midiProgram to the master dictionary of such things. Mark config as dirty so this change gets saved on close. mapper.configuration.midiPrograms.Add(midiProgram.key, midiProgram); mapper.configuration.dirty = true; // Create a new button for this sound generator patch Button btn = new Button(); btn.Font = buttonFont; btn.Text = midiProgram.mapping.name; btn.BackColor = System.Drawing.Color.DimGray; btn.ForeColor = System.Drawing.Color.White; btn.FlatStyle = System.Windows.Forms.FlatStyle.Flat; btn.FlatAppearance.BorderColor = System.Drawing.Color.LightGreen; btn.Visible = true; btn.Dock = DockStyle.Fill; btn.MouseDown += btnPrograms_MouseDown; btn.ContextMenuStrip = this.contextMenuStrip1; btn.Tag = midiProgram; midiProgram.activationButton = btn; btn.Click += new System.EventHandler(this.btnProgramChange_Click); // And add it to the table layout panel in the designated spot. tlpRandomAccess.Controls.Add(btn, col, row + FIRST_RANDOMACCESS_BTN_ROW); } }