diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs index 96338cf6a1a..61f0b18e0ef 100644 --- a/Flow.Launcher.Core/Resource/Theme.cs +++ b/Flow.Launcher.Core/Resource/Theme.cs @@ -176,8 +176,6 @@ public ResourceDictionary GetResourceDictionary(string theme) } if (dict["ItemTitleStyle"] is Style resultItemStyle && - dict["ItemSubTitleStyle"] is Style resultSubItemStyle && - dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle && dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle && dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle && dict["ItemHotkeySelectedStyle"] is Style resultHotkeyItemSelectedStyle) @@ -189,9 +187,25 @@ public ResourceDictionary GetResourceDictionary(string theme) Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch }; Array.ForEach( - new[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o + new[] { resultItemStyle, resultItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o + => Array.ForEach(setters, p => o.Setters.Add(p))); + } + + if ( + dict["ItemSubTitleStyle"] is Style resultSubItemStyle && + dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle) + { + Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(Settings.ResultSubFont)); + Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.ResultSubFontStyle)); + Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(Settings.ResultSubFontWeight)); + Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(Settings.ResultSubFontStretch)); + + Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch }; + Array.ForEach( + new[] { resultSubItemStyle,resultSubItemSelectedStyle}, o => Array.ForEach(setters, p => o.Setters.Add(p))); } + /* Ignore Theme Window Width and use setting */ var windowStyle = dict["WindowStyle"] as Style; var width = Settings.WindowSize; diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 3c2d6589ece..6528f626c23 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -56,6 +56,13 @@ public string Theme } } public bool UseDropShadowEffect { get; set; } = false; + + /* Appearance Settings. It should be separated from the setting later.*/ + public double WindowHeightSize { get; set; } = 42; + public double ItemHeightSize { get; set; } = 58; + public double QueryBoxFontSize { get; set; } = 20; + public double ResultItemFontSize { get; set; } = 16; + public double ResultSubItemFontSize { get; set; } = 13; public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name; public string QueryBoxFontStyle { get; set; } public string QueryBoxFontWeight { get; set; } @@ -64,6 +71,10 @@ public string Theme public string ResultFontStyle { get; set; } public string ResultFontWeight { get; set; } public string ResultFontStretch { get; set; } + public string ResultSubFont { get; set; } = FontFamily.GenericSansSerif.Name; + public string ResultSubFontStyle { get; set; } + public string ResultSubFontWeight { get; set; } + public string ResultSubFontStretch { get; set; } public bool UseGlyphIcons { get; set; } = true; public bool UseAnimation { get; set; } = true; public bool UseSound { get; set; } = true; @@ -205,6 +216,7 @@ public SearchPrecisionScore QuerySearchPrecision /// public double CustomWindowTop { get; set; } = 0; + public bool KeepMaxResults { get; set; } = false; public int MaxResultsToShow { get; set; } = 5; public int ActivateTimes { get; set; } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 3d5bd99c78c..28b51675731 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -56,6 +56,8 @@ Preserve Last Query Select last Query Empty last Query + Fixed Window Height + The window height will not be resizeable by dragging Maximum results shown You can also quickly adjust this by using CTRL+Plus and CTRL+Minus. Ignore hotkeys in fullscreen mode @@ -145,8 +147,13 @@ Launch programs as admin or a different user ProcessKiller Terminate unwanted processes + Search Bar Height + Item Height Query Box Font - Result Item Font + Result Title Font + Result Subtitle Font + Reset + Customize Window Mode Opacity Theme {0} not exists, fallback to default theme @@ -173,6 +180,7 @@ Clock Date + Hotkey Hotkeys diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index a8dfefb2ac9..788c3c597c2 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -12,8 +12,9 @@ xmlns:vm="clr-namespace:Flow.Launcher.ViewModel" Name="FlowMainWindow" Title="Flow Launcher" - MinWidth="{Binding MainWindowWidth, Mode=OneWay}" - MaxWidth="{Binding MainWindowWidth, Mode=OneWay}" + Width="{Binding MainWindowWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" + MinWidth="430" + MinHeight="30" d:DataContext="{d:DesignInstance Type=vm:MainViewModel}" AllowDrop="True" AllowsTransparency="True" @@ -27,15 +28,18 @@ Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" PreviewKeyDown="OnKeyDown" PreviewKeyUp="OnKeyUp" - ResizeMode="NoResize" + ResizeMode="CanResize" ShowInTaskbar="False" SizeToContent="Height" - Style="{DynamicResource WindowStyle}" Topmost="True" Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" WindowStartupLocation="Manual" WindowStyle="None" mc:Ignorable="d"> + + + + @@ -208,311 +212,315 @@ Command="{Binding ForwardHistoryCommand}" Modifiers="{Binding CycleHistoryDownHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='modifiers'}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - + + + - - - - - + + + + + + + + + + + + - - - + + + diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 0f96b88de4c..c333c4e8506 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -63,13 +63,68 @@ public MainWindow(Settings settings, MainViewModel mainVM) InitSoundEffects(); DataObject.AddPastingHandler(QueryTextBox, OnPaste); + + this.Loaded += (_, _) => + { + var handle = new WindowInteropHelper(this).Handle; + var win = HwndSource.FromHwnd(handle); + win.AddHook(WndProc); + }; } + DispatcherTimer timer = new DispatcherTimer + { + Interval = new TimeSpan(0, 0, 0, 0, 500), + IsEnabled = false + }; + public MainWindow() { InitializeComponent(); } + private const int WM_ENTERSIZEMOVE = 0x0231; + private const int WM_EXITSIZEMOVE = 0x0232; + private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + if (msg == WM_ENTERSIZEMOVE) + { + handled = true; + } + if (msg == WM_EXITSIZEMOVE) + { + OnResizeEnd(); + handled = true; + } + return IntPtr.Zero; + } + + private void OnResizeEnd() + { + int shadowMargin = 0; + if (_settings.UseDropShadowEffect) + { + shadowMargin = 32; + } + + if (!_settings.KeepMaxResults) + { + var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize; + + if (itemCount < 2) + { + _settings.MaxResultsToShow = 2; + } + else + { + _settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount)); + } + } + + _viewModel.MainWindowWidth = Width; + FlowMainWindow.SizeToContent = SizeToContent.Height; + } + private void OnCopy(object sender, ExecutedRoutedEventArgs e) { var result = _viewModel.Results.SelectedItem?.Result; @@ -96,7 +151,7 @@ private void OnPaste(object sender, DataObjectPastingEventArgs e) e.DataObject = data; } } - + private async void OnClosing(object sender, CancelEventArgs e) { _notifyIcon.Visible = false; @@ -557,11 +612,11 @@ private async void OnDeactivated(object sender, EventArgs e) { _settings.WindowLeft = Left; _settings.WindowTop = Top; - //This condition stops extra hide call when animator is on, + //This condition stops extra hide call when animator is on, // which causes the toggling to occasional hide instead of show. if (_viewModel.MainWindowVisibilityStatus) { - // Need time to initialize the main query window animation. + // Need time to initialize the main query window animation. // This also stops the mainwindow from flickering occasionally after Settings window is opened // and always after Settings window is closed. if (_settings.UseAnimation) @@ -632,7 +687,7 @@ public Screen SelectedScreen() } return screen ?? Screen.AllScreens[0]; } - + public double HorizonCenter(Screen screen) { var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml index cbb8285829b..a53e61f8c24 100644 --- a/Flow.Launcher/Resources/CustomControlTemplate.xaml +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -45,7 +45,7 @@ - + + @@ -867,7 +1029,7 @@ Grid.Row="1" Grid.Column="0" Margin="{TemplateBinding Padding}" - Padding="0,0,32,0" + Padding="0 0 32 0" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="{TemplateBinding ui:ControlHelper.PlaceholderForeground}" @@ -887,7 +1049,7 @@ Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" - Margin="0,0,0,0" + Margin="0 0 0 0" Padding="{DynamicResource ComboBoxEditableTextPadding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" @@ -906,7 +1068,7 @@ Grid.Row="1" Grid.Column="1" Width="30" - Margin="0,1,1,1" + Margin="0 1 1 1" HorizontalAlignment="Right" Background="Transparent" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" @@ -917,7 +1079,7 @@ Grid.Row="1" Grid.Column="1" MinHeight="{DynamicResource ComboBoxMinHeight}" - Margin="0,0,10,0" + Margin="0 0 10 0" HorizontalAlignment="Right" VerticalAlignment="Center" Data="{StaticResource ChevronDown}" @@ -944,7 +1106,7 @@ - + @@ -1063,7 +1225,7 @@ - + @@ -1073,7 +1235,7 @@ - + @@ -1083,7 +1245,7 @@ - + @@ -1121,7 +1283,7 @@ x:Key="DataGridComboBoxStyle" BasedOn="{StaticResource DefaultComboBoxStyle}" TargetType="ComboBox"> - + @@ -1133,7 +1295,7 @@ x:Key="DataGridTextBlockComboBoxStyle" BasedOn="{StaticResource DefaultComboBoxStyle}" TargetType="ComboBox"> - + @@ -1362,7 +1524,7 @@ - + @@ -1394,7 +1556,7 @@ BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox"> - + @@ -1549,7 +1711,7 @@ x:Name="SwitchAreaGrid" Grid.RowSpan="3" Grid.ColumnSpan="3" - Margin="0,5" + Margin="0 5" HorizontalAlignment="Right" ui:FocusVisualHelper.IsTemplateFocusTarget="True" Background="{DynamicResource ToggleSwitchContainerBackground}" /> @@ -1902,7 +2064,7 @@ - + @@ -2673,7 +2835,7 @@ x:Name="UpSpinButton" Grid.Row="1" Grid.Column="1" - Margin="4,0,0,0" + Margin="4 0 0 0" ui:ControlHelper.CornerRadius="4" Content="{StaticResource ChevronUp}" FontSize="{TemplateBinding FontSize}" @@ -2807,7 +2969,7 @@ BorderThickness="{TemplateBinding BorderThickness}" /> @@ -2961,7 +3123,7 @@ - + @@ -3219,7 +3381,7 @@ SnapsToDevicePixels="True"> @@ -4099,7 +4261,7 @@ Grid.Column="1" Width="48" Height="16" - Margin="0,0,0,0" + Margin="0 0 0 0" HorizontalAlignment="Center" VerticalAlignment="Center"> - + - + @@ -4391,7 +4553,7 @@ @@ -4414,7 +4576,7 @@ x:Name="IconBox" Width="16" Height="16" - Margin="16,0,0,0" + Margin="16 0 0 0" HorizontalAlignment="Center" VerticalAlignment="Center"> @@ -4841,7 +5003,7 @@ + Margin="0 0 0 8"> - + + diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml index 6e06b99af5a..9064303431f 100644 --- a/Flow.Launcher/Resources/Light.xaml +++ b/Flow.Launcher/Resources/Light.xaml @@ -1030,7 +1030,8 @@ - + + diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index ba4c9e9a451..38202fcf316 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -48,7 +48,6 @@ Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - Cursor="Hand" UseLayoutRounding="False"> @@ -173,8 +172,10 @@ - + diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs index 37f18edb950..99aafc8e66e 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs @@ -133,7 +133,6 @@ public bool ShouldUsePinyin } public List Languages => InternationalizationManager.Instance.LoadAvailableLanguages(); - public IEnumerable MaxResultsRange => Enumerable.Range(2, 16); public string AlwaysPreviewToolTip => string.Format( InternationalizationManager.Instance.GetTranslation("AlwaysPreviewToolTip"), diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs index 87c5b6aa846..667d0b72678 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using System.Windows; +using System.Windows.Controls; using System.Globalization; using System.IO; using System.Linq; -using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using CommunityToolkit.Mvvm.Input; @@ -62,6 +63,34 @@ public bool DropShadowEffect } } + public double WindowHeightSize + { + get => Settings.WindowHeightSize; + set => Settings.WindowHeightSize = value; + } + + public double ItemHeightSize + { + get => Settings.ItemHeightSize; + set => Settings.ItemHeightSize = value; + } + + public double QueryBoxFontSize + { + get => Settings.QueryBoxFontSize; + set => Settings.QueryBoxFontSize = value; + } + public double ResultItemFontSize + { + get => Settings.ResultItemFontSize; + set => Settings.ResultItemFontSize = value; + } + + public double ResultSubItemFontSize + { + get => Settings.ResultSubItemFontSize; + set => Settings.ResultSubItemFontSize = value; + } public List Themes => ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension).ToList(); @@ -134,6 +163,12 @@ public string DateFormat set => Settings.DateFormat = value; } + public IEnumerable MaxResultsRange => Enumerable.Range(2, 16); + public bool KeepMaxResults + { + get => Settings.KeepMaxResults; + set => Settings.KeepMaxResults = value; + } public string ClockText => DateTime.Now.ToString(TimeFormat, CultureInfo.CurrentCulture); public string DateText => DateTime.Now.ToString(DateFormat, CultureInfo.CurrentCulture); @@ -373,6 +408,50 @@ public FamilyTypeface SelectedResultFontFaces } } + public FontFamily SelectedResultSubFont + { + get + { + if (Fonts.SystemFontFamilies.Count(o => + o.FamilyNames.Values != null && + o.FamilyNames.Values.Contains(Settings.ResultSubFont)) > 0) + { + var font = new FontFamily(Settings.ResultSubFont); + return font; + } + else + { + var font = new FontFamily("Segoe UI"); + return font; + } + } + set + { + Settings.ResultSubFont = value.ToString(); + ThemeManager.Instance.ChangeTheme(Settings.Theme); + } + } + + public FamilyTypeface SelectedResultSubFontFaces + { + get + { + var typeface = SyntaxSugars.CallOrRescueDefault( + () => SelectedResultSubFont.ConvertFromInvariantStringsOrNormal( + Settings.ResultSubFontStyle, + Settings.ResultSubFontWeight, + Settings.ResultSubFontStretch + )); + return typeface; + } + set + { + Settings.ResultSubFontStretch = value.Stretch.ToString(); + Settings.ResultSubFontWeight = value.Weight.ToString(); + Settings.ResultSubFontStyle = value.Style.ToString(); + ThemeManager.Instance.ChangeTheme(Settings.Theme); + } + } public string ThemeImage => Constant.QueryTextBoxIconImagePath; [RelayCommand] @@ -396,4 +475,5 @@ public SettingsPaneThemeViewModel(Settings settings) { Settings = settings; } + } diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index 03a3bb7093a..6b301e33a2f 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -4,11 +4,11 @@ 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:ext="clr-namespace:Flow.Launcher.Resources.MarkupExtensions" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:settingsViewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels" xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure" - xmlns:ext="clr-namespace:Flow.Launcher.Resources.MarkupExtensions" Title="General" d:DataContext="{d:DesignInstance settingsViewModels:SettingsPaneGeneralViewModel}" d:DesignHeight="450" @@ -58,58 +58,62 @@ - + + SelectedValue="{Binding Settings.SearchWindowScreen}" + SelectedValuePath="Value" /> + Visibility="{ext:VisibleWhen {Binding Settings.SearchWindowScreen}, + IsEqualTo={x:Static userSettings:SearchWindowScreens.Custom}}" /> + Icon="" + Visibility="{ext:CollapsedWhen {Binding Settings.SearchWindowScreen}, + IsEqualTo={x:Static userSettings:SearchWindowScreens.RememberLastLaunchLocation}}"> + SelectedValue="{Binding Settings.SearchWindowAlign}" + SelectedValuePath="Value" /> - - - + Orientation="Horizontal" + Visibility="{ext:VisibleWhen {Binding Settings.SearchWindowAlign}, + IsEqualTo={x:Static userSettings:SearchWindowAligns.Custom}}"> + + + @@ -158,8 +162,7 @@ - + - - - - + SelectedValue="{Binding Settings.LastQueryMode}" + SelectedValuePath="Value" /> diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml index 0dca6b11ac4..08b49e745bb 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml @@ -24,109 +24,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +