Merge branch 'dev' into 250422-FixClockwhenStartUp

This commit is contained in:
Jack Ye 2025-04-25 11:32:05 +08:00 committed by GitHub
commit c4b992281b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 775 additions and 590 deletions

View file

@ -113,7 +113,7 @@ namespace Flow.Launcher.Core.Plugin
// If can parse the default value to bool, use it, otherwise use false
: value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString)
&& boolValueFromString;
checkBox.Dispatcher.Invoke(() =>checkBox.IsChecked = isChecked);
checkBox.Dispatcher.Invoke(() => checkBox.IsChecked = isChecked);
break;
}
}
@ -154,8 +154,7 @@ namespace Flow.Launcher.Core.Plugin
public Control CreateSettingPanel()
{
// No need to check if NeedCreateSettingPanel is true because CreateSettingPanel will only be called if it's true
// if (!NeedCreateSettingPanel()) return null;
if (!NeedCreateSettingPanel()) return null!;
// Create main grid with two columns (Column 1: Auto, Column 2: *)
var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center };

View file

@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Logger;
@ -31,7 +32,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
_storage.Save();
}
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
@ -103,6 +104,22 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool ShowBadges { get; set; } = false;
public bool ShowBadgesGlobalOnly { get; set; } = false;
private string _settingWindowFont { get; set; } = Win32Helper.GetSystemDefaultFont(false);
public string SettingWindowFont
{
get => _settingWindowFont;
set
{
if (_settingWindowFont != value)
{
_settingWindowFont = value;
OnPropertyChanged();
Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
}
}
}
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
public string TimeFormat { get; set; } = "hh:mm tt";

View file

@ -628,21 +628,33 @@ namespace Flow.Launcher.Infrastructure
{ "pt", "Noto Sans" }
};
public static string GetSystemDefaultFont()
/// <summary>
/// Gets the system default font.
/// </summary>
/// <param name="useNoto">
/// If true, it will try to find the Noto font for the current culture.
/// </param>
/// <returns>
/// The name of the system default font.
/// </returns>
public static string GetSystemDefaultFont(bool useNoto = true)
{
try
{
var culture = CultureInfo.CurrentCulture;
var language = culture.Name; // e.g., "zh-TW"
var langPrefix = language.Split('-')[0]; // e.g., "zh"
// First, try to find by full name, and if not found, fallback to prefix
if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
if (useNoto)
{
// If the font is installed, return it
if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
var culture = CultureInfo.CurrentCulture;
var language = culture.Name; // e.g., "zh-TW"
var langPrefix = language.Split('-')[0]; // e.g., "zh"
// First, try to find by full name, and if not found, fallback to prefix
if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
{
return notoFont;
// If the font is installed, return it
if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
{
return notoFont;
}
}
}

View file

@ -53,11 +53,11 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,12,26,0">
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<StackPanel Margin="26 12 26 0">
<StackPanel Grid.Row="0" Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource actionKeywordsTitle}"
@ -71,7 +71,7 @@
TextWrapping="WrapWithOverflow" />
</StackPanel>
<StackPanel Margin="0,18,0,0" Orientation="Horizontal">
<StackPanel Margin="0 18 0 0" Orientation="Horizontal">
<TextBlock
Grid.Row="0"
Grid.Column="1"
@ -83,14 +83,14 @@
x:Name="tbOldActionKeyword"
Grid.Row="0"
Grid.Column="1"
Margin="14,10,10,10"
Margin="14 10 10 10"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource Color05B}" />
</StackPanel>
<StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<StackPanel Margin="0 0 0 10" Orientation="Horizontal">
<TextBlock
Grid.Row="1"
Grid.Column="1"
@ -101,7 +101,7 @@
<TextBox
x:Name="tbAction"
Width="105"
Margin="10,10,15,10"
Margin="10 10 15 10"
HorizontalAlignment="Left"
VerticalAlignment="Center" />
</StackPanel>
@ -112,20 +112,20 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
Width="145"
Height="30"
Margin="10,0,5,0"
Margin="10 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
x:Name="btnDone"
Width="145"
Height="30"
Margin="5,0,10,0"
Margin="5 0 10 0"
Click="btnDone_OnClick"
Style="{StaticResource AccentButtonStyle}">
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />

View file

@ -4,6 +4,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
@ -18,6 +19,7 @@ using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -29,6 +31,7 @@ namespace Flow.Launcher
#region Public Properties
public static IPublicAPI API { get; private set; }
public static bool Exiting => _mainWindow.CanClose;
#endregion
@ -37,7 +40,7 @@ namespace Flow.Launcher
private static readonly string ClassName = nameof(App);
private static bool _disposed;
private MainWindow _mainWindow;
private static MainWindow _mainWindow;
private readonly MainViewModel _mainVM;
private readonly Settings _settings;
@ -73,14 +76,27 @@ namespace Flow.Launcher
.AddSingleton(_ => _settings)
.AddSingleton(sp => new Updater(sp.GetRequiredService<IPublicAPI>(), Launcher.Properties.Settings.Default.GithubRepo))
.AddSingleton<Portable>()
.AddSingleton<SettingWindowViewModel>()
.AddSingleton<IAlphabet, PinyinAlphabet>()
.AddSingleton<StringMatcher>()
.AddSingleton<Internationalization>()
.AddSingleton<IPublicAPI, PublicAPIInstance>()
.AddSingleton<MainViewModel>()
.AddSingleton<Theme>()
// Use one instance for main window view model because we only have one main window
.AddSingleton<MainViewModel>()
// Use one instance for welcome window view model & setting window view model because
// pages in welcome window & setting window need to share the same instance and
// these two view models do not need to be reset when creating new windows
.AddSingleton<WelcomeViewModel>()
.AddSingleton<SettingWindowViewModel>()
// Use transient instance for setting window page view models because
// pages in setting window need to be recreated when setting window is closed
.AddTransient<SettingsPaneAboutViewModel>()
.AddTransient<SettingsPaneGeneralViewModel>()
.AddTransient<SettingsPaneHotkeyViewModel>()
.AddTransient<SettingsPanePluginsViewModel>()
.AddTransient<SettingsPanePluginStoreViewModel>()
.AddTransient<SettingsPaneProxyViewModel>()
.AddTransient<SettingsPaneThemeViewModel>()
).Build();
Ioc.Default.ConfigureServices(host.Services);
}
@ -146,10 +162,14 @@ namespace Flow.Launcher
Log.SetLogLevel(_settings.LogLevel);
// Update dynamic resources base on settings
Current.Resources["SettingWindowFont"] = new FontFamily(_settings.SettingWindowFont);
Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(_settings.SettingWindowFont);
Ioc.Default.GetRequiredService<Portable>().PreStartCleanUpAfterPortabilityUpdate();
API.LogInfo(ClassName, "Begin Flow Launcher startup ----------------------------------------------------");
API.LogInfo(ClassName, "Runtime info:{ErrorReporting.RuntimeInfo()}");
API.LogInfo(ClassName, $"Runtime info:{ErrorReporting.RuntimeInfo()}");
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
@ -169,19 +189,16 @@ namespace Flow.Launcher
await PluginManager.InitializePluginsAsync();
// Change language after all plugins are initialized because we need to update plugin title based on their api
// TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
await Ioc.Default.GetRequiredService<Internationalization>().InitializeLanguageAsync();
await imageLoadertask;
_mainWindow = new MainWindow();
API.LogInfo(ClassName, "Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = _mainWindow;
Current.MainWindow.Title = Constant.FlowLauncher;
// main windows needs initialized before theme change because of blur settings
// Main windows needs initialized before theme change because of blur settings
Ioc.Default.GetRequiredService<Theme>().ChangeTheme();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@ -198,6 +215,10 @@ namespace Flow.Launcher
#pragma warning restore VSTHRD100 // Avoid async void methods
/// <summary>
/// Check startup only for Release
/// </summary>
[Conditional("RELEASE")]
private void AutoStartup()
{
// we try to enable auto-startup on first launch, or reenable if it was removed
@ -261,7 +282,7 @@ namespace Flow.Launcher
}
/// <summary>
/// let exception throw as normal is better for Debug
/// Let exception throw as normal is better for Debug
/// </summary>
[Conditional("RELEASE")]
private void RegisterDispatcherUnhandledException()
@ -270,7 +291,7 @@ namespace Flow.Launcher
}
/// <summary>
/// let exception throw as normal is better for Debug
/// Let exception throw as normal is better for Debug
/// </summary>
[Conditional("RELEASE")]
private static void RegisterAppDomainExceptions()
@ -279,7 +300,7 @@ namespace Flow.Launcher
}
/// <summary>
/// let exception throw as normal is better for Debug
/// Let exception throw as normal is better for Debug
/// </summary>
[Conditional("RELEASE")]
private static void RegisterTaskSchedulerUnhandledException()

View file

@ -1,16 +1,17 @@
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
private readonly Settings _settings;
private bool update;
private CustomPluginHotkey updateCustomHotkey;

View file

@ -56,11 +56,11 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,0,26,0">
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<StackPanel Margin="26 0 26 0">
<StackPanel Grid.Row="0" Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource customQueryShortcut}"
@ -73,18 +73,18 @@
TextAlignment="Left"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,20,0,0"
Margin="0 20 0 0"
FontSize="14"
Text="{DynamicResource customeQueryShortcutGuide}"
TextAlignment="Left"
TextWrapping="WrapWithOverflow" />
<Image
Width="478"
Margin="0,20,0,0"
Margin="0 20 0 0"
Source="/Images/illustration_02.png" />
</StackPanel>
<StackPanel Margin="0,10,0,10" Orientation="Horizontal">
<StackPanel Margin="0 10 0 10" Orientation="Horizontal">
<Grid Width="478">
<Grid.RowDefinitions>
<RowDefinition />
@ -124,14 +124,14 @@
LastChildFill="True">
<Button
x:Name="btnTestShortcut"
Margin="0,0,10,0"
Padding="10,5,10,5"
Margin="0 0 10 0"
Padding="10 5 10 5"
Click="BtnTestShortcut_OnClick"
Content="{DynamicResource preview}"
DockPanel.Dock="Right" />
<TextBox
x:Name="tbExpand"
Margin="10,0,10,0"
Margin="10 0 10 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="{Binding Value}" />
@ -142,21 +142,21 @@
</StackPanel>
<Border
Grid.Row="1"
Margin="0,10,0,0"
Margin="0 10 0 0"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
MinWidth="140"
Margin="10,0,5,0"
Margin="10 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
x:Name="btnAdd"
MinWidth="140"
Margin="5,0,10,0"
Margin="5 0 10 0"
Click="BtnAdd_OnClick"
Style="{StaticResource AccentButtonStyle}">
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />

View file

@ -1,5 +1,4 @@
using System;
using System.Windows;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
@ -8,8 +7,8 @@ namespace Flow.Launcher
public partial class CustomShortcutSetting : Window
{
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
public string Key { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;

View file

@ -1,11 +1,12 @@
using System;
using System.IO;
using System.Linq;
using System.Security.Principal;
using Flow.Launcher.Infrastructure;
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
#nullable enable
namespace Flow.Launcher.Helper;
public class AutoStartup
@ -59,11 +60,15 @@ public class AutoStartup
try
{
// Check if the action is the same as the current executable path
var action = task.Definition.Actions.FirstOrDefault()!.ToString().Trim();
if (!Constant.ExecutablePath.Equals(action, StringComparison.OrdinalIgnoreCase) && !File.Exists(action))
// If not, we need to unschedule and reschedule the task
if (task.Definition.Actions.FirstOrDefault() is Microsoft.Win32.TaskScheduler.Action taskAction)
{
UnscheduleLogonTask();
ScheduleLogonTask();
var action = taskAction.ToString().Trim();
if (!action.Equals(Constant.ExecutablePath, StringComparison.OrdinalIgnoreCase))
{
UnscheduleLogonTask();
ScheduleLogonTask();
}
}
return true;
@ -71,6 +76,7 @@ public class AutoStartup
catch (Exception e)
{
App.API.LogError(ClassName, $"Failed to check logon task: {e}");
throw; // Throw exception so that App.AutoStartup can show error message
}
}
@ -82,15 +88,27 @@ public class AutoStartup
try
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
var path = key?.GetValue(Constant.FlowLauncher) as string;
return path == Constant.ExecutablePath;
if (key != null)
{
// Check if the action is the same as the current executable path
// If not, we need to unschedule and reschedule the task
var action = (key.GetValue(Constant.FlowLauncher) as string) ?? string.Empty;
if (!action.Equals(Constant.ExecutablePath, StringComparison.OrdinalIgnoreCase))
{
UnscheduleRegistry();
ScheduleRegistry();
}
return true;
}
return false;
}
catch (Exception e)
{
App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
App.API.LogError(ClassName, $"Failed to check registry: {e}");
throw; // Throw exception so that App.AutoStartup can show error message
}
return false;
}
public static void DisableViaLogonTaskAndRegistry()
@ -121,8 +139,7 @@ public class AutoStartup
}
else
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.DeleteValue(Constant.FlowLauncher, false);
UnscheduleRegistry();
}
}
catch (Exception e)
@ -142,8 +159,7 @@ public class AutoStartup
}
else
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
ScheduleRegistry();
}
}
catch (Exception e)
@ -202,4 +218,18 @@ public class AutoStartup
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
private static bool UnscheduleRegistry()
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.DeleteValue(Constant.FlowLauncher, false);
return true;
}
private static bool ScheduleRegistry()
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
return true;
}
}

View file

@ -7,15 +7,15 @@
mc:Ignorable="d">
<Button
Width="Auto"
Click="GetNewHotkey"
FontSize="13"
FontWeight="Bold"
Foreground="{DynamicResource Color01B}"
Click="GetNewHotkey">
Foreground="{DynamicResource Color01B}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
x:Name="ButtonBorder"
Padding="5,0,5,0"
Padding="5 0 5 0"
Background="{DynamicResource ButtonBackgroundColor}"
BorderBrush="{DynamicResource ButtonInsideBorder}"
BorderThickness="1"
@ -28,26 +28,21 @@
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsPressed" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush"
Value="{DynamicResource ButtonMousePressedInsideBorder}" />
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource ButtonMousePressedInsideBorder}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMouseOver}" />
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMouseOver}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush"
Value="{DynamicResource CustomContextHover}" />
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource CustomContextHover}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
@ -62,8 +57,8 @@
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Margin="2,5,2,5"
Padding="10,5,10,5"
Margin="2 5 2 5"
Padding="10 5 10 5"
Background="{DynamicResource AccentButtonBackground}"
BorderThickness="1"
CornerRadius="5">

View file

@ -5,7 +5,7 @@
xmlns:ui="http://schemas.modernwpf.com/2019"
Background="{DynamicResource PopuBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0"
BorderThickness="0 1 0 0"
CornerRadius="8"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Foreground="{DynamicResource PopupTextColor}"
@ -24,14 +24,14 @@
</Grid.RowDefinitions>
<!-- Window title and the keys in the hotkey -->
<Grid Grid.Row="0" Margin="26,12,26,0">
<Grid Grid.Row="0" Margin="26 12 26 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{Binding WindowTitle}"
@ -42,8 +42,8 @@
Grid.Row="1"
Width="450"
Height="100"
Margin="0,100,0,0"
Padding="26,12,26,0">
Margin="0 100 0 0"
Padding="26 12 26 0">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl ItemsSource="{Binding KeysToDisplay}">
<ItemsControl.ItemsPanel>
@ -56,12 +56,12 @@
<Border
MinWidth="50"
MinHeight="50"
Margin="5,0,5,0"
Margin="5 0 5 0"
Padding="8"
Background="{DynamicResource AccentButtonBackground}"
CornerRadius="6">
<TextBlock
Margin="5,0,5,0"
Margin="5 0 5 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="18"
@ -82,9 +82,9 @@
<Border
x:Name="Alert"
Width="420"
Padding="0, 10"
VerticalAlignment="Center"
Padding="0 10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource InfoBarWarningBG}"
BorderBrush="{DynamicResource InfoBarBD}"
BorderThickness="1"
@ -97,21 +97,21 @@
</Grid.ColumnDefinitions>
<ui:FontIcon
Grid.Column="0"
Margin="20,0,14,0"
Margin="20 0 14 0"
VerticalAlignment="Center"
FontSize="15"
Foreground="{DynamicResource InfoBarWarningIcon}"
Glyph="&#xf167;" />
<TextBlock
Grid.Column="1"
x:Name="tbMsg"
Margin="0,0,0,2"
Padding="0,0,8,0"
Grid.Column="1"
Margin="0 0 0 2"
Padding="0 0 8 0"
HorizontalAlignment="Left"
FontSize="13"
FontWeight="SemiBold"
TextWrapping="Wrap"
Foreground="{DynamicResource Color05B}" />
Foreground="{DynamicResource Color05B}"
TextWrapping="Wrap" />
</Grid>
</Border>
@ -122,7 +122,7 @@
Grid.Row="2"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0"
BorderThickness="0 1 0 0"
CornerRadius="0 0 8 8">
<StackPanel
Margin="10"
@ -132,35 +132,35 @@
x:Name="OverwriteBtn"
Height="30"
MinWidth="100"
Margin="0,0,4,0"
Margin="0 0 4 0"
Click="Overwrite"
Content="{DynamicResource commonOverwrite}"
Visibility="Collapsed"
Style="{StaticResource AccentButtonStyle}" />
Style="{StaticResource AccentButtonStyle}"
Visibility="Collapsed" />
<Button
x:Name="SaveBtn"
Height="30"
MinWidth="100"
Margin="0,0,4,0"
Margin="0 0 4 0"
Click="Save"
Content="{DynamicResource commonSave}"
Style="{StaticResource AccentButtonStyle}" />
<Button
Height="30"
MinWidth="100"
Margin="4,0,4,0"
Margin="4 0 4 0"
Click="Reset"
Content="{DynamicResource commonReset}" />
<Button
Height="30"
MinWidth="100"
Margin="4,0,4,0"
Margin="4 0 4 0"
Click="Delete"
Content="{DynamicResource commonDelete}" />
<Button
Height="30"
MinWidth="100"
Margin="4,0,0,0"
Margin="4 0 0 0"
Click="Cancel"
Content="{DynamicResource commonCancel}" />
</StackPanel>

View file

@ -355,6 +355,7 @@
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<system:String x:Key="settingWindowFontTitle">Setting Window Font</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>

View file

@ -143,8 +143,9 @@ namespace Flow.Launcher
WindowAnimation();
}
}
// Show notify icon when flowlauncher is hidden
// Initialize context menu & notify icon
InitializeContextMenu();
InitializeNotifyIcon();
// Initialize color scheme
@ -274,6 +275,9 @@ namespace Flow.Launcher
case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
case nameof(Settings.SettingWindowFont):
InitializeContextMenu();
break;
}
};
@ -324,7 +328,7 @@ namespace Flow.Launcher
private void OnLocationChanged(object sender, EventArgs e)
{
if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
if (IsLoaded)
{
_settings.WindowLeft = Left;
_settings.WindowTop = Top;
@ -567,6 +571,44 @@ namespace Flow.Launcher
Icon = Constant.Version == "1.0.0" ? Properties.Resources.dev : Properties.Resources.app,
Visible = !_settings.HideNotifyIcon
};
_notifyIcon.MouseClick += (o, e) =>
{
switch (e.Button)
{
case MouseButtons.Left:
_viewModel.ToggleFlowLauncher();
break;
case MouseButtons.Right:
_contextMenu.IsOpen = true;
// Get context menu handle and bring it to the foreground
if (PresentationSource.FromVisual(_contextMenu) is HwndSource hwndSource)
{
Win32Helper.SetForegroundWindow(hwndSource.Handle);
}
_contextMenu.Focus();
break;
}
};
}
private void UpdateNotifyIconText()
{
var menu = _contextMenu;
((MenuItem)menu.Items[0]).Header = App.API.GetTranslation("iconTrayOpen") +
" (" + _settings.Hotkey + ")";
((MenuItem)menu.Items[1]).Header = App.API.GetTranslation("GameMode");
((MenuItem)menu.Items[2]).Header = App.API.GetTranslation("PositionReset");
((MenuItem)menu.Items[3]).Header = App.API.GetTranslation("iconTraySettings");
((MenuItem)menu.Items[4]).Header = App.API.GetTranslation("iconTrayExit");
}
private void InitializeContextMenu()
{
var menu = _contextMenu;
menu.Items.Clear();
var openIcon = new FontIcon { Glyph = "\ue71e" };
var open = new MenuItem
{
@ -612,38 +654,6 @@ namespace Flow.Launcher
_contextMenu.Items.Add(positionreset);
_contextMenu.Items.Add(settings);
_contextMenu.Items.Add(exit);
_notifyIcon.MouseClick += (o, e) =>
{
switch (e.Button)
{
case MouseButtons.Left:
_viewModel.ToggleFlowLauncher();
break;
case MouseButtons.Right:
_contextMenu.IsOpen = true;
// Get context menu handle and bring it to the foreground
if (PresentationSource.FromVisual(_contextMenu) is HwndSource hwndSource)
{
Win32Helper.SetForegroundWindow(hwndSource.Handle);
}
_contextMenu.Focus();
break;
}
};
}
private void UpdateNotifyIconText()
{
var menu = _contextMenu;
((MenuItem)menu.Items[0]).Header = App.API.GetTranslation("iconTrayOpen") +
" (" + _settings.Hotkey + ")";
((MenuItem)menu.Items[1]).Header = App.API.GetTranslation("GameMode");
((MenuItem)menu.Items[2]).Header = App.API.GetTranslation("PositionReset");
((MenuItem)menu.Items[3]).Header = App.API.GetTranslation("iconTraySettings");
((MenuItem)menu.Items[4]).Header = App.API.GetTranslation("iconTrayExit");
}
#endregion

View file

@ -23,12 +23,12 @@
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="{DynamicResource Color12B}" />
<Setter Property="Padding" Value="5,0,5,0" />
<Setter Property="Padding" Value="5 0 5 0" />
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding Type, RelativeSource={RelativeSource AncestorType=local:HotkeyDisplay}}" Value="Small">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="0,0,0,0" />
<Setter Property="Padding" Value="0 0 0 0" />
<Setter Property="BorderThickness" Value="0" />
</DataTrigger>
</Style.Triggers>
@ -51,14 +51,14 @@
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="Padding" Value="10,5,10,5" />
<Setter Property="Margin" Value="2,5,2,5" />
<Setter Property="Padding" Value="10 5 10 5" />
<Setter Property="Margin" Value="2 5 2 5" />
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding Type, RelativeSource={RelativeSource AncestorType=local:HotkeyDisplay}}" Value="Small">
<Setter Property="Background" Value="{DynamicResource AccentButtonBackground}" />
<Setter Property="Padding" Value="10,5,10,5" />
<Setter Property="Margin" Value="2,0,2,0" />
<Setter Property="Padding" Value="10 5 10 5" />
<Setter Property="Margin" Value="2 0 2 0" />
</DataTrigger>
</Style.Triggers>
</Style>

View file

@ -42,14 +42,11 @@ namespace Flow.Launcher.Resources.Controls
private static void keyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as UserControl;
if (null == control) return; // This should not be possible
if (d is not UserControl) return; // This should not be possible
var newValue = e.NewValue as string;
if (null == newValue) return;
if (e.NewValue is not string newValue) return;
if (d is not HotkeyDisplay hotkeyDisplay)
return;
if (d is not HotkeyDisplay hotkeyDisplay) return;
hotkeyDisplay.Values.Clear();
foreach (var key in newValue.Split('+'))

View file

@ -4,6 +4,24 @@
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019">
<!-- Setting Window Font -->
<FontFamily x:Key="SettingWindowFont">Segoe UI</FontFamily>
<Style TargetType="ui:FontIcon">
<Setter Property="FontFamily" Value="/Resources/#Segoe Fluent Icons" />
</Style>
<Style TargetType="Control">
<Setter Property="FontFamily" Value="{DynamicResource SettingWindowFont}" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="{DynamicResource SettingWindowFont}" />
</Style>
<Style TargetType="Window">
<Setter Property="FontFamily" Value="{DynamicResource SettingWindowFont}" />
</Style>
<FontFamily x:Key="ContentControlThemeFontFamily">
{DynamicResource SettingWindowFont}
</FontFamily>
<ContextMenu x:Key="TextBoxContextMenu">
<MenuItem Command="ApplicationCommands.Cut" Header="{DynamicResource cut}">
<MenuItem.Icon>
@ -1568,6 +1586,7 @@
<Style BasedOn="{StaticResource DefaultPasswordBoxStyle}" TargetType="PasswordBox">
<Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
<Setter Property="FontFamily" Value="{DynamicResource SettingWindowFont}" />
</Style>
<Style
@ -2728,6 +2747,7 @@
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
Focusable="False"
FontFamily="{DynamicResource ContentControlThemeFontFamily}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsTabStop="False"
@ -2740,6 +2760,7 @@
Grid.ColumnSpan="2"
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
FontFamily="{DynamicResource ContentControlThemeFontFamily}"
Foreground="{TemplateBinding ui:ControlHelper.PlaceholderForeground}"
IsHitTestVisible="False"
Text="{TemplateBinding ui:ControlHelper.PlaceholderText}"

View file

@ -127,7 +127,7 @@
Style="{DynamicResource StyleImageFadeIn}" />
<TextBlock
Canvas.Left="205"
Margin="12,0,0,0"
Margin="12 0 0 0"
VerticalAlignment="Center"
FontSize="30"
Foreground="White"
@ -151,30 +151,30 @@
Style="{DynamicResource WizardMove}" />
<StackPanel Width="550" Margin="24,20,24,20">
<StackPanel Margin="0,0,24,0">
<StackPanel Width="550" Margin="24 20 24 20">
<StackPanel Margin="0 0 24 0">
<TextBlock
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource Welcome_Page1_Title}" />
<TextBlock
Margin="0,10,24,0"
Margin="0 10 24 0"
FontSize="14"
Text="{DynamicResource Welcome_Page1_Text01}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,10,24,0"
Margin="0 10 24 0"
FontSize="14"
Text="{DynamicResource Welcome_Page1_Text02}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,30,0,0"
Margin="0 30 0 0"
FontSize="14"
FontWeight="SemiBold"
Text="{DynamicResource language}" />
<ComboBox
Width="200"
Margin="0,10,0,0"
Margin="0 10 0 0"
DisplayMemberPath="Display"
ItemsSource="{Binding Languages}"
SelectedValue="{Binding CustomLanguage, Mode=TwoWay}"

View file

@ -1,29 +1,35 @@
using System.Collections.Generic;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage1
{
public Settings Settings { get; private set; }
private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
if (!IsInitialized)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 1;
InitializeComponent();
_viewModel.PageNum = 1;
base.OnNavigatedTo(e);
}
private readonly Internationalization _translater = Ioc.Default.GetRequiredService<Internationalization>();
public List<Language> Languages => _translater.LoadAvailableLanguages();
public Settings Settings { get; set; }
public string CustomLanguage
{
get

View file

@ -56,7 +56,7 @@
Margin="0"
Background="{Binding PreviewBackground}">
<StackPanel
Margin="0,80,0,0"
Margin="0 80 0 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
@ -89,29 +89,29 @@
</StackPanel>
</Border>
<StackPanel Grid.Row="1" Margin="24,20,24,20">
<StackPanel Grid.Row="1" Margin="24 20 24 20">
<StackPanel>
<TextBlock
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource Welcome_Page2_Title}" />
<TextBlock
Margin="0,10,0,0"
Margin="0 10 0 0"
FontSize="14"
Text="{DynamicResource Welcome_Page2_Text01}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,10,0,0"
Margin="0 10 0 0"
FontSize="14"
Text="{DynamicResource Welcome_Page2_Text02}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,30,0,0"
Margin="0 30 0 0"
FontSize="14"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncherHotkey}" />
<flowlauncher:HotkeyControl
Margin="0,8,0,0"
Margin="0 8 0 0"
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space"
Type="Hotkey"

View file

@ -1,25 +1,31 @@
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using System.Windows.Media;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage2
{
public Settings Settings { get; set; }
public Settings Settings { get; private set; }
private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
if (!IsInitialized)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 2;
InitializeComponent();
_viewModel.PageNum = 2;
base.OnNavigatedTo(e);
}
[RelayCommand]

View file

@ -13,15 +13,15 @@
<Page.Resources>
<Style x:Key="KbdLine" TargetType="Border">
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Margin" Value="0,3,0,3" />
<Setter Property="Margin" Value="0 3 0 3" />
<Setter Property="Background" Value="{DynamicResource Color01B}" />
</Style>
<Style x:Key="Kbd" TargetType="Border">
<Setter Property="CornerRadius" Value="4" />
<Setter Property="Padding" Value="12,4,12,4" />
<Setter Property="Padding" Value="12 4 12 4" />
<Setter Property="Background" Value="{DynamicResource Color00B}" />
<Setter Property="BorderBrush" Value="{DynamicResource Color18B}" />
<Setter Property="BorderThickness" Value="1,1,1,2" />
<Setter Property="BorderThickness" Value="1 1 1 2" />
</Style>
<Style x:Key="KbdText" TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
@ -36,17 +36,17 @@
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Margin="24,20,24,14"
Margin="24 20 24 14"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource Welcome_Page3_Title}" />
<ScrollViewer
Grid.Row="1"
Height="478"
Margin="0,0,0,0"
Margin="0 0 0 0"
HorizontalAlignment="Stretch"
FontSize="13">
<StackPanel Margin="24,0,24,0">
<StackPanel Margin="24 0 24 0">
<Border
BorderBrush="{DynamicResource Color03B}"
BorderThickness="0"
@ -54,7 +54,7 @@
<StackPanel>
<cc:Card
Title="{DynamicResource HotkeyUpDownDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="←+→" Type="Small" />
@ -62,7 +62,7 @@
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyLeftRightDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="↑+↓" Type="Small" />
@ -70,7 +70,7 @@
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyESCDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="ESC" Type="Small" />
@ -78,13 +78,13 @@
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyRunDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<cc:HotkeyDisplay Keys="ENTER" Type="Small" />
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyShiftEnterDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="SHIFT+ENTER" Type="Small" />
@ -92,7 +92,7 @@
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyCtrlEnterDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="CTRL+ENTER" Type="Small" />
@ -100,7 +100,7 @@
</cc:Card>
<cc:Card
Title="{DynamicResource HotkeyCtrlShiftEnterDesc}"
BorderThickness="0,0,0,0"
BorderThickness="0 0 0 0"
Type="Inside">
<StackPanel Orientation="Horizontal">
<cc:HotkeyDisplay Keys="CTRL+SHIFT+ENTER" Type="Small" />

View file

@ -7,15 +7,21 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage3
{
public Settings Settings { get; private set; }
private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
if (!IsInitialized)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 3;
InitializeComponent();
_viewModel.PageNum = 3;
base.OnNavigatedTo(e);
}
public Settings Settings { get; set; }
}
}

View file

@ -4,8 +4,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Flow.Launcher.Resources.Pages"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
Title="WelcomePage4"
d:DesignHeight="450"
d:DesignWidth="800"
@ -36,8 +36,8 @@
</Style>
<Style x:Key="RecommendQuery" TargetType="Border">
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="20,7,12,7" />
<Setter Property="Margin" Value="4,4,4,4" />
<Setter Property="Padding" Value="20 7 12 7" />
<Setter Property="Margin" Value="4 4 4 4" />
<Setter Property="Background" Value="{DynamicResource Color01B}" />
</Style>
<Style x:Key="QueryText" TargetType="TextBlock">
@ -50,7 +50,7 @@
<Setter Property="TextAlignment" Value="Left" />
<Setter Property="TextAlignment" Value="Left" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="Margin" Value="0 4 0 0" />
<Setter Property="Foreground" Value="{DynamicResource Color04B}" />
</Style>
</Page.Resources>
@ -81,26 +81,26 @@
Canvas.Left="0"
Width="450"
Height="280"
Margin="0,0,0,0"
Margin="0 0 0 0"
Source="../../images/page_img01.png"
Style="{DynamicResource StyleImageFadeIn}" />
</Canvas>
</StackPanel>
</Border>
<StackPanel Grid.Row="1" Margin="24,20,24,20">
<StackPanel Grid.Row="1" Margin="24 20 24 20">
<StackPanel>
<TextBlock
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource Welcome_Page4_Title}" />
<TextBlock
Margin="0,10,0,10"
Margin="0 10 0 10"
FontSize="14"
Text="{DynamicResource Welcome_Page4_Text01}"
TextWrapping="WrapWithOverflow" />
<UniformGrid
Margin="0,14,0,0"
Margin="0 14 0 0"
Columns="2"
Rows="2">
<Border Style="{DynamicResource RecommendQuery}">

View file

@ -1,21 +1,27 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
using System.Windows.Navigation;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage4
{
public Settings Settings { get; private set; }
private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
if (!IsInitialized)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 4;
InitializeComponent();
_viewModel.PageNum = 4;
base.OnNavigatedTo(e);
}
public Settings Settings { get; set; }
}
}

View file

@ -79,18 +79,18 @@
</StackPanel>
</Border>
<StackPanel Grid.Row="1" Margin="24,20,24,20">
<StackPanel Grid.Row="1" Margin="24 20 24 20">
<StackPanel>
<TextBlock
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource Welcome_Page5_Title}" />
<TextBlock
Margin="0,10,0,0"
Margin="0 10 0 0"
FontSize="14"
Text="{DynamicResource Welcome_Page5_Text01}"
TextWrapping="WrapWithOverflow" />
<StackPanel Margin="0,30,0,0" Orientation="Horizontal">
<StackPanel Margin="0 30 0 0" Orientation="Horizontal">
<CheckBox
Checked="OnAutoStartupChecked"
Content="{DynamicResource startFlowLauncherOnSystemStartup}"
@ -98,7 +98,7 @@
Style="{DynamicResource DefaultCheckBoxStyle}"
Unchecked="OnAutoStartupUncheck" />
</StackPanel>
<StackPanel Margin="0,0,0,0" Orientation="Horizontal">
<StackPanel Margin="0 0 0 0" Orientation="Horizontal">
<CheckBox
Checked="OnHideOnStartupChecked"
Content="{DynamicResource hideOnStartup}"
@ -109,7 +109,7 @@
<Button
Width="150"
Height="40"
Margin="0,60,0,0"
Margin="0 60 0 0"
HorizontalAlignment="Right"
Click="BtnCancel_OnClick"
Content="{DynamicResource done}"

View file

@ -1,54 +1,74 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
using Flow.Launcher.Infrastructure;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage5
{
private const string StartupPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
public Settings Settings { get; set; }
public bool HideOnStartup { get; set; }
public Settings Settings { get; private set; }
private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
if (!IsInitialized)
{
Settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 5;
InitializeComponent();
_viewModel.PageNum = 5;
base.OnNavigatedTo(e);
}
private void OnAutoStartupChecked(object sender, RoutedEventArgs e)
{
SetStartup();
}
private void OnAutoStartupUncheck(object sender, RoutedEventArgs e)
{
RemoveStartup();
ChangeAutoStartup(true);
}
private void RemoveStartup()
private void OnAutoStartupUncheck(object sender, RoutedEventArgs e)
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.DeleteValue(Constant.FlowLauncher, false);
Settings.StartFlowLauncherOnSystemStartup = false;
ChangeAutoStartup(false);
}
private void SetStartup()
private void ChangeAutoStartup(bool value)
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
key?.SetValue(Constant.FlowLauncher, Constant.ExecutablePath);
Settings.StartFlowLauncherOnSystemStartup = true;
Settings.StartFlowLauncherOnSystemStartup = value;
try
{
if (value)
{
if (Settings.UseLogonTaskForStartup)
{
AutoStartup.ChangeToViaLogonTask();
}
else
{
AutoStartup.ChangeToViaRegistry();
}
}
else
{
AutoStartup.DisableViaLogonTaskAndRegistry();
}
}
catch (Exception e)
{
App.API.ShowMsg(App.API.GetTranslation("setAutoStartFailed"), e.Message);
}
}
private void OnHideOnStartupChecked(object sender, RoutedEventArgs e)
{
Settings.HideOnStartup = true;
}
private void OnHideOnStartupUnchecked(object sender, RoutedEventArgs e)
{
Settings.HideOnStartup = false;
@ -59,6 +79,5 @@ namespace Flow.Launcher.Resources.Pages
var window = Window.GetWindow(this);
window.Close();
}
}
}

View file

@ -54,11 +54,11 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,12,26,0">
<StackPanel Margin="0,0,0,12">
<StackPanel Margin="26 12 26 0">
<StackPanel Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource defaultBrowserTitle}"
@ -73,7 +73,7 @@
</StackPanel>
<StackPanel Margin="14,28,0,0" Orientation="Horizontal">
<StackPanel Margin="14 28 0 0" Orientation="Horizontal">
<TextBlock
Grid.Column="1"
HorizontalAlignment="Left"
@ -84,7 +84,7 @@
Name="comboBox"
Height="35"
MinWidth="200"
Margin="14,0,0,0"
Margin="14 0 0 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding CustomBrowsers}"
@ -96,11 +96,11 @@
</ComboBox.ItemTemplate>
</ComboBox>
<Button
Margin="10,0,0,0"
Margin="10 0 0 0"
Click="btnAdd_Click"
Content="{DynamicResource add}" />
<Button
Margin="10,0,0,0"
Margin="10 0 0 0"
Click="btnDelete_Click"
Content="{DynamicResource delete}"
IsEnabled="{Binding CustomBrowser.Editable}" />
@ -108,10 +108,10 @@
</StackPanel>
<Rectangle
Height="1"
Margin="0,20,0,12"
Margin="0 20 0 12"
Fill="{DynamicResource SeparatorForeground}" />
<StackPanel
Margin="0,0,0,0"
Margin="0 0 0 0"
HorizontalAlignment="Stretch"
DataContext="{Binding CustomBrowser}"
Orientation="Horizontal">
@ -129,7 +129,7 @@
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="14,5,10,0"
Margin="14 5 10 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -139,7 +139,7 @@
Grid.Row="0"
Grid.Column="1"
Width="Auto"
Margin="10,5,0,0"
Margin="10 5 0 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
IsEnabled="{Binding Editable}"
@ -147,7 +147,7 @@
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="14,10,0,0"
Margin="14 10 0 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -159,7 +159,7 @@
LastChildFill="True">
<Button
Name="btnBrowseFile"
Margin="0,10,0,0"
Margin="0 10 0 0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="btnBrowseFile_Click"
@ -177,7 +177,7 @@
</Button>
<TextBox
x:Name="PathTextBox"
Margin="10,10,5,0"
Margin="10 10 5 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
IsEnabled="{Binding Editable}"
@ -187,19 +187,17 @@
<StackPanel
Grid.Row="2"
Grid.Column="1"
Margin="14,10,14,0"
Margin="14 10 14 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<RadioButton IsChecked="{Binding OpenInTab}"
Content="{DynamicResource defaultBrowser_newTab}"></RadioButton>
<RadioButton IsChecked="{Binding OpenInNewWindow, Mode=OneTime}"
Content="{DynamicResource defaultBrowser_newWindow}"></RadioButton>
<RadioButton Content="{DynamicResource defaultBrowser_newTab}" IsChecked="{Binding OpenInTab}" />
<RadioButton Content="{DynamicResource defaultBrowser_newWindow}" IsChecked="{Binding OpenInNewWindow, Mode=OneTime}" />
</StackPanel>
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="14,10,0,20"
Margin="14 10 0 20"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -207,17 +205,17 @@
<StackPanel
Grid.Row="3"
Grid.Column="1"
Margin="0,10,0,15"
Margin="0 10 0 15"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBox
x:Name="fileArgTextBox"
Width="180"
Margin="10,0,0,0"
Margin="10 0 0 0"
Text="{Binding PrivateArg}" />
<CheckBox
Margin="12,0,0,0"
Margin="12 0 0 0"
VerticalAlignment="Center"
IsChecked="{Binding EnablePrivate}">
<CheckBox.Style>
@ -239,18 +237,18 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
Width="145"
Margin="0,0,5,0"
Margin="0 0 5 0"
Click="btnCancel_Click"
Content="{DynamicResource cancel}" />
<Button
x:Name="btnDone"
Width="145"
Margin="5,0,0,0"
Margin="5 0 0 0"
Click="btnDone_Click"
Content="{DynamicResource done}"
ForceCursor="True"

View file

@ -1,27 +1,26 @@
using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class SelectBrowserWindow : Window, INotifyPropertyChanged
[INotifyPropertyChanged]
public partial class SelectBrowserWindow : Window
{
private readonly Settings _settings;
private int selectedCustomBrowserIndex;
public event PropertyChangedEventHandler PropertyChanged;
public Settings Settings { get; }
public int SelectedCustomBrowserIndex
{
get => selectedCustomBrowserIndex; set
get => selectedCustomBrowserIndex;
set
{
selectedCustomBrowserIndex = value;
PropertyChanged?.Invoke(this, new(nameof(CustomBrowser)));
OnPropertyChanged(nameof(CustomBrowser));
}
}
public ObservableCollection<CustomBrowserViewModel> CustomBrowsers { get; set; }
@ -29,9 +28,9 @@ namespace Flow.Launcher
public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
public SelectBrowserWindow(Settings settings)
{
Settings = settings;
CustomBrowsers = new ObservableCollection<CustomBrowserViewModel>(Settings.CustomBrowserList.Select(x => x.Copy()));
SelectedCustomBrowserIndex = Settings.CustomBrowserIndex;
_settings = settings;
CustomBrowsers = new ObservableCollection<CustomBrowserViewModel>(_settings.CustomBrowserList.Select(x => x.Copy()));
SelectedCustomBrowserIndex = _settings.CustomBrowserIndex;
InitializeComponent();
}
@ -42,8 +41,8 @@ namespace Flow.Launcher
private void btnDone_Click(object sender, RoutedEventArgs e)
{
Settings.CustomBrowserList = CustomBrowsers.ToList();
Settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
_settings.CustomBrowserList = CustomBrowsers.ToList();
_settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
Close();
}
@ -64,8 +63,7 @@ namespace Flow.Launcher
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = dlg.ShowDialog();
var result = dlg.ShowDialog();
if (result == true)
{
TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");

View file

@ -1,28 +1,28 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
using System;
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class SelectFileManagerWindow : Window, INotifyPropertyChanged
[INotifyPropertyChanged]
public partial class SelectFileManagerWindow : Window
{
private readonly Settings _settings;
private int selectedCustomExplorerIndex;
public event PropertyChangedEventHandler PropertyChanged;
public Settings Settings { get; }
public int SelectedCustomExplorerIndex
{
get => selectedCustomExplorerIndex; set
get => selectedCustomExplorerIndex;
set
{
selectedCustomExplorerIndex = value;
PropertyChanged?.Invoke(this, new(nameof(CustomExplorer)));
OnPropertyChanged(nameof(CustomExplorer));
}
}
public ObservableCollection<CustomExplorerViewModel> CustomExplorers { get; set; }
@ -30,9 +30,9 @@ namespace Flow.Launcher
public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
public SelectFileManagerWindow(Settings settings)
{
Settings = settings;
CustomExplorers = new ObservableCollection<CustomExplorerViewModel>(Settings.CustomExplorerList.Select(x => x.Copy()));
SelectedCustomExplorerIndex = Settings.CustomExplorerIndex;
_settings = settings;
CustomExplorers = new ObservableCollection<CustomExplorerViewModel>(_settings.CustomExplorerList.Select(x => x.Copy()));
SelectedCustomExplorerIndex = _settings.CustomExplorerIndex;
InitializeComponent();
}
@ -43,8 +43,8 @@ namespace Flow.Launcher
private void btnDone_Click(object sender, RoutedEventArgs e)
{
Settings.CustomExplorerList = CustomExplorers.ToList();
Settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
_settings.CustomExplorerList = CustomExplorers.ToList();
_settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
Close();
}
@ -65,8 +65,7 @@ namespace Flow.Launcher
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = dlg.ShowDialog();
var result = dlg.ShowDialog();
if (result == true)
{
TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");

View file

@ -268,4 +268,23 @@ public partial class SettingsPaneAboutViewModel : BaseModel
return "0 B";
}
public string SettingWindowFont
{
get => _settings.SettingWindowFont;
set
{
if (_settings.SettingWindowFont != value)
{
_settings.SettingWindowFont = value;
OnPropertyChanged();
}
}
}
[RelayCommand]
private void ResetSettingWindowFont()
{
SettingWindowFont = Win32Helper.GetSystemDefaultFont(false);
}
}

View file

@ -17,11 +17,12 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneGeneralViewModel : BaseModel
{
public Settings Settings { get; }
private readonly Updater _updater;
private readonly IPortable _portable;
private readonly Portable _portable;
private readonly Internationalization _translater;
public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable, Internationalization translater)
public SettingsPaneGeneralViewModel(Settings settings, Updater updater, Portable portable, Internationalization translater)
{
Settings = settings;
_updater = updater;
@ -78,7 +79,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
try
{
if (UseLogonTaskForStartup)
if (value)
{
AutoStartup.ChangeToViaLogonTask();
}

View file

@ -2,7 +2,6 @@
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;

View file

@ -1,4 +1,6 @@
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure.UserSettings;
@ -8,49 +10,43 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneProxyViewModel : BaseModel
{
private readonly Updater _updater;
public Settings Settings { get; }
private readonly Updater _updater;
public SettingsPaneProxyViewModel(Settings settings, Updater updater)
{
_updater = updater;
Settings = settings;
_updater = updater;
}
[RelayCommand]
private void OnTestProxyClicked()
private async Task OnTestProxyClickedAsync()
{
var message = TestProxy();
var message = await TestProxyAsync();
App.API.ShowMsgBox(App.API.GetTranslation(message));
}
private string TestProxy()
private async Task<string> TestProxyAsync()
{
if (string.IsNullOrEmpty(Settings.Proxy.Server)) return "serverCantBeEmpty";
if (Settings.Proxy.Port <= 0) return "portCantBeEmpty";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_updater.GitHubRepository);
var handler = new HttpClientHandler
{
Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port)
};
if (string.IsNullOrEmpty(Settings.Proxy.UserName) || string.IsNullOrEmpty(Settings.Proxy.Password))
if (!string.IsNullOrEmpty(Settings.Proxy.UserName) && !string.IsNullOrEmpty(Settings.Proxy.Password))
{
request.Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port);
}
else
{
request.Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port)
{
Credentials = new NetworkCredential(Settings.Proxy.UserName, Settings.Proxy.Password)
};
handler.Proxy.Credentials = new NetworkCredential(Settings.Proxy.UserName, Settings.Proxy.Password);
}
using var client = new HttpClient(handler);
try
{
var response = (HttpWebResponse)request.GetResponse();
return response.StatusCode switch
{
HttpStatusCode.OK => "proxyIsCorrect",
_ => "proxyConnectFailed"
};
var response = await client.GetAsync(_updater.GitHubRepository);
return response.IsSuccessStatusCode ? "proxyIsCorrect" : "proxyConnectFailed";
}
catch
{

View file

@ -6,7 +6,6 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@ -22,10 +21,12 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneThemeViewModel : BaseModel
{
public Settings Settings { get; }
private readonly Theme _theme;
private readonly string DefaultFont = Win32Helper.GetSystemDefaultFont();
public string BackdropSubText => !Win32Helper.IsBackdropSupported() ? App.API.GetTranslation("BackdropTypeDisabledToolTip") : "";
public Settings Settings { get; }
private readonly Theme _theme = Ioc.Default.GetRequiredService<Theme>();
public static string LinkHowToCreateTheme => @"https://www.flowlauncher.com/theme-builder/";
public static string LinkThemeGallery => "https://github.com/Flow-Launcher/Flow.Launcher/discussions/1438";
@ -289,59 +290,14 @@ public partial class SettingsPaneThemeViewModel : BaseModel
set => Settings.UseDate = value;
}
public FontFamily ClockPanelFont { get; }
public Brush PreviewBackground
{
get => WallpaperPathRetrieval.GetWallpaperBrush();
}
public ResultsViewModel PreviewResults
{
get
{
var results = new List<Result>
{
new()
{
Title = App.API.GetTranslation("SampleTitleExplorer"),
SubTitle = App.API.GetTranslation("SampleSubTitleExplorer"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleWebSearch"),
SubTitle = App.API.GetTranslation("SampleSubTitleWebSearch"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleProgram"),
SubTitle = App.API.GetTranslation("SampleSubTitleProgram"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Program\Images\program.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleProcessKiller"),
SubTitle = App.API.GetTranslation("SampleSubTitleProcessKiller"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png"
)
}
};
var vm = new ResultsViewModel(Settings);
vm.AddResults(results, "PREVIEW");
return vm;
}
}
public ResultsViewModel PreviewResults { get; }
public FontFamily SelectedQueryBoxFont
{
@ -479,9 +435,53 @@ public partial class SettingsPaneThemeViewModel : BaseModel
public string ThemeImage => Constant.QueryTextBoxIconImagePath;
public SettingsPaneThemeViewModel(Settings settings)
public SettingsPaneThemeViewModel(Settings settings, Theme theme)
{
Settings = settings;
_theme = theme;
ClockPanelFont = new FontFamily(DefaultFont);
var results = new List<Result>
{
new()
{
Title = App.API.GetTranslation("SampleTitleExplorer"),
SubTitle = App.API.GetTranslation("SampleSubTitleExplorer"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleWebSearch"),
SubTitle = App.API.GetTranslation("SampleSubTitleWebSearch"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleProgram"),
SubTitle = App.API.GetTranslation("SampleSubTitleProgram"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Program\Images\program.png"
)
},
new()
{
Title = App.API.GetTranslation("SampleTitleProcessKiller"),
SubTitle = App.API.GetTranslation("SampleSubTitleProcessKiller"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png"
)
}
};
var vm = new ResultsViewModel(Settings);
vm.AddResults(results, "PREVIEW");
PreviewResults = vm;
}
[RelayCommand]

View file

@ -12,6 +12,11 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<ui:Page.Resources>
<ResourceDictionary>
<CollectionViewSource x:Key="SortedFonts" Source="{Binding Source={x:Static Fonts.SystemFontFamilies}}" />
</ResourceDictionary>
</ui:Page.Resources>
<ScrollViewer
Margin="0"
CanContentScroll="True"
@ -98,10 +103,8 @@
Margin="0 0 12 0"
Command="{Binding AskClearLogFolderConfirmationCommand}"
Content="{Binding LogFolderSize, Mode=OneWay}" />
<Button
Content="&#xec7a;"
FontFamily="/Resources/#Segoe Fluent Icons"
FontSize="20">
<Button>
<ui:FontIcon FontSize="20" Glyph="&#xec7a;" />
<ui:FlyoutService.Flyout>
<ui:MenuFlyout>
<MenuItem Command="{Binding OpenWelcomeWindowCommand}" Header="{DynamicResource welcomewindow}">
@ -127,13 +130,39 @@
</StackPanel>
</cc:Card>
<cc:Card Title="{DynamicResource logLevel}" Icon="&#xE749;">
<ComboBox
DisplayMemberPath="Display"
ItemsSource="{Binding LogLevels}"
SelectedValue="{Binding LogLevel}"
SelectedValuePath="Value" />
</cc:Card>
<cc:ExCard
Title="Advanced"
Margin="0 14 0 0"
Icon="&#xE8B7;">
<StackPanel>
<cc:Card
Title="{DynamicResource logLevel}"
Icon="&#xE749;"
Type="Inside">
<ComboBox
DisplayMemberPath="Display"
ItemsSource="{Binding LogLevels}"
SelectedValue="{Binding LogLevel}"
SelectedValuePath="Value" />
</cc:Card>
<cc:Card
Title="{DynamicResource settingWindowFontTitle}"
Icon="&#xf259;"
Type="Inside">
<StackPanel Orientation="Horizontal">
<Button Command="{Binding ResetSettingWindowFontCommand}" Content="Reset" />
<ComboBox
Margin="12 8 0 8"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
DisplayMemberPath="Source"
ItemsSource="{Binding Source={StaticResource SortedFonts}}"
SelectedValue="{Binding SettingWindowFont, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Source" />
</StackPanel>
</cc:Card>
</StackPanel>
</cc:ExCard>
<TextBlock
Margin="14 20 0 0"

View file

@ -1,8 +1,6 @@
using System.Windows.Navigation;
using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher.SettingPages.Views;
@ -14,9 +12,7 @@ public partial class SettingsPaneAbout
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
_viewModel = new SettingsPaneAboutViewModel(settings, updater);
_viewModel = Ioc.Default.GetRequiredService<SettingsPaneAboutViewModel>();
DataContext = _viewModel;
InitializeComponent();
}

View file

@ -1,9 +1,5 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher.SettingPages.Views;
@ -16,11 +12,7 @@ public partial class SettingsPaneGeneral
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
var portable = Ioc.Default.GetRequiredService<Portable>();
var translater = Ioc.Default.GetRequiredService<Internationalization>();
_viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable, translater);
_viewModel = Ioc.Default.GetRequiredService<SettingsPaneGeneralViewModel>();
DataContext = _viewModel;
InitializeComponent();
}

View file

@ -1,7 +1,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -13,8 +12,7 @@ public partial class SettingsPaneHotkey
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPaneHotkeyViewModel(settings);
_viewModel = Ioc.Default.GetRequiredService<SettingsPaneHotkeyViewModel>();
DataContext = _viewModel;
InitializeComponent();
}

View file

@ -37,9 +37,9 @@
<Border
Grid.Row="0"
Grid.Column="0"
Padding="5,18,0,0">
Padding="5 18 0 0">
<TextBlock
Margin="0,5"
Margin="0 5"
FontSize="30"
Style="{StaticResource PageTitle}"
Text="{DynamicResource pluginStore}"
@ -49,13 +49,13 @@
<DockPanel
Grid.Row="0"
Grid.Column="1"
Margin="5,24,0,0">
Margin="5 24 0 0">
<TextBox
Name="PluginStoreFilterTextbox"
Width="150"
Height="34"
Margin="0,0,26,0"
Margin="0 0 26 0"
HorizontalAlignment="Right"
ContextMenu="{StaticResource TextBoxContextMenu}"
DockPanel.Dock="Right"
@ -75,7 +75,7 @@
Stretch="None">
<VisualBrush.Visual>
<Label
Padding="10,0,0,0"
Padding="10 0 0 0"
Content="{DynamicResource searchplugin}"
Foreground="{DynamicResource CustomContextDisabled}" />
</VisualBrush.Visual>
@ -97,8 +97,8 @@
</TextBox>
<Button
Height="34"
Margin="0,5,10,5"
Padding="12,4"
Margin="0 5 10 5"
Padding="12 4"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding RefreshExternalPluginsCommand}"
@ -111,8 +111,8 @@
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="4,0,0,0"
Padding="0,0,18,0"
Margin="4 0 0 0"
Padding="0 0 18 0"
FontSize="14"
ItemContainerStyle="{StaticResource StoreList}"
ItemsSource="{Binding Source={StaticResource PluginStoreCollectionView}}"
@ -125,7 +125,7 @@
<ItemsPanelTemplate>
<wpftk:VirtualizingWrapPanel
x:Name="ItemWrapPanel"
Margin="0,0,0,10"
Margin="0 0 0 10"
ItemSize="216,184"
MouseWheelDelta="48"
ScrollLineDelta="16"
@ -143,7 +143,7 @@
<Grid>
<StackPanel Orientation="Vertical">
<TextBlock
Margin="2,0,0,10"
Margin="2 0 0 10"
VerticalAlignment="Top"
FontSize="16"
FontWeight="Bold"
@ -231,10 +231,10 @@
<VirtualizingStackPanel
Grid.Row="0"
Grid.Column="0"
Margin="5,0,0,0"
Margin="5 0 0 0"
Orientation="Horizontal">
<TextBlock
Margin="0,0,5,0"
Margin="0 0 5 0"
VerticalAlignment="Center"
FontSize="14"
FontWeight="Bold"
@ -253,7 +253,7 @@
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="5,4,0,0"
Margin="5 4 0 0"
TextWrapping="Wrap">
<Hyperlink
Foreground="{DynamicResource Color04B}"
@ -267,13 +267,13 @@
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="20,0,0,0"
Margin="20 0 0 0"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
MinHeight="42"
Margin="5,0"
Padding="15,5"
Margin="5 0"
Padding="15 5"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Command="{Binding ShowCommandQueryCommand}"
@ -282,8 +282,8 @@
Visibility="{Binding LabelInstalled, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter='!'}" />
<Button
MinHeight="42"
Margin="5,0"
Padding="15,5"
Margin="5 0"
Padding="15 5"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding ShowCommandQueryCommand}"
@ -292,8 +292,8 @@
Visibility="{Binding LabelInstalled, Converter={StaticResource BoolToVisibilityConverter}}" />
<Button
MinHeight="42"
Margin="5,0"
Padding="15,5"
Margin="5 0"
Padding="15 5"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding ShowCommandQueryCommand}"
@ -311,15 +311,15 @@
<Image
Width="32"
Height="32"
Margin="18,24,0,0"
Margin="18 24 0 0"
HorizontalAlignment="Left"
RenderOptions.BitmapScalingMode="Fant"
Source="{Binding IcoPath, IsAsync=True}" />
<Border
x:Name="LabelUpdate"
Height="12"
Margin="10,24,0,0"
Padding="6,2"
Margin="10 24 0 0"
Padding="6 2"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="#45BD59"
@ -328,7 +328,7 @@
Visibility="{Binding LabelUpdate, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
<TextBlock
Margin="18,10,18,0"
Margin="18 10 18 0"
FontWeight="SemiBold"
Foreground="{DynamicResource Color05B}"
Text="{Binding Name}"
@ -336,8 +336,8 @@
ToolTip="{Binding Version}" />
<TextBlock
Height="60"
Margin="18,6,18,0"
Padding="0,0,0,10"
Margin="18 6 18 0"
Padding="0 0 0 10"
FontSize="12"
Foreground="{DynamicResource Color04B}"
Text="{Binding Description, Mode=OneWay}"

View file

@ -5,7 +5,6 @@ using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -17,8 +16,7 @@ public partial class SettingsPanePluginStore
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPanePluginStoreViewModel();
_viewModel = Ioc.Default.GetRequiredService<SettingsPanePluginStoreViewModel>();
DataContext = _viewModel;
InitializeComponent();
}

View file

@ -58,9 +58,9 @@
Margin="0 0 20 0"
Command="{Binding OpenHelperCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content="&#xe9ce;"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="14" />
FontSize="14">
<ui:FontIcon FontSize="14" Glyph="&#xe9ce;" />
</Button>
<TextBox
Name="PluginFilterTextbox"
Width="150"

View file

@ -2,7 +2,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -14,8 +13,7 @@ public partial class SettingsPanePlugins
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPanePluginsViewModel(settings);
_viewModel = Ioc.Default.GetRequiredService<SettingsPanePluginsViewModel>();
DataContext = _viewModel;
InitializeComponent();
}

View file

@ -2,11 +2,11 @@
x:Class="Flow.Launcher.SettingPages.Views.SettingsPaneProxy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
xmlns:viewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels"
Title="Proxy"
d:DataContext="{d:DesignInstance viewModels:SettingsPaneProxyViewModel}"
@ -18,8 +18,8 @@
</Page.Resources>
<ScrollViewer
Padding="5 0 24 0"
FontSize="14"
CanContentScroll="True"
FontSize="14"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.ScrollUnit="Pixel">
@ -71,9 +71,9 @@
<cc:Card Title="{DynamicResource testProxy}" Margin="0 8 0 0">
<Button
Width="150"
Command="{Binding TestProxyClickedCommand}"
Content="{DynamicResource testProxy}"
IsEnabled="{Binding Settings.Proxy.Enabled}"
Command="{Binding TestProxyClickedCommand}"/>
IsEnabled="{Binding Settings.Proxy.Enabled}" />
</cc:Card>
</StackPanel>
</ScrollViewer>

View file

@ -1,8 +1,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -14,13 +12,10 @@ public partial class SettingsPaneProxy
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
_viewModel = new SettingsPaneProxyViewModel(settings, updater);
_viewModel = Ioc.Default.GetRequiredService<SettingsPaneProxyViewModel>();
DataContext = _viewModel;
InitializeComponent();
}
base.OnNavigatedTo(e);
}
}

View file

@ -331,20 +331,22 @@
IsReadOnly="True"
Style="{DynamicResource QueryBoxStyle}"
Text="{DynamicResource hiThere}" />
</Border>
<StackPanel
x:Name="ClockPanel"
IsHitTestVisible="False"
Style="{DynamicResource ClockPanel}"
Visibility="Visible">
<!-- Because these two textblock follow SettingWindowFont, we need to revert their font family explictly -->
<TextBlock
x:Name="ClockBox"
FontFamily="{Binding ClockPanelFont, Mode=OneTime}"
Style="{DynamicResource ClockBox}"
Text="{Binding ClockText}"
Visibility="{Binding UseClock, Converter={StaticResource BoolToVisibilityConverter}}" />
<TextBlock
x:Name="DateBox"
FontFamily="{Binding ClockPanelFont, Mode=OneTime}"
Style="{DynamicResource DateBox}"
Text="{Binding DateText}"
Visibility="{Binding UseDate, Converter={StaticResource BoolToVisibilityConverter}}" />

View file

@ -1,12 +1,10 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
using Page = ModernWpf.Controls.Page;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneTheme : Page
public partial class SettingsPaneTheme
{
private SettingsPaneThemeViewModel _viewModel = null!;
@ -14,12 +12,10 @@ public partial class SettingsPaneTheme : Page
{
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPaneThemeViewModel(settings);
_viewModel = Ioc.Default.GetRequiredService<SettingsPaneThemeViewModel>();
DataContext = _viewModel;
InitializeComponent();
}
base.OnNavigatedTo(e);
}
}

View file

@ -16,6 +16,7 @@
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
LocationChanged="Window_LocationChanged"
MouseDown="window_MouseDown"
ResizeMode="CanResize"
SnapsToDevicePixels="True"

View file

@ -1,6 +1,6 @@
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using CommunityToolkit.Mvvm.DependencyInjection;
@ -9,43 +9,53 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.Views;
using Flow.Launcher.ViewModel;
using ModernWpf.Controls;
using TextBox = System.Windows.Controls.TextBox;
using Screen = System.Windows.Forms.Screen;
namespace Flow.Launcher;
public partial class SettingWindow
{
#region Private Fields
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
#endregion
#region Constructor
public SettingWindow()
{
var viewModel = Ioc.Default.GetRequiredService<SettingWindowViewModel>();
_settings = Ioc.Default.GetRequiredService<Settings>();
var viewModel = Ioc.Default.GetRequiredService<SettingWindowViewModel>();
DataContext = viewModel;
_viewModel = viewModel;
InitializePosition();
InitializeComponent();
UpdatePositionAndState();
}
#endregion
#region Window Events
private void OnLoaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
// Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
InitializePosition();
UpdatePositionAndState();
}
private void OnClosed(object sender, EventArgs e)
{
_settings.SettingWindowState = WindowState;
_settings.SettingWindowTop = Top;
_settings.SettingWindowLeft = Left;
_viewModel.Save();
// If app is exiting, settings save is not needed because main window closing event will handle this
if (App.Exiting) return;
// Save settings when window is closed
_settings.Save();
App.API.SavePluginSettings();
}
@ -56,15 +66,32 @@ public partial class SettingWindow
private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
{
if (Keyboard.FocusedElement is not TextBox textBox)
{
return;
}
if (Keyboard.FocusedElement is not TextBox textBox) return;
var tRequest = new TraversalRequest(FocusNavigationDirection.Next);
textBox.MoveFocus(tRequest);
}
/* Custom TitleBar */
private void Window_StateChanged(object sender, EventArgs e)
{
RefreshMaximizeRestoreButton();
if (IsLoaded)
{
_settings.SettingWindowState = WindowState;
}
}
private void Window_LocationChanged(object sender, EventArgs e)
{
if (IsLoaded)
{
_settings.SettingWindowTop = Top;
_settings.SettingWindowLeft = Left;
}
}
#endregion
#region Window Custom TitleBar
private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
{
@ -99,12 +126,11 @@ public partial class SettingWindow
}
}
private void Window_StateChanged(object sender, EventArgs e)
{
RefreshMaximizeRestoreButton();
}
#endregion
public void InitializePosition()
#region Window Position
public void UpdatePositionAndState()
{
var previousTop = _settings.SettingWindowTop;
var previousLeft = _settings.SettingWindowLeft;
@ -119,6 +145,7 @@ public partial class SettingWindow
Top = previousTop.Value;
Left = previousLeft.Value;
}
WindowState = _settings.SettingWindowState;
}
@ -155,6 +182,10 @@ public partial class SettingWindow
return top;
}
#endregion
#region Navigation View Events
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.IsSettingsSelected)
@ -201,4 +232,6 @@ public partial class SettingWindow
{
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
#endregion
}

View file

@ -5,21 +5,13 @@ namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
private readonly Settings _settings;
private readonly Settings _settings;
public SettingWindowViewModel(Settings settings)
{
_settings = settings;
}
/// <summary>
/// Save Flow settings. Plugins settings are not included.
/// </summary>
public void Save()
{
_settings.Save();
}
public double SettingWindowWidth
{
get => _settings.SettingWindowWidth;

View file

@ -18,6 +18,7 @@ namespace Flow.Launcher.ViewModel
{
_pageNum = value;
OnPropertyChanged();
OnPropertyChanged(nameof(PageDisplay));
UpdateView();
}
}
@ -47,7 +48,6 @@ namespace Flow.Launcher.ViewModel
private void UpdateView()
{
OnPropertyChanged(nameof(PageDisplay));
if (PageNum == 1)
{
BackEnabled = false;

View file

@ -140,21 +140,19 @@
Height="40"
Margin="8 5 0 5"
Click="ForwardButton_Click"
Content="&#xe76c;"
DockPanel.Dock="Right"
FontFamily="/Resources/#Segoe Fluent Icons"
FontSize="18"
IsEnabled="{Binding NextEnabled, Mode=OneWay}" />
IsEnabled="{Binding NextEnabled, Mode=OneWay}">
<ui:FontIcon FontSize="18" Glyph="&#xe76c;" />
</Button>
<Button
x:Name="BackButton"
Width="40"
Height="40"
Click="BackwardButton_Click"
Content="&#xe76b;"
DockPanel.Dock="Right"
FontFamily="/Resources/#Segoe Fluent Icons"
FontSize="18"
IsEnabled="{Binding BackEnabled, Mode=OneWay}" />
IsEnabled="{Binding BackEnabled, Mode=OneWay}">
<ui:FontIcon FontSize="18" Glyph="&#xe76b;" />
</Button>
<StackPanel />
</DockPanel>

View file

@ -2,16 +2,17 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Resources.Pages;
using ModernWpf.Media.Animation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Resources.Pages;
using Flow.Launcher.ViewModel;
using ModernWpf.Media.Animation;
namespace Flow.Launcher
{
public partial class WelcomeWindow : Window
{
private readonly Settings _settings;
private readonly WelcomeViewModel _viewModel;
private readonly NavigationTransitionInfo _forwardTransitionInfo = new SlideNavigationTransitionInfo()
@ -25,6 +26,7 @@ namespace Flow.Launcher
public WelcomeWindow()
{
_settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
DataContext = _viewModel;
InitializeComponent();
@ -76,10 +78,7 @@ namespace Flow.Launcher
private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
{
if (Keyboard.FocusedElement is not TextBox textBox)
{
return;
}
if (Keyboard.FocusedElement is not TextBox textBox) return;
var tRequest = new TraversalRequest(FocusNavigationDirection.Next);
textBox.MoveFocus(tRequest);
}
@ -96,8 +95,10 @@ namespace Flow.Launcher
private void Window_Closed(object sender, EventArgs e)
{
// If app is exiting, settings save is not needed because main window closing event will handle this
if (App.Exiting) return;
// Save settings when window is closed
Ioc.Default.GetRequiredService<Settings>().Save();
_settings.Save();
}
}
}

View file

@ -60,17 +60,17 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,0,26,0">
<StackPanel Margin="0,0,0,12">
<StackPanel Margin="26 0 26 0">
<StackPanel Margin="0 0 0 12">
<TextBlock
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_browserbookmark_bookmarkDataSetting}"
TextAlignment="Left" />
</StackPanel>
<StackPanel Margin="0,0,0,20" Orientation="Horizontal">
<StackPanel Margin="0 0 0 20" Orientation="Horizontal">
<Grid Width="474" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -86,23 +86,23 @@
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="5,0,0,20">
Margin="5 0 0 20">
<TextBlock
Margin="0,0,0,4"
Margin="0 0 0 4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_browserbookmark_guideMessage01}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,4,0,4"
Margin="0 4 0 4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_browserbookmark_guideMessage02}"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,4,0,0"
Margin="0 4 0 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -112,7 +112,7 @@
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="5,0,20,0"
Margin="5 0 20 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -122,14 +122,14 @@
Grid.Column="1"
Width="120"
Height="34"
Margin="5,0,10,0"
Margin="5 0 10 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding Name}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="5,10,20,0"
Margin="5 10 20 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -139,7 +139,7 @@
Grid.Column="1"
Width="120"
Height="34"
Margin="5,10,10,0"
Margin="5 10 10 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding Source={ui:EnumBindingSource {x:Type local:BrowserType}}}"
@ -147,7 +147,7 @@
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="5,10,20,0"
Margin="5 10 20 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -159,7 +159,7 @@
<Button
Height="34"
MinWidth="100"
Margin="5,10,0,0"
Margin="5 10 0 0"
VerticalContentAlignment="Stretch"
Click="OnSelectPathClick"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_browseBrowserBookmark}"
@ -167,7 +167,7 @@
<TextBox
Name="PathTextBox"
Height="34"
Margin="5,10,0,0"
Margin="5 10 0 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="{Binding DataDirectoryPath}" />
@ -180,18 +180,18 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
MinWidth="145"
Margin="0,0,5,0"
Margin="0 0 5 0"
Click="CancelEditCustomBrowser"
Content="{DynamicResource cancel}" />
<Button
Name="btnConfirm"
MinWidth="145"
Margin="5,0,0,0"
Margin="5 0 0 0"
Click="ConfirmEditCustomBrowser"
Style="{StaticResource AccentButtonStyle}">
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />

View file

@ -57,20 +57,20 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,0,26,0">
<StackPanel Margin="0,0,0,12">
<StackPanel Margin="26 0 26 0">
<StackPanel Margin="0 0 0 12">
<TextBlock
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource plugin_explorer_manageactionkeywords_header}"
TextAlignment="Left" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
<StackPanel Margin="0 10 0 0" Orientation="Horizontal">
<TextBlock
MinWidth="150"
Margin="0,10,15,10"
Margin="0 10 15 10"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -84,10 +84,10 @@
PreviewKeyDown="TxtCurrentActionKeyword_OnKeyDown"
Text="{Binding ActionKeyword}" />
</StackPanel>
<StackPanel Margin="0,10,0,15" Orientation="Horizontal">
<StackPanel Margin="0 10 0 15" Orientation="Horizontal">
<TextBlock
MinWidth="150"
Margin="0,0,18,0"
Margin="0 0 18 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -105,20 +105,20 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
Width="145"
Height="30"
Margin="0,0,5,0"
Margin="0 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
Name="DownButton"
Width="145"
Height="30"
Margin="5,0,0,0"
Margin="5 0 0 0"
Click="OnDoneButtonClick"
Style="{StaticResource AccentButtonStyle}">
<TextBlock x:Name="lblAdd" Text="{DynamicResource plugin_explorer_actionkeyword_done}" />

View file

@ -5,21 +5,21 @@
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.Program.ViewModels"
mc:Ignorable="d"
Title="{DynamicResource flowlauncher_plugin_program_directory}"
d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}"
Width="Auto"
Height="276"
d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}"
Background="{DynamicResource PopuBGColor}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Width"
WindowStartupLocation="CenterScreen">
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</WindowChrome.WindowChrome>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
@ -59,11 +59,11 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,0,26,0">
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<StackPanel Margin="26 0 26 0">
<StackPanel Grid.Row="0" Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_edit_program_source_title}"
@ -77,7 +77,7 @@
TextWrapping="WrapWithOverflow" />
</StackPanel>
<StackPanel Margin="0,10,10,0" Orientation="Horizontal">
<StackPanel Margin="0 10 10 0" Orientation="Horizontal">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
@ -104,16 +104,16 @@
HorizontalAlignment="Stretch"
Click="BrowseButton_Click"
Content="{DynamicResource flowlauncher_plugin_program_browse}"
Visibility="{Binding IsCustomSource, Converter={StaticResource BooleanToVisibilityConverter}}"
DockPanel.Dock="Right" />
DockPanel.Dock="Right"
Visibility="{Binding IsCustomSource, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBox
Name="Directory"
Width="350"
Margin="10"
Text="{Binding Location, Mode=TwoWay}"
IsReadOnly="{Binding IsNotCustomSource}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" />
VerticalAlignment="Center"
IsReadOnly="{Binding IsNotCustomSource}"
Text="{Binding Location, Mode=TwoWay}" />
</DockPanel>
<TextBlock
Grid.Row="1"
@ -127,30 +127,30 @@
x:Name="Chkbox"
Grid.Row="1"
Grid.Column="1"
Margin="10,0"
IsChecked="{Binding Enabled, Mode=TwoWay}"
VerticalAlignment="Center" />
Margin="10 0"
VerticalAlignment="Center"
IsChecked="{Binding Enabled, Mode=TwoWay}" />
</Grid>
</StackPanel>
</StackPanel>
</StackPanel>
<Border
Grid.Row="1"
Margin="0,14,0,0"
Margin="0 14 0 0"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
MinWidth="140"
Margin="10,0,5,0"
Margin="10 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
x:Name="btnAdd"
MinWidth="140"
Margin="5,0,10,0"
Margin="5 0 10 0"
Click="BtnAdd_OnClick"
Content="{Binding AddBtnText}"
Style="{DynamicResource AccentButtonStyle}" />

View file

@ -46,8 +46,8 @@
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Margin" Value="0,5,0,0" />
<Setter Property="Padding" Value="15,15,15,15" />
<Setter Property="Margin" Value="0 5 0 0" />
<Setter Property="Padding" Value="15 15 15 15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
@ -65,8 +65,8 @@
<Setter Property="BorderBrush" Value="{DynamicResource Color03B}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Margin" Value="0,5,0,0" />
<Setter Property="Padding" Value="15,15,15,15" />
<Setter Property="Margin" Value="0 5 0 0" />
<Setter Property="Padding" Value="15 15 15 15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
@ -120,20 +120,20 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,12,26,0">
<StackPanel Margin="26 12 26 0">
<StackPanel Margin="0,0,0,12">
<StackPanel Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_suffixes}"
TextAlignment="Left" />
</StackPanel>
<TextBlock
Margin="0,0,0,10"
Margin="0 0 0 10"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_program_only_index_tip}"
TextWrapping="Wrap" />
@ -151,82 +151,82 @@
TextWrapping="Wrap" />
</Border>
<Grid Margin="0,20,0,12">
<Grid Margin="0 20 0 12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="250" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,0,0,0">
<StackPanel Grid.Column="0" Margin="0 0 0 0">
<TextBlock
Margin="0,0,0,8"
Margin="0 0 0 8"
FontSize="16"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_suffixes_executable_types}" />
<CheckBox
Name="apprefMS"
Margin="10,0,0,0"
Margin="10 0 0 0"
IsChecked="{Binding SuffixesStatus[appref-ms]}">
appref-ms
</CheckBox>
<CheckBox
Name="exe"
Margin="10,0,0,0"
Margin="10 0 0 0"
IsChecked="{Binding SuffixesStatus[exe]}">
exe
</CheckBox>
<CheckBox
Name="lnk"
Margin="10,0,0,0"
Margin="10 0 0 0"
IsChecked="{Binding SuffixesStatus[lnk]}">
lnk
</CheckBox>
<CheckBox
Name="CustomFiles"
Margin="10,0,0,0"
Margin="10 0 0 0"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_file_types}"
IsChecked="{Binding UseCustomSuffixes}" />
<TextBox
x:Name="tbSuffixes"
Margin="10,4,0,10"
Margin="10 4 0 10"
Style="{StaticResource CustomFileTypeTextBox}" />
</StackPanel>
<Border
Grid.Column="1"
Margin="20,0,0,10"
Padding="20,0,0,0"
Margin="20 0 0 10"
Padding="20 0 0 0"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="1,0,0,0">
BorderThickness="1 0 0 0">
<StackPanel>
<TextBlock
Margin="0,0,0,8"
Margin="0 0 0 8"
FontSize="16"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_program_suffixes_URL_types}" />
<CheckBox
Name="steam"
Margin="10,0,0,0"
Margin="10 0 0 0"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_URL_steam}"
IsChecked="{Binding ProtocolsStatus[steam]}" />
<CheckBox
Name="epic"
Margin="10,0,0,0"
Margin="10 0 0 0"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_URL_epic}"
IsChecked="{Binding ProtocolsStatus[epic]}" />
<CheckBox
Name="http"
Margin="10,0,0,0"
Margin="10 0 0 0"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_URL_http}"
IsChecked="{Binding ProtocolsStatus[http]}" />
<CheckBox
Name="CustomProtocol"
Margin="10,0,0,0"
Margin="10 0 0 0"
Content="{DynamicResource flowlauncher_plugin_program_suffixes_custom_urls}"
IsChecked="{Binding UseCustomProtocols}" />
<TextBox
x:Name="tbProtocols"
Margin="10,4,0,0"
Margin="10 4 0 0"
Style="{StaticResource CustomURLTypeTextBox}" />
</StackPanel>
</Border>
@ -237,27 +237,27 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnReset"
Height="30"
MinWidth="140"
Margin="0,0,5,0"
Margin="0 0 5 0"
Click="BtnReset_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_reset}" />
<Button
x:Name="btnCancel"
Height="30"
MinWidth="140"
Margin="5,0,5,0"
Margin="5 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
Height="30"
MinWidth="140"
Margin="5,0,0,0"
Margin="5 0 0 0"
HorizontalAlignment="Right"
Click="BtnAdd_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_update}"