Skip to content

Commit d60ba01

Browse files
committed
Implement {clipboard} feature and the setting panel
1 parent c0a61c0 commit d60ba01

File tree

9 files changed

+327
-24
lines changed

9 files changed

+327
-24
lines changed

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ public bool HideNotifyIcon
204204

205205
// This needs to be loaded last by staying at the bottom
206206
public PluginsSettings PluginSettings { get; set; } = new PluginsSettings();
207-
internal ObservableCollection<KeyValuePair<string, string>> ShortCuts { get; set; } = new()
207+
internal ObservableCollection<ShortCutModel> ShortCuts { get; set; } = new()
208208
{
209-
new("spp", "sp play")
209+
("spp", "sp play")
210210
};
211211
}
212212

@@ -223,4 +223,44 @@ public enum ColorSchemes
223223
Light,
224224
Dark
225225
}
226+
227+
public struct ShortCutModel
228+
{
229+
public string Key { get; set; }
230+
public string Value { get; set; }
231+
232+
public ShortCutModel(string key, string value)
233+
{
234+
Key = key;
235+
Value = value;
236+
}
237+
238+
public override bool Equals(object obj)
239+
{
240+
return obj is ShortCutModel other &&
241+
Key == other.Key &&
242+
Value == other.Value;
243+
}
244+
245+
public override int GetHashCode()
246+
{
247+
return HashCode.Combine(Key, Value);
248+
}
249+
250+
public void Deconstruct(out string key, out string value)
251+
{
252+
key = Key;
253+
value = Value;
254+
}
255+
256+
public static implicit operator (string Key, string Value)(ShortCutModel value)
257+
{
258+
return (value.Key, value.Value);
259+
}
260+
261+
public static implicit operator ShortCutModel((string Key, string Value) value)
262+
{
263+
return new ShortCutModel(value.Key, value.Value);
264+
}
265+
}
226266
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<Window
2+
x:Class="Flow.Launcher.CustomShortcutSetting"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
6+
Title="{DynamicResource customeQueryHotkeyTitle}"
7+
Width="530"
8+
Background="{DynamicResource PopuBGColor}"
9+
Foreground="{DynamicResource PopupTextColor}"
10+
Icon="Images\app.png"
11+
ResizeMode="NoResize"
12+
SizeToContent="Height"
13+
WindowStartupLocation="CenterScreen"
14+
DataContext="{Binding RelativeSource={RelativeSource Self}}">
15+
<WindowChrome.WindowChrome>
16+
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
17+
</WindowChrome.WindowChrome>
18+
<Window.InputBindings>
19+
<KeyBinding Key="Escape" Command="Close" />
20+
</Window.InputBindings>
21+
<Window.CommandBindings>
22+
<CommandBinding Command="Close" Executed="cmdEsc_OnPress" />
23+
</Window.CommandBindings>
24+
<Grid>
25+
<Grid.RowDefinitions>
26+
<RowDefinition />
27+
<RowDefinition Height="80" />
28+
</Grid.RowDefinitions>
29+
<StackPanel Grid.Row="0">
30+
<StackPanel>
31+
<Grid>
32+
<Grid.ColumnDefinitions>
33+
<ColumnDefinition Width="Auto" />
34+
<ColumnDefinition Width="*" />
35+
<ColumnDefinition Width="Auto" />
36+
<ColumnDefinition Width="Auto" />
37+
<ColumnDefinition Width="Auto" />
38+
</Grid.ColumnDefinitions>
39+
<Button
40+
Grid.Column="4"
41+
Click="BtnCancel_OnClick"
42+
Style="{StaticResource TitleBarCloseButtonStyle}">
43+
<Path
44+
Width="46"
45+
Height="32"
46+
Data="M 18,11 27,20 M 18,20 27,11"
47+
Stroke="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
48+
StrokeThickness="1">
49+
<Path.Style>
50+
<Style TargetType="Path">
51+
<Style.Triggers>
52+
<DataTrigger Binding="{Binding Path=IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Value="False">
53+
<Setter Property="Opacity" Value="0.5" />
54+
</DataTrigger>
55+
</Style.Triggers>
56+
</Style>
57+
</Path.Style>
58+
</Path>
59+
</Button>
60+
</Grid>
61+
</StackPanel>
62+
<StackPanel Margin="26,0,26,0">
63+
<StackPanel Grid.Row="0" Margin="0,0,0,12">
64+
<TextBlock
65+
Grid.Column="0"
66+
Margin="0,0,0,0"
67+
FontFamily="Segoe UI"
68+
FontSize="20"
69+
FontWeight="SemiBold"
70+
Text="{DynamicResource customeQueryHotkeyTitle}"
71+
TextAlignment="Left" />
72+
</StackPanel>
73+
<StackPanel>
74+
<TextBlock
75+
FontSize="14"
76+
Text="{DynamicResource customeQueryHotkeyTips}"
77+
TextAlignment="Left"
78+
TextWrapping="WrapWithOverflow" />
79+
</StackPanel>
80+
81+
<StackPanel Margin="0,20,0,0" Orientation="Horizontal">
82+
<Grid Width="470">
83+
<Grid.RowDefinitions>
84+
<RowDefinition />
85+
<RowDefinition />
86+
</Grid.RowDefinitions>
87+
<Grid.ColumnDefinitions>
88+
<ColumnDefinition Width="Auto" />
89+
<ColumnDefinition Width="*" />
90+
</Grid.ColumnDefinitions>
91+
<TextBlock
92+
Grid.Row="0"
93+
Grid.Column="0"
94+
Margin="10"
95+
HorizontalAlignment="Left"
96+
VerticalAlignment="Center"
97+
FontSize="14"
98+
Text="{DynamicResource customShortcut}" />
99+
<TextBox
100+
Grid.Row="0"
101+
Grid.Column="1"
102+
Margin="10"
103+
Text="{Binding Key}"
104+
/>
105+
<TextBlock
106+
Grid.Row="1"
107+
Grid.Column="0"
108+
Margin="10"
109+
HorizontalAlignment="Left"
110+
VerticalAlignment="Center"
111+
FontSize="14"
112+
Text="{DynamicResource customShortcutExpansion}" />
113+
<TextBox
114+
Grid.Row="1"
115+
Grid.Column="1"
116+
Margin="10"
117+
HorizontalAlignment="Stretch"
118+
VerticalAlignment="Center"
119+
Text="{Binding Value}"/>
120+
</Grid>
121+
</StackPanel>
122+
</StackPanel>
123+
</StackPanel>
124+
<Border
125+
Grid.Row="1"
126+
Margin="0,14,0,0"
127+
Background="{DynamicResource PopupButtonAreaBGColor}"
128+
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
129+
BorderThickness="0,1,0,0">
130+
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
131+
<Button
132+
x:Name="btnCancel"
133+
MinWidth="140"
134+
Margin="10,0,5,0"
135+
Click="BtnCancel_OnClick"
136+
Content="{DynamicResource cancel}" />
137+
<Button
138+
x:Name="btnAdd"
139+
MinWidth="140"
140+
Margin="5,0,10,0"
141+
Click="btnAdd_OnClick"
142+
Style="{StaticResource AccentButtonStyle}">
143+
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />
144+
</Button>
145+
</StackPanel>
146+
</Border>
147+
</Grid>
148+
</Window>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Flow.Launcher.Core.Resource;
2+
using Flow.Launcher.Helper;
3+
using Flow.Launcher.Infrastructure.UserSettings;
4+
using System.Collections.ObjectModel;
5+
using System.Linq;
6+
using System.Windows;
7+
using System.Windows.Input;
8+
using System.Windows.Controls;
9+
using System.Collections.Generic;
10+
11+
namespace Flow.Launcher
12+
{
13+
public partial class CustomShortcutSetting : Window
14+
{
15+
private SettingWindow _settingWidow;
16+
private bool update;
17+
private CustomPluginHotkey updateCustomHotkey;
18+
private Settings _settings;
19+
20+
public string Key { get; set; }
21+
public string Value { get; set; }
22+
public ShortCutModel ShortCut => (Key, Value);
23+
public CustomShortcutSetting()
24+
{
25+
InitializeComponent();
26+
}
27+
28+
public CustomShortcutSetting((string, string) shortcut)
29+
{
30+
(Key, Value) = shortcut;
31+
InitializeComponent();
32+
}
33+
34+
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
35+
{
36+
DialogResult = false;
37+
Close();
38+
}
39+
40+
private void btnAdd_OnClick(object sender, RoutedEventArgs e)
41+
{
42+
DialogResult = true;
43+
Close();
44+
}
45+
46+
private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
47+
{
48+
DialogResult = false;
49+
Close();
50+
}
51+
}
52+
}

Flow.Launcher/Flow.Launcher.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
1313
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
1414
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
15+
<ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
1516
</PropertyGroup>
1617

1718
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

Flow.Launcher/Languages/en.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@
115115
<system:String x:Key="showOpenResultHotkeyToolTip">Show result selection hotkey with results.</system:String>
116116
<system:String x:Key="customQueryHotkey">Custom Query Hotkey</system:String>
117117
<system:String x:Key="customQuery">Query</system:String>
118+
<system:String x:Key="customShortcut">Shortcut</system:String>
119+
<system:String x:Key="customShortcutExpansion">Expanded</system:String>
118120
<system:String x:Key="delete">Delete</system:String>
119121
<system:String x:Key="edit">Edit</system:String>
120122
<system:String x:Key="add">Add</system:String>

Flow.Launcher/SettingWindow.xaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,7 @@
21592159
<Button
21602160
MinWidth="100"
21612161
Margin="10"
2162-
Click="OnnEditCustomHotkeyClick"
2162+
Click="OnEditCustomHotkeyClick"
21632163
Content="{DynamicResource edit}" />
21642164
<Button
21652165
MinWidth="100"
@@ -2183,7 +2183,8 @@
21832183
BorderBrush="DarkGray"
21842184
BorderThickness="1"
21852185
ItemsSource="{Binding ShortCuts}"
2186-
SelectedItem="{Binding SelectedCustomPluginHotkey}"
2186+
SelectedItem="{Binding SelectedCustomShortcut}"
2187+
SelectedIndex="{Binding SelectCustomShortcutIndex}"
21872188
Style="{StaticResource {x:Static GridView.GridViewStyleKey}}">
21882189
<ListView.View>
21892190
<GridView>
@@ -2212,17 +2213,17 @@
22122213
<Button
22132214
MinWidth="100"
22142215
Margin="10"
2215-
Click="OnDeleteCustomHotkeyClick"
2216+
Click="OnDeleteCustomShortCutClick"
22162217
Content="{DynamicResource delete}" />
22172218
<Button
22182219
MinWidth="100"
22192220
Margin="10"
2220-
Click="OnnEditCustomHotkeyClick"
2221+
Click="OnEditCustomShortCutClick"
22212222
Content="{DynamicResource edit}" />
22222223
<Button
22232224
MinWidth="100"
22242225
Margin="10,10,0,10"
2225-
Click="OnAddCustomeHotkeyClick"
2226+
Click="OnAddCustomeShortCutClick"
22262227
Content="{DynamicResource add}" />
22272228
</StackPanel>
22282229
</StackPanel>

Flow.Launcher/SettingWindow.xaml.cs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ private void OnDeleteCustomHotkeyClick(object sender, RoutedEventArgs e)
175175
}
176176
}
177177

178-
private void OnnEditCustomHotkeyClick(object sender, RoutedEventArgs e)
178+
private void OnEditCustomHotkeyClick(object sender, RoutedEventArgs e)
179179
{
180180
var item = viewModel.SelectedCustomPluginHotkey;
181181
if (item != null)
@@ -307,7 +307,7 @@ private void OnPluginStoreRefreshClick(object sender, RoutedEventArgs e)
307307

308308
private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e)
309309
{
310-
if(sender is Button { DataContext: UserPlugin plugin })
310+
if (sender is Button { DataContext: UserPlugin plugin })
311311
{
312312
var pluginsManagerPlugin = PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7");
313313
var actionKeyword = pluginsManagerPlugin.Metadata.ActionKeywords.Count == 0 ? "" : pluginsManagerPlugin.Metadata.ActionKeywords[0];
@@ -326,7 +326,7 @@ private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e)
326326
textBox.MoveFocus(tRequest);
327327
}
328328

329-
private void ColorSchemeSelectedIndexChanged(object sender, EventArgs e)
329+
private void ColorSchemeSelectedIndexChanged(object sender, EventArgs e)
330330
=> ThemeManager.Current.ApplicationTheme = settings.ColorScheme switch
331331
{
332332
Constant.Light => ApplicationTheme.Light,
@@ -370,5 +370,49 @@ private void Window_StateChanged(object sender, EventArgs e)
370370
RefreshMaximizeRestoreButton();
371371
}
372372

373+
private void OnDeleteCustomShortCutClick(object sender, RoutedEventArgs e)
374+
{
375+
var item = viewModel.SelectedCustomShortcut;
376+
if (item == null)
377+
{
378+
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
379+
return;
380+
}
381+
382+
string deleteWarning =
383+
string.Format(InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"),
384+
item.Value.Key);
385+
if (
386+
MessageBox.Show(deleteWarning, InternationalizationManager.Instance.GetTranslation("delete"),
387+
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
388+
{
389+
settings.ShortCuts.Remove(item.Value);
390+
}
391+
}
392+
private void OnEditCustomShortCutClick(object sender, RoutedEventArgs e)
393+
{
394+
var item = viewModel.SelectedCustomShortcut;
395+
if (item != null)
396+
{
397+
var shortcutSettingWindow = new CustomShortcutSetting(item.Value);
398+
if (shortcutSettingWindow.ShowDialog() == true)
399+
{
400+
settings.ShortCuts[viewModel.SelectCustomShortcutIndex.Value] = shortcutSettingWindow.ShortCut;
401+
}
402+
}
403+
else
404+
{
405+
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
406+
}
407+
}
408+
409+
private void OnAddCustomeShortCutClick(object sender, RoutedEventArgs e)
410+
{
411+
var shortcutSettingWindow = new CustomShortcutSetting();
412+
if (shortcutSettingWindow.ShowDialog() == true)
413+
{
414+
settings.ShortCuts.Add(shortcutSettingWindow.ShortCut);
415+
}
416+
}
373417
}
374418
}

0 commit comments

Comments
 (0)