diff --git a/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.Designer.cs b/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.Designer.cs index 885b5da..527cefa 100644 --- a/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.Designer.cs +++ b/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.Designer.cs @@ -42,7 +42,6 @@ private void InitializeComponent() this.openFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.saveFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.groupBoxDefineStimuli = new System.Windows.Forms.GroupBox(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.panelWaveform = new System.Windows.Forms.Panel(); this.tabControlVisualization = new System.Windows.Forms.TabControl(); @@ -51,8 +50,12 @@ private void InitializeComponent() this.tabPageTable = new System.Windows.Forms.TabPage(); this.dataGridViewStimulusTable = new System.Windows.Forms.DataGridView(); this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); - this.button1 = new System.Windows.Forms.Button(); + this.buttonResetZoom = new System.Windows.Forms.Button(); + this.tabControlProperties = new System.Windows.Forms.TabControl(); + this.tabPageDefineStimuli = new System.Windows.Forms.TabPage(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.tabPageProperties = new System.Windows.Forms.TabPage(); + this.propertyGrid = new System.Windows.Forms.PropertyGrid(); this.statusStrip.SuspendLayout(); this.menuStrip.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); @@ -63,6 +66,8 @@ private void InitializeComponent() this.tabPageTable.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridViewStimulusTable)).BeginInit(); this.flowLayoutPanel2.SuspendLayout(); + this.tabControlProperties.SuspendLayout(); + this.tabPageProperties.SuspendLayout(); this.SuspendLayout(); // // buttonCancel @@ -178,11 +183,11 @@ private void InitializeComponent() this.tableLayoutPanel1.ColumnCount = 2; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 451F)); - this.tableLayoutPanel1.Controls.Add(this.groupBoxDefineStimuli, 1, 1); this.tableLayoutPanel1.Controls.Add(this.panelProbe, 1, 0); this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 3); this.tableLayoutPanel1.Controls.Add(this.panelWaveform, 0, 0); this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.tabControlProperties, 1, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); @@ -195,19 +200,6 @@ private void InitializeComponent() this.tableLayoutPanel1.Size = new System.Drawing.Size(1146, 563); this.tableLayoutPanel1.TabIndex = 8; // - // groupBoxDefineStimuli - // - this.groupBoxDefineStimuli.Dock = System.Windows.Forms.DockStyle.Fill; - this.groupBoxDefineStimuli.Location = new System.Drawing.Point(698, 173); - this.groupBoxDefineStimuli.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.groupBoxDefineStimuli.Name = "groupBoxDefineStimuli"; - this.groupBoxDefineStimuli.Padding = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.tableLayoutPanel1.SetRowSpan(this.groupBoxDefineStimuli, 2); - this.groupBoxDefineStimuli.Size = new System.Drawing.Size(445, 346); - this.groupBoxDefineStimuli.TabIndex = 0; - this.groupBoxDefineStimuli.TabStop = false; - this.groupBoxDefineStimuli.Text = "Define Stimuli"; - // // flowLayoutPanel1 // this.tableLayoutPanel1.SetColumnSpan(this.flowLayoutPanel1, 2); @@ -300,24 +292,66 @@ private void InitializeComponent() // // flowLayoutPanel2 // - this.flowLayoutPanel2.Controls.Add(this.button1); + this.flowLayoutPanel2.Controls.Add(this.buttonResetZoom); this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.flowLayoutPanel2.Location = new System.Drawing.Point(3, 482); this.flowLayoutPanel2.Name = "flowLayoutPanel2"; this.flowLayoutPanel2.Size = new System.Drawing.Size(689, 36); this.flowLayoutPanel2.TabIndex = 9; // - // button1 - // - this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button1.Location = new System.Drawing.Point(3, 2); - this.button1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(144, 32); - this.button1.TabIndex = 5; - this.button1.Text = "Reset Zoom"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.ResetZoom_Click); + // buttonResetZoom + // + this.buttonResetZoom.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonResetZoom.Location = new System.Drawing.Point(3, 2); + this.buttonResetZoom.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.buttonResetZoom.Name = "buttonResetZoom"; + this.buttonResetZoom.Size = new System.Drawing.Size(144, 32); + this.buttonResetZoom.TabIndex = 5; + this.buttonResetZoom.Text = "Reset Zoom"; + this.buttonResetZoom.UseVisualStyleBackColor = true; + this.buttonResetZoom.Click += new System.EventHandler(this.ResetZoom_Click); + // + // tabControlProperties + // + this.tabControlProperties.Controls.Add(this.tabPageDefineStimuli); + this.tabControlProperties.Controls.Add(this.tabPageProperties); + this.tabControlProperties.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlProperties.Location = new System.Drawing.Point(698, 174); + this.tabControlProperties.Name = "tabControlProperties"; + this.tableLayoutPanel1.SetRowSpan(this.tabControlProperties, 2); + this.tabControlProperties.SelectedIndex = 0; + this.tabControlProperties.Size = new System.Drawing.Size(445, 344); + this.tabControlProperties.TabIndex = 10; + // + // tabPageDefineStimuli + // + this.tabPageDefineStimuli.Location = new System.Drawing.Point(4, 25); + this.tabPageDefineStimuli.Name = "tabPageDefineStimuli"; + this.tabPageDefineStimuli.Padding = new System.Windows.Forms.Padding(3); + this.tabPageDefineStimuli.Size = new System.Drawing.Size(437, 315); + this.tabPageDefineStimuli.TabIndex = 0; + this.tabPageDefineStimuli.Text = "Define Stimuli"; + this.tabPageDefineStimuli.UseVisualStyleBackColor = true; + // + // tabPageProperties + // + this.tabPageProperties.Controls.Add(this.propertyGrid); + this.tabPageProperties.Location = new System.Drawing.Point(4, 25); + this.tabPageProperties.Name = "tabPageProperties"; + this.tabPageProperties.Padding = new System.Windows.Forms.Padding(3); + this.tabPageProperties.Size = new System.Drawing.Size(437, 315); + this.tabPageProperties.TabIndex = 1; + this.tabPageProperties.Text = "Properties"; + this.tabPageProperties.UseVisualStyleBackColor = true; + // + // propertyGrid + // + this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.propertyGrid.Location = new System.Drawing.Point(3, 3); + this.propertyGrid.Name = "propertyGrid"; + this.propertyGrid.Size = new System.Drawing.Size(431, 309); + this.propertyGrid.TabIndex = 0; + this.propertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyValueChanged); // // GenericStimulusSequenceDialog // @@ -348,6 +382,8 @@ private void InitializeComponent() this.tabPageTable.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.dataGridViewStimulusTable)).EndInit(); this.flowLayoutPanel2.ResumeLayout(false); + this.tabControlProperties.ResumeLayout(false); + this.tabPageProperties.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -367,7 +403,6 @@ private void InitializeComponent() private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - internal System.Windows.Forms.GroupBox groupBoxDefineStimuli; private System.Windows.Forms.Panel panelWaveform; private ZedGraph.ZedGraphControl zedGraphWaveform; private System.Windows.Forms.TabControl tabControlVisualization; @@ -376,6 +411,10 @@ private void InitializeComponent() internal System.Windows.Forms.DataGridView dataGridViewStimulusTable; internal System.Windows.Forms.ToolStripMenuItem stimulusWaveformToolStripMenuItem; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; - private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button buttonResetZoom; + private System.Windows.Forms.TabControl tabControlProperties; + internal System.Windows.Forms.TabPage tabPageDefineStimuli; + internal System.Windows.Forms.TabPage tabPageProperties; + internal System.Windows.Forms.PropertyGrid propertyGrid; } } diff --git a/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.cs index 4176c06..4260114 100644 --- a/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/GenericStimulusSequenceDialog.cs @@ -12,6 +12,12 @@ namespace OpenEphys.Onix1.Design /// public partial class GenericStimulusSequenceDialog : Form { + internal object Device + { + get => propertyGrid.SelectedObject; + set => propertyGrid.SelectedObject = value; + } + readonly int NumberOfChannels; readonly bool UseProbeGroup; readonly bool UseTable; @@ -29,13 +35,16 @@ public partial class GenericStimulusSequenceDialog : Form } /// - /// Opens a dialog allowing for easy changing of stimulus sequence parameters, with visual feedback on what the resulting stimulus sequence looks like. + /// Opens a dialog allowing for easy changing of stimulus sequence parameters, + /// with visual feedback on what the resulting stimulus sequence looks like. /// - public GenericStimulusSequenceDialog(int numberOfChannels, bool useProbeGroup, bool useTable = false) + public GenericStimulusSequenceDialog(object device, int numberOfChannels, bool useProbeGroup, bool useTable = false) { InitializeComponent(); Shown += FormShown; + Device = device; + NumberOfChannels = numberOfChannels; UseProbeGroup = useProbeGroup; UseTable = useTable; @@ -43,9 +52,9 @@ public GenericStimulusSequenceDialog(int numberOfChannels, bool useProbeGroup, b if (!UseProbeGroup) { tableLayoutPanel1.Controls.Remove(panelProbe); - GroupBox gb = tableLayoutPanel1.Controls[nameof(groupBoxDefineStimuli)] as GroupBox; - tableLayoutPanel1.SetRow(gb, 0); - tableLayoutPanel1.SetRowSpan(gb, 2); + var control = tableLayoutPanel1.Controls[nameof(tabControlProperties)] as TabControl; + tableLayoutPanel1.SetRow(control, 0); + tableLayoutPanel1.SetRowSpan(control, 3); } if (!UseTable) @@ -524,5 +533,12 @@ void ResetZoom() zedGraphWaveform.Refresh(); } + void PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + var propertyGrid = (PropertyGrid)s; + UpdateControls(propertyGrid.SelectedObject); + } + + internal virtual void UpdateControls(object obj) { throw new NotImplementedException(); } } } diff --git a/OpenEphys.Onix1.Design/Headstage64Dialog.Designer.cs b/OpenEphys.Onix1.Design/Headstage64Dialog.Designer.cs index 1b64c41..f267278 100644 --- a/OpenEphys.Onix1.Design/Headstage64Dialog.Designer.cs +++ b/OpenEphys.Onix1.Design/Headstage64Dialog.Designer.cs @@ -97,7 +97,7 @@ private void InitializeComponent() this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.Click += new System.EventHandler(this.OnClickOk); // - // tabControl + // tabControlProperties // this.tabControl.Controls.Add(this.tabPageElectricalStimulator); this.tabControl.Controls.Add(this.tabPageOpticalStimulator); @@ -107,7 +107,7 @@ private void InitializeComponent() this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl.Location = new System.Drawing.Point(3, 2); this.tabControl.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.tabControl.Name = "tabControl"; + this.tabControl.Name = "tabControlProperties"; this.tabControl.SelectedIndex = 0; this.tabControl.Size = new System.Drawing.Size(1178, 541); this.tabControl.TabIndex = 1; diff --git a/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorOptions.cs b/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorOptions.cs index d596855..e783ce0 100644 --- a/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorOptions.cs +++ b/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorOptions.cs @@ -21,6 +21,11 @@ public Headstage64ElectricalStimulatorOptions() /// public Headstage64ElectricalStimulatorOptions(ConfigureHeadstage64ElectricalStimulator electricalStimulator) : this() + { + UpdateControls(electricalStimulator); + } + + internal void UpdateControls(ConfigureHeadstage64ElectricalStimulator electricalStimulator) { textBoxPhaseOneCurrent.Text = electricalStimulator.PhaseOneCurrent.ToString(); textBoxPhaseOneDuration.Text = electricalStimulator.PhaseOneDuration.ToString(); diff --git a/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorSequenceDialog.cs b/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorSequenceDialog.cs index c5b749f..3068ab3 100644 --- a/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Headstage64ElectricalStimulatorSequenceDialog.cs @@ -12,7 +12,10 @@ namespace OpenEphys.Onix1.Design /// public partial class Headstage64ElectricalStimulatorSequenceDialog : GenericStimulusSequenceDialog { - internal readonly ConfigureHeadstage64ElectricalStimulator ElectricalStimulator; + internal ConfigureHeadstage64ElectricalStimulator ElectricalStimulator + { + get => (ConfigureHeadstage64ElectricalStimulator)Device; + } readonly Headstage64ElectricalStimulatorOptions StimulusSequenceOptions; readonly static int NumberOfChannels = 1; @@ -27,16 +30,16 @@ public partial class Headstage64ElectricalStimulatorSequenceDialog : GenericStim /// /// Existing stimulus sequence. public Headstage64ElectricalStimulatorSequenceDialog(ConfigureHeadstage64ElectricalStimulator electricalStimulator) - : base(NumberOfChannels, false) + : base(new ConfigureHeadstage64ElectricalStimulator(electricalStimulator), NumberOfChannels, false) { InitializeComponent(); HideMenuStrip(); - ElectricalStimulator = new(electricalStimulator); - StimulusSequenceOptions = new(ElectricalStimulator); StimulusSequenceOptions.SetChildFormProperties(this); - groupBoxDefineStimuli.Controls.Add(StimulusSequenceOptions); + tabPageDefineStimuli.Controls.Add(StimulusSequenceOptions); + + void refreshPropertyGrid() => propertyGrid.Refresh(); currentBindings = new() { @@ -44,17 +47,20 @@ public Headstage64ElectricalStimulatorSequenceDialog(ConfigureHeadstage64Electri new TextBoxBinding( StimulusSequenceOptions.textBoxPhaseOneCurrent, value => { ElectricalStimulator.PhaseOneCurrent = value; return ElectricalStimulator.PhaseOneCurrent; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxInterPhaseCurrent, new TextBoxBinding( StimulusSequenceOptions.textBoxInterPhaseCurrent, value => { ElectricalStimulator.InterPhaseCurrent = value; return ElectricalStimulator.InterPhaseCurrent; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxPhaseTwoCurrent, new TextBoxBinding( StimulusSequenceOptions.textBoxPhaseTwoCurrent, value => { ElectricalStimulator.PhaseTwoCurrent = value; return ElectricalStimulator.PhaseTwoCurrent; }, - double.Parse) } + double.Parse, + onChanged: refreshPropertyGrid) } }; timeBindings = new Dictionary> @@ -63,32 +69,38 @@ public Headstage64ElectricalStimulatorSequenceDialog(ConfigureHeadstage64Electri new TextBoxBinding( StimulusSequenceOptions.textBoxPhaseOneDuration, value => { ElectricalStimulator.PhaseOneDuration = value; return ElectricalStimulator.PhaseOneDuration; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxPhaseTwoDuration, new TextBoxBinding( StimulusSequenceOptions.textBoxPhaseTwoDuration, value => { ElectricalStimulator.PhaseTwoDuration = value; return ElectricalStimulator.PhaseTwoDuration; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxInterPhaseDuration, new TextBoxBinding( StimulusSequenceOptions.textBoxInterPhaseDuration, value => { ElectricalStimulator.InterPhaseInterval = value; return ElectricalStimulator.InterPhaseInterval; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxInterBurstInterval, new TextBoxBinding( StimulusSequenceOptions.textBoxInterBurstInterval, value => { ElectricalStimulator.InterBurstInterval = value; return ElectricalStimulator.InterBurstInterval; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxPulsePeriod, new TextBoxBinding( StimulusSequenceOptions.textBoxPulsePeriod, value => { ElectricalStimulator.InterPulseInterval = value; return ElectricalStimulator.InterPulseInterval; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxTrainDelay, new TextBoxBinding( StimulusSequenceOptions.textBoxTrainDelay, value => { ElectricalStimulator.TriggerDelay = value; return ElectricalStimulator.TriggerDelay; }, - uint.Parse) } + uint.Parse, + onChanged: refreshPropertyGrid) } }; countBindings = new Dictionary> @@ -97,12 +109,14 @@ public Headstage64ElectricalStimulatorSequenceDialog(ConfigureHeadstage64Electri new TextBoxBinding( StimulusSequenceOptions.textBoxBurstPulseCount, value => { ElectricalStimulator.BurstPulseCount = value; return ElectricalStimulator.BurstPulseCount; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxTrainBurstCount, new TextBoxBinding( StimulusSequenceOptions.textBoxTrainBurstCount, value => { ElectricalStimulator.TrainBurstCount = value; return ElectricalStimulator.TrainBurstCount; }, - uint.Parse) } + uint.Parse, + onChanged: refreshPropertyGrid) } }; foreach (var binding in currentBindings) @@ -157,7 +171,6 @@ void TextBoxChanged(object sender, EventArgs e) throw new Exception($"No valid text box found when updating parameters in {nameof(Headstage64ElectricalStimulatorSequenceDialog)}"); } - SetStatusValidity(); DrawStimulusWaveform(); } } @@ -325,5 +338,12 @@ internal override void SetStatusValidity() toolStripStatusIsValid.Text = "Warning: " + reason; } } + + internal override void UpdateControls(object obj) + { + StimulusSequenceOptions.UpdateControls((ConfigureHeadstage64ElectricalStimulator)obj); + + DrawStimulusWaveform(); + } } } diff --git a/OpenEphys.Onix1.Design/Headstage64OpticalStimulatorSequenceDialog.cs b/OpenEphys.Onix1.Design/Headstage64OpticalStimulatorSequenceDialog.cs index 6661149..cc55997 100644 --- a/OpenEphys.Onix1.Design/Headstage64OpticalStimulatorSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Headstage64OpticalStimulatorSequenceDialog.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.IO; using System.Linq; using System.Windows.Forms; using ZedGraph; @@ -15,7 +14,10 @@ public partial class Headstage64OpticalStimulatorSequenceDialog : GenericStimulu { readonly static int NumberOfChannels = 2; - internal readonly ConfigureHeadstage64OpticalStimulator OpticalStimulator; + internal ConfigureHeadstage64OpticalStimulator OpticalStimulator + { + get => (ConfigureHeadstage64OpticalStimulator)Device; + } readonly Headstage64OpticalStimulatorOptions StimulusSequenceOptions; readonly Dictionary> currentBindings; @@ -28,27 +30,28 @@ public partial class Headstage64OpticalStimulatorSequenceDialog : GenericStimulu /// /// Existing stimulus sequence. public Headstage64OpticalStimulatorSequenceDialog(ConfigureHeadstage64OpticalStimulator opticalStimulator) - : base(NumberOfChannels, false) + : base(new ConfigureHeadstage64OpticalStimulator(opticalStimulator), NumberOfChannels, false) { InitializeComponent(); HideMenuStrip(); - OpticalStimulator = new(opticalStimulator); - StimulusSequenceOptions = new(OpticalStimulator); StimulusSequenceOptions.SetChildFormProperties(this); - groupBoxDefineStimuli.Controls.Add(StimulusSequenceOptions); + tabPageDefineStimuli.Controls.Add(StimulusSequenceOptions); StimulusSequenceOptions.trackBarChannelOnePercent.Scroll += ChannelPercentTrackBarChanged; StimulusSequenceOptions.trackBarChannelTwoPercent.Scroll += ChannelPercentTrackBarChanged; + void refreshPropertyGrid() => propertyGrid.Refresh(); + currentBindings = new() { { StimulusSequenceOptions.textBoxMaxCurrent, new TextBoxBinding( StimulusSequenceOptions.textBoxMaxCurrent, value => { OpticalStimulator.MaxCurrent = value; return OpticalStimulator.MaxCurrent; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxChannelOnePercent, new TextBoxBinding( StimulusSequenceOptions.textBoxChannelOnePercent, @@ -58,7 +61,8 @@ public Headstage64OpticalStimulatorSequenceDialog(ConfigureHeadstage64OpticalSti StimulusSequenceOptions.trackBarChannelOnePercent.Value = (int)(OpticalStimulator.ChannelOneCurrent * StimulusSequenceOptions.channelOneScalingFactor); return OpticalStimulator.ChannelOneCurrent; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxChannelTwoPercent, new TextBoxBinding( StimulusSequenceOptions.textBoxChannelTwoPercent, @@ -68,7 +72,8 @@ public Headstage64OpticalStimulatorSequenceDialog(ConfigureHeadstage64OpticalSti StimulusSequenceOptions.trackBarChannelTwoPercent.Value = (int)(OpticalStimulator.ChannelTwoCurrent * StimulusSequenceOptions.channelTwoScalingFactor); return OpticalStimulator.ChannelTwoCurrent; }, - double.Parse) } + double.Parse, + onChanged: refreshPropertyGrid) } }; timeBindings = new() @@ -77,22 +82,26 @@ public Headstage64OpticalStimulatorSequenceDialog(ConfigureHeadstage64OpticalSti new TextBoxBinding( StimulusSequenceOptions.textBoxInterBurstInterval, value => { OpticalStimulator.InterBurstInterval = value; return OpticalStimulator.InterBurstInterval; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxDelay, new TextBoxBinding( StimulusSequenceOptions.textBoxDelay, value => { OpticalStimulator.Delay = value; return OpticalStimulator.Delay; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxPulseDuration, new TextBoxBinding( StimulusSequenceOptions.textBoxPulseDuration, value => { OpticalStimulator.PulseDuration = value; return OpticalStimulator.PulseDuration; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxPulsePeriod, new TextBoxBinding( StimulusSequenceOptions.textBoxPulsePeriod, value => { OpticalStimulator.PulsesPerSecond = value; return OpticalStimulator.PulsesPerSecond; }, - double.Parse) }, + double.Parse, + onChanged: refreshPropertyGrid) }, }; countBindings = new() @@ -101,12 +110,14 @@ public Headstage64OpticalStimulatorSequenceDialog(ConfigureHeadstage64OpticalSti new TextBoxBinding( StimulusSequenceOptions.textBoxPulsesPerBurst, value => { OpticalStimulator.PulsesPerBurst = value; return OpticalStimulator.PulsesPerBurst; }, - uint.Parse) }, + uint.Parse, + onChanged: refreshPropertyGrid) }, { StimulusSequenceOptions.textBoxBurstsPerTrain, new TextBoxBinding( StimulusSequenceOptions.textBoxBurstsPerTrain, value => { OpticalStimulator.BurstsPerTrain = value; return OpticalStimulator.BurstsPerTrain; }, - uint.Parse) } + uint.Parse, + onChanged: refreshPropertyGrid) } }; foreach (var binding in currentBindings) @@ -196,6 +207,8 @@ void ChannelPercentTrackBarChanged(object sender, EventArgs eventArgs) throw new NotImplementedException($"Could not find a valid track bar when updating parameters in {nameof(Headstage64OpticalStimulatorSequenceDialog)}"); } + propertyGrid.Refresh(); + DrawStimulusWaveform(); } } @@ -305,5 +318,12 @@ internal override void SetStatusValidity() toolStripStatusIsValid.Text = "Warning: " + reason; } } + + internal override void UpdateControls(object obj) + { + StimulusSequenceOptions.UpdateSequenceParameters((ConfigureHeadstage64OpticalStimulator)obj); + + DrawStimulusWaveform(); + } } } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV1Dialog.cs b/OpenEphys.Onix1.Design/NeuropixelsV1Dialog.cs index f41b672..84c1231 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV1Dialog.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV1Dialog.cs @@ -14,7 +14,11 @@ public partial class NeuropixelsV1Dialog : Form /// Public interface that is manipulated by /// . /// - public IConfigureNeuropixelsV1 ConfigureNode { get; set; } + public IConfigureNeuropixelsV1 ConfigureNode + { + get => (IConfigureNeuropixelsV1)ProbeConfigurationDialog.propertyGrid.SelectedObject; + set => ProbeConfigurationDialog.propertyGrid.SelectedObject = value; + } /// /// Initializes a new instance of . @@ -25,24 +29,8 @@ public NeuropixelsV1Dialog(IConfigureNeuropixelsV1 configureNode) InitializeComponent(); Shown += FormShown; - if (configureNode is ConfigureNeuropixelsV1e configureV1e) - { - ConfigureNode = new ConfigureNeuropixelsV1e(configureV1e); - } - else if (configureNode is ConfigureNeuropixelsV1f configureV1f) - { - ConfigureNode = new ConfigureNeuropixelsV1f(configureV1f); - } - - ProbeConfigurationDialog = new(ConfigureNode.ProbeConfiguration, ConfigureNode.AdcCalibrationFile, ConfigureNode.GainCalibrationFile, ConfigureNode.InvertPolarity) - { - TopLevel = false, - FormBorderStyle = FormBorderStyle.None, - Dock = DockStyle.Fill, - Parent = this - }; - - panelProbe.Controls.Add(ProbeConfigurationDialog); + ProbeConfigurationDialog = new(configureNode); + ProbeConfigurationDialog.SetChildFormProperties(this).AddDialogToPanel(panelProbe); this.AddMenuItemsFromDialogToFileOption(ProbeConfigurationDialog); } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.Designer.cs b/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.Designer.cs index fa2edd5..650d1ec 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.Designer.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.Designer.cs @@ -53,6 +53,10 @@ private void InitializeComponent() this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.buttonCancel = new System.Windows.Forms.Button(); this.buttonOkay = new System.Windows.Forms.Button(); + this.panelTrackBar = new System.Windows.Forms.Panel(); + this.trackBarProbePosition = new System.Windows.Forms.TrackBar(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPageConfiguration = new System.Windows.Forms.TabPage(); this.panelOptions = new System.Windows.Forms.Panel(); this.checkBoxInvertPolarity = new System.Windows.Forms.CheckBox(); this.textBoxLfpCorrection = new System.Windows.Forms.TextBox(); @@ -69,8 +73,8 @@ private void InitializeComponent() this.comboBoxReference = new System.Windows.Forms.ComboBox(); this.comboBoxLfpGain = new System.Windows.Forms.ComboBox(); this.comboBoxApGain = new System.Windows.Forms.ComboBox(); - this.panelTrackBar = new System.Windows.Forms.Panel(); - this.trackBarProbePosition = new System.Windows.Forms.TrackBar(); + this.tabPageProperties = new System.Windows.Forms.TabPage(); + this.propertyGrid = new System.Windows.Forms.PropertyGrid(); label4 = new System.Windows.Forms.Label(); label2 = new System.Windows.Forms.Label(); labelPresets = new System.Windows.Forms.Label(); @@ -85,9 +89,12 @@ private void InitializeComponent() this.menuStrip.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout(); - this.panelOptions.SuspendLayout(); this.panelTrackBar.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.trackBarProbePosition)).BeginInit(); + this.tabControl1.SuspendLayout(); + this.tabPageConfiguration.SuspendLayout(); + this.panelOptions.SuspendLayout(); + this.tabPageProperties.SuspendLayout(); this.SuspendLayout(); // // label4 @@ -255,8 +262,8 @@ private void InitializeComponent() this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 315F)); this.tableLayoutPanel1.Controls.Add(this.panelProbe, 0, 0); this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.panelOptions, 2, 0); this.tableLayoutPanel1.Controls.Add(this.panelTrackBar, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.tabControl1, 2, 0); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4); @@ -312,6 +319,55 @@ private void InitializeComponent() this.buttonOkay.Text = "OK"; this.buttonOkay.UseVisualStyleBackColor = true; // + // panelTrackBar + // + this.panelTrackBar.Controls.Add(this.trackBarProbePosition); + this.panelTrackBar.Location = new System.Drawing.Point(868, 4); + this.panelTrackBar.Margin = new System.Windows.Forms.Padding(4); + this.panelTrackBar.Name = "panelTrackBar"; + this.panelTrackBar.Size = new System.Drawing.Size(47, 662); + this.panelTrackBar.TabIndex = 33; + // + // trackBarProbePosition + // + this.trackBarProbePosition.AutoSize = false; + this.trackBarProbePosition.BackColor = System.Drawing.SystemColors.Control; + this.trackBarProbePosition.Dock = System.Windows.Forms.DockStyle.Fill; + this.trackBarProbePosition.Location = new System.Drawing.Point(0, 0); + this.trackBarProbePosition.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.trackBarProbePosition.Maximum = 100; + this.trackBarProbePosition.Name = "trackBarProbePosition"; + this.trackBarProbePosition.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trackBarProbePosition.Size = new System.Drawing.Size(47, 662); + this.trackBarProbePosition.TabIndex = 30; + this.trackBarProbePosition.TabStop = false; + this.trackBarProbePosition.TickFrequency = 2; + this.trackBarProbePosition.TickStyle = System.Windows.Forms.TickStyle.TopLeft; + this.trackBarProbePosition.Value = 50; + this.trackBarProbePosition.Scroll += new System.EventHandler(this.TrackBarScroll); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPageConfiguration); + this.tabControl1.Controls.Add(this.tabPageProperties); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(922, 3); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(309, 664); + this.tabControl1.TabIndex = 34; + // + // tabPageConfiguration + // + this.tabPageConfiguration.Controls.Add(this.panelOptions); + this.tabPageConfiguration.Location = new System.Drawing.Point(4, 25); + this.tabPageConfiguration.Name = "tabPageConfiguration"; + this.tabPageConfiguration.Padding = new System.Windows.Forms.Padding(3); + this.tabPageConfiguration.Size = new System.Drawing.Size(301, 635); + this.tabPageConfiguration.TabIndex = 0; + this.tabPageConfiguration.Text = "Configuration"; + this.tabPageConfiguration.UseVisualStyleBackColor = true; + // // panelOptions // this.panelOptions.BackColor = System.Drawing.SystemColors.ControlLightLight; @@ -341,10 +397,10 @@ private void InitializeComponent() this.panelOptions.Controls.Add(this.comboBoxApGain); this.panelOptions.Controls.Add(apGain); this.panelOptions.Dock = System.Windows.Forms.DockStyle.Fill; - this.panelOptions.Location = new System.Drawing.Point(922, 2); + this.panelOptions.Location = new System.Drawing.Point(3, 3); this.panelOptions.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.panelOptions.Name = "panelOptions"; - this.panelOptions.Size = new System.Drawing.Size(309, 666); + this.panelOptions.Size = new System.Drawing.Size(295, 629); this.panelOptions.TabIndex = 2; // // checkBoxInvertPolarity @@ -366,7 +422,7 @@ private void InitializeComponent() this.textBoxLfpCorrection.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.textBoxLfpCorrection.Name = "textBoxLfpCorrection"; this.textBoxLfpCorrection.ReadOnly = true; - this.textBoxLfpCorrection.Size = new System.Drawing.Size(195, 22); + this.textBoxLfpCorrection.Size = new System.Drawing.Size(181, 22); this.textBoxLfpCorrection.TabIndex = 14; this.textBoxLfpCorrection.TabStop = false; // @@ -378,7 +434,7 @@ private void InitializeComponent() this.textBoxApCorrection.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.textBoxApCorrection.Name = "textBoxApCorrection"; this.textBoxApCorrection.ReadOnly = true; - this.textBoxApCorrection.Size = new System.Drawing.Size(195, 22); + this.textBoxApCorrection.Size = new System.Drawing.Size(181, 22); this.textBoxApCorrection.TabIndex = 10; this.textBoxApCorrection.TabStop = false; // @@ -387,10 +443,10 @@ private void InitializeComponent() this.buttonViewAdcs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.buttonViewAdcs.Enabled = false; - this.buttonViewAdcs.Location = new System.Drawing.Point(13, 66); + this.buttonViewAdcs.Location = new System.Drawing.Point(12, 66); this.buttonViewAdcs.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonViewAdcs.Name = "buttonViewAdcs"; - this.buttonViewAdcs.Size = new System.Drawing.Size(284, 38); + this.buttonViewAdcs.Size = new System.Drawing.Size(270, 38); this.buttonViewAdcs.TabIndex = 3; this.buttonViewAdcs.Text = "View ADC Correction Values"; this.buttonViewAdcs.UseVisualStyleBackColor = true; @@ -399,7 +455,7 @@ private void InitializeComponent() // buttonChooseAdcCalibrationFile // this.buttonChooseAdcCalibrationFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonChooseAdcCalibrationFile.Location = new System.Drawing.Point(260, 30); + this.buttonChooseAdcCalibrationFile.Location = new System.Drawing.Point(245, 30); this.buttonChooseAdcCalibrationFile.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonChooseAdcCalibrationFile.Name = "buttonChooseAdcCalibrationFile"; this.buttonChooseAdcCalibrationFile.Size = new System.Drawing.Size(37, 25); @@ -411,7 +467,7 @@ private void InitializeComponent() // buttonChooseGainCalibrationFile // this.buttonChooseGainCalibrationFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonChooseGainCalibrationFile.Location = new System.Drawing.Point(260, 133); + this.buttonChooseGainCalibrationFile.Location = new System.Drawing.Point(245, 133); this.buttonChooseGainCalibrationFile.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonChooseGainCalibrationFile.Name = "buttonChooseGainCalibrationFile"; this.buttonChooseGainCalibrationFile.Size = new System.Drawing.Size(37, 25); @@ -427,7 +483,7 @@ private void InitializeComponent() this.buttonEnableContacts.Location = new System.Drawing.Point(13, 464); this.buttonEnableContacts.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonEnableContacts.Name = "buttonEnableContacts"; - this.buttonEnableContacts.Size = new System.Drawing.Size(283, 44); + this.buttonEnableContacts.Size = new System.Drawing.Size(269, 44); this.buttonEnableContacts.TabIndex = 23; this.buttonEnableContacts.Text = "Enable Selected Electrodes"; this.buttonEnableContacts.UseVisualStyleBackColor = true; @@ -440,7 +496,7 @@ private void InitializeComponent() this.buttonClearSelections.Location = new System.Drawing.Point(13, 512); this.buttonClearSelections.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonClearSelections.Name = "buttonClearSelections"; - this.buttonClearSelections.Size = new System.Drawing.Size(283, 44); + this.buttonClearSelections.Size = new System.Drawing.Size(269, 44); this.buttonClearSelections.TabIndex = 24; this.buttonClearSelections.Text = "Clear Electrode Selection"; this.buttonClearSelections.UseVisualStyleBackColor = true; @@ -455,7 +511,7 @@ private void InitializeComponent() this.comboBoxChannelPresets.Location = new System.Drawing.Point(101, 411); this.comboBoxChannelPresets.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.comboBoxChannelPresets.Name = "comboBoxChannelPresets"; - this.comboBoxChannelPresets.Size = new System.Drawing.Size(195, 24); + this.comboBoxChannelPresets.Size = new System.Drawing.Size(181, 24); this.comboBoxChannelPresets.TabIndex = 22; // // checkBoxSpikeFilter @@ -476,7 +532,7 @@ private void InitializeComponent() this.textBoxAdcCalibrationFile.Location = new System.Drawing.Point(13, 30); this.textBoxAdcCalibrationFile.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.textBoxAdcCalibrationFile.Name = "textBoxAdcCalibrationFile"; - this.textBoxAdcCalibrationFile.Size = new System.Drawing.Size(241, 22); + this.textBoxAdcCalibrationFile.Size = new System.Drawing.Size(226, 22); this.textBoxAdcCalibrationFile.TabIndex = 1; this.textBoxAdcCalibrationFile.TabStop = false; this.textBoxAdcCalibrationFile.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; @@ -490,7 +546,7 @@ private void InitializeComponent() this.textBoxGainCalibrationFile.Location = new System.Drawing.Point(13, 133); this.textBoxGainCalibrationFile.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.textBoxGainCalibrationFile.Name = "textBoxGainCalibrationFile"; - this.textBoxGainCalibrationFile.Size = new System.Drawing.Size(241, 22); + this.textBoxGainCalibrationFile.Size = new System.Drawing.Size(226, 22); this.textBoxGainCalibrationFile.TabIndex = 5; this.textBoxGainCalibrationFile.TabStop = false; this.textBoxGainCalibrationFile.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; @@ -506,7 +562,7 @@ private void InitializeComponent() this.comboBoxReference.Location = new System.Drawing.Point(101, 373); this.comboBoxReference.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.comboBoxReference.Name = "comboBoxReference"; - this.comboBoxReference.Size = new System.Drawing.Size(195, 24); + this.comboBoxReference.Size = new System.Drawing.Size(181, 24); this.comboBoxReference.TabIndex = 20; // // comboBoxLfpGain @@ -518,7 +574,7 @@ private void InitializeComponent() this.comboBoxLfpGain.Location = new System.Drawing.Point(101, 240); this.comboBoxLfpGain.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.comboBoxLfpGain.Name = "comboBoxLfpGain"; - this.comboBoxLfpGain.Size = new System.Drawing.Size(195, 24); + this.comboBoxLfpGain.Size = new System.Drawing.Size(181, 24); this.comboBoxLfpGain.TabIndex = 12; // // comboBoxApGain @@ -527,38 +583,31 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.comboBoxApGain.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxApGain.FormattingEnabled = true; - this.comboBoxApGain.Location = new System.Drawing.Point(101, 174); + this.comboBoxApGain.Location = new System.Drawing.Point(100, 174); this.comboBoxApGain.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.comboBoxApGain.Name = "comboBoxApGain"; - this.comboBoxApGain.Size = new System.Drawing.Size(196, 24); + this.comboBoxApGain.Size = new System.Drawing.Size(182, 24); this.comboBoxApGain.TabIndex = 8; // - // panelTrackBar + // tabPageProperties // - this.panelTrackBar.Controls.Add(this.trackBarProbePosition); - this.panelTrackBar.Location = new System.Drawing.Point(868, 4); - this.panelTrackBar.Margin = new System.Windows.Forms.Padding(4); - this.panelTrackBar.Name = "panelTrackBar"; - this.panelTrackBar.Size = new System.Drawing.Size(47, 662); - this.panelTrackBar.TabIndex = 33; + this.tabPageProperties.Controls.Add(this.propertyGrid); + this.tabPageProperties.Location = new System.Drawing.Point(4, 25); + this.tabPageProperties.Name = "tabPageProperties"; + this.tabPageProperties.Padding = new System.Windows.Forms.Padding(3); + this.tabPageProperties.Size = new System.Drawing.Size(301, 635); + this.tabPageProperties.TabIndex = 1; + this.tabPageProperties.Text = "Properties"; + this.tabPageProperties.UseVisualStyleBackColor = true; // - // trackBarProbePosition + // propertyGrid // - this.trackBarProbePosition.AutoSize = false; - this.trackBarProbePosition.BackColor = System.Drawing.SystemColors.Control; - this.trackBarProbePosition.Dock = System.Windows.Forms.DockStyle.Fill; - this.trackBarProbePosition.Location = new System.Drawing.Point(0, 0); - this.trackBarProbePosition.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.trackBarProbePosition.Maximum = 100; - this.trackBarProbePosition.Name = "trackBarProbePosition"; - this.trackBarProbePosition.Orientation = System.Windows.Forms.Orientation.Vertical; - this.trackBarProbePosition.Size = new System.Drawing.Size(47, 662); - this.trackBarProbePosition.TabIndex = 30; - this.trackBarProbePosition.TabStop = false; - this.trackBarProbePosition.TickFrequency = 2; - this.trackBarProbePosition.TickStyle = System.Windows.Forms.TickStyle.TopLeft; - this.trackBarProbePosition.Value = 50; - this.trackBarProbePosition.Scroll += new System.EventHandler(this.TrackBarScroll); + this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.propertyGrid.Location = new System.Drawing.Point(3, 3); + this.propertyGrid.Name = "propertyGrid"; + this.propertyGrid.Size = new System.Drawing.Size(295, 629); + this.propertyGrid.TabIndex = 0; + this.propertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyValueChanged); // // NeuropixelsV1ProbeConfigurationDialog // @@ -579,10 +628,13 @@ private void InitializeComponent() this.menuStrip.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.ResumeLayout(false); - this.panelOptions.ResumeLayout(false); - this.panelOptions.PerformLayout(); this.panelTrackBar.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.trackBarProbePosition)).EndInit(); + this.tabControl1.ResumeLayout(false); + this.tabPageConfiguration.ResumeLayout(false); + this.panelOptions.ResumeLayout(false); + this.panelOptions.PerformLayout(); + this.tabPageProperties.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -621,5 +673,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripStatusLabel toolStripLabelAdcCalibrationSN; private System.Windows.Forms.ToolStripStatusLabel toolStripLabelGainCalibrationSn; private System.Windows.Forms.CheckBox checkBoxInvertPolarity; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPageConfiguration; + internal System.Windows.Forms.PropertyGrid propertyGrid; + private System.Windows.Forms.TabPage tabPageProperties; } } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.cs b/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.cs index 85daa7a..511309e 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV1ProbeConfigurationDialog.cs @@ -26,16 +26,26 @@ private enum ChannelPreset } /// - /// Public interface that is manipulated by - /// . + /// Public interface that is manipulated by + /// . /// /// - /// When a is passed to - /// , it is copied and stored in this + /// When a is passed to + /// , it is copied and stored in this /// variable so that any modifications made to configuration settings can be easily reversed /// by not copying the new settings back to the original instance. /// - public NeuropixelsV1ProbeConfiguration ProbeConfiguration { get; set; } + public NeuropixelsV1ProbeConfiguration ProbeConfiguration + { + get => ((IConfigureNeuropixelsV1)propertyGrid.SelectedObject).ProbeConfiguration; + set => ((IConfigureNeuropixelsV1)propertyGrid.SelectedObject).ProbeConfiguration = value; + } + + IConfigureNeuropixelsV1 ConfigureNode + { + get => (IConfigureNeuropixelsV1)propertyGrid.SelectedObject; + set => propertyGrid.SelectedObject = value; + } /// public bool InvertPolarity { get; set; } @@ -43,18 +53,13 @@ private enum ChannelPreset /// /// Initializes a new instance of . /// - /// A object holding the current configuration settings. - /// String defining the path to the ADC calibration file. - /// String defining the path to the gain calibration file. - /// Boolean denoting whether or not to invert the polarity of neural data. - public NeuropixelsV1ProbeConfigurationDialog(NeuropixelsV1ProbeConfiguration probeConfiguration, string adcCalibrationFile, string gainCalibrationFile, bool invertPolarity) + /// Existing configuration node. + public NeuropixelsV1ProbeConfigurationDialog(IConfigureNeuropixelsV1 configureNode) { InitializeComponent(); Shown += FormShown; - ProbeConfiguration = new(probeConfiguration); - - ChannelConfiguration = new(ProbeConfiguration) + ChannelConfiguration = new(configureNode.ProbeConfiguration) { TopLevel = false, FormBorderStyle = FormBorderStyle.None, @@ -62,7 +67,7 @@ public NeuropixelsV1ProbeConfigurationDialog(NeuropixelsV1ProbeConfiguration pro Parent = this, }; - InvertPolarity = invertPolarity; + InvertPolarity = configureNode.InvertPolarity; panelProbe.Controls.Add(ChannelConfiguration); this.AddMenuItemsFromDialogToFileOption(ChannelConfiguration); @@ -71,37 +76,40 @@ public NeuropixelsV1ProbeConfigurationDialog(NeuropixelsV1ProbeConfiguration pro ChannelConfiguration.OnFileLoad += OnFileLoadEvent; comboBoxApGain.DataSource = Enum.GetValues(typeof(NeuropixelsV1Gain)); - comboBoxApGain.SelectedItem = ProbeConfiguration.SpikeAmplifierGain; + comboBoxApGain.SelectedItem = configureNode.ProbeConfiguration.SpikeAmplifierGain; comboBoxApGain.SelectedIndexChanged += SpikeAmplifierGainIndexChanged; comboBoxLfpGain.DataSource = Enum.GetValues(typeof(NeuropixelsV1Gain)); - comboBoxLfpGain.SelectedItem = ProbeConfiguration.LfpAmplifierGain; + comboBoxLfpGain.SelectedItem = configureNode.ProbeConfiguration.LfpAmplifierGain; comboBoxLfpGain.SelectedIndexChanged += LfpAmplifierGainIndexChanged; comboBoxReference.DataSource = Enum.GetValues(typeof(NeuropixelsV1ReferenceSource)); - comboBoxReference.SelectedItem = ProbeConfiguration.Reference; + comboBoxReference.SelectedItem = configureNode.ProbeConfiguration.Reference; comboBoxReference.SelectedIndexChanged += ReferenceIndexChanged; - checkBoxSpikeFilter.Checked = ProbeConfiguration.SpikeFilter; + checkBoxSpikeFilter.Checked = configureNode.ProbeConfiguration.SpikeFilter; checkBoxSpikeFilter.CheckedChanged += SpikeFilterIndexChanged; checkBoxInvertPolarity.Checked = InvertPolarity; checkBoxInvertPolarity.CheckedChanged += InvertPolarityIndexChanged; - textBoxAdcCalibrationFile.Text = adcCalibrationFile; - - textBoxGainCalibrationFile.Text = gainCalibrationFile; + textBoxAdcCalibrationFile.Text = configureNode.AdcCalibrationFile; + textBoxGainCalibrationFile.Text = configureNode.GainCalibrationFile; comboBoxChannelPresets.DataSource = Enum.GetValues(typeof(ChannelPreset)); CheckForExistingChannelPreset(); comboBoxChannelPresets.SelectedIndexChanged += ChannelPresetIndexChanged; + propertyGrid.SelectedObject = configureNode; + CheckStatus(); } private void InvertPolarityIndexChanged(object sender, EventArgs e) { InvertPolarity = ((CheckBox)sender).Checked; + + propertyGrid.Refresh(); } private void FormShown(object sender, EventArgs e) @@ -120,11 +128,13 @@ private void FormShown(object sender, EventArgs e) private void GainCalibrationFileTextChanged(object sender, EventArgs e) { + ConfigureNode.GainCalibrationFile = ((TextBox)sender).Text; CheckStatus(); } private void AdcCalibrationFileTextChanged(object sender, EventArgs e) { + ConfigureNode.AdcCalibrationFile = ((TextBox)sender).Text; CheckStatus(); } @@ -327,6 +337,8 @@ private void CheckStatus() toolStripLabelGainCalibrationSn.Image = Properties.Resources.StatusBlockedImage; else toolStripLabelGainCalibrationSn.Image = Properties.Resources.StatusReadyImage; + + propertyGrid.Refresh(); } private void ChooseGainCalibrationFile_Click(object sender, EventArgs e) @@ -459,5 +471,24 @@ void TextBoxKeyPress(object sender, KeyPressEventArgs e) { CheckStatus(); } + + void PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + var propertyGrid = (PropertyGrid)s; + IConfigureNeuropixelsV1 configureNode = propertyGrid.SelectedObject as IConfigureNeuropixelsV1; + + UpdateControls(configureNode); + } + + void UpdateControls(IConfigureNeuropixelsV1 configureNode) + { + comboBoxApGain.SelectedItem = configureNode.ProbeConfiguration.SpikeAmplifierGain; + comboBoxLfpGain.SelectedItem = configureNode.ProbeConfiguration.LfpAmplifierGain; + comboBoxReference.SelectedItem = configureNode.ProbeConfiguration.Reference; + checkBoxSpikeFilter.Checked = configureNode.ProbeConfiguration.SpikeFilter; + checkBoxInvertPolarity.Checked = configureNode.InvertPolarity; + textBoxAdcCalibrationFile.Text = configureNode.AdcCalibrationFile; + textBoxGainCalibrationFile.Text = configureNode.GainCalibrationFile; + } } } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.Designer.cs b/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.Designer.cs index 74b7f29..9d01840 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.Designer.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.Designer.cs @@ -36,9 +36,13 @@ private void InitializeComponent() this.buttonOkay = new System.Windows.Forms.Button(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.tabPageProperties = new System.Windows.Forms.TabPage(); + this.propertyGrid = new Bonsai.Design.PropertyGrid(); this.menuStrip.SuspendLayout(); + this.tabControlProbe.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout(); + this.tabPageProperties.SuspendLayout(); this.SuspendLayout(); // // menuStrip @@ -61,6 +65,7 @@ private void InitializeComponent() // // tabControlProbe // + this.tabControlProbe.Controls.Add(this.tabPageProperties); this.tabControlProbe.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControlProbe.Location = new System.Drawing.Point(3, 2); this.tabControlProbe.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); @@ -121,6 +126,25 @@ private void InitializeComponent() this.flowLayoutPanel1.Size = new System.Drawing.Size(1131, 41); this.flowLayoutPanel1.TabIndex = 2; // + // tabPageProperties + // + this.tabPageProperties.Controls.Add(this.propertyGrid); + this.tabPageProperties.Location = new System.Drawing.Point(4, 25); + this.tabPageProperties.Name = "tabPageProperties"; + this.tabPageProperties.Size = new System.Drawing.Size(1125, 605); + this.tabPageProperties.TabIndex = 0; + this.tabPageProperties.Text = "Properties"; + this.tabPageProperties.UseVisualStyleBackColor = true; + // + // propertyGrid + // + this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Right; + this.propertyGrid.Location = new System.Drawing.Point(832, 0); + this.propertyGrid.Name = "propertyGrid"; + this.propertyGrid.Size = new System.Drawing.Size(293, 605); + this.propertyGrid.TabIndex = 0; + this.propertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyValueChanged); + // // NeuropixelsV2eDialog // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); @@ -137,8 +161,10 @@ private void InitializeComponent() this.Text = "NeuropixelsV2e Configuration"; this.menuStrip.ResumeLayout(false); this.menuStrip.PerformLayout(); + this.tabControlProbe.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.ResumeLayout(false); + this.tabPageProperties.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -153,5 +179,7 @@ private void InitializeComponent() private System.Windows.Forms.TabControl tabControlProbe; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.TabPage tabPageProperties; + private Bonsai.Design.PropertyGrid propertyGrid; } } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.cs b/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.cs index b80302d..bafe38f 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV2eDialog.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Windows.Forms; namespace OpenEphys.Onix1.Design @@ -15,7 +16,11 @@ public partial class NeuropixelsV2eDialog : Form /// Public interface that is manipulated by /// . /// - public IConfigureNeuropixelsV2 ConfigureNode { get; set; } + public IConfigureNeuropixelsV2 ConfigureNode + { + get => (IConfigureNeuropixelsV2)propertyGrid.SelectedObject; + set => propertyGrid.SelectedObject = value; + } /// /// Initializes a new instance of . @@ -55,17 +60,6 @@ public NeuropixelsV2eDialog(IConfigureNeuropixelsV2 configureNode) Tag = NeuropixelsV2Probe.ProbeB } }; - - foreach (var channelConfiguration in ProbeConfigurations) - { - channelConfiguration.InvertPolarityChanged += InvertPolarityChanged; - - string probeName = GetProbeName((NeuropixelsV2Probe)channelConfiguration.Tag); - - tabControlProbe.TabPages.Add(probeName, probeName); - tabControlProbe.TabPages[probeName].Controls.Add(channelConfiguration); - this.AddMenuItemsFromDialogToFileOption(channelConfiguration, probeName); - } } private void InvertPolarityChanged(object sender, EventArgs e) @@ -78,6 +72,8 @@ private void InvertPolarityChanged(object sender, EventArgs e) channelConfiguration.SetInvertPolarity(sendingDialog.InvertPolarity); } } + + ConfigureNode.InvertPolarity = sendingDialog.InvertPolarity; } private string GetProbeName(NeuropixelsV2Probe probe) @@ -105,10 +101,38 @@ private void FormShown(object sender, EventArgs e) menuStrip.Visible = false; } + int index = 0; + foreach (var channelConfiguration in ProbeConfigurations) { + channelConfiguration.InvertPolarityChanged += InvertPolarityChanged; + channelConfiguration.ValueChanged += RefreshPropertyGrid; + + string probeName = GetProbeName((NeuropixelsV2Probe)channelConfiguration.Tag); + + tabControlProbe.TabPages.Insert(index++, probeName, probeName); + tabControlProbe.TabPages[probeName].Controls.Add(channelConfiguration); + this.AddMenuItemsFromDialogToFileOption(channelConfiguration, probeName); + channelConfiguration.Show(); } + + tabControlProbe.SelectedIndex = 0; + } + + void RefreshPropertyGrid(object s, EventArgs e) + { + var dialog = (NeuropixelsV2eProbeConfigurationDialog)s; + if ((NeuropixelsV2Probe)dialog.Tag == NeuropixelsV2Probe.ProbeA) + { + ConfigureNode.GainCalibrationFileA = dialog.textBoxProbeCalibrationFile.Text; + } + else if ((NeuropixelsV2Probe)dialog.Tag == NeuropixelsV2Probe.ProbeB) + { + ConfigureNode.GainCalibrationFileB = dialog.textBoxProbeCalibrationFile.Text; + } + + propertyGrid.Refresh(); } internal void Okay_Click(object sender, EventArgs e) @@ -128,5 +152,25 @@ internal void SaveVariables() ConfigureNode.InvertPolarity = ProbeConfigurations[GetProbeIndex(NeuropixelsV2Probe.ProbeA)].InvertPolarity; } + + void PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + var propertyGrid = (PropertyGrid)s; + var configureNode = (IConfigureNeuropixelsV2)propertyGrid.SelectedObject; + + foreach (var configuration in ProbeConfigurations) + { + if ((NeuropixelsV2Probe)configuration.Tag == NeuropixelsV2Probe.ProbeA) + { + configuration.UpdateControls(configureNode.ProbeConfigurationA, configureNode.GainCalibrationFileA, configureNode.InvertPolarity); + } + else if ((NeuropixelsV2Probe)configuration.Tag == NeuropixelsV2Probe.ProbeB) + { + configuration.UpdateControls(configureNode.ProbeConfigurationB, configureNode.GainCalibrationFileB, configureNode.InvertPolarity); + } + else + throw new InvalidEnumArgumentException(); + } + } } } diff --git a/OpenEphys.Onix1.Design/NeuropixelsV2eProbeConfigurationDialog.cs b/OpenEphys.Onix1.Design/NeuropixelsV2eProbeConfigurationDialog.cs index 66961a6..afffd89 100644 --- a/OpenEphys.Onix1.Design/NeuropixelsV2eProbeConfigurationDialog.cs +++ b/OpenEphys.Onix1.Design/NeuropixelsV2eProbeConfigurationDialog.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Windows.Forms; -using System.Drawing; using System.IO; namespace OpenEphys.Onix1.Design @@ -14,6 +13,7 @@ public partial class NeuropixelsV2eProbeConfigurationDialog : Form readonly NeuropixelsV2eChannelConfigurationDialog ChannelConfiguration; internal event EventHandler InvertPolarityChanged; + internal event EventHandler ValueChanged; private enum ChannelPreset { @@ -110,6 +110,8 @@ private void InvertPolarityIndexChanged(object sender, EventArgs e) { InvertPolarity = ((CheckBox)sender).Checked; OnInvertPolarityChangedHandler(); + + ValueChanged?.Invoke(this, EventArgs.Empty); } /// @@ -143,6 +145,8 @@ private void FormShown(object sender, EventArgs e) private void SelectedReferenceChanged(object sender, EventArgs e) { ProbeConfiguration.Reference = (NeuropixelsV2QuadShankReference)((ComboBox)sender).SelectedItem; + + ValueChanged?.Invoke(this, EventArgs.Empty); } private void SelectedChannelPresetChanged(object sender, EventArgs e) @@ -532,6 +536,8 @@ private void OnFileLoadEvent(object sender, EventArgs e) private void FileTextChanged(object sender, EventArgs e) { CheckStatus(); + + ValueChanged?.Invoke(this, EventArgs.Empty); } private void CheckStatus() @@ -592,6 +598,8 @@ internal void ChooseCalibrationFile_Click(object sender, EventArgs e) } CheckStatus(); + + ValueChanged?.Invoke(this, EventArgs.Empty); } internal void ClearSelection_Click(object sender, EventArgs e) @@ -646,5 +654,12 @@ void TextBoxKeyPress(object sender, KeyPressEventArgs e) { CheckStatus(); } + + internal void UpdateControls(NeuropixelsV2QuadShankProbeConfiguration configuration, string calibrationFile, bool invertPolarity) + { + comboBoxReference.SelectedItem = configuration.Reference; + checkBoxInvertPolarity.Checked = invertPolarity; + textBoxProbeCalibrationFile.Text = calibrationFile; + } } } diff --git a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs index 93a8c9b..8e6b068 100644 --- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs @@ -17,7 +17,11 @@ public partial class Rhs2116StimulusSequenceDialog : GenericStimulusSequenceDial internal Rhs2116StimulusSequencePair Sequence { get => Trigger.StimulusSequence; } - internal ConfigureRhs2116Trigger Trigger { get; set; } + internal ConfigureRhs2116Trigger Trigger + { + get => (ConfigureRhs2116Trigger)Device; + private set => Device = value; + } readonly Rhs2116StimulusSequencePair SequenceCopy = new(); @@ -39,7 +43,7 @@ public partial class Rhs2116StimulusSequenceDialog : GenericStimulusSequenceDial /// /// Existing object. public Rhs2116StimulusSequenceDialog(ConfigureRhs2116Trigger rhs2116Trigger) - : base(NumberOfChannels, true, true) + : base(new ConfigureRhs2116Trigger(rhs2116Trigger), NumberOfChannels, true, true) { if (rhs2116Trigger.ProbeGroup.NumberOfContacts != NumberOfChannels) { @@ -75,7 +79,7 @@ public Rhs2116StimulusSequenceDialog(ConfigureRhs2116Trigger rhs2116Trigger) ChannelDialog.Show(); StimulusSequenceOptions = new(); - groupBoxDefineStimuli.Controls.Add(StimulusSequenceOptions.SetChildFormProperties(this)); + tabPageDefineStimuli.Controls.Add(StimulusSequenceOptions.SetChildFormProperties(this)); StimulusSequenceOptions.buttonAddPulses.Click += ButtonAddPulses_Click; StimulusSequenceOptions.buttonReadPulses.Click += ButtonReadPulses_Click; diff --git a/OpenEphys.Onix1.Design/TextBoxBinding.cs b/OpenEphys.Onix1.Design/TextBoxBinding.cs index 0649739..5cfe2c7 100644 --- a/OpenEphys.Onix1.Design/TextBoxBinding.cs +++ b/OpenEphys.Onix1.Design/TextBoxBinding.cs @@ -9,17 +9,20 @@ internal class TextBoxBinding readonly Func setter; readonly Func parser; readonly T defaultValue; + readonly Action onChanged; public TextBoxBinding( TextBox textBox, Func setter, Func parser, - T defaultValue = default) + T defaultValue = default, + Action onChanged = null) { this.textBox = textBox; this.setter = setter; this.parser = parser; this.defaultValue = defaultValue; + this.onChanged = onChanged; } public void UpdateFromTextBox() @@ -27,20 +30,23 @@ public void UpdateFromTextBox() if (string.IsNullOrEmpty(textBox.Text)) { setter(defaultValue); - return; } - - try + else { - var value = parser(textBox.Text); - value = setter(value); - textBox.Text = value.ToString(); - } - catch - { - setter(defaultValue); - textBox.Text = defaultValue.ToString(); + try + { + var value = parser(textBox.Text); + value = setter(value); + textBox.Text = value.ToString(); + } + catch + { + setter(defaultValue); + textBox.Text = defaultValue.ToString(); + } } + + onChanged?.Invoke(); } } }