diff options
| author | a1xd <[email protected]> | 2021-09-24 02:04:43 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-09-24 02:04:43 -0400 |
| commit | 2896b8a09ce42e965705c58593b8738adc454f7f (patch) | |
| tree | 71e4d0cff60b5a1ad11427d78e1f8c7b775e5690 /grapher/Models | |
| parent | Merge pull request #107 from a1xd/1.5.0-fix (diff) | |
| parent | make note clearer (diff) | |
| download | rawaccel-dark-mode.tar.xz rawaccel-dark-mode.zip | |
v1.6
Diffstat (limited to 'grapher/Models')
28 files changed, 1598 insertions, 573 deletions
diff --git a/grapher/Models/AccelGUI.cs b/grapher/Models/AccelGUI.cs index 4ce6ed8..23d5017 100644 --- a/grapher/Models/AccelGUI.cs +++ b/grapher/Models/AccelGUI.cs @@ -4,6 +4,7 @@ using grapher.Models.Mouse; using grapher.Models.Options; using grapher.Models.Serialized; using System; +using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; @@ -25,7 +26,7 @@ namespace grapher ButtonBase resetButton, MouseWatcher mouseWatcher, ToolStripMenuItem scaleMenuItem, - DeviceIDManager deviceIDManager) + ToolStripMenuItem deviceMenuItem) { AccelForm = accelForm; AccelCalculator = accelCalculator; @@ -34,18 +35,19 @@ namespace grapher WriteButton = writeButton; ResetButton = (CheckBox)resetButton; ScaleMenuItem = scaleMenuItem; + DeviceMenuItem = deviceMenuItem; Settings = settings; DefaultButtonFont = WriteButton.Font; SmallButtonFont = new Font(WriteButton.Font.Name, WriteButton.Font.Size * Constants.SmallButtonSizeFactor); MouseWatcher = mouseWatcher; - DeviceIDManager = deviceIDManager; + DeviceMenuItem.Click += DeviceMenuItemClick; ScaleMenuItem.Click += new System.EventHandler(OnScaleMenuItemClick); WriteButton.Click += new System.EventHandler(OnWriteButtonClick); ResetButton.Click += new System.EventHandler(ResetDriverEventHandler); AccelForm.FormClosing += new FormClosingEventHandler(SaveGUISettingsOnClose); - ButtonTimerInterval = Convert.ToInt32(DriverSettings.WriteDelayMs); + ButtonTimerInterval = Convert.ToInt32(DriverConfig.WriteDelayMs); ButtonTimer = new Timer(); ButtonTimer.Tick += new System.EventHandler(OnButtonTimerTick); @@ -85,7 +87,7 @@ namespace grapher public ToolStripMenuItem ScaleMenuItem { get; } - public DeviceIDManager DeviceIDManager { get; } + public ToolStripMenuItem DeviceMenuItem { get; } private Timer ChartRefresh { get; } @@ -112,21 +114,23 @@ namespace grapher } } - public DriverSettings MakeSettingsFromFields() + public Profile MakeSettingsFromFields() { - var settings = new DriverSettings(); + var settings = new Profile(); settings.rotation = ApplyOptions.Rotation.Field.Data; - settings.sensitivity = new Vec2<double> - { - x = ApplyOptions.Sensitivity.Fields.X, - y = ApplyOptions.Sensitivity.Fields.Y - }; + settings.sensitivity = ApplyOptions.Sensitivity.Field.Data; + + // TODO - separate sensitivity fields, add new label for ratio + settings.yxSensRatio = ApplyOptions.YToXRatio.Value; settings.combineMagnitudes = ApplyOptions.IsWhole; - ApplyOptions.SetArgs(ref settings.args); - settings.domainArgs = ApplyOptions.Directionality.GetDomainArgs(); + ApplyOptions.SetArgsFromActiveValues(ref settings.argsX, ref settings.argsY); + + var (domWeights, lpNorm) = ApplyOptions.Directionality.GetDomainArgs(); + settings.domainXY = domWeights; + settings.lpNorm = lpNorm; + settings.rangeXY = ApplyOptions.Directionality.GetRangeXY(); - settings.deviceID = DeviceIDManager.ID; Settings.SetHiddenOptions(settings); @@ -141,16 +145,15 @@ namespace grapher { ButtonDelay(WriteButton); - var settings = MakeSettingsFromFields(); - SettingsErrors errors = Settings.TryActivate(settings); - if (errors.Empty()) + if (!Settings.TryActivate(MakeSettingsFromFields(), out string errors)) { - RefreshActive(); - return; + error_message = errors.ToString(); } else { - error_message = errors.ToString(); + RefreshActive(); + Settings.SetActiveHandles(); + return; } } catch (ApplicationException e) @@ -158,37 +161,30 @@ namespace grapher error_message = e.Message; } - new MessageDialog(error_message, "bad input").ShowDialog(); - } - - - public void UpdateInputManagers() - { - MouseWatcher.UpdateHandles(Settings.ActiveSettings.baseSettings.deviceID); - DeviceIDManager.Update(Settings.ActiveSettings.baseSettings.deviceID); + using (var form = new MessageDialog(error_message, "bad input")) + { + form.ShowDialog(); + } } public void RefreshActive() { - UpdateShownActiveValues(Settings.UserSettings); + UpdateShownActiveValues(Settings.ActiveProfile); UpdateGraph(); - UpdateInputManagers(); } public void RefreshUser() { - UpdateShownActiveValues(Settings.UserSettings); + UpdateShownActiveValues(Settings.UserProfile); } public void UpdateGraph() { - AccelCharts.Calculate( - Settings.ActiveAccel, - Settings.ActiveSettings.baseSettings); + AccelCharts.Calculate(Settings.ActiveAccel, Settings.ActiveProfile); AccelCharts.Bind(); } - public void UpdateShownActiveValues(DriverSettings args) + public void UpdateShownActiveValues(Profile args) { AccelForm.ResetAutoScroll(); AccelCharts.ShowActive(args); @@ -207,7 +203,7 @@ namespace grapher private void SetupButtons() { WriteButton.Top = Constants.SensitivityChartAloneHeight - Constants.ButtonVerticalOffset; - + ResetButton.Appearance = Appearance.Button; ResetButton.FlatStyle = FlatStyle.System; ResetButton.TextAlign = ContentAlignment.MiddleCenter; @@ -243,7 +239,7 @@ namespace grapher private void ResetDriverEventHandler(object sender, EventArgs e) { ButtonDelay(ResetButton); - Settings.DisableDriver(); + Settings.ResetDriver(); RefreshActive(); } @@ -251,10 +247,12 @@ namespace grapher { ButtonTimer.Stop(); SetButtonDefaults(); + DeviceMenuItem.Enabled = true; } private void StartButtonTimer() { + DeviceMenuItem.Enabled = false; ButtonTimer.Interval = ButtonTimerInterval; ButtonTimer.Start(); } @@ -279,6 +277,18 @@ namespace grapher MouseWatcher.UpdateLastMove(); } + private void DeviceMenuItemClick(object sender, EventArgs e) + { + using (var devMenu = new DeviceMenuForm(Settings)) + { + if (devMenu.ShowDialog() == DialogResult.OK) + { + Settings.Submit(devMenu.defaultConfig, devMenu.Items); + UpdateActiveSettingsFromFields(); + } + } + } + #endregion Methods } diff --git a/grapher/Models/AccelGUIFactory.cs b/grapher/Models/AccelGUIFactory.cs index 7e5ae9b..5fc7b8b 100644 --- a/grapher/Models/AccelGUIFactory.cs +++ b/grapher/Models/AccelGUIFactory.cs @@ -2,6 +2,7 @@ using grapher.Models.Devices; using grapher.Models.Mouse; using grapher.Models.Options; +using grapher.Models.Options.Cap; using grapher.Models.Options.Directionality; using grapher.Models.Options.LUT; using grapher.Models.Serialized; @@ -17,7 +18,6 @@ namespace grapher.Models public static AccelGUI Construct( RawAcceleration form, - ManagedAccel activeAccel, Chart accelerationChart, Chart accelerationChartY, Chart velocityChart, @@ -28,13 +28,17 @@ namespace grapher.Models ComboBox accelTypeDropY, ComboBox lutApplyDropdownX, ComboBox lutApplyDropdownY, + ComboBox capTypeDropdownXClassic, + ComboBox capTypeDropdownYClassic, + ComboBox capTypeDropdownXPower, + ComboBox capTypeDropdownYPower, Button writeButton, ButtonBase toggleButton, ToolStripMenuItem showVelocityGainToolStripMenuItem, ToolStripMenuItem showLastMouseMoveMenuItem, ToolStripMenuItem streamingModeToolStripMenuItem, ToolStripMenuItem autoWriteMenuItem, - ToolStripMenuItem useSpecificDeviceMenuItem, + ToolStripMenuItem deviceMenuItem, ToolStripMenuItem scaleMenuItem, ToolStripTextBox dpiTextBox, ToolStripTextBox pollRateTextBox, @@ -42,12 +46,22 @@ namespace grapher.Models TextBox sensitivityBoxX, TextBox sensitivityBoxY, TextBox rotationBox, - TextBox weightBoxX, - TextBox weightBoxY, - TextBox capBoxX, - TextBox capBoxY, - TextBox offsetBoxX, - TextBox offsetBoxY, + TextBox inCapBoxXClassic, + TextBox inCapBoxYClassic, + TextBox outCapBoxXClassic, + TextBox outCapBoxYClassic, + TextBox inCapBoxXPower, + TextBox inCapBoxYPower, + TextBox outCapBoxXPower, + TextBox outCapBoxYPower, + TextBox inputJumpBoxX, + TextBox inputJumpBoxY, + TextBox outputJumpBoxX, + TextBox outputJumpBoxY, + TextBox inputOffsetBoxX, + TextBox inputOffsetBoxY, + TextBox outputOffsetBoxX, + TextBox outputOffsetBoxY, TextBox accelerationBoxX, TextBox accelerationBoxY, TextBox decayRateBoxX, @@ -84,13 +98,28 @@ namespace grapher.Models RichTextBox yLutPointsBox, Label lockXYLabel, Label sensitivityLabel, + Label yxRatioLabel, Label rotationLabel, - Label weightLabelX, - Label weightLabelY, - Label capLabelX, - Label capLabelY, - Label offsetLabelX, - Label offsetLabelY, + Label inCapLabelXClassic, + Label inCapLabelYClassic, + Label outCapLabelXClassic, + Label outCapLabelYClassic, + Label capTypeLabelXClassic, + Label capTypeLabelYClassic, + Label inCapLabelXPower, + Label inCapLabelYPower, + Label outCapLabelXPower, + Label outCapLabelYPower, + Label capTypeLabelXPower, + Label capTypeLabelYPower, + Label inputJumpLabelX, + Label inputJumpLabelY, + Label outputJumpLabelX, + Label outputJumpLabelY, + Label inputOffsetLabelX, + Label inputOffsetLabelY, + Label outputOffsetLabelX, + Label outputOffsetLabelY, Label constantOneLabelX, Label constantOneLabelY, Label decayRateLabelX, @@ -113,15 +142,29 @@ namespace grapher.Models Label constantThreeLabelY, Label activeValueTitleX, Label activeValueTitleY, - Label sensitivityActiveXLabel, - Label sensitivityActiveYLabel, + Label sensitivityActiveLabel, + Label yxRatioActiveLabel, Label rotationActiveLabel, - Label weightActiveXLabel, - Label weightActiveYLabel, - Label capActiveXLabel, - Label capActiveYLabel, - Label offsetActiveLabelX, - Label offsetActiveLabelY, + Label inCapActiveXLabelClassic, + Label inCapActiveYLabelClassic, + Label outCapActiveXLabelClassic, + Label outCapActiveYLabelClassic, + Label capTypeActiveXLabelClassic, + Label capTypeActiveYLabelClassic, + Label inCapActiveXLabelPower, + Label inCapActiveYLabelPower, + Label outCapActiveXLabelPower, + Label outCapActiveYLabelPower, + Label capTypeActiveXLabelPower, + Label capTypeActiveYLabelPower, + Label inputJumpActiveLabelX, + Label inputJumpActiveLabelY, + Label outputJumpActiveLabelX, + Label outputJumpActiveLabelY, + Label inputOffsetActiveLabelX, + Label inputOffsetActiveLabelY, + Label outputOffsetActiveLabelX, + Label outputOffsetActiveLabelY, Label accelerationActiveLabelX, Label accelerationActiveLabelY, Label decayRateActiveLabelX, @@ -182,18 +225,27 @@ namespace grapher.Models writeButton, accelCalculator); - var sensitivity = new OptionXY( + var sensitivity = new Option( sensitivityBoxX, - sensitivityBoxY, - sensXYLock, form, 1, sensitivityLabel, - new ActiveValueLabelXY( - new ActiveValueLabel(sensitivityActiveXLabel, activeValueTitleX), - new ActiveValueLabel(sensitivityActiveYLabel, activeValueTitleX)), + 0, + new ActiveValueLabel(sensitivityActiveLabel, activeValueTitleX), "Sens Multiplier"); + var yxRatio = new LockableOption( + new Option( + sensitivityBoxY, + form, + 1, + yxRatioLabel, + 0, + new ActiveValueLabel(yxRatioActiveLabel, activeValueTitleX), + "Y/X Ratio"), + sensXYLock, + 1); + var rotation = new Option( rotationBox, form, @@ -207,58 +259,76 @@ namespace grapher.Models var directionalityLeft = directionalityPanel.Left; - var weightX = new Option( - weightBoxX, + var inputJumpX = new Option( + inputJumpBoxX, form, - 1, - weightLabelX, 0, - new ActiveValueLabel(weightActiveXLabel, activeValueTitleX), - "Weight"); + inputJumpLabelX, + 0, + new ActiveValueLabel(inputJumpActiveLabelX, activeValueTitleX), + "Jump"); - var weightY = new Option( - weightBoxY, + var inputJumpY = new Option( + inputJumpBoxY, form, - 1, - weightLabelY, + 0, + inputJumpLabelY, optionSetYLeft, - new ActiveValueLabel(weightActiveYLabel, activeValueTitleY), - "Weight"); + new ActiveValueLabel(inputJumpActiveLabelY, activeValueTitleY), + "Jump"); - var capX = new Option( - capBoxX, + var outputJumpX = new Option( + outputJumpBoxX, form, 0, - capLabelX, + outputJumpLabelX, 0, - new ActiveValueLabel(capActiveXLabel, activeValueTitleX), - "Cap"); + new ActiveValueLabel(outputJumpActiveLabelX, activeValueTitleX), + "Jump"); - var capY = new Option( - capBoxY, + var outputJumpY = new Option( + outputJumpBoxY, form, 0, - capLabelY, + outputJumpLabelY, optionSetYLeft, - new ActiveValueLabel(capActiveYLabel, activeValueTitleY), - "Cap"); + new ActiveValueLabel(outputJumpActiveLabelY, activeValueTitleY), + "Jump"); - var offsetX = new Option( - offsetBoxX, + var inputOffsetX = new Option( + inputOffsetBoxX, form, 0, - offsetLabelX, + inputOffsetLabelX, 0, - new ActiveValueLabel(offsetActiveLabelX, activeValueTitleX), + new ActiveValueLabel(inputOffsetActiveLabelX, activeValueTitleX), "Offset"); - var offsetY = new Option( - offsetBoxY, + var inputOffsetY = new Option( + inputOffsetBoxY, form, 0, - offsetLabelY, + inputOffsetLabelY, optionSetYLeft, - new ActiveValueLabel(offsetActiveLabelY, activeValueTitleY), + new ActiveValueLabel(inputOffsetActiveLabelY, activeValueTitleY), + "Offset"); + + var outputOffsetX = new Option( + outputOffsetBoxX, + form, + 0, + outputOffsetLabelX, + 0, + new ActiveValueLabel(outputOffsetActiveLabelX, activeValueTitleX), + "Offset"); + + var outputOffsetY = new Option( + outputOffsetBoxY, + form, + 0, + outputOffsetLabelY, + optionSetYLeft, + new ActiveValueLabel(outputOffsetActiveLabelY, activeValueTitleY), "Offset"); var accelerationX = new Option( @@ -369,6 +439,114 @@ namespace grapher.Models new ActiveValueLabel(midpointActiveLabelY, activeValueTitleY), optionSetYLeft); + var inCapXClassic = new Option( + inCapBoxXClassic, + form, + 0, + inCapLabelXClassic, + 0, + new ActiveValueLabel(inCapActiveXLabelClassic, activeValueTitleX), + "Cap: Input"); + + var inCapYClassic = new Option( + inCapBoxYClassic, + form, + 0, + inCapLabelYClassic, + optionSetYLeft, + new ActiveValueLabel(inCapActiveYLabelClassic, activeValueTitleY), + "Cap"); + + var outCapXClassic = new Option( + outCapBoxXClassic, + form, + 0, + outCapLabelXClassic, + 0, + new ActiveValueLabel(outCapActiveXLabelClassic, activeValueTitleX), + "Cap: Input"); + + var outCapYClassic = new Option( + outCapBoxYClassic, + form, + 0, + outCapLabelYClassic, + optionSetYLeft, + new ActiveValueLabel(outCapActiveYLabelClassic, activeValueTitleY), + "Cap"); + + var capTypeXClassic = new CapTypeOptions( + capTypeLabelXClassic, + capTypeDropdownXClassic, + new ActiveValueLabel(capTypeActiveXLabelClassic, activeValueTitleX), + 0); + + var capTypeYClassic = new CapTypeOptions( + capTypeLabelYClassic, + capTypeDropdownYClassic, + new ActiveValueLabel(capTypeActiveYLabelClassic, activeValueTitleY), + optionSetYLeft); + + var classicCapOptionsX = new CapOptions( + capTypeXClassic, + inCapXClassic, + outCapXClassic, + accelerationX); + + var classicCapOptionsY = new CapOptions( + capTypeYClassic, + inCapYClassic, + outCapYClassic, + accelerationY); + + var inCapXPower = new Option( + inCapBoxXPower, + form, + 0, + inCapLabelXPower, + 0, + new ActiveValueLabel(inCapActiveXLabelPower, activeValueTitleX), + "Cap: Input"); + + var inCapYPower = new Option( + inCapBoxYPower, + form, + 0, + inCapLabelYPower, + optionSetYLeft, + new ActiveValueLabel(inCapActiveYLabelPower, activeValueTitleY), + "Cap"); + + var outCapXPower = new Option( + outCapBoxXPower, + form, + 0, + outCapLabelXPower, + 0, + new ActiveValueLabel(outCapActiveXLabelPower, activeValueTitleX), + "Cap: Input"); + + var outCapYPower = new Option( + outCapBoxYPower, + form, + 0, + outCapLabelYPower, + optionSetYLeft, + new ActiveValueLabel(outCapActiveYLabelPower, activeValueTitleY), + "Cap"); + + var capTypeXPower = new CapTypeOptions( + capTypeLabelXPower, + capTypeDropdownXPower, + new ActiveValueLabel(capTypeActiveXLabelPower, activeValueTitleX), + 0); + + var capTypeYPower = new CapTypeOptions( + capTypeLabelYPower, + capTypeDropdownYPower, + new ActiveValueLabel(capTypeActiveYLabelPower, activeValueTitleY), + optionSetYLeft); + var lpNorm = new Option( new Field(lpNormBox, form, 2), lpNormLabel, @@ -409,17 +587,34 @@ namespace grapher.Models gainSwitchY, new ActiveValueLabel(gainSwitchActiveLabelY, activeValueTitleY)); + var powerCapOptionsX = new CapOptions( + capTypeXPower, + inCapXPower, + outCapXPower, + scaleX, + outputOffsetX, + gainSwitchOptionX); + + var powerCapOptionsY = new CapOptions( + capTypeYPower, + inCapYPower, + outCapYPower, + scaleY, + outputOffsetY, + gainSwitchOptionY); + var accelerationOptionsX = new AccelTypeOptions( accelTypeDropX, gainSwitchOptionX, - accelerationX, + classicCapOptionsX, + powerCapOptionsX, + outputJumpX, + outputOffsetX, decayRateX, growthRateX, smoothX, - scaleX, - capX, - weightX, - offsetX, + inputJumpX, + inputOffsetX, limitX, powerClassicX, exponentX, @@ -436,14 +631,15 @@ namespace grapher.Models var accelerationOptionsY = new AccelTypeOptions( accelTypeDropY, gainSwitchOptionY, - accelerationY, + classicCapOptionsY, + powerCapOptionsY, + outputJumpY, + outputOffsetY, decayRateY, growthRateY, smoothY, - scaleY, - capY, - weightY, - offsetY, + inputJumpY, + inputOffsetY, limitY, powerClassicY, exponentY, @@ -488,21 +684,18 @@ namespace grapher.Models optionsSetY, directionalOptions, sensitivity, + yxRatio, rotation, lockXYLabel, accelCharts); - var deviceIdManager = new DeviceIDManager(useSpecificDeviceMenuItem); - var settings = new SettingsManager( - activeAccel, accelCalculator.DPI, accelCalculator.PollRate, autoWriteMenuItem, showLastMouseMoveMenuItem, showVelocityGainToolStripMenuItem, - streamingModeToolStripMenuItem, - deviceIdManager); + streamingModeToolStripMenuItem); var mouseWatcher = new MouseWatcher(form, mouseLabel, accelCharts, settings); @@ -516,7 +709,7 @@ namespace grapher.Models toggleButton, mouseWatcher, scaleMenuItem, - deviceIdManager); + deviceMenuItem); } #endregion Methods diff --git a/grapher/Models/Calculations/AccelCalculator.cs b/grapher/Models/Calculations/AccelCalculator.cs index 574f55a..6b9cbf3 100644 --- a/grapher/Models/Calculations/AccelCalculator.cs +++ b/grapher/Models/Calculations/AccelCalculator.cs @@ -107,7 +107,7 @@ namespace grapher.Models.Calculations continue; } - var output = accel.Accelerate(simulatedInputDatum.x, simulatedInputDatum.y, simulatedInputDatum.time); + var output = accel.Accelerate(simulatedInputDatum.x, simulatedInputDatum.y, 1, simulatedInputDatum.time); var outMagnitude = DecimalCheck(Velocity(output.Item1, output.Item2, simulatedInputDatum.time)); var inDiff = Math.Round(simulatedInputDatum.velocity - lastInputMagnitude, 5); var outDiff = Math.Round(outMagnitude - lastOutputMagnitude, 5); @@ -193,7 +193,7 @@ namespace grapher.Models.Calculations data.MinGain = minSlope; } - public void CalculateDirectional(AccelChartData[] dataByAngle, ManagedAccel accel, DriverSettings settings, IReadOnlyCollection<IReadOnlyCollection<SimulatedMouseInput>> simulatedInputData) + public void CalculateDirectional(AccelChartData[] dataByAngle, ManagedAccel accel, Profile settings, IReadOnlyCollection<IReadOnlyCollection<SimulatedMouseInput>> simulatedInputData) { double maxRatio = 0.0; double minRatio = Double.MaxValue; @@ -219,7 +219,7 @@ namespace grapher.Models.Calculations continue; } - var output = accel.Accelerate(simulatedInputDatum.x, simulatedInputDatum.y, simulatedInputDatum.time); + var output = accel.Accelerate(simulatedInputDatum.x, simulatedInputDatum.y, 1, simulatedInputDatum.time); var magnitude = DecimalCheck(Velocity(output.Item1, output.Item2, simulatedInputDatum.time)); var inDiff = Math.Round(simulatedInputDatum.velocity - lastInputMagnitude, 5); var outDiff = Math.Round(magnitude - lastOutputMagnitude, 5); @@ -246,7 +246,7 @@ namespace grapher.Models.Calculations } var ratio = DecimalCheck(magnitude / simulatedInputDatum.velocity); - var slope = DecimalCheck(inDiff > 0 ? outDiff / inDiff : settings.sensitivity.x); + var slope = DecimalCheck(inDiff > 0 ? outDiff / inDiff : settings.sensitivity); bool indexToMeasureExtrema = (angleIndex == 0) || (angleIndex == (Constants.AngleDivisions - 1)); @@ -477,16 +477,16 @@ namespace grapher.Models.Calculations return Magnitude(x, y) / time; } - public static bool ShouldStripSens(ref DriverSettings settings) => - settings.sensitivity.x != settings.sensitivity.y; + public static bool ShouldStripSens(Profile settings) => + settings.yxSensRatio != 1; - public static bool ShouldStripRot(ref DriverSettings settings) => + public static bool ShouldStripRot(Profile settings) => settings.rotation > 0; - public static (double, double) GetSens(ref DriverSettings settings) => - (settings.sensitivity.x, settings.sensitivity.y); + public static (double, double) GetSens(Profile settings) => + (settings.sensitivity, settings.sensitivity * settings.yxSensRatio); - public static (double, double) GetRotVector(ref DriverSettings settings) => + public static (double, double) GetRotVector(Profile settings) => (Math.Cos(settings.rotation), Math.Sin(settings.rotation)); public static (double, double) StripSens(double outputX, double outputY, double sensitivityX, double sensitivityY) => diff --git a/grapher/Models/Calculations/Data/AccelDataCombined.cs b/grapher/Models/Calculations/Data/AccelDataCombined.cs index 8efb9ac..025a344 100644 --- a/grapher/Models/Calculations/Data/AccelDataCombined.cs +++ b/grapher/Models/Calculations/Data/AccelDataCombined.cs @@ -40,10 +40,10 @@ namespace grapher.Models.Calculations.Data X.Clear(); } - public void CreateGraphData(ManagedAccel accel, DriverSettings settings) + public void CreateGraphData(ManagedAccel accel, Profile settings) { Clear(); - Calculator.Calculate(X, accel, settings.sensitivity.x, Calculator.SimulatedInputCombined); + Calculator.Calculate(X, accel, settings.sensitivity, Calculator.SimulatedInputCombined); } } } diff --git a/grapher/Models/Calculations/Data/AccelDataXYComponential.cs b/grapher/Models/Calculations/Data/AccelDataXYComponential.cs index 6231eb3..f954230 100644 --- a/grapher/Models/Calculations/Data/AccelDataXYComponential.cs +++ b/grapher/Models/Calculations/Data/AccelDataXYComponential.cs @@ -54,11 +54,12 @@ namespace grapher.Models.Calculations.Data Y.Clear(); } - public void CreateGraphData(ManagedAccel accel, DriverSettings settings) + public void CreateGraphData(ManagedAccel accel, Profile settings) { Clear(); - Calculator.Calculate(X, accel, settings.sensitivity.x, Calculator.SimulatedInputX); - Calculator.Calculate(Y, accel, settings.sensitivity.y, Calculator.SimulatedInputY); + var sensY = settings.sensitivity * settings.yxSensRatio; + Calculator.Calculate(X, accel, settings.sensitivity, Calculator.SimulatedInputX); + Calculator.Calculate(Y, accel, sensY, Calculator.SimulatedInputY); } } } diff --git a/grapher/Models/Calculations/Data/AccelDataXYDirectional.cs b/grapher/Models/Calculations/Data/AccelDataXYDirectional.cs index 8bd889d..b139719 100644 --- a/grapher/Models/Calculations/Data/AccelDataXYDirectional.cs +++ b/grapher/Models/Calculations/Data/AccelDataXYDirectional.cs @@ -67,7 +67,7 @@ namespace grapher.Models.Calculations.Data } } - public void CreateGraphData(ManagedAccel accel, DriverSettings settings) + public void CreateGraphData(ManagedAccel accel, Profile settings) { Clear(); Calculator.CalculateDirectional(AngleToData, accel, settings, Calculator.SimulatedDirectionalInput); diff --git a/grapher/Models/Calculations/Data/IAccelData.cs b/grapher/Models/Calculations/Data/IAccelData.cs index 576e6df..2ae6716 100644 --- a/grapher/Models/Calculations/Data/IAccelData.cs +++ b/grapher/Models/Calculations/Data/IAccelData.cs @@ -10,7 +10,7 @@ namespace grapher.Models.Calculations.Data { void CalculateDots(double x, double y, double timeInMs); - void CreateGraphData(ManagedAccel accel, DriverSettings settings); + void CreateGraphData(ManagedAccel accel, Profile settings); void Clear(); diff --git a/grapher/Models/Charts/AccelCharts.cs b/grapher/Models/Charts/AccelCharts.cs index 631c2e2..93c9218 100644 --- a/grapher/Models/Charts/AccelCharts.cs +++ b/grapher/Models/Charts/AccelCharts.cs @@ -121,9 +121,9 @@ namespace grapher ChartState.Bind(); } - public void ShowActive(DriverSettings driverSettings) + public void ShowActive(Profile args) { - ChartState = ChartStateManager.DetermineState(driverSettings); + ChartState = ChartStateManager.DetermineState(args); ChartState.Activate(); Bind(); } @@ -134,9 +134,9 @@ namespace grapher ChartState.Redraw(); } - public void Calculate(ManagedAccel accel, DriverSettings settings) + public void Calculate(ManagedAccel accel, Profile settings) { - ChartState.SetUpCalculate(settings); + ChartState.SetUpCalculate(); ChartState.Calculate(accel, settings); } diff --git a/grapher/Models/Charts/ChartState/ChartState.cs b/grapher/Models/Charts/ChartState/ChartState.cs index a50eaf0..eca2e43 100644 --- a/grapher/Models/Charts/ChartState/ChartState.cs +++ b/grapher/Models/Charts/ChartState/ChartState.cs @@ -35,7 +35,7 @@ namespace grapher.Models.Charts.ChartState public AccelCalculator Calculator { get; } - public virtual DriverSettings Settings { get; set; } + public virtual Profile Settings { get; set; } internal bool TwoDotsPerGraph { get; set; } @@ -48,7 +48,7 @@ namespace grapher.Models.Charts.ChartState public abstract void Activate(); - public virtual void Calculate(ManagedAccel accel, DriverSettings settings) + public virtual void Calculate(ManagedAccel accel, Profile settings) { Data.CreateGraphData(accel, settings); } @@ -60,7 +60,7 @@ namespace grapher.Models.Charts.ChartState GainChart.Update(); } - public virtual void SetUpCalculate(DriverSettings settings) + public virtual void SetUpCalculate() { Data.Clear(); Calculator.ScaleByMouseSettings(); diff --git a/grapher/Models/Charts/ChartState/ChartStateManager.cs b/grapher/Models/Charts/ChartState/ChartStateManager.cs index 3d4bbec..1e5386c 100644 --- a/grapher/Models/Charts/ChartState/ChartStateManager.cs +++ b/grapher/Models/Charts/ChartState/ChartStateManager.cs @@ -50,14 +50,14 @@ namespace grapher.Models.Charts.ChartState private XYTwoGraphState XYTwoGraphState { get; } - public ChartState DetermineState(DriverSettings settings) + public ChartState DetermineState(Profile settings) { ChartState chartState; if (settings.combineMagnitudes) { - if (settings.sensitivity.x != settings.sensitivity.y || - settings.domainArgs.domainXY.x != settings.domainArgs.domainXY.y || + if (settings.yxSensRatio != 1 || + settings.domainXY.x != settings.domainXY.y || settings.rangeXY.x != settings.rangeXY.y) { chartState = XYOneGraphState; diff --git a/grapher/Models/Charts/ChartState/XYTwoGraphState.cs b/grapher/Models/Charts/ChartState/XYTwoGraphState.cs index 5b6c2b8..387d1b1 100644 --- a/grapher/Models/Charts/ChartState/XYTwoGraphState.cs +++ b/grapher/Models/Charts/ChartState/XYTwoGraphState.cs @@ -23,7 +23,7 @@ namespace grapher.Models.Charts.ChartState Data = new AccelDataXYComponential(xPoints, yPoints, accelCalculator); } - public override DriverSettings Settings { get; set; } + public override Profile Settings { get; set; } public override void Activate() { diff --git a/grapher/Models/Devices/DeviceDialogItem.cs b/grapher/Models/Devices/DeviceDialogItem.cs new file mode 100644 index 0000000..9ca5528 --- /dev/null +++ b/grapher/Models/Devices/DeviceDialogItem.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace grapher.Models.Devices +{ + public class DeviceDialogItem + { + public MultiHandleDevice device; + public DeviceSettings oldSettings; + public DeviceConfig newConfig; + public string newProfile; + public bool overrideDefaultConfig; + + public override string ToString() + { + return string.IsNullOrWhiteSpace(device.name) ? + device.id : + device.name; + } + } +} diff --git a/grapher/Models/Devices/DeviceIDItem.cs b/grapher/Models/Devices/DeviceIDItem.cs deleted file mode 100644 index 8f1587b..0000000 --- a/grapher/Models/Devices/DeviceIDItem.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace grapher.Models.Devices -{ - public class DeviceIDItem - { - public DeviceIDItem(string name, string id, DeviceIDManager manager) - { - Name = name; - ID = id; - Manager = manager; - DeviceIDMenuItem = new ToolStripMenuItem(); - DeviceIDMenuItem.Checked = false; - DeviceIDMenuItem.Text = MenuItemText(); - DeviceIDMenuItem.Click += OnClicked; - manager.DeviceIDsMenuItem.DropDownItems.Add(DeviceIDMenuItem); - } - - private ToolStripMenuItem DeviceIDMenuItem { get; } - - public string Name { get; } - - public string ID { get; } - - private DeviceIDManager Manager { get; } - - public void SetActivated() - { - DeviceIDMenuItem.Checked = true; - } - - public void SetDeactivated() - { - DeviceIDMenuItem.Checked = false; - } - - private string MenuItemText() => string.IsNullOrEmpty(ID) ? $"{Name}" : ID.Replace("&", "&&"); - - private string DisconnectedText() => $"Disconnected: {ID}"; - - public void SetDisconnected() - { - DeviceIDMenuItem.ForeColor = Color.DarkGray; - DeviceIDMenuItem.Text = DisconnectedText(); - } - - public void OnClicked(object sender, EventArgs e) - { - Manager.SetActive(this); - } - - public override bool Equals(object obj) - { - return obj is DeviceIDItem item && - Name == item.Name && - ID == item.ID; - } - - public override int GetHashCode() - { - int hashCode = -1692744877; - hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name); - hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(ID); - return hashCode; - } - } -} diff --git a/grapher/Models/Devices/DeviceIDManager.cs b/grapher/Models/Devices/DeviceIDManager.cs deleted file mode 100644 index 39856a1..0000000 --- a/grapher/Models/Devices/DeviceIDManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Management; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace grapher.Models.Devices -{ - public class DeviceIDManager - { - public DeviceIDManager(ToolStripMenuItem deviceIDs) - { - DeviceIDsMenuItem = deviceIDs; - DeviceIDsMenuItem.Checked = false; - } - - public ToolStripMenuItem DeviceIDsMenuItem { get; } - - public string ID { get => SelectedDeviceID.ID; } - - public DeviceIDItem SelectedDeviceID { get; private set; } - - public Dictionary<string, DeviceIDItem> DeviceIDs { get; private set; } - - public void SetActive(DeviceIDItem deviceIDItem) - { - if (SelectedDeviceID != null) - { - SelectedDeviceID.SetDeactivated(); - } - - SelectedDeviceID = deviceIDItem; - SelectedDeviceID.SetActivated(); - } - - public void Update(string devID) - { - DeviceIDsMenuItem.DropDownItems.Clear(); - - bool found = string.IsNullOrEmpty(devID); - - var anyDevice = new DeviceIDItem("Any", string.Empty, this); - - if (found) SetActive(anyDevice); - - foreach (string id in RawInputInterop.GetDeviceIDs()) - { - var deviceItem = new DeviceIDItem(string.Empty, id, this); - if (!found && deviceItem.ID.Equals(devID)) - { - SetActive(deviceItem); - found = true; - } - } - - if (!found) - { - var deviceItem = new DeviceIDItem(string.Empty, devID, this); - deviceItem.SetDisconnected(); - SetActive(deviceItem); - } - } - - } -} diff --git a/grapher/Models/Mouse/MouseWatcher.cs b/grapher/Models/Mouse/MouseWatcher.cs index c5c2ae5..fb34dd6 100644 --- a/grapher/Models/Mouse/MouseWatcher.cs +++ b/grapher/Models/Mouse/MouseWatcher.cs @@ -691,7 +691,9 @@ namespace grapher.Models.Mouse AccelCharts = accelCharts; SettingsManager = setMngr; MouseData = new MouseData(); - DeviceHandles = new List<IntPtr>(); + + LastMoveDisplayFormat = Constants.MouseMoveDefaultFormat; + LastMoveNormalized = false; RAWINPUTDEVICE device = new RAWINPUTDEVICE(); device.WindowHandle = ContainingForm.Handle; @@ -722,9 +724,9 @@ namespace grapher.Models.Mouse private Stopwatch Stopwatch { get; } - private List<IntPtr> DeviceHandles { get; } + private string LastMoveDisplayFormat { get; set; } - private bool AnyDevice { get; set; } + private bool LastMoveNormalized { get; set; } private double PollTime { @@ -735,20 +737,10 @@ namespace grapher.Models.Mouse #region Methods - public void UpdateHandles(string devID) - { - DeviceHandles.Clear(); - AnyDevice = string.IsNullOrEmpty(devID); - if (!AnyDevice) - { - RawInputInterop.AddHandlesFromID(devID, DeviceHandles); - } - } - public void UpdateLastMove() { MouseData.Get(out var x, out var y); - Display.Text = $"Last (x, y): ({x}, {y})"; + Display.Text = string.Format(LastMoveDisplayFormat, x, y); } public void ReadMouseMove(Message message) @@ -758,7 +750,25 @@ namespace grapher.Models.Mouse _ = GetRawInputData(message.LParam, RawInputCommand.Input, out rawInput, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER))); bool relative = !rawInput.Data.Mouse.Flags.HasFlag(RawMouseFlags.MoveAbsolute); - bool deviceMatch = AnyDevice || DeviceHandles.Contains(rawInput.Header.Device); + + bool deviceMatch = false; + foreach (var (handle, normalized) in SettingsManager.ActiveNormTaggedHandles) + { + if (handle == rawInput.Header.Device) + { + deviceMatch = true; + + if (normalized != LastMoveNormalized) + { + LastMoveDisplayFormat = normalized ? + Constants.MouseMoveNormalizedFormat : + Constants.MouseMoveDefaultFormat; + LastMoveNormalized = normalized; + } + + break; + } + } if (relative && deviceMatch && (rawInput.Data.Mouse.LastX != 0 || rawInput.Data.Mouse.LastY != 0)) { @@ -772,8 +782,11 @@ namespace grapher.Models.Mouse // strip negative directional multipliers, charts calculated from positive input - Vec2<double> dirMults = SettingsManager.ActiveSettings.baseSettings - .directionalMultipliers; + Vec2<double> dirMults = new Vec2<double> + { + x = SettingsManager.ActiveProfile.lrSensRatio, + y = SettingsManager.ActiveProfile.udSensRatio + }; if (dirMults.x > 0 && x < 0) { diff --git a/grapher/Models/Options/AccelOptionSet.cs b/grapher/Models/Options/AccelOptionSet.cs index 75eb017..3451402 100644 --- a/grapher/Models/Options/AccelOptionSet.cs +++ b/grapher/Models/Options/AccelOptionSet.cs @@ -99,7 +99,7 @@ namespace grapher.Models.Options Options.Top = TopAnchor; } - public void SetArgs(ref AccelArgs args) + public void SetArgsFromActiveValues(ref AccelArgs args) { Options.SetArgs(ref args); } diff --git a/grapher/Models/Options/AccelTypeOptions.cs b/grapher/Models/Options/AccelTypeOptions.cs index 44c9ea8..359b6b8 100644 --- a/grapher/Models/Options/AccelTypeOptions.cs +++ b/grapher/Models/Options/AccelTypeOptions.cs @@ -1,10 +1,8 @@ using grapher.Layouts; using grapher.Models.Options; +using grapher.Models.Options.Cap; using grapher.Models.Options.LUT; -using grapher.Models.Serialized; using System; -using System.Collections.Generic; -using System.Linq; using System.Windows.Forms; namespace grapher @@ -21,7 +19,6 @@ namespace grapher public static readonly LayoutBase Power = new PowerLayout(); public static readonly LayoutBase LUT = new LUTLayout(); public static readonly LayoutBase Off = new OffLayout(); - public static readonly LayoutBase Unsupported = new UnsupportedLayout(); #endregion Fields @@ -30,14 +27,15 @@ namespace grapher public AccelTypeOptions( ComboBox accelDropdown, CheckBoxOption gainSwitch, - Option acceleration, + CapOptions classicCap, + CapOptions powerCap, + Option outputJump, + Option outputOffset, Option decayRate, Option growthRate, Option smooth, - Option scale, - Option cap, - Option weight, - Option offset, + Option inputJump, + Option inputOffset, Option limit, Option powerClassic, Option exponent, @@ -66,17 +64,18 @@ namespace grapher AccelDropdown.SelectedIndexChanged += new System.EventHandler(OnIndexChanged); GainSwitch = gainSwitch; - Acceleration = acceleration; DecayRate = decayRate; GrowthRate = growthRate; Smooth = smooth; - Scale = scale; - Cap = cap; - Weight = weight; - Offset = offset; + ClassicCap = classicCap; + PowerCap = powerCap; + InputJump = inputJump; + InputOffset = inputOffset; Limit = limit; PowerClassic = powerClassic; Exponent = exponent; + OutputJump = outputJump; + OutputOffset = outputOffset; Midpoint = midpoint; WriteButton = writeButton; AccelTypeActiveValue = accelTypeActiveValue; @@ -86,7 +85,7 @@ namespace grapher AccelTypeActiveValue.Left = AccelDropdown.Left + AccelDropdown.Width; AccelTypeActiveValue.Height = AccelDropdown.Height; - GainSwitch.Left = Acceleration.Field.Left; + GainSwitch.Left = DecayRate.Field.Left; LutPanel.Left = AccelDropdown.Left; LutPanel.Width = AccelDropdown.Width + AccelTypeActiveValue.Width; @@ -109,21 +108,23 @@ namespace grapher public ActiveValueLabel AccelTypeActiveValue { get; } - public Option Acceleration { get; } - public Option DecayRate { get; } public Option GrowthRate { get; } public Option Smooth { get; } - public Option Scale { get; } + public CapOptions ClassicCap { get; } + + public CapOptions PowerCap { get; } + + public Option InputJump { get; } - public Option Cap { get; } + public Option OutputJump { get; } - public Option Weight { get; } + public Option InputOffset { get; } - public Option Offset { get; } + public Option OutputOffset { get; } public Option Limit { get; } @@ -229,14 +230,15 @@ namespace grapher AccelTypeActiveValue.Hide(); GainSwitch.Hide(); - Acceleration.Hide(); DecayRate.Hide(); GrowthRate.Hide(); Smooth.Hide(); - Scale.Hide(); - Cap.Hide(); - Weight.Hide(); - Offset.Hide(); + ClassicCap.Hide(); + PowerCap.Hide(); + OutputOffset.Hide(); + InputOffset.Hide(); + InputJump.Hide(); + OutputJump.Hide(); Limit.Hide(); PowerClassic.Hide(); Exponent.Hide(); @@ -262,21 +264,30 @@ namespace grapher { AccelerationType = AccelTypeFromSettings(ref args); AccelTypeActiveValue.SetValue(AccelerationType.ActiveName); - GainSwitch.SetActiveValue(args.legacy); - Weight.SetActiveValue(args.weight); - Cap.SetActiveValue(args.cap); - Offset.SetActiveValue(args.offset); - Acceleration.SetActiveValue(args.accelClassic); + GainSwitch.SetActiveValue(args.gain); + ClassicCap.SetActiveValues( + args.acceleration, + args.cap.x, + args.cap.y, + args.capMode); + PowerCap.SetActiveValues( + args.scale, + args.cap.x, + args.cap.y, + args.capMode); + InputJump.SetActiveValue(args.cap.x); + OutputJump.SetActiveValue(args.cap.y); + OutputOffset.SetActiveValue(args.outputOffset); + InputOffset.SetActiveValue(args.inputOffset); DecayRate.SetActiveValue(args.decayRate); GrowthRate.SetActiveValue(args.growthRate); Smooth.SetActiveValue(args.smooth); - Scale.SetActiveValue(args.scale); Limit.SetActiveValue((args.mode == AccelMode.motivity) ? args.motivity : args.limit); - PowerClassic.SetActiveValue(args.power); - Exponent.SetActiveValue(args.exponent); + PowerClassic.SetActiveValue(args.exponentClassic); + Exponent.SetActiveValue(args.exponentPower); Midpoint.SetActiveValue(args.midpoint); - LutPanel.SetActiveValues(args.tableData.points, args.tableData.length); - LutApply.SetActiveValue(args.tableData.velocity); + LutPanel.SetActiveValues(args.data, args.length, args.mode); + LutApply.SetActiveValue(args.gain); } public void ShowFull() @@ -286,8 +297,8 @@ namespace grapher AccelDropdown.Text = Constants.AccelDropDownDefaultFullText; } - Left = Acceleration.Left + Constants.DropDownLeftSeparation; - Width = Acceleration.Width - Constants.DropDownLeftSeparation; + Left = DecayRate.Left + Constants.DropDownLeftSeparation; + Width = DecayRate.Width - Constants.DropDownLeftSeparation; LutText.Expand(); HandleLUTOptionsOnResize(); @@ -300,25 +311,38 @@ namespace grapher AccelDropdown.Text = Constants.AccelDropDownDefaultShortText; } - Left = Acceleration.Field.Left; - Width = Acceleration.Field.Width; + Left = DecayRate.Field.Left; + Width = DecayRate.Field.Width; LutText.Shorten(); } public void SetArgs(ref AccelArgs args) { - if (AccelerationType == Unsupported) throw new NotImplementedException(); - args.mode = AccelerationType.Mode; - args.legacy = !GainSwitch.CheckBox.Checked; + args.gain = LutPanel.Visible ? + LutApply.ApplyType == LutApplyOptions.LutApplyType.Velocity : + GainSwitch.CheckBox.Checked; - if (Acceleration.Visible) args.accelClassic = Acceleration.Field.Data; if (DecayRate.Visible) args.decayRate = DecayRate.Field.Data; if (GrowthRate.Visible) args.growthRate = GrowthRate.Field.Data; if (Smooth.Visible) args.smooth = Smooth.Field.Data; - if (Scale.Visible) args.scale = Scale.Field.Data; - if (Cap.Visible) args.cap = Cap.Field.Data; + if (ClassicCap.Visible) + { + args.acceleration = ClassicCap.Slope.Field.Data; + args.cap.x = ClassicCap.In.Field.Data; + args.cap.y = ClassicCap.Out.Field.Data; + args.capMode = ClassicCap.CapTypeOptions.GetSelectedCapMode(); + } + if (PowerCap.Visible) + { + args.scale = PowerCap.Slope.Field.Data; + args.cap.x = PowerCap.In.Field.Data; + args.cap.y = PowerCap.Out.Field.Data; + args.capMode = PowerCap.CapTypeOptions.GetSelectedCapMode(); + } + if (InputJump.Visible) args.cap.x = InputJump.Field.Data; + if (OutputJump.Visible) args.cap.y = OutputJump.Field.Data; if (Limit.Visible) { if (args.mode == AccelMode.motivity) @@ -328,34 +352,43 @@ namespace grapher else { args.limit = Limit.Field.Data; - } + } } - if (PowerClassic.Visible) args.power = PowerClassic.Field.Data; - if (Exponent.Visible)args.exponent = Exponent.Field.Data; - if (Offset.Visible) args.offset = Offset.Field.Data; + if (PowerClassic.Visible) args.exponentClassic = PowerClassic.Field.Data; + if (Exponent.Visible) args.exponentPower = Exponent.Field.Data; + if (InputOffset.Visible) args.inputOffset = InputOffset.Field.Data; + if (OutputOffset.Visible) args.outputOffset = OutputOffset.Field.Data; + if (Midpoint.Visible) args.midpoint = Midpoint.Field.Data; - if (Weight.Visible) args.weight = Weight.Field.Data; if (LutPanel.Visible) { (var points, var length) = LutPanel.GetPoints(); - args.tableData.points = points; - args.tableData.length = length; + args.length = length * 2; + + for (int i = 0; i < length; i++) + { + ref var p = ref points[i]; + var data_idx = i * 2; + args.data[data_idx] = p.x; + args.data[data_idx + 1] = p.y; + } } - if (LutApply.Visible) args.tableData.velocity = LutApply.ApplyType == LutApplyOptions.LutApplyType.Velocity; + } public override void AlignActiveValues() { AccelTypeActiveValue.Align(); GainSwitch.AlignActiveValues(); - Acceleration.AlignActiveValues(); DecayRate.AlignActiveValues(); GrowthRate.AlignActiveValues(); Smooth.AlignActiveValues(); - Scale.AlignActiveValues(); - Cap.AlignActiveValues(); - Offset.AlignActiveValues(); - Weight.AlignActiveValues(); + ClassicCap.AlignActiveValues(); + PowerCap.AlignActiveValues(); + OutputOffset.AlignActiveValues(); + InputOffset.AlignActiveValues(); + OutputJump.AlignActiveValues(); + InputJump.AlignActiveValues(); Limit.AlignActiveValues(); PowerClassic.AlignActiveValues(); Exponent.AlignActiveValues(); @@ -367,7 +400,7 @@ namespace grapher { LutText.Left = AccelDropdown.Left; LutPanel.Left = GainSwitch.Left - 100; - LutPanel.Width = Acceleration.ActiveValueLabel.CenteringLabel.Right - LutPanel.Left; + LutPanel.Width = DecayRate.ActiveValueLabel.CenteringLabel.Right - LutPanel.Left; LutApply.Left = LutPanel.Left; LutApply.Width = AccelDropdown.Right - LutPanel.Left; } @@ -387,17 +420,18 @@ namespace grapher AccelerationType.Layout( GainSwitch, - Acceleration, + ClassicCap, + PowerCap, DecayRate, GrowthRate, Smooth, - Scale, - Cap, - Weight, - Offset, + InputJump, + InputOffset, Limit, PowerClassic, Exponent, + OutputJump, + OutputOffset, Midpoint, LutText, LutPanel, @@ -407,19 +441,9 @@ namespace grapher private LayoutBase AccelTypeFromSettings(ref AccelArgs args) { - if (args.spacedTableArgs.mode != SpacedTableMode.off) - { - if (!AccelDropdown.Items.Contains(Unsupported)) - { - AccelDropdown.Items.Add(Unsupported); - } - - return Unsupported; - } - switch (args.mode) { - case AccelMode.classic: return (args.power == 2) ? Linear : Classic; + case AccelMode.classic: return (args.exponentClassic == 2) ? Linear : Classic; case AccelMode.jump: return Jump; case AccelMode.natural: return Natural; case AccelMode.motivity: return Motivity; diff --git a/grapher/Models/Options/ApplyOptions.cs b/grapher/Models/Options/ApplyOptions.cs index 06854b8..4946414 100644 --- a/grapher/Models/Options/ApplyOptions.cs +++ b/grapher/Models/Options/ApplyOptions.cs @@ -15,7 +15,8 @@ namespace grapher.Models.Options AccelOptionSet optionSetX, AccelOptionSet optionSetY, DirectionalityOptions directionalityOptions, - OptionXY sensitivity, + Option sensitivity, + LockableOption yxRatio, Option rotation, Label lockXYLabel, AccelCharts accelCharts) @@ -34,6 +35,7 @@ namespace grapher.Models.Options OptionSetX = optionSetX; OptionSetY = optionSetY; Sensitivity = sensitivity; + YToXRatio = yxRatio; Rotation = rotation; LockXYLabel = lockXYLabel; AccelCharts = accelCharts; @@ -44,7 +46,8 @@ namespace grapher.Models.Options ByComponentVectorXYLock.CheckedChanged += new System.EventHandler(OnByComponentXYLockChecked); ByComponentVectorXYLock.Checked = true; - Rotation.SnapTo(Sensitivity); + YToXRatio.SnapTo(Sensitivity); + Rotation.SnapTo(YToXRatio); EnableWholeApplication(); } @@ -65,7 +68,9 @@ namespace grapher.Models.Options public DirectionalityOptions Directionality { get; } - public OptionXY Sensitivity { get; } + public Option Sensitivity { get; } + + public LockableOption YToXRatio { get; } public Option Rotation { get; } @@ -81,30 +86,31 @@ namespace grapher.Models.Options #region Methods - public void SetArgs(ref Vec2<AccelArgs> args) + public void SetArgsFromActiveValues(ref AccelArgs argsX, ref AccelArgs argsY) { - OptionSetX.SetArgs(ref args.x); + OptionSetX.SetArgsFromActiveValues(ref argsX); if (ByComponentVectorXYLock.Checked) { - OptionSetX.SetArgs(ref args.y); + OptionSetX.SetArgsFromActiveValues(ref argsY); } else { - OptionSetY.SetArgs(ref args.y); + OptionSetY.SetArgsFromActiveValues(ref argsY); } } - public void SetActiveValues(DriverSettings settings) + public void SetActiveValues(Profile settings) { - Sensitivity.SetActiveValues(settings.sensitivity.x, settings.sensitivity.y); + Sensitivity.SetActiveValue(settings.sensitivity); + YToXRatio.SetActiveValue(settings.yxSensRatio); Rotation.SetActiveValue(settings.rotation); WholeVectorCheckBox.Checked = settings.combineMagnitudes; ByComponentVectorCheckBox.Checked = !settings.combineMagnitudes; - ByComponentVectorXYLock.Checked = settings.args.x.Equals(settings.args.y); - OptionSetX.SetActiveValues(ref settings.args.x); - OptionSetY.SetActiveValues(ref settings.args.y); + ByComponentVectorXYLock.Checked = settings.argsX.Equals(settings.argsY); + OptionSetX.SetActiveValues(ref settings.argsX); + OptionSetY.SetActiveValues(ref settings.argsY); Directionality.SetActiveValues(settings); @@ -210,8 +216,8 @@ namespace grapher.Models.Options LockXYLabel.Width = (AccelCharts.Left - OptionSetX.ActiveValuesTitle.Left) / 2; OptionSetX.ActiveValuesTitle.Width = LockXYLabel.Width; LockXYLabel.Left = OptionSetX.ActiveValuesTitle.Left + OptionSetX.ActiveValuesTitle.Width; - Sensitivity.Fields.LockCheckBox.Left = LockXYLabel.Left + LockXYLabel.Width / 2 - Sensitivity.Fields.LockCheckBox.Width / 2; - ByComponentVectorXYLock.Left = Sensitivity.Fields.LockCheckBox.Left; + YToXRatio.LockBox.Left = LockXYLabel.Left + LockXYLabel.Width / 2 - YToXRatio.LockBox.Width / 2; + ByComponentVectorXYLock.Left = YToXRatio.LockBox.Left; AlignActiveValues(); } diff --git a/grapher/Models/Options/Cap/CapOptions.cs b/grapher/Models/Options/Cap/CapOptions.cs new file mode 100644 index 0000000..68326e5 --- /dev/null +++ b/grapher/Models/Options/Cap/CapOptions.cs @@ -0,0 +1,249 @@ +using System; +using System.Windows.Forms; +using static grapher.Models.Options.Cap.CapTypeOptions; + +namespace grapher.Models.Options.Cap +{ + public class CapOptions : OptionBase + { + #region Constants + + public const string InCapLabel = "Cap: Input"; + public const string OutCapLabel = "Cap: Output"; + + #endregion Constants + + #region Fields + + private int _top; + + #endregion Fields + + #region Constructors + + public CapOptions( + CapTypeOptions capTypeOptions, + Option capIn, + Option capOut, + Option slope, + Option disableOptionInBoth = null, + CheckBoxOption disableInBoth = null) + { + CapTypeOptions = capTypeOptions; + In = capIn; + Out = capOut; + Slope = slope; + DisableOptionInBoth = disableOptionInBoth; + DisableInBoth = disableInBoth; + + ShouldShow = true; + _top = Slope.Top; + BottomElement = In; + CapTypeOptions.OptionsDropdown.SelectedIndexChanged += OnCapTypeDropdownSelectedItemChanged; + CapTypeOptions.SelectedCapOption = InCap; + + if (DisableInBoth != null) + { + DisableInBoth.CheckBox.CheckedChanged += OnDisableInBothCheckedChange; + } + } + + #endregion Constructors + + #region Properties + + public CapTypeOptions CapTypeOptions { get; } + + public Option In { get; } + + public Option Out { get; } + + public Option Slope { get; } + + private Option DisableOptionInBoth { get; } + + private CheckBoxOption DisableInBoth { get; } + + public override int Left + { + get => In.Left; + + set + { + In.Left = value; + Out.Left = value; + Slope.Left = value; + } + } + + public override int Top + { + get => _top; + set + { + _top = value; + Layout(value); + } + } + + public override int Height + { + get => BottomElement.Top + BottomElement.Height - Top; + } + + public override int Width + { + get => CapTypeOptions.Width; + + set + { + CapTypeOptions.Width = value; + In.Width = value; + Out.Width = value; + Slope.Width = value; + } + } + + public override bool Visible + { + get => ShouldShow; + } + + private bool ShouldShow { get; set; } + + private IOption BottomElement { get; set; } + + #endregion Properties + + #region Methods + + public override void AlignActiveValues() + { + Slope.AlignActiveValues(); + CapTypeOptions.AlignActiveValues(); + In.AlignActiveValues(); + Out.AlignActiveValues(); + } + + public override void Show(string name) + { + ShouldShow = true; + Layout(Top, name); + } + + public override void Hide() + { + ShouldShow = false; + CapTypeOptions.Hide(); + Slope.Hide(); + In.Hide(); + Out.Hide(); + } + + public void SetActiveValues( + double scale, + double inCap, + double outCap, + CapMode capMode) + { + Slope.SetActiveValue(scale); + In.SetActiveValue(inCap); + Out.SetActiveValue(outCap); + CapTypeOptions.SetActiveValue(capMode); + } + + private void Layout(int top, string name = null) + { + switch (CapTypeOptions.SelectedCapType) + { + case CapType.Input: + if (ShouldShow) + { + Slope.Show(); + CapTypeOptions.Show(name); + ShowInCap(); + Out.Hide(); + } + + Slope.Top = top; + CapTypeOptions.SnapTo(Slope); + In.SnapTo(CapTypeOptions); + + BottomElement = In; + break; + case CapType.Output: + if (ShouldShow) + { + Slope.Show(); + CapTypeOptions.Show(name); + In.Hide(); + ShowOutCap(); + } + + Slope.Top = top; + CapTypeOptions.SnapTo(Slope); + Out.SnapTo(CapTypeOptions); + + BottomElement = Out; + break; + case CapType.Both: + if (ShouldShow) + { + CapTypeOptions.Show(name); + Slope.Hide(); + ShowInCap(); + ShowOutCap(); + } + + CapTypeOptions.Top = top; + In.SnapTo(CapTypeOptions); + Out.SnapTo(In); + + BottomElement = Out; + break; + } + + DisableBuggedOptionIfApplicable(); + } + + private void DisableBuggedOptionIfApplicable() + { + if (DisableOptionInBoth != null) + { + if (CapTypeOptions.SelectedCapType == CapType.Both && + DisableInBoth != null && + !DisableInBoth.CheckBox.Checked) + { + DisableOptionInBoth.Field.SetToUnavailable(); + } + else + { + DisableOptionInBoth.Field.SetToDefault(); + } + } + } + + private void ShowInCap() + { + In.Show(InCapLabel); + } + + private void ShowOutCap() + { + Out.Show(OutCapLabel); + } + + private void OnCapTypeDropdownSelectedItemChanged(object sender, EventArgs e) + { + Layout(Top); + CapTypeOptions.CheckIfDefault(); + } + + private void OnDisableInBothCheckedChange(object sender, EventArgs e) + { + DisableBuggedOptionIfApplicable(); + } + + #endregion Methods + } +} diff --git a/grapher/Models/Options/Cap/CapTypeOptions.cs b/grapher/Models/Options/Cap/CapTypeOptions.cs new file mode 100644 index 0000000..6447feb --- /dev/null +++ b/grapher/Models/Options/Cap/CapTypeOptions.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace grapher.Models.Options.Cap +{ + public class CapTypeOptions : ComboBoxOptionsBase + { + #region Enum + + public enum CapType + { + Input, + Output, + Both, + } + + #endregion Enum + + #region Classes + + public class CapTypeOption + { + public CapType Type { get; set; } + + public string Name => Type.ToString(); + + public override string ToString() => Name; + } + + #endregion Classes + + #region Static + + public static readonly CapTypeOption InCap = new CapTypeOption + { + Type = CapType.Input, + }; + + public static readonly CapTypeOption OutCap = new CapTypeOption + { + Type = CapType.Output, + }; + + public static readonly CapTypeOption BothCap = new CapTypeOption + { + Type = CapType.Both, + }; + + public static readonly CapTypeOption[] AllCapTypeOptions = new CapTypeOption[] + { + InCap, + OutCap, + BothCap + }; + + #endregion Static + + #region Constructors + + public CapTypeOptions( + Label label, + ComboBox dropdown, + ActiveValueLabel activeValueLabel, + int left) + : base( + label, + dropdown, + activeValueLabel) + { + OptionsDropdown.Items.AddRange( + new CapTypeOption[] + { + InCap, + OutCap, + BothCap + }); + + Default = OutCap; + + label.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + label.Left = left; + label.Width = OptionsDropdown.Left - left - Constants.OptionLabelBoxSeperation; + label.Height = OptionsDropdown.Height; + } + + #endregion Constructors + + #region Properties + + public CapType SelectedCapType => SelectedCapOption.Type; + + public CapTypeOption SelectedCapOption + { + get + { + return OptionsDropdown.SelectedItem as CapTypeOption; + } + set + { + OptionsDropdown.SelectedItem = value; + } + } + + private CapTypeOption Default { get; set; } + + public CapMode GetSelectedCapMode() + { + switch(SelectedCapType) + { + case CapType.Output: return CapMode.output; + case CapType.Both: return CapMode.in_out; + case CapType.Input: + default: return CapMode.input; + } + } + + #endregion Properties + + #region Methods + + public static CapTypeOption CapTypeOptionFromSettings(CapMode capMode) + { + switch (capMode) + { + case CapMode.output: + return OutCap; + case CapMode.in_out: + return BothCap; + case CapMode.input: + default: + return InCap; + } + } + + public void SetActiveValue(CapMode capMode) + { + Default = CapTypeOptionFromSettings(capMode); + SelectedCapOption = Default; + ActiveValueLabel.SetValue(SelectedCapOption.Name); + } + + public void CheckIfDefault() + { + if (SelectedCapOption.Equals(Default)) + { + OptionsDropdown.ForeColor = System.Drawing.Color.Gray; + } + else + { + OptionsDropdown.ForeColor = System.Drawing.Color.Black; + } + } + + #endregion Methods + } +} diff --git a/grapher/Models/Options/CheckBoxOption.cs b/grapher/Models/Options/CheckBoxOption.cs index abf96d3..8c125ec 100644 --- a/grapher/Models/Options/CheckBoxOption.cs +++ b/grapher/Models/Options/CheckBoxOption.cs @@ -2,6 +2,9 @@ namespace grapher.Models.Options { + /// <summary> + /// This is an option type that is just a checkbox. + /// </summary> public class CheckBoxOption : OptionBase { public CheckBoxOption( @@ -99,10 +102,10 @@ namespace grapher.Models.Options ActiveValueLabel.Show(); } - public void SetActiveValue(bool legacy) + public void SetActiveValue(bool gain) { - CheckBox.Checked = !legacy; - var activeValueString = legacy ? "Legacy" : "Gain"; + CheckBox.Checked = gain; + var activeValueString = gain ? "Gain" : "Legacy"; ActiveValueLabel.SetValue(activeValueString); } } diff --git a/grapher/Models/Options/ComboBoxOptionsBase.cs b/grapher/Models/Options/ComboBoxOptionsBase.cs new file mode 100644 index 0000000..6999e99 --- /dev/null +++ b/grapher/Models/Options/ComboBoxOptionsBase.cs @@ -0,0 +1,124 @@ +using System.Windows.Forms; + +namespace grapher.Models.Options +{ + public abstract class ComboBoxOptionsBase : OptionBase + { + #region Constructors + + public ComboBoxOptionsBase( + Label label, + ComboBox dropdown, + ActiveValueLabel activeValueLabel) + { + OptionsDropdown = dropdown; + OptionsDropdown.Items.Clear(); + + Label = label; + Label.AutoSize = false; + Label.Width = 50; + + ActiveValueLabel = activeValueLabel; + } + + #endregion Constructors + + #region Properties + + public Label Label { get; } + + public ActiveValueLabel ActiveValueLabel { get; } + + public ComboBox OptionsDropdown { get; } + + public override bool Visible + { + get + { + return Label.Visible || ShouldShow; + } + } + + public override int Left + { + get + { + return Label.Left; + } + set + { + Label.Left = value; + OptionsDropdown.Left = Label.Left + Label.Width + Constants.OptionVerticalSeperation; + } + } + + public override int Height + { + get + { + return OptionsDropdown.Height; + } + } + + public override int Top + { + get + { + return OptionsDropdown.Top; + } + set + { + OptionsDropdown.Top = value; + Label.Top = (OptionsDropdown.Height - Label.Height) / 2 + OptionsDropdown.Top; + ActiveValueLabel.Top = value; + } + } + + public override int Width + { + get + { + return Label.Width; + } + set + { + OptionsDropdown.Width = value - Label.Width - Constants.OptionLabelBoxSeperation; + } + } + + protected bool ShouldShow { get; set; } + + #endregion Properties + + #region Methods + + public override void Hide() + { + Label.Hide(); + OptionsDropdown.Hide(); + ActiveValueLabel.Hide(); + ShouldShow = false; + } + + public override void Show(string labelText) + { + Label.Show(); + + if (!string.IsNullOrWhiteSpace(labelText)) + { + Label.Text = labelText; + } + + OptionsDropdown.Show(); + ActiveValueLabel.Show(); + ShouldShow = true; + } + + public override void AlignActiveValues() + { + ActiveValueLabel.Align(); + } + + #endregion Methods + } +} diff --git a/grapher/Models/Options/Directionality/DirectionalityOptions.cs b/grapher/Models/Options/Directionality/DirectionalityOptions.cs index 9288132..35d2575 100644 --- a/grapher/Models/Options/Directionality/DirectionalityOptions.cs +++ b/grapher/Models/Options/Directionality/DirectionalityOptions.cs @@ -70,17 +70,16 @@ namespace grapher.Models.Options.Directionality private bool IsHidden { get; set; } - public DomainArgs GetDomainArgs() + public Tuple<Vec2<double>, double> GetDomainArgs() { - return new DomainArgs + var weights = new Vec2<double> { - domainXY = new Vec2<double> - { - x = Domain.Fields.X, - y = Domain.Fields.Y, - }, - lpNorm = ByComponentCheckBox.Checked ? 2 : LpNorm.Field.Data + x = Domain.Fields.X, + y = Domain.Fields.Y }; + double p = ByComponentCheckBox.Checked ? 2 : LpNorm.Field.Data; + + return new Tuple<Vec2<double>, double>(weights, p); } public Vec2<double> GetRangeXY() @@ -92,14 +91,14 @@ namespace grapher.Models.Options.Directionality }; } - public void SetActiveValues(DriverSettings settings) + public void SetActiveValues(Profile settings) { - Domain.SetActiveValues(settings.domainArgs.domainXY.x, settings.domainArgs.domainXY.y); + Domain.SetActiveValues(settings.domainXY.x, settings.domainXY.y); Range.SetActiveValues(settings.rangeXY.x, settings.rangeXY.y); if (settings.combineMagnitudes) { - LpNorm.SetActiveValue(settings.domainArgs.lpNorm); + LpNorm.SetActiveValue(settings.lpNorm); } else { diff --git a/grapher/Models/Options/LUT/LUTPanelOptions.cs b/grapher/Models/Options/LUT/LUTPanelOptions.cs index 3690c76..eedcfa8 100644 --- a/grapher/Models/Options/LUT/LUTPanelOptions.cs +++ b/grapher/Models/Options/LUT/LUTPanelOptions.cs @@ -111,15 +111,26 @@ namespace grapher.Models.Options.LUT // Nothing to do here. } - public void SetActiveValues(IEnumerable<Vec2<float>> activePoints, int length) + public void SetActiveValues(IEnumerable<float> rawData, int length, AccelMode mode) { - if (length > 0 && activePoints.First().x != 0) + if (mode == AccelMode.lut && length > 1 && rawData.First() != 0) { - ActiveValuesTextBox.Text = PointsToActiveValuesText(activePoints, length); + var pointsLen = length / 2; + var points = new Vec2<float>[pointsLen]; + for (int i = 0; i < pointsLen; i++) + { + var data_idx = i * 2; + points[i] = new Vec2<float> + { + x = rawData.ElementAt(data_idx), + y = rawData.ElementAt(data_idx + 1) + }; + } + ActiveValuesTextBox.Text = PointsToActiveValuesText(points, pointsLen); if (string.IsNullOrWhiteSpace(PointsTextBox.Text)) { - PointsTextBox.Text = PointsToEntryTextBoxText(activePoints, length); + PointsTextBox.Text = PointsToEntryTextBoxText(points, pointsLen); } } else @@ -135,14 +146,12 @@ namespace grapher.Models.Options.LUT private static (Vec2<float>[], int length) UserTextToPoints(string userText) { - const int MaxPoints = 256; - if (string.IsNullOrWhiteSpace(userText)) { throw new ApplicationException("Text must be entered in text box to fill Look Up Table."); } - Vec2<float>[] points = new Vec2<float>[MaxPoints]; + Vec2<float>[] points = new Vec2<float>[AccelArgs.MaxLutPoints]; var userTextSplit = userText.Trim().Trim(';').Split(';'); int index = 0; @@ -155,9 +164,9 @@ namespace grapher.Models.Options.LUT throw new ApplicationException("At least 2 points required"); } - if (pointsCount > MaxPoints) + if (pointsCount > AccelArgs.MaxLutPoints) { - throw new ApplicationException($"Number of points exceeds max ({MaxPoints})"); + throw new ApplicationException($"Number of points exceeds max ({AccelArgs.MaxLutPoints})"); } foreach(var pointEntry in userTextSplit) diff --git a/grapher/Models/Options/LUT/LutApplyOptions.cs b/grapher/Models/Options/LUT/LutApplyOptions.cs index 7d8c737..61cae61 100644 --- a/grapher/Models/Options/LUT/LutApplyOptions.cs +++ b/grapher/Models/Options/LUT/LutApplyOptions.cs @@ -7,10 +7,9 @@ using System.Windows.Forms; namespace grapher.Models.Options.LUT { - public class LutApplyOptions : OptionBase + public class LutApplyOptions : ComboBoxOptionsBase { - public const string LUTApplyOptionsLabelText = "Apply as:"; - public const int LUTApplyLabelDropdownSeparation = 4; + #region Enum public enum LutApplyType { @@ -18,6 +17,10 @@ namespace grapher.Models.Options.LUT Velocity } + #endregion Enum + + #region Classes + public class LutApplyOption { public LutApplyType Type { get; set; } @@ -27,6 +30,10 @@ namespace grapher.Models.Options.LUT public override string ToString() => Name; } + #endregion Classes + + #region Static + public static readonly LutApplyOption Sensitivity = new LutApplyOption { Type = LutApplyType.Sensitivity, @@ -37,129 +44,58 @@ namespace grapher.Models.Options.LUT Type = LutApplyType.Velocity, }; + #endregion Static + + #region Constructors + public LutApplyOptions( Label label, ComboBox applyOptionsDropdown, ActiveValueLabel lutApplyActiveValue) + : base( + label, + applyOptionsDropdown, + lutApplyActiveValue) { - ApplyOptions = applyOptionsDropdown; - ApplyOptions.Items.Clear(); - ApplyOptions.Items.AddRange( + OptionsDropdown.Items.AddRange( new LutApplyOption[] { Sensitivity, Velocity, }); + } - Label = label; - Label.Text = LUTApplyOptionsLabelText; - Label.AutoSize = false; - Label.Width = 50; + #endregion Constructors - ActiveValueLabel = lutApplyActiveValue; - } + #region Properties public LutApplyType ApplyType { get => ApplyOption.Type; } public LutApplyOption ApplyOption { get { - return ApplyOptions.SelectedItem as LutApplyOption; - } - set - { - ApplyOptions.SelectedItem = value; - } - } - - public Label Label { get; } - - public ActiveValueLabel ActiveValueLabel { get; } - - public ComboBox ApplyOptions { get; } - - public override bool Visible - { - get - { - return Label.Visible || ShouldShow; - } - } - - public override int Left - { - get - { - return Label.Left; + return OptionsDropdown.SelectedItem as LutApplyOption; } set { - Label.Left = value; - ApplyOptions.Left = Label.Left + Label.Width + LUTApplyLabelDropdownSeparation; + OptionsDropdown.SelectedItem = value; } } - public override int Height - { - get - { - return Label.Height; - } - } + #endregion Properties - public override int Top - { - get - { - return Label.Top; - } - set - { - ApplyOptions.Top = value; - Label.Top = (ApplyOptions.Height - Label.Height) / 2 + ApplyOptions.Top; - ActiveValueLabel.Top = value; - } - } + #region Methods - public override int Width + public static LutApplyOption ApplyOptionFromSettings(bool applyAsVelocity) { - get - { - return Label.Width; - } - set + if (applyAsVelocity) { - ApplyOptions.Width = value - Label.Width - Constants.OptionLabelBoxSeperation; + return Velocity; } - } - - private bool ShouldShow { get; set; } - - public override void Hide() - { - Label.Hide(); - ApplyOptions.Hide(); - ActiveValueLabel.Hide(); - ShouldShow = false; - } - - public override void Show(string labelText) - { - Label.Show(); - - if (!string.IsNullOrWhiteSpace(labelText)) + else { - Label.Text = labelText; + return Sensitivity; } - - ApplyOptions.Show(); - ActiveValueLabel.Show(); - ShouldShow = true; - } - - public override void AlignActiveValues() - { - ActiveValueLabel.Align(); } public void SetActiveValue(bool applyAsVelocity) @@ -168,16 +104,6 @@ namespace grapher.Models.Options.LUT ActiveValueLabel.SetValue(ApplyOption.Name); } - public LutApplyOption ApplyOptionFromSettings(bool applyAsVelocity) - { - if (applyAsVelocity) - { - return Velocity; - } - else - { - return Sensitivity; - } - } + #endregion Methods } } diff --git a/grapher/Models/Options/LockableOption.cs b/grapher/Models/Options/LockableOption.cs new file mode 100644 index 0000000..6e78783 --- /dev/null +++ b/grapher/Models/Options/LockableOption.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace grapher.Models.Options +{ + /// <summary> + /// This is an option type that is a regular option with a checkbox that disables it. + /// </summary> + public class LockableOption : OptionBase + { + public LockableOption( + Option option, + CheckBox checkBox, + int lockedvalue) + { + Option = option; + LockBox = checkBox; + LockedValue = lockedvalue; + + LockBox.Click += OnLockedBoxClicked; + LockBox.AutoCheck = false; + + Option.Field.SetNewDefault(LockedValue); + SetLocked(); + } + + public Option Option { get; } + + public CheckBox LockBox { get; } + + public int LockedValue { get; } + + public override int Left + { + get => Option.Left; + + set + { + Option.Left = value; + } + } + + public override int Top + { + get => Option.Top; + + set + { + Option.Top = value; + LockBox.Top = value; + } + } + + public override int Width + { + get => Option.Width; + + set + { + Option.Width = value; + } + } + + public override int Height + { + get => Option.Height; + } + + public override bool Visible + { + get => Option.Visible; + } + + public double Value + { + get => LockBox.Checked ? LockedValue : Option.Field.Data; + } + + public void SetActiveValue(double activeValue) + { + Option.SetActiveValue(activeValue); + + if (activeValue == LockedValue) + { + SetLocked(); + } + else + { + SetUnlocked(); + } + } + + public override void AlignActiveValues() + { + Option.AlignActiveValues(); + } + + public override void Hide() + { + Option.Hide(); + LockBox.Hide(); + } + + public override void Show(string Name) + { + Option.Show(Name); + LockBox.Show(); + } + private void SetLocked() + { + LockBox.Checked = true; + Option.Field.SetToUnavailable(); + } + + private void SetUnlocked() + { + LockBox.Checked = false; + Option.Field.SetToDefault(); + } + + private void OnLockedBoxClicked(object sender, EventArgs e) + { + if (LockBox.Checked) + { + SetUnlocked(); + } + else + { + SetLocked(); + } + } + } +} diff --git a/grapher/Models/Options/SwitchOption.cs b/grapher/Models/Options/SwitchOption.cs new file mode 100644 index 0000000..79991c1 --- /dev/null +++ b/grapher/Models/Options/SwitchOption.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace grapher.Models.Options +{ + public class SwitchOption : OptionBase + { + + #region Constructors + + public SwitchOption( + Label label, + CheckBox firstCheckBox, + CheckBox secondCheckBox, + ActiveValueLabel activeValueLabel, + int left) + { + Label = label; + First = firstCheckBox; + Second = secondCheckBox; + ActiveValueLabel = activeValueLabel; + Left = left; + + label.AutoSize = false; + label.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + label.Width = First.Left - left - Constants.OptionLabelBoxSeperation; + label.Height = First.Height; + + ActiveValueLabel.Height = First.Height; + + First.CheckedChanged += OnFirstCheckedChange; + Second.CheckedChanged += OnSecondCheckedChange; + + First.Checked = true; + Second.Left = First.Left + First.Width + Constants.OptionLabelBoxSeperation; + Show(string.Empty); + } + + #endregion Constructors + + #region Properties + + public Label Label { get; } + + public CheckBox First { get; } + + public CheckBox Second { get; } + + public ActiveValueLabel ActiveValueLabel { get; } + + public override int Height + { + get => Label.Height; + } + + public override int Left + { + get => Label.Left; + set + { + Label.Left = value; + } + } + + public override bool Visible + { + get => ShouldShow; + } + + public override int Width + { + get => Second.Left + Second.Width - Label.Left; + set + { + } + } + + public override int Top + { + get => Label.Top; + set + { + Label.Top = value; + First.Top = value; + Second.Top = value; + ActiveValueLabel.Top = value; + } + } + + private bool ShouldShow { get; set; } + + #endregion Properties + + #region Methods + + public override void AlignActiveValues() + { + ActiveValueLabel.Align(); + } + + public override void Hide() + { + ShouldShow = false; + + Label.Hide(); + First.Hide(); + Second.Hide(); + ActiveValueLabel.Hide(); + } + + public override void Show(string name) + { + ShouldShow = true; + + if (!string.IsNullOrWhiteSpace(name)) + { + Label.Text = name; + } + + Label.Show(); + First.Show(); + Second.Show(); + ActiveValueLabel.Show(); + } + + public void SetActiveValue(bool shouldFirstBeChecked) + { + if (shouldFirstBeChecked) + { + First.Checked = true; + ActiveValueLabel.SetValue(First.Text); + } + else + { + Second.Checked = true; + ActiveValueLabel.SetValue(Second.Text); + } + } + + private void OnFirstCheckedChange(object sender, EventArgs e) + { + if (First.Checked) + { + Second.Checked = false; + } + } + + private void OnSecondCheckedChange(object sender, EventArgs e) + { + if (Second.Checked) + { + First.Checked = false; + } + } + + #endregion Methods + } +} diff --git a/grapher/Models/Serialized/SettingsManager.cs b/grapher/Models/Serialized/SettingsManager.cs index 346bc9b..43550c5 100644 --- a/grapher/Models/Serialized/SettingsManager.cs +++ b/grapher/Models/Serialized/SettingsManager.cs @@ -6,6 +6,8 @@ using System.Threading; using System.Text; using System.Drawing; using grapher.Models.Devices; +using System.Collections.Generic; +using System.Linq; namespace grapher.Models.Serialized { @@ -14,14 +16,12 @@ namespace grapher.Models.Serialized #region Constructors public SettingsManager( - ManagedAccel activeAccel, Field dpiField, Field pollRateField, ToolStripMenuItem autoWrite, ToolStripMenuItem showLastMouseMove, ToolStripMenuItem showVelocityAndGain, - ToolStripMenuItem streamingMode, - DeviceIDManager deviceIDManager) + ToolStripMenuItem streamingMode) { DpiField = dpiField; PollRateField = pollRateField; @@ -29,9 +29,9 @@ namespace grapher.Models.Serialized ShowLastMouseMoveMenuItem = showLastMouseMove; ShowVelocityAndGainMoveMenuItem = showVelocityAndGain; StreamingModeMenuItem = streamingMode; - DeviceIDManager = deviceIDManager; - SetActiveFields(activeAccel); + SystemDevices = new List<MultiHandleDevice>(); + ActiveNormTaggedHandles = new List<(IntPtr, bool)>(); GuiSettings = GUISettings.MaybeLoad(); @@ -45,43 +45,92 @@ namespace grapher.Models.Serialized UpdateFieldsFromGUISettings(); } - UserSettings = InitUserSettings(); + UserConfigField = InitActiveAndGetUserConfig(); } #endregion Constructors + #region Fields + + private EventHandler DeviceChangeField; + + private DriverConfig ActiveConfigField; + private DriverConfig UserConfigField; + + #endregion Fields + #region Properties public GUISettings GuiSettings { get; private set; } - public ManagedAccel ActiveAccel { get; private set; } + public event EventHandler DeviceChange + { + add => DeviceChangeField += value; + remove => DeviceChangeField -= value; + } + + public DriverConfig ActiveConfig + { + get => ActiveConfigField; + + private set + { + if (ActiveConfigField != value) + { + ActiveConfigField = value; + ActiveProfileNamesSet = new HashSet<string>(value.profiles.Select(p => p.name)); + } + } + } - public ExtendedSettings ActiveSettings { get; private set; } + public Profile ActiveProfile + { + get => ActiveConfigField.profiles[0]; + private set => ActiveConfigField.SetProfileAt(0, value); + } - public DriverSettings UserSettings { get; private set; } + public ManagedAccel ActiveAccel + { + get => ActiveConfig.accels[0]; + } + + public DriverConfig UserConfig + { + get => UserConfigField; + private set => UserConfigField = value; + } + + public Profile UserProfile + { + get => UserConfigField.profiles[0]; + private set => UserConfigField.SetProfileAt(0, value); + } + + public HashSet<string> ActiveProfileNamesSet { get; private set; } public Field DpiField { get; private set; } public Field PollRateField { get; private set; } - public DeviceIDManager DeviceIDManager { get; } + public IList<MultiHandleDevice> SystemDevices { get; private set; } + + public List<(IntPtr, bool)> ActiveNormTaggedHandles { get; } private ToolStripMenuItem AutoWriteMenuItem { get; set; } private ToolStripMenuItem ShowLastMouseMoveMenuItem { get; set; } private ToolStripMenuItem ShowVelocityAndGainMoveMenuItem { get; set; } + private ToolStripMenuItem StreamingModeMenuItem{ get; set; } #endregion Properties #region Methods - public void DisableDriver() + public void ResetDriver() { - var defaultSettings = new ExtendedSettings(); - ActiveSettings = defaultSettings; - ActiveAccel.Settings = defaultSettings; - new Thread(() => ActiveAccel.Activate()).Start(); + ActiveConfig = DriverConfig.GetDefault(); + new Thread(() => DriverConfig.Deactivate()).Start(); } public void UpdateFieldsFromGUISettings() @@ -94,36 +143,44 @@ namespace grapher.Models.Serialized AutoWriteMenuItem.Checked = GuiSettings.AutoWriteToDriverOnStartup; } - public SettingsErrors TryActivate(DriverSettings settings) + public bool TryActivate(Profile settings, out string errors) { - var errors = new SettingsErrors(settings); + var old = UserProfile; + UserProfile = settings; + bool success = TryActivate(UserConfig, out errors); + if (!success) + { + UserProfile = old; + } + return success; + } + + public bool TryActivate(DriverConfig settings, out string errors) + { + errors = settings.Errors(); - if (errors.Empty()) + if (errors == null) { GuiSettings = MakeGUISettingsFromFields(); GuiSettings.Save(); - UserSettings = settings; - File.WriteAllText(Constants.DefaultSettingsFileName, RaConvert.Settings(settings)); + UserConfig = settings; + ActiveConfig = settings; + File.WriteAllText(Constants.DefaultSettingsFileName, settings.ToJSON()); - ActiveSettings = new ExtendedSettings(settings); - ActiveAccel.Settings = ActiveSettings; - - new Thread(() => ActiveAccel.Activate()).Start(); + new Thread(() => ActiveConfig.Activate()).Start(); } - return errors; + return errors == null; } - public void SetHiddenOptions(DriverSettings settings) + public void SetHiddenOptions(Profile settings) { - settings.snap = UserSettings.snap; - settings.maximumSpeed = UserSettings.maximumSpeed; - settings.minimumSpeed = UserSettings.minimumSpeed; - settings.minimumTime = UserSettings.minimumTime; - settings.maximumTime = UserSettings.maximumTime; - settings.ignore = UserSettings.ignore; - settings.directionalMultipliers = UserSettings.directionalMultipliers; + settings.snap = UserProfile.snap; + settings.maximumSpeed = UserProfile.maximumSpeed; + settings.minimumSpeed = UserProfile.minimumSpeed; + settings.lrSensRatio = UserProfile.lrSensRatio; + settings.udSensRatio = UserProfile.udSensRatio; } public GUISettings MakeGUISettingsFromFields() @@ -139,33 +196,108 @@ namespace grapher.Models.Serialized }; } - public bool TableActive() + public void SetActiveHandles() { - return ActiveSettings.tables.x != null || ActiveSettings.tables.y != null; + ActiveNormTaggedHandles.Clear(); + + bool ActiveProfileIsFirst = ActiveProfile == ActiveConfig.profiles[0]; + + foreach (var sysDev in SystemDevices) + { + void AddHandlesFromSysDev(bool normalized) + { + ActiveNormTaggedHandles.AddRange(sysDev.handles.Select(h => (h, normalized))); + } + + var settings = ActiveConfig.devices.Find(d => d.id == sysDev.id); + + if (settings is null) + { + if (ActiveProfileIsFirst && !ActiveConfig.defaultDeviceConfig.disable) + { + AddHandlesFromSysDev(ActiveConfig.defaultDeviceConfig.dpi > 0); + } + } + else if (!settings.config.disable && + ((ActiveProfileIsFirst && + (string.IsNullOrEmpty(settings.profile) || + !ActiveProfileNamesSet.Contains(settings.profile))) || + ActiveProfile.name == settings.profile)) + { + AddHandlesFromSysDev(settings.config.dpi > 0); + } + } + } + + public void Submit(DeviceConfig newDefaultConfig, DeviceDialogItem[] items) + { + UserConfig.defaultDeviceConfig = newDefaultConfig; + foreach (var item in items) + { + if (item.overrideDefaultConfig) + { + if (item.oldSettings is null) + { + UserConfig.devices.Add( + new DeviceSettings + { + name = item.device.name, + profile = item.newProfile, + id = item.device.id, + config = item.newConfig + }); + } + else + { + item.oldSettings.config = item.newConfig; + item.oldSettings.profile = item.newProfile; + } + } + else if (!(item.oldSettings is null)) + { + UserConfig.devices.Remove(item.oldSettings); + } + } } - public void SetActiveFields(ManagedAccel activeAccel) + public void OnProfileSelectionChange() { - ActiveAccel = activeAccel; - ActiveSettings = activeAccel.Settings; + SetActiveHandles(); } - private DriverSettings InitUserSettings() + public void OnDeviceChangeMessage() + { + SystemDevices = MultiHandleDevice.GetList(); + SetActiveHandles(); + + DeviceChangeField?.Invoke(this, EventArgs.Empty); + } + + private DriverConfig InitActiveAndGetUserConfig() { var path = Constants.DefaultSettingsFileName; if (File.Exists(path)) { try { - DriverSettings settings = RaConvert.Settings(File.ReadAllText(path)); + var (cfg, err) = DriverConfig.Convert(File.ReadAllText(path)); - if (!GuiSettings.AutoWriteToDriverOnStartup || - TableActive() || - TryActivate(settings).Empty()) + if (err == null) { - return settings; + if (GuiSettings.AutoWriteToDriverOnStartup) + { + if (!TryActivate(cfg, out string _)) + { + throw new Exception("deserialization succeeded but TryActivate failed"); + } + } + else + { + ActiveConfig = DriverConfig.GetActive(); + } + + return cfg; } - } catch (JsonException e) { @@ -173,17 +305,9 @@ namespace grapher.Models.Serialized } } - if (!TableActive()) - { - File.WriteAllText(path, RaConvert.Settings(ActiveSettings.baseSettings)); - return ActiveSettings.baseSettings; - } - else - { - var defaultSettings = new DriverSettings(); - File.WriteAllText(path, RaConvert.Settings(defaultSettings)); - return defaultSettings; - } + ActiveConfig = DriverConfig.GetActive(); + File.WriteAllText(path, ActiveConfig.ToJSON()); + return ActiveConfig; } #endregion Methods |