Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
706 changes: 706 additions & 0 deletions Helios/Controls/DualPotentiometer.cs

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions Helios/Controls/DualPotentiometerAppearanceEditor.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<HeliosSdk:HeliosPropertyEditor x:Class="GadrocsWorkshop.Helios.Controls.DualPotentiometerAppearanceEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:HeliosSdk="clr-namespace:GadrocsWorkshop.Helios.Windows.Controls"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Height="Auto" d:DesignWidth="180">
<Grid Background="Transparent" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="50"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="4,10,2,2" Style="{StaticResource Heading2}">Pot 1 (Lower)</TextBlock>
<Label Grid.Column="0" Grid.Row="1" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Image used for pot 1, the lower pot. It is rotated about the center of the control.</Label.ToolTip> Image
</Label>
<HeliosSdk:ImagePicker Grid.Column="1" Grid.Row="1" ImageFilename="{Binding Control.Potentiometer1Image, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="2" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Size of the pot 1 image relative to the control. At the far right the image fills the control.</Label.ToolTip> Scale
</Label>
<Slider Grid.Column="1" Grid.Row="2" Minimum="0" Maximum="1" Value="{Binding Control.Potentiometer1Scale}" Margin="2" TickPlacement="BottomRight" TickFrequency="0.1"/>
<Label Grid.Column="0" Grid.Row="3" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Rotation of pot 1 at its minimum value when pot 2 is also at its minimum value.</Label.ToolTip> Initial
</Label>
<Slider Grid.Column="1" Grid.Row="3" Minimum="0" Maximum="360" Value="{Binding Control.Potentiometer1InitialRotation}" Margin="2" GotFocus="Potentiometer1InitialRotation_GotFocus"/>
<Label Grid.Column="0" Grid.Row="4" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Degrees pot 1 turns between its minimum and maximum value, measured relative to pot 2 when it follows pot 2.</Label.ToolTip> Travel
</Label>
<Slider Grid.Column="1" Grid.Row="4" Minimum="0" Maximum="360" Value="{Binding Control.Potentiometer1RotationTravel}" Margin="2" GotFocus="Potentiometer1RotationTravel_GotFocus"/>
<Label Grid.Column="0" Grid.Row="5" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>When set, pot 1 turns counter-clockwise as its value increases.</Label.ToolTip> Reverse
</Label>
<CheckBox Grid.Column="1" Grid.Row="5" VerticalAlignment="Top" Margin="0,6,6,6" IsChecked="{Binding Path=Control.Potentiometer1CounterClockwise}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="6" Margin="4,10,2,2" Style="{StaticResource Heading2}">Pot 2 (Upper)</TextBlock>
<Label Grid.Column="0" Grid.Row="7" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Image used for pot 2, the upper pot. It is rotated about the center of the control.</Label.ToolTip> Image
</Label>
<HeliosSdk:ImagePicker Grid.Column="1" Grid.Row="7" ImageFilename="{Binding Control.Potentiometer2Image, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="8" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Size of the pot 2 image relative to the control. At the far right the image fills the control. The mouse wheel turns pot 2 while the pointer is over this image, and pot 1 elsewhere.</Label.ToolTip> Scale
</Label>
<Slider Grid.Column="1" Grid.Row="8" Minimum="0" Maximum="1" Value="{Binding Control.Potentiometer2Scale}" Margin="2" TickPlacement="BottomRight" TickFrequency="0.1"/>
<Label Grid.Column="0" Grid.Row="9" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Rotation of pot 2 at its minimum value when pot 1 is also at its minimum value.</Label.ToolTip> Initial
</Label>
<Slider Grid.Column="1" Grid.Row="9" Minimum="0" Maximum="360" Value="{Binding Control.Potentiometer2InitialRotation}" Margin="2" GotFocus="Potentiometer2InitialRotation_GotFocus"/>
<Label Grid.Column="0" Grid.Row="10" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Degrees pot 2 turns between its minimum and maximum value, measured relative to pot 1 when it follows pot 1.</Label.ToolTip> Travel
</Label>
<Slider Grid.Column="1" Grid.Row="10" Minimum="0" Maximum="360" Value="{Binding Control.Potentiometer2RotationTravel}" Margin="2" GotFocus="Potentiometer2RotationTravel_GotFocus"/>
<Label Grid.Column="0" Grid.Row="11" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>When set, pot 2 turns counter-clockwise as its value increases, which is the opposite direction to pot 1 if pot 1 is not reversed.</Label.ToolTip> Reverse
</Label>
<CheckBox Grid.Column="1" Grid.Row="11" VerticalAlignment="Top" Margin="0,6,6,6" IsChecked="{Binding Path=Control.Potentiometer2CounterClockwise}" />
<Label Grid.Column="0" Grid.Row="12" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>When set, pot 2 is drawn over pot 1. Clear this to draw pot 1 over pot 2.</Label.ToolTip> On Top
</Label>
<CheckBox Grid.Column="1" Grid.Row="12" VerticalAlignment="Top" Margin="0,6,6,6" IsChecked="{Binding Path=Control.Potentiometer2OnTop}" />
</Grid>
</HeliosSdk:HeliosPropertyEditor>
73 changes: 73 additions & 0 deletions Helios/Controls/DualPotentiometerAppearanceEditor.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2014 Craig Courtney
// Copyright 2026 Helios Contributors
//
// Helios is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Helios is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

namespace GadrocsWorkshop.Helios.Controls
{
using GadrocsWorkshop.Helios.ComponentModel;
using GadrocsWorkshop.Helios.Windows.Controls;
using System.Windows;

/// <summary>
/// Interaction logic for DualPotentiometerAppearanceEditor.xaml
/// </summary>
[HeliosPropertyEditor("Helios.Base.DualPotentiometer", "Appearance")]
public partial class DualPotentiometerAppearanceEditor : HeliosPropertyEditor
{
public DualPotentiometerAppearanceEditor()
{
InitializeComponent();
}

// while a rotation slider is being adjusted, move the pots to the position that slider
// describes, so the effect can be seen in the editor

private void Potentiometer1InitialRotation_GotFocus(object sender, RoutedEventArgs e)
{
if (Control is DualPotentiometer pots)
{
pots.Potentiometer1Value = pots.Potentiometer1MinValue;
pots.Potentiometer2Value = pots.Potentiometer2MinValue;
}
}

private void Potentiometer1RotationTravel_GotFocus(object sender, RoutedEventArgs e)
{
if (Control is DualPotentiometer pots)
{
pots.Potentiometer1Value = pots.Potentiometer1MaxValue;
pots.Potentiometer2Value = pots.Potentiometer2MinValue;
}
}

private void Potentiometer2InitialRotation_GotFocus(object sender, RoutedEventArgs e)
{
if (Control is DualPotentiometer pots)
{
pots.Potentiometer1Value = pots.Potentiometer1MinValue;
pots.Potentiometer2Value = pots.Potentiometer2MinValue;
}
}

private void Potentiometer2RotationTravel_GotFocus(object sender, RoutedEventArgs e)
{
if (Control is DualPotentiometer pots)
{
pots.Potentiometer1Value = pots.Potentiometer1MinValue;
pots.Potentiometer2Value = pots.Potentiometer2MaxValue;
}
}
}
}
89 changes: 89 additions & 0 deletions Helios/Controls/DualPotentiometerBehaviorEditor.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<HeliosSdk:HeliosPropertyEditor x:Class="GadrocsWorkshop.Helios.Controls.DualPotentiometerBehaviorEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:Helios="clr-namespace:GadrocsWorkshop.Helios"
xmlns:HeliosBase="clr-namespace:GadrocsWorkshop.Helios.Controls"
xmlns:HeliosSdk="clr-namespace:GadrocsWorkshop.Helios.Windows.Controls"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Height="Auto" d:DesignWidth="180">
<Grid Background="Transparent" Margin="4">
<Grid.Resources>
<Helios:EnumConverter Type="{x:Type HeliosBase:DualPotentiometerFollowMode}" x:Key="FollowModes" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="80"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="4,10,2,2" Style="{StaticResource Heading2}">Pot 1 (Lower) Value</TextBlock>
<Label Grid.Column="0" Grid.Row="1" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Name used for pot 1 in the bindings lists. Changing it does not break existing bindings.</Label.ToolTip> Name
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="1" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer1Name}" />
<Label Grid.Column="0" Grid.Row="2" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Value of pot 1 when a profile is started or reset.</Label.ToolTip> Initial
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="2" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer1InitialValue}" />
<Label Grid.Column="0" Grid.Row="3" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Input value at which pot 1 is at its initial rotation.</Label.ToolTip> Min
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="3" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer1MinValue}" />
<Label Grid.Column="0" Grid.Row="4" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Input value at which pot 1 has turned through its full rotation travel.</Label.ToolTip> Max
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="4" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer1MaxValue}" />
<Label Grid.Column="0" Grid.Row="5" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Amount the value of pot 1 changes for each click of the mouse wheel.</Label.ToolTip> Step
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="5" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer1StepValue}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="6" Margin="4,10,2,2" Style="{StaticResource Heading2}">Pot 2 (Upper) Value</TextBlock>
<Label Grid.Column="0" Grid.Row="7" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Name used for pot 2 in the bindings lists. Changing it does not break existing bindings.</Label.ToolTip> Name
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="7" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer2Name}" />
<Label Grid.Column="0" Grid.Row="8" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Value of pot 2 when a profile is started or reset.</Label.ToolTip> Initial
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="8" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer2InitialValue}" />
<Label Grid.Column="0" Grid.Row="9" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Input value at which pot 2 is at its initial rotation.</Label.ToolTip> Min
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="9" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer2MinValue}" />
<Label Grid.Column="0" Grid.Row="10" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Input value at which pot 2 has turned through its full rotation travel.</Label.ToolTip> Max
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="10" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer2MaxValue}" />
<Label Grid.Column="0" Grid.Row="11" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Amount the value of pot 2 changes for each click of the mouse wheel.</Label.ToolTip> Step
</Label>
<HeliosSdk:HeliosTextBox Grid.Column="1" Grid.Row="11" FontSize="10" Margin="2" Text="{Binding Control.Potentiometer2StepValue}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="12" Margin="4,10,2,2" Style="{StaticResource Heading2}">Linkage</TextBlock>
<Label Grid.Column="0" Grid.Row="13" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>Selects which pot is carried around by the other one. The following pot's own value turns it relative to the pot it follows. Choose Independent to have neither pot follow the other.</Label.ToolTip> Follow
</Label>
<ComboBox Grid.Column="1" Grid.Row="13" FontSize="10" Margin="0,2,0,2" HorizontalAlignment="Stretch" ItemsSource="{Binding Source={StaticResource FollowModes}, Path=DisplayNames}" SelectedItem="{Binding Path=Control.FollowMode, Converter={StaticResource FollowModes}}" />
<Label Grid.Column="0" Grid.Row="14" FontSize="10" HorizontalAlignment="Right">
<Label.ToolTip>When set, the mouse wheel turns pot 2 while the pointer is over the pot 2 image, and pot 1 anywhere else on the control.</Label.ToolTip> Mouse Wheel
</Label>
<CheckBox Grid.Column="1" Grid.Row="14" VerticalAlignment="Top" Margin="0,6,6,6" IsChecked="{Binding Path=Control.MouseWheelAction}" />
</Grid>
</HeliosSdk:HeliosPropertyEditor>
33 changes: 33 additions & 0 deletions Helios/Controls/DualPotentiometerBehaviorEditor.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2014 Craig Courtney
// Copyright 2026 Helios Contributors
//
// Helios is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Helios is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

namespace GadrocsWorkshop.Helios.Controls
{
using GadrocsWorkshop.Helios.ComponentModel;
using GadrocsWorkshop.Helios.Windows.Controls;

/// <summary>
/// Interaction logic for DualPotentiometerBehaviorEditor.xaml
/// </summary>
[HeliosPropertyEditor("Helios.Base.DualPotentiometer", "Behavior")]
public partial class DualPotentiometerBehaviorEditor : HeliosPropertyEditor
{
public DualPotentiometerBehaviorEditor()
{
InitializeComponent();
}
}
}
Loading