Refactor ShellSettings with Binding logic

This commit is contained in:
Jack251970 2025-09-29 23:00:32 +08:00
parent d363cf8137
commit 175571a130
7 changed files with 180 additions and 157 deletions

View file

@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Flow.Launcher.Plugin.Shell.Converters;
public class CloseShellAfterPressEnabledConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not bool)
return Binding.DoNothing;
var leaveShellOpen = (bool)value;
return !leaveShellOpen;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View file

@ -0,0 +1,25 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Flow.Launcher.Plugin.Shell.Converters;
public class LeaveShellOpenEnabledConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (
values.Length != 2 ||
values[0] is not bool closeShellAfterPress ||
values[1] is not Shell shell
)
return Binding.DoNothing;
return (!closeShellAfterPress) && shell != Shell.RunCommand;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View file

@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.Shell.Views;
using WindowsInput;
using WindowsInput.Native;
using Control = System.Windows.Controls.Control;

View file

@ -1,142 +0,0 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Shell
{
public partial class CMDSetting : UserControl
{
private readonly Settings _settings;
public CMDSetting(Settings settings)
{
InitializeComponent();
_settings = settings;
}
private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
{
ReplaceWinR.IsChecked = _settings.ReplaceWinR;
CloseShellAfterPress.IsChecked = _settings.CloseShellAfterPress;
LeaveShellOpen.IsChecked = _settings.LeaveShellOpen;
AlwaysRunAsAdministrator.IsChecked = _settings.RunAsAdministrator;
UseWindowsTerminal.IsChecked = _settings.UseWindowsTerminal;
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
ShowOnlyMostUsedCMDs.IsChecked = _settings.ShowOnlyMostUsedCMDs;
if (ShowOnlyMostUsedCMDs.IsChecked != true)
ShowOnlyMostUsedCMDsNumber.IsEnabled = false;
ShowOnlyMostUsedCMDsNumber.ItemsSource = new List<int>() { 5, 10, 20 };
if (_settings.ShowOnlyMostUsedCMDsNumber == 0)
{
ShowOnlyMostUsedCMDsNumber.SelectedIndex = 0;
_settings.ShowOnlyMostUsedCMDsNumber = (int)ShowOnlyMostUsedCMDsNumber.SelectedItem;
}
CloseShellAfterPress.Checked += (o, e) =>
{
_settings.CloseShellAfterPress = true;
LeaveShellOpen.IsChecked = false;
LeaveShellOpen.IsEnabled = false;
};
CloseShellAfterPress.Unchecked += (o, e) =>
{
_settings.CloseShellAfterPress = false;
LeaveShellOpen.IsEnabled = true;
};
LeaveShellOpen.Checked += (o, e) =>
{
_settings.LeaveShellOpen = true;
CloseShellAfterPress.IsChecked = false;
CloseShellAfterPress.IsEnabled = false;
};
LeaveShellOpen.Unchecked += (o, e) =>
{
_settings.LeaveShellOpen = false;
CloseShellAfterPress.IsEnabled = true;
};
AlwaysRunAsAdministrator.Checked += (o, e) =>
{
_settings.RunAsAdministrator = true;
};
AlwaysRunAsAdministrator.Unchecked += (o, e) =>
{
_settings.RunAsAdministrator = false;
};
UseWindowsTerminal.Checked += (o, e) =>
{
_settings.UseWindowsTerminal = true;
};
UseWindowsTerminal.Unchecked += (o, e) =>
{
_settings.UseWindowsTerminal = false;
};
ReplaceWinR.Checked += (o, e) =>
{
_settings.ReplaceWinR = true;
};
ReplaceWinR.Unchecked += (o, e) =>
{
_settings.ReplaceWinR = false;
};
ShellComboBox.SelectedIndex = _settings.Shell switch
{
Shell.Cmd => 0,
Shell.Powershell => 1,
Shell.Pwsh => 2,
_ => ShellComboBox.Items.Count - 1
};
ShellComboBox.SelectionChanged += (o, e) =>
{
_settings.Shell = ShellComboBox.SelectedIndex switch
{
0 => Shell.Cmd,
1 => Shell.Powershell,
2 => Shell.Pwsh,
_ => Shell.RunCommand
};
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
};
ShowOnlyMostUsedCMDs.Checked += (o, e) =>
{
_settings.ShowOnlyMostUsedCMDs = true;
ShowOnlyMostUsedCMDsNumber.IsEnabled = true;
};
ShowOnlyMostUsedCMDs.Unchecked += (o, e) =>
{
_settings.ShowOnlyMostUsedCMDs = false;
ShowOnlyMostUsedCMDsNumber.IsEnabled = false;
};
ShowOnlyMostUsedCMDsNumber.SelectedItem = _settings.ShowOnlyMostUsedCMDsNumber;
ShowOnlyMostUsedCMDsNumber.SelectionChanged += (o, e) =>
{
_settings.ShowOnlyMostUsedCMDsNumber = (int)ShowOnlyMostUsedCMDsNumber.SelectedItem;
};
}
}
}

View file

@ -0,0 +1,78 @@
using System.Collections.Generic;
namespace Flow.Launcher.Plugin.Shell.ViewModels;
public class ShellSettingViewModel : BaseModel
{
public Settings Settings { get; }
public List<ShellLocalized> AllShells { get; } = ShellLocalized.GetValues();
public Shell SelectedShell
{
get => Settings.Shell;
set
{
if (Settings.Shell != value)
{
Settings.Shell = value;
OnPropertyChanged();
}
}
}
public List<int> OnlyMostUsedCMDsNumbers { get; } = [5, 10, 20];
public int SelectedOnlyMostUsedCMDsNumber
{
get => Settings.ShowOnlyMostUsedCMDsNumber;
set
{
if (Settings.ShowOnlyMostUsedCMDsNumber != value)
{
Settings.ShowOnlyMostUsedCMDsNumber = value;
OnPropertyChanged();
}
}
}
public bool CloseShellAfterPress
{
get => Settings.CloseShellAfterPress;
set
{
if (Settings.CloseShellAfterPress != value)
{
Settings.CloseShellAfterPress = value;
OnPropertyChanged();
// Only allow CloseShellAfterPress to be true when LeaveShellOpen is false
if (value)
{
LeaveShellOpen = false;
}
}
}
}
public bool LeaveShellOpen
{
get => Settings.LeaveShellOpen;
set
{
if (Settings.LeaveShellOpen != value)
{
Settings.LeaveShellOpen = value;
OnPropertyChanged();
// Only allow LeaveShellOpen to be true when CloseShellAfterPress is false
if (value)
{
CloseShellAfterPress = false;
}
}
}
}
public ShellSettingViewModel(Settings settings)
{
Settings = settings;
}
}

View file

@ -1,13 +1,20 @@
<UserControl
x:Class="Flow.Launcher.Plugin.Shell.CMDSetting"
x:Class="Flow.Launcher.Plugin.Shell.Views.CMDSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Flow.Launcher.Plugin.Shell.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Flow.Launcher.Plugin.Shell.ViewModels"
d:DataContext="{d:DesignInstance vm:ShellSettingViewModel}"
d:DesignHeight="300"
d:DesignWidth="300"
Loaded="CMDSetting_OnLoaded"
mc:Ignorable="d">
<UserControl.Resources>
<converters:CloseShellAfterPressEnabledConverter x:Key="CloseShellAfterPressEnabledConverter" />
<converters:LeaveShellOpenEnabledConverter x:Key="LeaveShellOpenEnabledConverter" />
</UserControl.Resources>
<Grid Margin="{StaticResource SettingPanelMargin}" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition />
@ -23,50 +30,66 @@
Grid.Row="0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_relace_winr}" />
Content="{DynamicResource flowlauncher_plugin_cmd_relace_winr}"
IsChecked="{Binding Settings.ReplaceWinR, Mode=TwoWay}" />
<CheckBox
x:Name="CloseShellAfterPress"
Grid.Row="1"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_close_cmd_after_press}" />
Content="{DynamicResource flowlauncher_plugin_cmd_close_cmd_after_press}"
IsChecked="{Binding CloseShellAfterPress, Mode=TwoWay}"
IsEnabled="{Binding LeaveShellOpen, Converter={StaticResource CloseShellAfterPressEnabledConverter}, Mode=OneWay}" />
<CheckBox
x:Name="LeaveShellOpen"
Grid.Row="2"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_leave_cmd_open}" />
Content="{DynamicResource flowlauncher_plugin_cmd_leave_cmd_open}"
IsChecked="{Binding LeaveShellOpen, Mode=TwoWay}">
<CheckBox.IsEnabled>
<MultiBinding Converter="{StaticResource LeaveShellOpenEnabledConverter}">
<Binding Mode="OneWay" Path="CloseShellAfterPress" />
<Binding Mode="OneWay" Path="SelectedShell" />
</MultiBinding>
</CheckBox.IsEnabled>
</CheckBox>
<CheckBox
x:Name="AlwaysRunAsAdministrator"
Grid.Row="3"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_always_run_as_administrator}" />
Content="{DynamicResource flowlauncher_plugin_cmd_always_run_as_administrator}"
IsChecked="{Binding Settings.RunAsAdministrator, Mode=TwoWay}" />
<CheckBox
x:Name="UseWindowsTerminal"
Grid.Row="4"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_use_windows_terminal}" />
Content="{DynamicResource flowlauncher_plugin_cmd_use_windows_terminal}"
IsChecked="{Binding Settings.UseWindowsTerminal, Mode=TwoWay}" />
<ComboBox
x:Name="ShellComboBox"
Grid.Row="5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left">
<ComboBoxItem>CMD</ComboBoxItem>
<ComboBoxItem>PowerShell</ComboBoxItem>
<ComboBoxItem>Pwsh</ComboBoxItem>
<ComboBoxItem>RunCommand</ComboBoxItem>
</ComboBox>
HorizontalAlignment="Left"
DisplayMemberPath="Display"
ItemsSource="{Binding AllShells, Mode=OneTime}"
SelectedValue="{Binding SelectedShell, Mode=TwoWay}"
SelectedValuePath="Value" />
<StackPanel Grid.Row="6" Orientation="Horizontal">
<CheckBox
x:Name="ShowOnlyMostUsedCMDs"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource flowlauncher_plugin_cmd_history}" />
Content="{DynamicResource flowlauncher_plugin_cmd_history}"
IsChecked="{Binding Settings.ShowOnlyMostUsedCMDs, Mode=TwoWay}" />
<ComboBox
x:Name="ShowOnlyMostUsedCMDsNumber"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left" />
HorizontalAlignment="Left"
IsEnabled="{Binding Settings.ShowOnlyMostUsedCMDs, Mode=OneWay}"
ItemsSource="{Binding OnlyMostUsedCMDsNumbers, Mode=OneTime}"
SelectedItem="{Binding SelectedOnlyMostUsedCMDsNumber, Mode=TwoWay}" />
</StackPanel>
</Grid>
</UserControl>

View file

@ -0,0 +1,16 @@
using System.Windows.Controls;
using Flow.Launcher.Plugin.Shell.ViewModels;
namespace Flow.Launcher.Plugin.Shell.Views
{
public partial class CMDSetting : UserControl
{
public CMDSetting(Settings settings)
{
var viewModel = new ShellSettingViewModel(settings);
DataContext = viewModel;
InitializeComponent();
DataContext = viewModel;
}
}
}