Implement separate inner and outer threshold sliders, and a custom threshold slider.
@ -13,9 +13,18 @@
|
||||
<setting name="LaunchOnStartup" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="AuxSensors" serializeAs="String">
|
||||
<setting name="CustomSensors" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UseInnerSensorThresholds" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="UseOuterSensorThresholds" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="AdvancedMode" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
</smx_config.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
|
@ -137,7 +137,7 @@ namespace smx_config
|
||||
// and corners. Rev1 firmware uses those only. Copy cardinal directions (down) to the
|
||||
// other cardinal directions (except for up, which already had its own setting) and corners
|
||||
// to the other corners.
|
||||
static public void SyncUnifiedThresholds(ref SMX.SMXConfig config)
|
||||
static private void SyncUnifiedThresholds(ref SMX.SMXConfig config)
|
||||
{
|
||||
for(int fromPanel = 0; fromPanel < 9; ++fromPanel)
|
||||
{
|
||||
@ -155,14 +155,5 @@ namespace smx_config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the panel thresholds are already synced, so SyncUnifiedThresholds would
|
||||
// have no effect.
|
||||
static public bool AreUnifiedThresholdsSynced(SMX.SMXConfig config)
|
||||
{
|
||||
SMX.SMXConfig config2 = Helpers.DeepClone(config);
|
||||
SyncUnifiedThresholds(ref config2);
|
||||
return SamePreset(config, config2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ namespace smx_config
|
||||
|
||||
// The threshold sliders in the advanced tab affect different panels and sensors depending
|
||||
// on the user's settings. This handles managing which sensors each slider controls.
|
||||
static class ThresholdSettings
|
||||
static public class ThresholdSettings
|
||||
{
|
||||
[Serializable]
|
||||
public struct PanelAndSensor
|
||||
@ -393,6 +393,17 @@ namespace smx_config
|
||||
public int sensor;
|
||||
};
|
||||
|
||||
public static List<string> thresholdSliderNames = new List<string>()
|
||||
{
|
||||
"up-left", "up", "up-right",
|
||||
"left", "center", "right",
|
||||
"down-left", "down", "down-right",
|
||||
"cardinal", "corner",
|
||||
"inner-sensors",
|
||||
"outer-sensors",
|
||||
"custom-sensors",
|
||||
};
|
||||
|
||||
// These correspond with ThresholdSlider.Type.
|
||||
static Dictionary<string, int> panelNameToIndex = new Dictionary<string, int>() {
|
||||
{ "up-left", 0 },
|
||||
@ -409,15 +420,12 @@ namespace smx_config
|
||||
// are then synced to the other panels.
|
||||
{ "cardinal", 7 },
|
||||
{ "corner", 2 },
|
||||
|
||||
// The aux threshold allows giving a list of specific sensors different thresholds.
|
||||
{ "aux", -1 },
|
||||
};
|
||||
|
||||
// Save and load the list of aux sensors to settings. These aren't saved to the pad, we just
|
||||
// keep them in application settings.
|
||||
static List<PanelAndSensor> cachedAuxSensors;
|
||||
static public void SetAuxSensors(List<PanelAndSensor> panelAndSensors)
|
||||
// Save and load the list of custom threshold sensors to settings. These aren't saved to the pad, we
|
||||
// just keep them in application settings.
|
||||
static List<PanelAndSensor> cachedCustomSensors;
|
||||
static public void SetCustomSensors(List<PanelAndSensor> panelAndSensors)
|
||||
{
|
||||
List<object> result = new List<object>();
|
||||
foreach(PanelAndSensor panelAndSensor in panelAndSensors)
|
||||
@ -426,31 +434,38 @@ namespace smx_config
|
||||
result.Add(panelAndSensorArray);
|
||||
}
|
||||
|
||||
Properties.Settings.Default.AuxSensors = SerializeJSON.Serialize(result);
|
||||
SetCustomSensorsJSON(result);
|
||||
}
|
||||
|
||||
// Set CustomSensors from a [[1,1],[2,2]] array. This is what we save to settings and
|
||||
// export to JSON.
|
||||
static public void SetCustomSensorsJSON(List<object> panelAndSensors)
|
||||
{
|
||||
Properties.Settings.Default.CustomSensors = SerializeJSON.Serialize(panelAndSensors);
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
// Clear the cache. Set it to null instead of assigning panelAndSensors to it to force
|
||||
// it to re-parse at least once, to catch problems early.
|
||||
cachedAuxSensors = null;
|
||||
cachedCustomSensors = null;
|
||||
}
|
||||
|
||||
// Return the sensors that are controlled by the aux threshold slider. The other
|
||||
// Return the sensors that are controlled by the custom-sensors slider. The other
|
||||
// threshold sliders will leave these alone.
|
||||
static public List<PanelAndSensor> GetAuxSensors()
|
||||
static public List<PanelAndSensor> GetCustomSensors()
|
||||
{
|
||||
// Properties.Settings.Default.AuxSensors = "[[0,0], [1,0]]";
|
||||
// This is only ever changed with calls to SetSavedAuxSensors.
|
||||
if(cachedAuxSensors != null)
|
||||
return Helpers.DeepClone(cachedAuxSensors);
|
||||
// Properties.Settings.Default.CustomSensors = "[[0,0], [1,0]]";
|
||||
// This is only ever changed with calls to SetCustomSensors.
|
||||
if(cachedCustomSensors != null)
|
||||
return Helpers.DeepClone(cachedCustomSensors);
|
||||
|
||||
List<PanelAndSensor> result = new List<PanelAndSensor>();
|
||||
if(Properties.Settings.Default.AuxSensors == "")
|
||||
if(Properties.Settings.Default.CustomSensors == "")
|
||||
return result;
|
||||
|
||||
try {
|
||||
// This is a list of [panel,sensor] arrays:
|
||||
// [[0,0], [0,1], [1,0]]
|
||||
List<object> sensors = SMXJSON.ParseJSON.Parse<List<object>>(Properties.Settings.Default.AuxSensors);
|
||||
List<object> sensors = GetCustomSensorsJSON();
|
||||
foreach(object panelAndSensorObj in sensors)
|
||||
{
|
||||
List<object> panelAndSensor = (List<object>) panelAndSensorObj;
|
||||
@ -465,18 +480,104 @@ namespace smx_config
|
||||
return result;
|
||||
}
|
||||
|
||||
cachedAuxSensors = result;
|
||||
// SetAuxSensors(result); // XXX
|
||||
cachedCustomSensors = result;
|
||||
|
||||
// SetSavedAuxSensors(result);
|
||||
return Helpers.DeepClone(cachedAuxSensors);
|
||||
return Helpers.DeepClone(cachedCustomSensors);
|
||||
}
|
||||
|
||||
static public List<PanelAndSensor> GetControlledSensorsForSliderType(string Type, bool advancedMode)
|
||||
static public List<object> GetCustomSensorsJSON()
|
||||
{
|
||||
// The aux threshold slider always controls the aux sensors.
|
||||
if(Type == "aux")
|
||||
return GetAuxSensors();
|
||||
return SMXJSON.ParseJSON.Parse<List<object>>(Properties.Settings.Default.CustomSensors);
|
||||
}
|
||||
|
||||
const int SensorLeft = 0;
|
||||
const int SensorRight = 1;
|
||||
const int SensorUp = 2;
|
||||
const int SensorDown = 3;
|
||||
static public List<PanelAndSensor> GetInnerSensors()
|
||||
{
|
||||
return new List<PanelAndSensor>()
|
||||
{
|
||||
new PanelAndSensor(1,SensorDown), // up panel, bottom sensor
|
||||
new PanelAndSensor(3,SensorRight), // left panel, right sensor
|
||||
new PanelAndSensor(5,SensorLeft), // right panel, left sensor
|
||||
new PanelAndSensor(7,SensorUp), // down panel, top sensor
|
||||
};
|
||||
}
|
||||
|
||||
static public List<PanelAndSensor> GetOuterSensors()
|
||||
{
|
||||
return new List<PanelAndSensor>()
|
||||
{
|
||||
new PanelAndSensor(1,SensorUp), // up panel, top sensor
|
||||
new PanelAndSensor(3,SensorLeft), // left panel, left sensor
|
||||
new PanelAndSensor(5,SensorRight), // right panel, right sensor
|
||||
new PanelAndSensor(7,SensorDown), // down panel, bottom sensor
|
||||
};
|
||||
}
|
||||
// Return the sensors controlled by the given slider. Most of the work is done
|
||||
// in GetControlledSensorsForSliderTypeInternal. This just handles removing overlapping
|
||||
// sensors. If inner-sensors is enabled, the inner sensors are removed from the normal
|
||||
// thresholds.
|
||||
//
|
||||
// This is really inefficient: it calls GetControlledSensorsForSliderTypeInternal a lot,
|
||||
// and the filtering is a linear search, but it doesn't matter.
|
||||
//
|
||||
// If includeOverridden is true, include sensors that would be controlled by this slider
|
||||
// by default, but which have been overridden by a higher priority slider, or which are
|
||||
// disabled by checkboxes. This is used for the UI.
|
||||
static public List<PanelAndSensor> GetControlledSensorsForSliderType(string Type, bool advancedMode, bool includeOverridden)
|
||||
{
|
||||
List<PanelAndSensor> result = GetControlledSensorsForSliderTypeInternal(Type, advancedMode, includeOverridden);
|
||||
|
||||
if(!includeOverridden)
|
||||
{
|
||||
// inner-sensors, outer-sensors and custom thresholds overlap each other and the standard
|
||||
// sliders. inner-sensors and outer-sensors take over the equivalent sensors in the standard
|
||||
// sliders, and custom thresholds take priority over everything else.
|
||||
//
|
||||
// We always pass false to includeOverridden here, since we need to know the real state of the
|
||||
// sliders we're removing.
|
||||
if(Type == "inner-sensors" || Type == "outer-sensors")
|
||||
{
|
||||
// Remove any sensors controlled by the custom threshold.
|
||||
RemoveFromSensorList(result, GetControlledSensorsForSliderTypeInternal("custom-sensors", advancedMode, false));
|
||||
}
|
||||
else if(Type != "custom-sensors")
|
||||
{
|
||||
// This is a regular slider. Remove any sensors controlled by inner-sensors, outer-sensors
|
||||
// or custom-sensors.
|
||||
RemoveFromSensorList(result, GetControlledSensorsForSliderTypeInternal("inner-sensors", advancedMode, false));
|
||||
RemoveFromSensorList(result, GetControlledSensorsForSliderTypeInternal("outer-sensors", advancedMode, false));
|
||||
RemoveFromSensorList(result, GetControlledSensorsForSliderTypeInternal("custom-sensors", advancedMode, false));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static private void RemoveFromSensorList(List<PanelAndSensor> target, List<PanelAndSensor> sensorsToRemove)
|
||||
{
|
||||
foreach(PanelAndSensor panelAndSensor in sensorsToRemove)
|
||||
target.Remove(panelAndSensor);
|
||||
}
|
||||
|
||||
static private List<PanelAndSensor> GetControlledSensorsForSliderTypeInternal(string Type, bool advancedMode, bool includeOverridden)
|
||||
{
|
||||
// inner-sensors and outer-sensors do nothing if their checkbox is disabled. We do this here because we
|
||||
// need to skip this for the RemoveFromSensorList logic above.
|
||||
if(!includeOverridden)
|
||||
{
|
||||
if(Type == "inner-sensors" && !Properties.Settings.Default.UseInnerSensorThresholds)
|
||||
return new List<PanelAndSensor>();
|
||||
if(Type == "outer-sensors" && !Properties.Settings.Default.UseOuterSensorThresholds)
|
||||
return new List<PanelAndSensor>();
|
||||
}
|
||||
|
||||
// Special sliders:
|
||||
if(Type == "custom-sensors") return GetCustomSensors();
|
||||
if(Type == "inner-sensors") return GetInnerSensors();
|
||||
if(Type == "outer-sensors") return GetOuterSensors();
|
||||
|
||||
List<PanelAndSensor> result = new List<PanelAndSensor>();
|
||||
|
||||
@ -498,7 +599,6 @@ namespace smx_config
|
||||
// If advanced mode is disabled, save to all panels this slider affects. The down arrow controls
|
||||
// all four cardinal panels. (If advanced mode is enabled we'll never be a different cardinal
|
||||
// direction, since those widgets won't exist.) If it's disabled, just write to our own panel.
|
||||
List<PanelAndSensor> auxSensors = GetAuxSensors();
|
||||
List<int> saveToPanels = new List<int>();
|
||||
int ourPanelIdx = panelNameToIndex[Type];
|
||||
saveToPanels.Add(ourPanelIdx);
|
||||
@ -508,18 +608,60 @@ namespace smx_config
|
||||
foreach(int panelIdx in saveToPanels)
|
||||
{
|
||||
for(int sensor = 0; sensor < 4; ++sensor)
|
||||
{
|
||||
// Ignore sensors controlled by the aux threshold.
|
||||
PanelAndSensor panelAndSensor = new PanelAndSensor(panelIdx, sensor);
|
||||
if(auxSensors.Contains(panelAndSensor))
|
||||
continue;
|
||||
|
||||
result.Add(panelAndSensor);
|
||||
}
|
||||
result.Add(new PanelAndSensor(panelIdx, sensor));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// If the user disables inner-sensors after setting a value and control of those thresholds
|
||||
// goes back to other sliders, the old inner-sensors thresholds will still be set in config
|
||||
// until the user changes them, which is confusing. Make sure the value of each slider is
|
||||
// actually set to config, even if the user doesn't change them.
|
||||
//
|
||||
// This isn't perfect. If the user assigns the first up sensor to custom and then removes it,
|
||||
// so that sensor goes back to the normal up slider, this will sync the custom value to up.
|
||||
// That's because we don't know which thresholds were actually being controlled by the up slider
|
||||
// before it was changed. This is tricky to fix and not a big problem.
|
||||
private static void SyncSliderThresholdsForConfig(ref SMX.SMXConfig config)
|
||||
{
|
||||
if(!config.fsr())
|
||||
return;
|
||||
|
||||
bool AdvancedModeEnabled = Properties.Settings.Default.AdvancedMode;
|
||||
foreach(string sliderName in thresholdSliderNames)
|
||||
{
|
||||
List<PanelAndSensor> controlledSensors = GetControlledSensorsForSliderType(sliderName, AdvancedModeEnabled, false);
|
||||
if(controlledSensors.Count == 0)
|
||||
continue;
|
||||
PanelAndSensor firstSensor = controlledSensors[0];
|
||||
|
||||
foreach(PanelAndSensor panelAndSensor in controlledSensors)
|
||||
{
|
||||
config.panelSettings[panelAndSensor.panel].fsrLowThreshold[panelAndSensor.sensor] =
|
||||
config.panelSettings[firstSensor.panel].fsrLowThreshold[firstSensor.sensor];
|
||||
config.panelSettings[panelAndSensor.panel].fsrHighThreshold[panelAndSensor.sensor] =
|
||||
config.panelSettings[firstSensor.panel].fsrHighThreshold[firstSensor.sensor];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SyncSliderThresholds()
|
||||
{
|
||||
foreach(Tuple<int,SMX.SMXConfig> activePad in ActivePad.ActivePads())
|
||||
{
|
||||
SMX.SMXConfig config = activePad.Item2;
|
||||
SyncSliderThresholdsForConfig(ref config);
|
||||
SMX.SMX.SetConfig(activePad.Item1, config);
|
||||
}
|
||||
|
||||
CurrentSMXDevice.singleton.FireConfigurationChanged(null);
|
||||
}
|
||||
|
||||
public static bool IsAdvancedModeRequired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This class just makes it easier to assemble binary command packets.
|
||||
@ -735,6 +877,11 @@ namespace smx_config
|
||||
}
|
||||
dict.Add("panelColors", panelColors);
|
||||
|
||||
dict.Add("advancedMode", Properties.Settings.Default.AdvancedMode);
|
||||
dict.Add("useOuterSensorThresholds", Properties.Settings.Default.UseOuterSensorThresholds);
|
||||
dict.Add("useInnerSensorThresholds", Properties.Settings.Default.UseInnerSensorThresholds);
|
||||
dict.Add("customSensors", ThresholdSettings.GetCustomSensorsJSON());
|
||||
|
||||
return SMXJSON.SerializeJSON.Serialize(dict);
|
||||
}
|
||||
|
||||
@ -798,6 +945,14 @@ namespace smx_config
|
||||
config.stepColor[PanelIndex*3+2] = color.B;
|
||||
}
|
||||
}
|
||||
|
||||
// Older exported settings don't have advancedMode. Set it to true if it's missing.
|
||||
Properties.Settings.Default.AdvancedMode = dict.Get<bool>("advancedMode", true);
|
||||
Properties.Settings.Default.UseOuterSensorThresholds = dict.Get<bool>("useOuterSensorThresholds", false);
|
||||
Properties.Settings.Default.UseInnerSensorThresholds = dict.Get<bool>("useInnerSensorThresholds", false);
|
||||
List<object> customSensors = dict.Get<List<object>>("customSensors", null);
|
||||
if(customSensors != null)
|
||||
ThresholdSettings.SetCustomSensorsJSON(customSensors);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -135,15 +135,15 @@ Use if the platform is too sensitive.</clr:String>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:ThresholdSlider}">
|
||||
<Grid Margin="0,0,0,0" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image
|
||||
<Grid Margin="0,0,0,0" Width="500" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<controls:PlatformSensorDisplay
|
||||
x:Name="PlatformSensorDisplay"
|
||||
Margin="-370,0,0,0"
|
||||
Height="28" Width="28"
|
||||
VerticalAlignment="Top"
|
||||
Source="{TemplateBinding Icon}"
|
||||
/>
|
||||
|
||||
<Label Margin="-300,0,0,0" x:Name="LowerValue" Content="0" Width="30" HorizontalContentAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Visibility="{Binding Path=SliderActive, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
/>
|
||||
<Image x:Name="ThresholdWarning"
|
||||
Source="Resources/threshold_warning.png" Width="9" Height="28"
|
||||
@ -158,10 +158,28 @@ Use if the platform is too sensitive.</clr:String>
|
||||
Width="240"
|
||||
Focusable="False"
|
||||
Style="{DynamicResource DoubleSlider}"
|
||||
IsEnabled="{Binding Path=SliderActive, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
/>
|
||||
<Label Margin="360,0,0,0" x:Name="UpperValue" Content="0" Width="40" HorizontalContentAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
VerticalAlignment="Top"
|
||||
Visibility="{Binding Path=SliderActive, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
/>
|
||||
|
||||
<!-- This is only shown for inner-sensors and outer-sensors. It's always hidden and
|
||||
checked for other sliders. -->
|
||||
<controls:ThresholdEnabledButton
|
||||
x:Name="EnabledCheckbox"
|
||||
controls:Type="{Binding Path=Type, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="-450,0,0,0"
|
||||
IsChecked="{Binding Path=ThresholdEnabled, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
/>
|
||||
|
||||
<Button
|
||||
x:Name="EditCustomSensorsButton"
|
||||
Visibility="Hidden"
|
||||
Content="Edit" Width="35" Height="30" Margin="-450 0 0 0" Padding="0 0" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
@ -333,7 +351,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
<Style TargetType="{x:Type controls:PanelColorButton}"
|
||||
BasedOn="{StaticResource {x:Type controls:ColorButton}}">
|
||||
|
||||
@ -601,7 +619,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
Text="Some sensors on this panel aren't responding correctly."
|
||||
/>
|
||||
</DockPanel>
|
||||
|
||||
|
||||
<DockPanel
|
||||
x:Name="BadSensorDIPSwitches"
|
||||
Width="200"
|
||||
@ -702,7 +720,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
<!-- P1, P2 labels in the top right: -->
|
||||
<Style x:Key="EnabledIcon" TargetType="Label">
|
||||
<Style.Triggers>
|
||||
@ -715,6 +733,76 @@ Use if the platform is too sensitive.</clr:String>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:PlatformSensorDisplay}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:PlatformSensorDisplay}">
|
||||
<Grid Width="34" Height="34">
|
||||
<controls:PanelIconWithSensors x:Name="Panel0" Margin="-22,-22,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel1" Margin=" 0,-22,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel2" Margin="+22,-22,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel3" Margin="-22, 0,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel4" Margin=" 0, 0,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel5" Margin="+22, 0,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel6" Margin="-22,+22,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel7" Margin=" 0,+22,0,0" />
|
||||
<controls:PanelIconWithSensors x:Name="Panel8" Margin="+22,+22,0,0" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- An icon that highlights sensors for a panel. -->
|
||||
<Style TargetType="{x:Type controls:PanelIconWithSensors}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:PanelIconWithSensors}">
|
||||
<Border Padding="1">
|
||||
<Grid Width="10" Height="10" Background="Black">
|
||||
<controls:PanelIconWithSensorsSensor x:Name="Sensor0"
|
||||
Width="2" Height="4" HorizontalAlignment="Left" Margin="1,0,0,0" />
|
||||
<controls:PanelIconWithSensorsSensor x:Name="Sensor1"
|
||||
Width="2" Height="4" HorizontalAlignment="Right" Margin="0,0,1,0" />
|
||||
<controls:PanelIconWithSensorsSensor x:Name="Sensor2"
|
||||
Width="4" Height="2" VerticalAlignment="Top" Margin="0,1,0,0" />
|
||||
<controls:PanelIconWithSensorsSensor x:Name="Sensor3"
|
||||
Width="4" Height="2" VerticalAlignment="Bottom" Margin="0,0,0,1"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:PanelIconWithSensorsSensor}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:PanelIconWithSensorsSensor}">
|
||||
<Border x:Name="border" BorderBrush="#000000" BorderThickness="0" SnapsToDevicePixels="true">
|
||||
<ContentPresenter
|
||||
SnapsToDevicePixels="true"
|
||||
Focusable="False"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Highlight" Value="0">
|
||||
<Setter Property="Background" TargetName="border" Value="#00000000"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Highlight" Value="1">
|
||||
<Setter Property="Background" TargetName="border" Value="#FFA0A0A0"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Highlight" Value="2">
|
||||
<Setter Property="Background" TargetName="border" Value="#FFFFFFFF"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Background="#DDD">
|
||||
@ -729,7 +817,12 @@ Use if the platform is too sensitive.</clr:String>
|
||||
SelectionChanged="MainTab_Selected">
|
||||
<TabItem Header="Settings">
|
||||
<Grid Background="#FFE5E5E5" RenderTransformOrigin="0.5,0.5">
|
||||
<StackPanel Margin="0,0,0,0" VerticalAlignment="Top">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80*"/>
|
||||
<ColumnDefinition Width="17*"/>
|
||||
<ColumnDefinition Width="416*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Margin="0,0,0,0" VerticalAlignment="Top" Grid.ColumnSpan="3">
|
||||
<TextBlock HorizontalAlignment="Center" Margin="0,15,0,10" VerticalAlignment="Top"
|
||||
TextAlignment="Center"
|
||||
xml:space="preserve" FontSize="16">Panel sensitivity</TextBlock>
|
||||
@ -769,7 +862,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
Leave this application running to play animations.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel
|
||||
Visibility="Visible"
|
||||
Name="ColorPickerGroup" HorizontalAlignment="Center" Orientation="Vertical">
|
||||
@ -795,7 +888,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
</Grid>
|
||||
<controls:FloorColorButton x:Name="P1_Floor" Pad="0" Content="=" Margin="0,0,0,0" />
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel x:Name="PanelColorP2" Orientation="Vertical">
|
||||
<Grid Width="100" Height="100">
|
||||
<controls:PanelColorButton x:Name="P2_0" Panel="9" Content="↖" Margin="-60,-50,0,0" />
|
||||
@ -827,7 +920,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
shifts it by a couple pixels, which makes it fidget around when we connect
|
||||
and disconnect. -->
|
||||
<Label x:Name="Version2" Content="Version"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="15" Margin="0 0 0 7" />
|
||||
HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="15" Margin="130,0,227,7" Grid.Column="2" />
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
@ -849,7 +942,7 @@ Use if the platform is too sensitive.</clr:String>
|
||||
<DockPanel Margin="0,0,0,0" VerticalAlignment="Top" x:Name="ThresholdSliderContainer">
|
||||
<!-- CreateThresholdSliders adds ThresholdSliders here. The slider below is only
|
||||
for the UI preview, and is removed on refresh. -->
|
||||
<controls:ThresholdSlider DockPanel.Dock="Top" controls:ThresholdSlider.Type="up-left" controls:ThresholdSlider.Icon="Resources/pad_up_left.png" Margin="0,8,0,0" />
|
||||
<controls:ThresholdSlider DockPanel.Dock="Top" controls:ThresholdSlider.Type="up-left" Margin="0,8,0,0" />
|
||||
</DockPanel>
|
||||
</ScrollViewer>
|
||||
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="0,25,0,0" VerticalAlignment="Top"
|
||||
@ -933,11 +1026,6 @@ instead of only panels with sensors.</TextBlock>
|
||||
<Button Content="Import" Width="50" Padding="5,2" Margin="5,10" Click="ImportSettings" />
|
||||
</StackPanel>
|
||||
|
||||
<Separator Margin="0,10,0,10" />
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
xml:space="preserve" FontSize="16">Aux sensors</TextBlock>
|
||||
<Button Content="Set auxilliary sensors" Width="140" Margin="0 10 0 0" Padding="0 4" Click="SetAuxSensors_Click"/>
|
||||
|
||||
<Separator Margin="0,10,0,10" />
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
xml:space="preserve" FontSize="16">Reset all settings</TextBlock>
|
||||
@ -950,7 +1038,7 @@ instead of only panels with sensors.</TextBlock>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
|
||||
<!-- A list of which pads are connected, overlapping the tab bar in the top right. -->
|
||||
<StackPanel x:Name="ConnectedPads" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Label Content="Connected:" FontSize="10"/>
|
||||
|
@ -69,39 +69,29 @@ namespace smx_config
|
||||
};
|
||||
}
|
||||
|
||||
List<string> thresholdSliderNames = new List<string>()
|
||||
{
|
||||
"up-left", "up", "up-right", "left", "center", "right", "down-left", "down", "down-right", "cardinal", "corner", "aux",
|
||||
};
|
||||
|
||||
Dictionary<string, string> thresholdToIcon = new Dictionary<string, string>()
|
||||
{
|
||||
{ "up-left", "Resources/pad_up_left.png" },
|
||||
{ "up", "Resources/pad_up.png" },
|
||||
{ "up-right", "Resources/pad_up_right.png" },
|
||||
{ "left", "Resources/pad_left.png" },
|
||||
{ "center", "Resources/pad_center.png" },
|
||||
{ "right", "Resources/pad_right.png" },
|
||||
{ "down-left", "Resources/pad_down_left.png" },
|
||||
{ "down", "Resources/pad_down.png" },
|
||||
{ "down-right","Resources/pad_down_right.png" },
|
||||
{ "cardinal", "Resources/pad_cardinal.png" },
|
||||
{ "corner", "Resources/pad_diagonal.png" },
|
||||
{ "aux", "Resources/pad_diagonal.png" },
|
||||
};
|
||||
|
||||
bool IsThresholdSliderShown(string type)
|
||||
{
|
||||
bool AdvancedModeEnabled = (bool)AdvancedModeEnabledCheckbox.IsChecked;
|
||||
bool AdvancedModeEnabled = Properties.Settings.Default.AdvancedMode;
|
||||
SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig();
|
||||
bool[] enabledPanels = config.GetEnabledPanels();
|
||||
|
||||
// Check the list of sensors this slider controls. If the list is empty, don't show it.
|
||||
// For example, if the user adds all four sensors on the up panel to aux, the up button
|
||||
// has nothing left to control, so we'll hide it.
|
||||
List<ThresholdSettings.PanelAndSensor> panelAndSensors = ThresholdSettings.GetControlledSensorsForSliderType(type, AdvancedModeEnabled);
|
||||
if(panelAndSensors.Count == 0)
|
||||
return false;
|
||||
// For example, if the user adds all four sensors on the up panel to custom-sensors, the
|
||||
// up button has nothing left to control, so we'll hide it.
|
||||
//
|
||||
// Don't do this for custom, inner-sensors or outer-sensors. Those are always shown in
|
||||
// advanced mode.
|
||||
List<ThresholdSettings.PanelAndSensor> panelAndSensors = ThresholdSettings.GetControlledSensorsForSliderType(type, AdvancedModeEnabled, false);
|
||||
if(type == "custom-sensors" || type == "inner-sensors" || type == "outer-sensors")
|
||||
{
|
||||
if(!AdvancedModeEnabled || !config.fsr())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(panelAndSensors.Count == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide thresholds that only affect panels that are disabled, so we don't show
|
||||
// corner panel sliders in advanced mode if the corner panels are disabled. We
|
||||
@ -131,24 +121,17 @@ namespace smx_config
|
||||
{
|
||||
ThresholdSlider slider = new ThresholdSlider();
|
||||
slider.Type = type;
|
||||
string iconPath = "pack://application:,,,/" + thresholdToIcon[type];
|
||||
slider.Icon = (new ImageSourceConverter()).ConvertFromString(iconPath) as ImageSource;
|
||||
return slider;
|
||||
}
|
||||
|
||||
void CreateThresholdSliders()
|
||||
{
|
||||
SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig();
|
||||
bool[] enabledPanels = config.GetEnabledPanels();
|
||||
|
||||
// remove the threshold sliders from xaml, create them all here
|
||||
//
|
||||
// remove the AdvancedModeEnabled binding and ShouldBeDisplayed, handle that here
|
||||
// by creating the ones we need
|
||||
//
|
||||
// then we can add custom sliders too
|
||||
ThresholdSliderContainer.Children.Clear();
|
||||
foreach(string sliderName in thresholdSliderNames)
|
||||
foreach(string sliderName in ThresholdSettings.thresholdSliderNames)
|
||||
{
|
||||
if(!IsThresholdSliderShown(sliderName))
|
||||
continue;
|
||||
@ -158,6 +141,8 @@ namespace smx_config
|
||||
slider.Margin = new Thickness(0, 8, 0, 0);
|
||||
ThresholdSliderContainer.Children.Add(slider);
|
||||
}
|
||||
|
||||
ThresholdSettings.SyncSliderThresholds();
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
@ -600,12 +585,6 @@ namespace smx_config
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAuxSensors_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SetAuxSensors dialog = new SetAuxSensors();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void UploadLatestGIF()
|
||||
{
|
||||
// Create a progress window. Center it on top of the main window.
|
||||
|
42
smx-config/Properties/Settings.Designer.cs
generated
@ -38,12 +38,48 @@ namespace smx_config.Properties {
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string AuxSensors {
|
||||
public string CustomSensors {
|
||||
get {
|
||||
return ((string)(this["AuxSensors"]));
|
||||
return ((string)(this["CustomSensors"]));
|
||||
}
|
||||
set {
|
||||
this["AuxSensors"] = value;
|
||||
this["CustomSensors"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool UseInnerSensorThresholds {
|
||||
get {
|
||||
return ((bool)(this["UseInnerSensorThresholds"]));
|
||||
}
|
||||
set {
|
||||
this["UseInnerSensorThresholds"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool UseOuterSensorThresholds {
|
||||
get {
|
||||
return ((bool)(this["UseOuterSensorThresholds"]));
|
||||
}
|
||||
set {
|
||||
this["UseOuterSensorThresholds"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool AdvancedMode {
|
||||
get {
|
||||
return ((bool)(this["AdvancedMode"]));
|
||||
}
|
||||
set {
|
||||
this["AdvancedMode"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,17 @@
|
||||
<Setting Name="LaunchOnStartup" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="AuxSensors" Type="System.String" Scope="User">
|
||||
<Setting Name="CustomSensors" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="UseInnerSensorThresholds" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="UseOuterSensorThresholds" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="AdvancedMode" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
@ -105,8 +105,8 @@
|
||||
<Compile Include="DiagnosticsWidgets.cs" />
|
||||
<Compile Include="DoubleSlider.cs" />
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="SetAuxSensors.xaml.cs">
|
||||
<DependentUpon>SetAuxSensors.xaml</DependentUpon>
|
||||
<Compile Include="SetCustomSensors.xaml.cs">
|
||||
<DependentUpon>SetCustomSensors.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ProgressWindow.xaml.cs">
|
||||
<DependentUpon>ProgressWindow.xaml</DependentUpon>
|
||||
@ -126,7 +126,7 @@
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="SetAuxSensors.xaml">
|
||||
<Page Include="SetCustomSensors.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@ -174,14 +174,6 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\pad_cardinal.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\pad_center.png" />
|
||||
<Resource Include="Resources\pad_diagonal.png" />
|
||||
<Resource Include="Resources\pad_up.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\window icon.png" />
|
||||
</ItemGroup>
|
||||
@ -191,15 +183,6 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="window icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\pad_down.png" />
|
||||
<Resource Include="Resources\pad_down_left.png" />
|
||||
<Resource Include="Resources\pad_down_right.png" />
|
||||
<Resource Include="Resources\pad_left.png" />
|
||||
<Resource Include="Resources\pad_right.png" />
|
||||
<Resource Include="Resources\pad_up_left.png" />
|
||||
<Resource Include="Resources\pad_up_right.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\sdk\Windows\SMX.vcxproj">
|
||||
<Project>{c5fc0823-9896-4b7c-bfe1-b60db671a462}</Project>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<Window x:Class="smx_config.SetAuxSensors"
|
||||
<Window x:Class="smx_config.SetCustomSensors"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@ -6,7 +6,7 @@
|
||||
mc:Ignorable="d"
|
||||
Icon="Resources/window icon.png"
|
||||
Background="#DDD"
|
||||
Height="418" Width="325" ResizeMode="NoResize"
|
||||
Height="422" Width="325" ResizeMode="NoResize"
|
||||
xmlns:controls="clr-namespace:smx_config"
|
||||
x:Name="root"
|
||||
Title="Select Auxilliary Sensors"
|
||||
@ -52,15 +52,14 @@
|
||||
<ControlTemplate TargetType="{x:Type controls:SensorSelector}">
|
||||
<Border Padding="1">
|
||||
<Grid Width="70" Height="70">
|
||||
<!-- XXX: the order of these is wrong -->
|
||||
<controls:SensorSelectionButton x:Name="Sensor0" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="40" Height="13" VerticalAlignment="Top" />
|
||||
<controls:SensorSelectionButton x:Name="Sensor1" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="40" Height="13" VerticalAlignment="Bottom" />
|
||||
<controls:SensorSelectionButton x:Name="Sensor2" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="13" Height="40" HorizontalAlignment="Left" />
|
||||
<controls:SensorSelectionButton x:Name="Sensor3" Style="{StaticResource SensorSelectionButton}"
|
||||
<controls:SensorSelectionButton x:Name="Sensor1" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="13" Height="40" HorizontalAlignment="Right" />
|
||||
<controls:SensorSelectionButton x:Name="Sensor2" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="40" Height="13" VerticalAlignment="Top" />
|
||||
<controls:SensorSelectionButton x:Name="Sensor3" Style="{StaticResource SensorSelectionButton}"
|
||||
Width="40" Height="13" VerticalAlignment="Bottom" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
@ -50,22 +50,25 @@ namespace smx_config
|
||||
{
|
||||
// Toggle the clicked sensor.
|
||||
Console.WriteLine("Clicked sensor " + sensor);
|
||||
List<ThresholdSettings.PanelAndSensor> auxSensors = ThresholdSettings.GetAuxSensors();
|
||||
bool enabled = !IsSensorEnabled(auxSensors, sensor);
|
||||
List<ThresholdSettings.PanelAndSensor> customSensors = ThresholdSettings.GetCustomSensors();
|
||||
bool enabled = !IsSensorEnabled(customSensors, sensor);
|
||||
|
||||
if(enabled)
|
||||
auxSensors.Add(new ThresholdSettings.PanelAndSensor(Panel, sensor));
|
||||
customSensors.Add(new ThresholdSettings.PanelAndSensor(Panel, sensor));
|
||||
else
|
||||
auxSensors.Remove(new ThresholdSettings.PanelAndSensor(Panel, sensor));
|
||||
ThresholdSettings.SetAuxSensors(auxSensors);
|
||||
customSensors.Remove(new ThresholdSettings.PanelAndSensor(Panel, sensor));
|
||||
ThresholdSettings.SetCustomSensors(customSensors);
|
||||
|
||||
// Sync thresholds after changing custom sensors.
|
||||
ThresholdSettings.SyncSliderThresholds();
|
||||
|
||||
CurrentSMXDevice.singleton.FireConfigurationChanged(this);
|
||||
}
|
||||
|
||||
// Return true if the given sensor is marked as an aux sensor.
|
||||
bool IsSensorEnabled(List<ThresholdSettings.PanelAndSensor> auxSensors, int sensor)
|
||||
// Return true if the given sensor is included in custom-sensors.
|
||||
bool IsSensorEnabled(List<ThresholdSettings.PanelAndSensor> customSensors, int sensor)
|
||||
{
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in auxSensors)
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in customSensors)
|
||||
{
|
||||
if(panelAndSensor.panel == Panel && panelAndSensor.sensor == sensor)
|
||||
return true;
|
||||
@ -75,18 +78,18 @@ namespace smx_config
|
||||
|
||||
private void LoadUIFromConfig(LoadFromConfigDelegateArgs args)
|
||||
{
|
||||
// Check the selected aux sensors.
|
||||
List<ThresholdSettings.PanelAndSensor> auxSensors = ThresholdSettings.GetAuxSensors();
|
||||
// Check the selected custom-sensors.
|
||||
List<ThresholdSettings.PanelAndSensor> customSensors = ThresholdSettings.GetCustomSensors();
|
||||
for(int sensor = 0; sensor < 4; ++sensor)
|
||||
SensorSelectionButtons[sensor].IsChecked = IsSensorEnabled(auxSensors, sensor);
|
||||
SensorSelectionButtons[sensor].IsChecked = IsSensorEnabled(customSensors, sensor);
|
||||
}
|
||||
}
|
||||
|
||||
// This dialog sets which sensors are controlled by the auxilliary threshold. The actual
|
||||
// work is done by SensorSelector above.
|
||||
public partial class SetAuxSensors: Window
|
||||
// This dialog sets which sensors are controlled by custom-sensors. The actual work is done
|
||||
// by SensorSelector above.
|
||||
public partial class SetCustomSensors: Window
|
||||
{
|
||||
public SetAuxSensors()
|
||||
public SetCustomSensors()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
@ -12,11 +12,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace smx_config
|
||||
{
|
||||
// The checkbox to enable and disable the advanced per-panel sliders.
|
||||
//
|
||||
// This is always enabled if the thresholds in the configuration are set to different
|
||||
// values. If the user enables us, we'll remember that we were forced on. If the user
|
||||
// disables us, we'll sync the thresholds back up and turn the ForcedOn flag off.
|
||||
// The checkbox to enable and disable the advanced per-panel sliders (Settings.Default.AdvancedMode).
|
||||
public class AdvancedThresholdViewCheckbox: CheckBox
|
||||
{
|
||||
public static readonly DependencyProperty AdvancedModeEnabledProperty = DependencyProperty.Register("AdvancedModeEnabled",
|
||||
@ -28,10 +24,6 @@ namespace smx_config
|
||||
|
||||
OnConfigChange onConfigChange;
|
||||
|
||||
// If true, the user enabled advanced view and we should display it even if
|
||||
// the thresholds happen to be synced. If false, we'll only show the advanced
|
||||
// view if we need to because the thresholds aren't synced.
|
||||
bool ForcedOn;
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
@ -48,38 +40,21 @@ namespace smx_config
|
||||
bool SupportsAdvancedMode = config.masterVersion != 0xFF && config.masterVersion >= 2;
|
||||
Visibility = SupportsAdvancedMode? Visibility.Visible:Visibility.Collapsed;
|
||||
|
||||
// If the thresholds are different, force the checkbox on. This way, if you load the application
|
||||
// with a platform with per-panel thresholds, and change the thresholds to no longer be different,
|
||||
// advanced mode stays forced on. It'll only turn off if you uncheck the box, or if you exit
|
||||
// the application with synced thresholds and then restart it.
|
||||
if(SupportsAdvancedMode && !ConfigPresets.AreUnifiedThresholdsSynced(config))
|
||||
ForcedOn = true;
|
||||
// If the controller doesn't support advanced mode, make sure advanced mode is disabled.
|
||||
if(!SupportsAdvancedMode)
|
||||
Properties.Settings.Default.AdvancedMode = false;
|
||||
|
||||
// Enable advanced mode if the master says it's supported, and either the user has checked the
|
||||
// box to turn it on or the thresholds are different in the current configuration.
|
||||
AdvancedModeEnabled = SupportsAdvancedMode && ForcedOn;
|
||||
AdvancedModeEnabled = Properties.Settings.Default.AdvancedMode;
|
||||
}
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
if(AdvancedModeEnabled)
|
||||
Properties.Settings.Default.AdvancedMode = !Properties.Settings.Default.AdvancedMode;
|
||||
if(!Properties.Settings.Default.AdvancedMode)
|
||||
{
|
||||
// Stop forcing advanced mode on, and sync the thresholds so we exit advanced mode.
|
||||
ForcedOn = false;
|
||||
|
||||
foreach(Tuple<int,SMX.SMXConfig> activePad in ActivePad.ActivePads())
|
||||
{
|
||||
int pad = activePad.Item1;
|
||||
SMX.SMXConfig config = activePad.Item2;
|
||||
ConfigPresets.SyncUnifiedThresholds(ref config);
|
||||
SMX.SMX.SetConfig(pad, config);
|
||||
}
|
||||
CurrentSMXDevice.singleton.FireConfigurationChanged(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable advanced mode.
|
||||
ForcedOn = true;
|
||||
// Sync thresholds when we exit advanced mode. XXX: not needed since MainWindow is recreating
|
||||
// sliders anyway
|
||||
ThresholdSettings.SyncSliderThresholds();
|
||||
}
|
||||
|
||||
// Refresh the UI.
|
||||
@ -90,14 +65,6 @@ namespace smx_config
|
||||
// This implements the threshold slider widget for changing an upper/lower threshold pair.
|
||||
public class ThresholdSlider: Control
|
||||
{
|
||||
public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon",
|
||||
typeof(ImageSource), typeof(ThresholdSlider), new FrameworkPropertyMetadata(null));
|
||||
|
||||
public ImageSource Icon {
|
||||
get { return (ImageSource) GetValue(IconProperty); }
|
||||
set { SetValue(IconProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type",
|
||||
typeof(string), typeof(ThresholdSlider), new FrameworkPropertyMetadata(""));
|
||||
|
||||
@ -106,6 +73,27 @@ namespace smx_config
|
||||
set { SetValue(TypeProperty, value); }
|
||||
}
|
||||
|
||||
// If false, this threshold hasn't been enabled by the user. The slider will be greyed out. This
|
||||
// is different from our own IsEnabled, since setting that to false would also disable EnabledCheckbox,
|
||||
// preventing it from being turned back on.
|
||||
public static readonly DependencyProperty ThresholdEnabledProperty = DependencyProperty.Register("ThresholdEnabled",
|
||||
typeof(bool), typeof(ThresholdSlider), new FrameworkPropertyMetadata(true));
|
||||
|
||||
public bool ThresholdEnabled {
|
||||
get { return (bool) GetValue(ThresholdEnabledProperty); }
|
||||
set { SetValue(ThresholdEnabledProperty, value); }
|
||||
}
|
||||
|
||||
// This is set to true if the slider is enabled and the low/high values are displayed. We set this to
|
||||
// false when the slider is disabled (or has no selected sensors, for custom-sliders).
|
||||
public static readonly DependencyProperty SliderActiveProperty = DependencyProperty.Register("SliderActive",
|
||||
typeof(bool), typeof(ThresholdSlider), new FrameworkPropertyMetadata(true));
|
||||
|
||||
public bool SliderActive {
|
||||
get { return (bool) GetValue(SliderActiveProperty); }
|
||||
set { SetValue(SliderActiveProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty AdvancedModeEnabledProperty = DependencyProperty.Register("AdvancedModeEnabled",
|
||||
typeof(bool), typeof(ThresholdSlider), new FrameworkPropertyMetadata(false));
|
||||
|
||||
@ -117,6 +105,7 @@ namespace smx_config
|
||||
DoubleSlider slider;
|
||||
Label LowerLabel, UpperLabel;
|
||||
Image ThresholdWarning;
|
||||
PlatformSensorDisplay SensorDisplay;
|
||||
|
||||
OnConfigChange onConfigChange;
|
||||
|
||||
@ -128,27 +117,46 @@ namespace smx_config
|
||||
LowerLabel = GetTemplateChild("LowerValue") as Label;
|
||||
UpperLabel = GetTemplateChild("UpperValue") as Label;
|
||||
ThresholdWarning = GetTemplateChild("ThresholdWarning") as Image;
|
||||
SensorDisplay = GetTemplateChild("PlatformSensorDisplay") as PlatformSensorDisplay;
|
||||
|
||||
slider.ValueChanged += delegate(DoubleSlider slider) { SaveToConfig(); };
|
||||
|
||||
// Show the edit button for the custom-sensors slider.
|
||||
Button EditCustomSensorsButton = GetTemplateChild("EditCustomSensorsButton") as Button;
|
||||
EditCustomSensorsButton.Visibility = Type == "custom-sensors"? Visibility.Visible:Visibility.Hidden;
|
||||
EditCustomSensorsButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SetCustomSensors dialog = new SetCustomSensors();
|
||||
dialog.Owner = Window.GetWindow(this);
|
||||
dialog.ShowDialog();
|
||||
};
|
||||
|
||||
onConfigChange = new OnConfigChange(this, delegate (LoadFromConfigDelegateArgs args) {
|
||||
LoadUIFromConfig(ActivePad.GetFirstActivePadConfig(args));
|
||||
});
|
||||
}
|
||||
|
||||
private void RefreshSliderActiveProperty()
|
||||
{
|
||||
if(Type == "custom-sensors")
|
||||
SliderActive = ThresholdSettings.GetCustomSensors().Count > 0;
|
||||
else
|
||||
SliderActive = ThresholdEnabled;
|
||||
}
|
||||
|
||||
// Return the panel/sensors this widget controls.
|
||||
//
|
||||
// This returns values for FSRs. We don't configure individual sensors with load cells,
|
||||
// and the sensor value will be ignored.
|
||||
private List<ThresholdSettings.PanelAndSensor> GetControlledSensors()
|
||||
private List<ThresholdSettings.PanelAndSensor> GetControlledSensors(bool includeOverridden)
|
||||
{
|
||||
return ThresholdSettings.GetControlledSensorsForSliderType(Type, AdvancedModeEnabled);
|
||||
return ThresholdSettings.GetControlledSensorsForSliderType(Type, AdvancedModeEnabled, includeOverridden);
|
||||
}
|
||||
|
||||
|
||||
private void SetValueToConfig(ref SMX.SMXConfig config)
|
||||
{
|
||||
List<ThresholdSettings.PanelAndSensor> panelAndSensors = GetControlledSensors();
|
||||
List<ThresholdSettings.PanelAndSensor> panelAndSensors = GetControlledSensors(false);
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in panelAndSensors)
|
||||
{
|
||||
if(!config.fsr())
|
||||
@ -171,7 +179,7 @@ namespace smx_config
|
||||
lower = upper = 0;
|
||||
|
||||
// Use the first controlled sensor. The rest should be the same.
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in GetControlledSensors())
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in GetControlledSensors(false))
|
||||
{
|
||||
if(!config.fsr())
|
||||
{
|
||||
@ -208,6 +216,8 @@ namespace smx_config
|
||||
// Make sure SaveToConfig doesn't treat these as the user changing values.
|
||||
UpdatingUI = true;
|
||||
|
||||
RefreshSliderActiveProperty();
|
||||
|
||||
// Set the range for the slider.
|
||||
if(config.fsr())
|
||||
{
|
||||
@ -240,8 +250,9 @@ namespace smx_config
|
||||
UpperLabel.Content = upper.ToString();
|
||||
}
|
||||
|
||||
List<ThresholdSettings.PanelAndSensor> controlledSensors = GetControlledSensors(false);
|
||||
bool ShowThresholdWarning = false;
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in GetControlledSensors())
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in controlledSensors)
|
||||
{
|
||||
if(config.ShowThresholdWarning(panelAndSensor.panel, panelAndSensor.sensor))
|
||||
ShowThresholdWarning = true;
|
||||
@ -249,10 +260,74 @@ namespace smx_config
|
||||
|
||||
ThresholdWarning.Visibility = ShowThresholdWarning? Visibility.Visible:Visibility.Hidden;
|
||||
|
||||
// SensorDisplay shows which sensors we control. If this sensor is enabled, show the
|
||||
// sensors this sensor controls.
|
||||
//
|
||||
// If we're disabled, the icon will be empty. That looks
|
||||
// weird, so in that case we show
|
||||
// Set the icon next to the slider to show which sensors we control.
|
||||
List<ThresholdSettings.PanelAndSensor> defaultControlledSensors = GetControlledSensors(true);
|
||||
SensorDisplay.SetFromPanelAndSensors(controlledSensors, defaultControlledSensors);
|
||||
|
||||
UpdatingUI = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The checkbox next to the threshold slider to turn it on or off. This is only used
|
||||
// for inner-sensors and outer-sensors, and hides itself automatically for others.
|
||||
public class ThresholdEnabledButton: CheckBox
|
||||
{
|
||||
// Which threshold slider this is for. This is bound to ThresholdSlider.Type above.
|
||||
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type",
|
||||
typeof(string), typeof(ThresholdEnabledButton), new FrameworkPropertyMetadata(""));
|
||||
public string Type {
|
||||
get { return (string) GetValue(TypeProperty); }
|
||||
set { SetValue(TypeProperty, value); }
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
if(Type != "inner-sensors" && Type != "outer-sensors")
|
||||
{
|
||||
Visibility = Visibility.Hidden;
|
||||
IsChecked = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Checked += delegate(object sender, RoutedEventArgs e) { SaveToSettings(); };
|
||||
Unchecked += delegate(object sender, RoutedEventArgs e) { SaveToSettings(); };
|
||||
|
||||
OnConfigChange onConfigChange;
|
||||
onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) {
|
||||
LoadFromSettings();
|
||||
});
|
||||
}
|
||||
|
||||
private void LoadFromSettings()
|
||||
{
|
||||
if(Type == "inner-sensors")
|
||||
IsChecked = Properties.Settings.Default.UseInnerSensorThresholds;
|
||||
else if(Type == "outer-sensors")
|
||||
IsChecked = Properties.Settings.Default.UseOuterSensorThresholds;
|
||||
}
|
||||
|
||||
private void SaveToSettings()
|
||||
{
|
||||
if(Type == "inner-sensors")
|
||||
Properties.Settings.Default.UseInnerSensorThresholds = (bool) IsChecked;
|
||||
else if(Type == "outer-sensors")
|
||||
Properties.Settings.Default.UseOuterSensorThresholds = (bool) IsChecked;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
// Sync thresholds after enabling or disabling a slider.
|
||||
ThresholdSettings.SyncSliderThresholds();
|
||||
|
||||
CurrentSMXDevice.singleton.FireConfigurationChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
// A button with a selectable highlight.
|
||||
public class SelectableButton: Button
|
||||
{
|
||||
@ -1009,4 +1084,79 @@ namespace smx_config
|
||||
CurrentSMXDevice.singleton.FireConfigurationChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class PanelIconWithSensorsSensor: Control
|
||||
{
|
||||
// 0: black
|
||||
// 1: dim highlight
|
||||
// 2: bright highlight
|
||||
public static readonly DependencyProperty HighlightProperty = DependencyProperty.Register("Highlight",
|
||||
typeof(int), typeof(PanelIconWithSensorsSensor), new FrameworkPropertyMetadata(0));
|
||||
public int Highlight {
|
||||
get { return (int) GetValue(HighlightProperty); }
|
||||
set { SetValue(HighlightProperty, value); }
|
||||
}
|
||||
}
|
||||
|
||||
// A control with one button for each of four sensors:
|
||||
class PanelIconWithSensors: Control
|
||||
{
|
||||
PanelIconWithSensorsSensor[] panelIconWithSensorsSensor;
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
panelIconWithSensorsSensor = new PanelIconWithSensorsSensor[4];
|
||||
for(int sensor = 0; sensor < 4; ++sensor)
|
||||
panelIconWithSensorsSensor[sensor] = GetTemplateChild("Sensor" + sensor) as PanelIconWithSensorsSensor;
|
||||
}
|
||||
|
||||
|
||||
public PanelIconWithSensorsSensor GetSensorControl(int sensor)
|
||||
{
|
||||
return panelIconWithSensorsSensor[sensor];
|
||||
}
|
||||
}
|
||||
|
||||
public class PlatformSensorDisplay: Control
|
||||
{
|
||||
PanelIconWithSensors[] panelIconWithSensors;
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
panelIconWithSensors = new PanelIconWithSensors[9];
|
||||
for(int panel = 0; panel < 9; ++panel)
|
||||
panelIconWithSensors[panel] = GetTemplateChild("Panel" + panel) as PanelIconWithSensors;
|
||||
}
|
||||
|
||||
private PanelIconWithSensorsSensor GetSensor(int panel, int sensor)
|
||||
{
|
||||
return panelIconWithSensors[panel].GetSensorControl(sensor);
|
||||
}
|
||||
|
||||
// Highlight the sensors included in panelAndSensors, and dimly highlight the sensors in
|
||||
// disabledPanelAndSensors. If a sensor is in both lists, panelAndSensors takes priority.
|
||||
public void SetFromPanelAndSensors(
|
||||
List<ThresholdSettings.PanelAndSensor> panelAndSensors,
|
||||
List<ThresholdSettings.PanelAndSensor> disabledPanelAndSensors)
|
||||
{
|
||||
UnhighlightAllSensors();
|
||||
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in disabledPanelAndSensors)
|
||||
GetSensor(panelAndSensor.panel, panelAndSensor.sensor).Highlight = 1;
|
||||
foreach(ThresholdSettings.PanelAndSensor panelAndSensor in panelAndSensors)
|
||||
GetSensor(panelAndSensor.panel, panelAndSensor.sensor).Highlight = 2;
|
||||
}
|
||||
|
||||
// Clear all sensor highlighting.
|
||||
public void UnhighlightAllSensors()
|
||||
{
|
||||
for(int panel = 0; panel < 9; ++panel)
|
||||
{
|
||||
for(int sensor = 0; sensor < 4; ++sensor)
|
||||
GetSensor(panel, sensor).Highlight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|