Skip to content
Merged
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
21 changes: 17 additions & 4 deletions RadialActions.Tests/Actions/ActionsSettingsViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,33 @@ public void SelectAction_SelectsMatchingAction()
}

[Fact]
public void AddAction_AppendsBlankActionAndSelectsIt()
public void AddAction_InsertsBlankActionAfterSelectedActionAndSelectsIt()
{
var viewModel = CreateViewModel(PieAction.CreateKeyAction("Mute"));
var first = PieAction.CreateKeyAction("Mute");
var second = PieAction.CreateKeyAction("VolumeUp");
var third = PieAction.CreateKeyAction("VolumeDown");
var viewModel = CreateViewModel(first, second, third);
viewModel.SelectAction(second);

viewModel.AddActionCommand.Execute(null);

var added = Assert.Single(viewModel.Actions.Skip(1));
var added = viewModel.Actions[2];
Assert.Equal([first, second, added, third], viewModel.Actions);
Assert.Equal("Blank action", added.Name);
Assert.Equal(ActionType.None, added.Type);
Assert.Same(added, viewModel.SelectedAction);
Assert.Equal(1, viewModel.SelectedActionIndex);
Assert.Equal(2, viewModel.SelectedActionIndex);
Assert.Same(added, viewModel.Editor.SelectedAction);
}

[Fact]
public void ActionEditorViewModel_ActionTypes_HidesNoneType()
{
var viewModel = new ActionEditorViewModel(new ActionDefaultsService(), []);

Assert.Equal([ActionType.Key, ActionType.Shell], viewModel.ActionTypes.Select(option => option.Type));
}

[Fact]
public void RemoveAction_SelectsNextAvailableAction()
{
Expand Down
138 changes: 59 additions & 79 deletions RadialActions/Settings/ActionEditorView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,67 +13,53 @@
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<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" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0"
Text="Enabled:"
<StackPanel>
<TextBlock Text="Enabled:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<CheckBox Grid.Row="1"
Content="Show this action"
IsChecked="{Binding SelectedAction.IsEnabled, Mode=TwoWay}"
Margin="0,0,0,8" />
<CheckBox Content="Show this action in the menu"
IsChecked="{Binding SelectedAction.IsEnabled, Mode=TwoWay}" />
<TextBlock Text="Turn this off to keep the action configured without showing it as a menu slice."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="2"
Text="Name:"
<TextBlock Text="Name:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<TextBox Grid.Row="3"
Text="{Binding SelectedAction.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,8" />
<TextBox Text="{Binding SelectedAction.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="This label appears next to the icon in the radial menu."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="4"
Text="Icon:"
<TextBlock Text="Icon:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<TextBox Grid.Row="5"
Text="{Binding SelectedAction.Icon, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,8" />
<TextBox Text="{Binding SelectedAction.Icon, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Use a short symbol or emoji that fits inside the slice."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="6"
Text="Type:"
<TextBlock Text="Type:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<ComboBox Grid.Row="7"
Margin="0,0,0,8"
ItemsSource="{Binding ActionTypes}"
SelectedItem="{Binding SelectedActionType, Mode=TwoWay}" />
<ComboBox ItemsSource="{Binding ActionTypes}"
SelectedValue="{Binding SelectedActionType, Mode=TwoWay}"
SelectedValuePath="Type">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Icon}"
Width="20"
FontSize="14" />
<TextBlock Text="{Binding Name}"
Margin="4,0,0,0"
VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="Choose Key for keyboard or media controls, or Shell to launch an app, file, folder, or URL."
Style="{StaticResource DescriptionTextBlock}" />

<Grid Grid.Row="8"
Margin="0,0,0,8"
<StackPanel Margin="0,0,0,4"
Visibility="{Binding SelectedActionType, Converter={local:MatchToVisibilityConverter}, ConverterParameter={x:Static local:ActionType.Key}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0"
Text="Key Action:"
<TextBlock Text="Key Action:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<ComboBox Grid.Row="1"
SelectedValue="{Binding SelectedKeyActionId, Mode=TwoWay}"
<ComboBox SelectedValue="{Binding SelectedKeyActionId, Mode=TwoWay}"
SelectedValuePath="Id"
Margin="0,0,0,8"
IsTextSearchEnabled="True"
ItemsSource="{Binding KeyActionOptions}">
<ComboBox.ItemTemplate>
Expand All @@ -89,32 +75,24 @@
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="Pick a built-in media or volume command, or choose Custom Shortcut to enter one manually."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="2"
Text="Shortcut:"
<TextBlock Text="Shortcut:"
Style="{StaticResource ActionEditorLabelTextBlock}"
Visibility="{Binding SelectedKeyActionId, Converter={local:MatchToVisibilityConverter}, ConverterParameter={x:Static local:ActionEditorViewModel.CustomKeyActionId}}" />
<TextBox Grid.Row="3"
Text="{Binding SelectedAction.Parameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
<TextBox Text="{Binding SelectedAction.Parameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding SelectedKeyActionId, Converter={local:MatchToVisibilityConverter}, ConverterParameter={x:Static local:ActionEditorViewModel.CustomKeyActionId}}" />
</Grid>
<TextBlock Text="Enter a shortcut such as Ctrl+Shift+M when Custom Shortcut is selected."
Style="{StaticResource DescriptionTextBlock}"
Visibility="{Binding SelectedKeyActionId, Converter={local:MatchToVisibilityConverter}, ConverterParameter={x:Static local:ActionEditorViewModel.CustomKeyActionId}}" />
</StackPanel>

<Grid Grid.Row="9"
<StackPanel
Visibility="{Binding SelectedActionType, Converter={local:MatchToVisibilityConverter}, ConverterParameter={x:Static local:ActionType.Shell}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0"
Text="Target:"
<TextBlock Text="Target:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<Grid Grid.Row="1"
Margin="0,0,0,8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="6" />
Expand All @@ -127,18 +105,18 @@
Command="{Binding BrowseShellTargetCommand}"
Padding="8,2" />
</Grid>
<TextBlock Text="Select the app, file, folder, URL, or command this action should open."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="2"
Text="Arguments:"
<TextBlock Text="Arguments:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<TextBox Grid.Row="3"
Text="{Binding SelectedAction.Arguments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,8" />
<TextBox Text="{Binding SelectedAction.Arguments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Optional command-line arguments passed to the target."
Style="{StaticResource DescriptionTextBlock}" />

<TextBlock Grid.Row="4"
Text="Working Directory:"
<TextBlock Text="Working Directory:"
Style="{StaticResource ActionEditorLabelTextBlock}" />
<Grid Grid.Row="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="6" />
Expand All @@ -151,6 +129,8 @@
Command="{Binding BrowseWorkingDirectoryCommand}"
Padding="8,2" />
</Grid>
</Grid>
</Grid>
<TextBlock Text="Optional folder used as the starting location when the target runs."
Style="{StaticResource DescriptionTextBlock}" />
</StackPanel>
</StackPanel>
</UserControl>
21 changes: 20 additions & 1 deletion RadialActions/Settings/ActionEditorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ public ActionEditorViewModel(ActionDefaultsService actionDefaultsService, IEnume
_actionDefaultsService.TrackExistingDefaults(actions);
}

public ActionType[] ActionTypes { get; } = [ActionType.None, ActionType.Key, ActionType.Shell];
public IReadOnlyList<ActionTypeOption> ActionTypes { get; } =
[
new(ActionType.Key, "Key", "⌨️"),
new(ActionType.Shell, "Shell", "🚀"),
];

public IReadOnlyList<KeyActionDefinition> KeyActionOptions { get; } =
[.. PieAction.KeyActions, CustomKeyActionOption];
public bool HasSelectedAction => SelectedAction != null;
Expand Down Expand Up @@ -194,3 +199,17 @@ private void SelectedActionPropertyChanged(object sender, PropertyChangedEventAr
}
}
}

public sealed class ActionTypeOption
{
public ActionTypeOption(ActionType type, string name, string icon)
{
Type = type;
Name = name;
Icon = icon;
}

public ActionType Type { get; }
public string Name { get; }
public string Icon { get; }
}
8 changes: 6 additions & 2 deletions RadialActions/Settings/ActionsSettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ public void SelectAction(PieAction action)
private void AddAction()
{
var newAction = new PieAction("Blank action") { Type = ActionType.None };
Actions.Add(newAction);
SelectedActionIndex = Actions.Count - 1;

var selectedIndex = SelectedAction == null ? -1 : Actions.IndexOf(SelectedAction);
var insertionIndex = selectedIndex >= 0 ? selectedIndex + 1 : Actions.Count;

Actions.Insert(insertionIndex, newAction);
SelectedActionIndex = insertionIndex;
SelectedAction = newAction;
Log.Debug("Added new action");
}
Expand Down
Loading