diff --git a/Flow.Launcher.Core/Plugin/JsonRPCConfigurationModel.cs b/Flow.Launcher.Core/Plugin/JsonRPCConfigurationModel.cs index 1f63f85a8..6dc4be881 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCConfigurationModel.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCConfigurationModel.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Flow.Launcher.Core.Plugin { @@ -26,6 +27,8 @@ namespace Flow.Launcher.Core.Plugin public string Name { get; set; } public string Label { get; set; } public string Description { get; set; } + public string urlLabel { get; set; } + public Uri url { get; set; } public bool Validation { get; set; } public List Options { get; set; } public string DefaultValue { get; set; } @@ -40,4 +43,4 @@ namespace Flow.Launcher.Core.Plugin DefaultValue = this.DefaultValue; } } -} \ No newline at end of file +} diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index e3efcd296..4df5037a5 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -22,6 +22,10 @@ using Control = System.Windows.Controls.Control; using Orientation = System.Windows.Controls.Orientation; using TextBox = System.Windows.Controls.TextBox; using UserControl = System.Windows.Controls.UserControl; +using System.Windows.Documents; +using static System.Windows.Forms.LinkLabel; +using Droplex; +using System.Windows.Forms; namespace Flow.Launcher.Core.Plugin { @@ -33,7 +37,6 @@ namespace Flow.Launcher.Core.Plugin { protected PluginInitContext context; public const string JsonRPC = "JsonRPC"; - /// /// The language this JsonRPCPlugin support /// @@ -340,9 +343,14 @@ namespace Flow.Launcher.Core.Plugin this.context = context; await InitSettingAsync(); } - private static readonly Thickness settingControlMargin = new(10, 4, 10, 4); - private static readonly Thickness settingPanelMargin = new(15, 20, 15, 20); - private static readonly Thickness settingTextBlockMargin = new(10, 4, 10, 4); + private static readonly Thickness settingControlMargin = new(0, 9, 18, 9); + private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9); + private static readonly Thickness settingPanelMargin = new(0, 0, 0, 0); + private static readonly Thickness settingTextBlockMargin = new(70, 9, 18, 9); + private static readonly Thickness settingLabelPanelMargin = new(70, 9, 18, 9); + private static readonly Thickness settingLabelMargin = new(0, 0, 0, 0); + private static readonly Thickness settingDescMargin = new(0, 2, 0, 0); + private static readonly Thickness settingSepMargin = new(0, 0, 0, 2); private JsonRpcConfigurationModel _settingsTemplate; public Control CreateSettingPanel() @@ -350,26 +358,60 @@ namespace Flow.Launcher.Core.Plugin if (Settings == null) return new(); var settingWindow = new UserControl(); - var mainPanel = new StackPanel + var mainPanel = new Grid { - Margin = settingPanelMargin, Orientation = Orientation.Vertical + Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center }; - settingWindow.Content = mainPanel; + ColumnDefinition gridCol1 = new ColumnDefinition(); + ColumnDefinition gridCol2 = new ColumnDefinition(); + gridCol1.Width = new GridLength(70, GridUnitType.Star); + gridCol2.Width = new GridLength(30, GridUnitType.Star); + mainPanel.ColumnDefinitions.Add(gridCol1); + mainPanel.ColumnDefinitions.Add(gridCol2); + settingWindow.Content = mainPanel; + int rowCount = 0; foreach (var (type, attribute) in _settingsTemplate.Body) { + Separator sep = new Separator(); + sep.VerticalAlignment = VerticalAlignment.Top; + sep.Margin = settingSepMargin; + sep.SetResourceReference(Separator.BackgroundProperty, "Color03B"); /* for theme change */ var panel = new StackPanel { - Orientation = Orientation.Horizontal, Margin = settingControlMargin + Orientation = Orientation.Vertical, VerticalAlignment = VerticalAlignment.Center, + Margin = settingLabelPanelMargin }; + RowDefinition gridRow = new RowDefinition(); + mainPanel.RowDefinitions.Add(gridRow); var name = new TextBlock() { Text = attribute.Label, - Width = 120, VerticalAlignment = VerticalAlignment.Center, - Margin = settingControlMargin, + Margin = settingLabelMargin, TextWrapping = TextWrapping.WrapWithOverflow }; + var desc = new TextBlock() + { + Text = attribute.Description, FontSize = 12, + VerticalAlignment = VerticalAlignment.Center,Margin = settingDescMargin, + TextWrapping = TextWrapping.WrapWithOverflow + }; + desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); + + if (attribute.Description == null) /* if no description, hide */ + desc.Visibility = Visibility.Collapsed; + + + if (type != "textBlock") /* if textBlock, hide desc */ + { + panel.Children.Add(name); + panel.Children.Add(desc); + } + + + Grid.SetColumn(panel, 0); + Grid.SetRow(panel, rowCount); FrameworkElement contentControl; @@ -381,18 +423,28 @@ namespace Flow.Launcher.Core.Plugin { Text = attribute.Description.Replace("\\r\\n", "\r\n"), Margin = settingTextBlockMargin, - MaxWidth = 500, - TextWrapping = TextWrapping.WrapWithOverflow + Padding = new Thickness(0,0,0,0), + HorizontalAlignment = System.Windows.HorizontalAlignment.Left, + TextAlignment = TextAlignment.Left, + TextWrapping = TextWrapping.Wrap }; - break; + Grid.SetColumn(contentControl, 0); + Grid.SetColumnSpan(contentControl, 2); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; } case "input": { var textBox = new TextBox() { - Width = 300, Text = Settings[attribute.Name] as string ?? string.Empty, Margin = settingControlMargin, + HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, ToolTip = attribute.Description }; textBox.TextChanged += (_, _) => @@ -400,17 +452,60 @@ namespace Flow.Launcher.Core.Plugin Settings[attribute.Name] = textBox.Text; }; contentControl = textBox; - break; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; } + case "inputWithFileBtn": + { + var textBox = new TextBox() + { + Margin = new Thickness(10, 0, 0, 0), + Text = Settings[attribute.Name] as string ?? string.Empty, + HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, + ToolTip = attribute.Description + }; + textBox.TextChanged += (_, _) => + { + Settings[attribute.Name] = textBox.Text; + }; + var Btn = new System.Windows.Controls.Button() + { + Margin = new Thickness(10,0,0,0), + Content = "Browse" + }; + var dockPanel = new DockPanel() + { + Margin = settingControlMargin + }; + DockPanel.SetDock(Btn, Dock.Right); + dockPanel.Children.Add(Btn); + dockPanel.Children.Add(textBox); + contentControl = dockPanel; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; + } case "textarea": { var textBox = new TextBox() { - Width = 300, Height = 120, Margin = settingControlMargin, + VerticalAlignment = VerticalAlignment.Center, TextWrapping = TextWrapping.WrapWithOverflow, AcceptsReturn = true, + HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, Text = Settings[attribute.Name] as string ?? string.Empty, ToolTip = attribute.Description }; @@ -419,16 +514,23 @@ namespace Flow.Launcher.Core.Plugin Settings[attribute.Name] = ((TextBox)sender).Text; }; contentControl = textBox; - break; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; } case "passwordBox": { var passwordBox = new PasswordBox() { - Width = 300, Margin = settingControlMargin, Password = Settings[attribute.Name] as string ?? string.Empty, PasswordChar = attribute.passwordChar == default ? '*' : attribute.passwordChar, + HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, ToolTip = attribute.Description }; passwordBox.PasswordChanged += (sender, _) => @@ -436,29 +538,45 @@ namespace Flow.Launcher.Core.Plugin Settings[attribute.Name] = ((PasswordBox)sender).Password; }; contentControl = passwordBox; - break; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; } case "dropdown": { - var comboBox = new ComboBox() + var comboBox = new System.Windows.Controls.ComboBox() { ItemsSource = attribute.Options, SelectedItem = Settings[attribute.Name], Margin = settingControlMargin, + HorizontalAlignment = System.Windows.HorizontalAlignment.Right, ToolTip = attribute.Description }; comboBox.SelectionChanged += (sender, _) => { - Settings[attribute.Name] = (string)((ComboBox)sender).SelectedItem; + Settings[attribute.Name] = (string)((System.Windows.Controls.ComboBox)sender).SelectedItem; }; contentControl = comboBox; - break; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; } case "checkbox": var checkBox = new CheckBox { IsChecked = Settings[attribute.Name] is bool isChecked ? isChecked : bool.Parse(attribute.DefaultValue), - Margin = settingControlMargin, + Margin = settingCheckboxMargin, + HorizontalAlignment = System.Windows.HorizontalAlignment.Right, ToolTip = attribute.Description }; checkBox.Click += (sender, _) => @@ -466,15 +584,45 @@ namespace Flow.Launcher.Core.Plugin Settings[attribute.Name] = ((CheckBox)sender).IsChecked; }; contentControl = checkBox; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); + break; + case "hyperlink": + var hyperlink = new Hyperlink + { + ToolTip = attribute.Description, + NavigateUri = attribute.url + }; + var linkbtn = new System.Windows.Controls.Button + { + HorizontalAlignment = System.Windows.HorizontalAlignment.Right, + Margin = settingControlMargin + }; + linkbtn.Content = attribute.urlLabel; + + contentControl = linkbtn; + Grid.SetColumn(contentControl, 1); + Grid.SetRow(contentControl, rowCount); + if (rowCount != 0) + mainPanel.Children.Add(sep); + Grid.SetRow(sep, rowCount); + Grid.SetColumn(sep, 0); + Grid.SetColumnSpan(sep, 2); break; default: continue; } if (type != "textBlock") _settingControls[attribute.Name] = contentControl; - panel.Children.Add(name); - panel.Children.Add(contentControl); mainPanel.Children.Add(panel); + mainPanel.Children.Add(contentControl); + rowCount++; + } return settingWindow; } @@ -510,7 +658,7 @@ namespace Flow.Launcher.Core.Plugin case PasswordBox passwordBox: passwordBox.Dispatcher.Invoke(() => passwordBox.Password = value as string); break; - case ComboBox comboBox: + case System.Windows.Controls.ComboBox comboBox: comboBox.Dispatcher.Invoke(() => comboBox.SelectedItem = value); break; case CheckBox checkBox: diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index b0eebd2df..56f421e30 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -29,6 +29,7 @@ namespace Flow.Launcher.Infrastructure public static readonly string DefaultIcon = Path.Combine(ImagesDirectory, "app.png"); public static readonly string ErrorIcon = Path.Combine(ImagesDirectory, "app_error.png"); public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png"); + public static readonly string LoadingImgIcon = Path.Combine(ImagesDirectory, "loading.png"); public static string PythonPath; diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 130221379..deb858a79 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net; @@ -21,8 +22,10 @@ namespace Flow.Launcher.Infrastructure.Image private static readonly ConcurrentDictionary GuidToKey = new(); private static IImageHashGenerator _hashGenerator; private static readonly bool EnableImageHash = true; - public static ImageSource DefaultImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon)); - public const int SmallIconSize = 32; + public static ImageSource MissingImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon)); + public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon)); + public const int SmallIconSize = 64; + public const int FullIconSize = 256; private static readonly string[] ImageExtensions = @@ -99,6 +102,7 @@ namespace Flow.Launcher.Infrastructure.Image Folder, Data, ImageFile, + FullImageFile, Error, Cache } @@ -111,7 +115,7 @@ namespace Flow.Launcher.Infrastructure.Image { if (string.IsNullOrEmpty(path)) { - return new ImageResult(DefaultImage, ImageType.Error); + return new ImageResult(MissingImage, ImageType.Error); } if (ImageCache.ContainsKey(path, loadFullImage)) @@ -201,6 +205,7 @@ namespace Flow.Launcher.Infrastructure.Image if (loadFullImage) { image = LoadFullImage(path); + type = ImageType.FullImageFile; } else { @@ -215,7 +220,7 @@ namespace Flow.Launcher.Infrastructure.Image else { type = ImageType.File; - image = GetThumbnail(path, ThumbnailOptions.None); + image = GetThumbnail(path, ThumbnailOptions.None, loadFullImage ? FullIconSize : SmallIconSize); } } else @@ -232,12 +237,12 @@ namespace Flow.Launcher.Infrastructure.Image return new ImageResult(image, type); } - private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly) + private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly, int size = SmallIconSize) { return WindowsThumbnailProvider.GetThumbnail( path, - Constant.ThumbnailSize, - Constant.ThumbnailSize, + size, + size, option); } @@ -254,6 +259,10 @@ namespace Flow.Launcher.Infrastructure.Image if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache) { // we need to get image hash string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null; + if (imageResult.ImageType == ImageType.FullImageFile) + { + path = $"{path}_{ImageType.FullImageFile}"; + } if (hash != null) { @@ -263,6 +272,7 @@ namespace Flow.Launcher.Infrastructure.Image } else { // new guid + GuidToKey[hash] = path; } } @@ -279,9 +289,33 @@ namespace Flow.Launcher.Infrastructure.Image BitmapImage image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; - image.UriSource = new Uri(path); + image.UriSource = new Uri(path); image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; image.EndInit(); + + if (image.PixelWidth > 320) + { + BitmapImage resizedWidth = new BitmapImage(); + resizedWidth.BeginInit(); + resizedWidth.CacheOption = BitmapCacheOption.OnLoad; + resizedWidth.UriSource = new Uri(path); + resizedWidth.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; + resizedWidth.DecodePixelWidth = 320; + resizedWidth.EndInit(); + + if (resizedWidth.PixelHeight > 320) + { + BitmapImage resizedHeight = new BitmapImage(); + resizedHeight.BeginInit(); + resizedHeight.CacheOption = BitmapCacheOption.OnLoad; + resizedHeight.UriSource = new Uri(path); + resizedHeight.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; + resizedHeight.DecodePixelHeight = 320; + resizedHeight.EndInit(); + return resizedHeight; + } + return resizedWidth; + } return image; } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 3561c6ffe..09fad990b 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -146,6 +146,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings /// when false Alphabet static service will always return empty results /// public bool ShouldUsePinyin { get; set; } = false; + public bool AlwaysPreview { get; set; } = false; [JsonInclude, JsonConverter(typeof(JsonStringEnumConverter))] public SearchPrecisionScore QuerySearchPrecision { get; private set; } = SearchPrecisionScore.Regular; diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index f2d9323ef..912a23a6f 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using System.Windows.Controls; using System.Windows.Media; namespace Flow.Launcher.Plugin @@ -203,6 +204,11 @@ namespace Flow.Launcher.Plugin /// public string SubTitleToolTip { get; set; } + /// + /// Customized Preview Panel + /// + public Lazy PreviewPanel { get; set; } + /// /// Run this result, asynchronously /// @@ -223,5 +229,30 @@ namespace Flow.Launcher.Plugin /// /// #26a0da (blue) public string ProgressBarColor { get; set; } = "#26a0da"; + + public PreviewInfo Preview { get; set; } = PreviewInfo.Default; + + /// + /// Info of the preview image. + /// + public record PreviewInfo + { + /// + /// Full image used for preview panel + /// + public string PreviewImagePath { get; set; } + /// + /// Determines if the preview image should occupy the full width of the preveiw panel. + /// + public bool IsMedia { get; set; } + public string Description { get; set; } + + public static PreviewInfo Default { get; } = new() + { + PreviewImagePath = null, + Description = null, + IsMedia = false, + }; + } } } diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index b1a822fb6..931e97153 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -1,4 +1,4 @@ - + WinExe @@ -92,7 +92,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher/Images/Browser.png b/Flow.Launcher/Images/Browser.png index 5d475f82e..a5bc848c7 100644 Binary files a/Flow.Launcher/Images/Browser.png and b/Flow.Launcher/Images/Browser.png differ diff --git a/Flow.Launcher/Images/app_missing_img.png b/Flow.Launcher/Images/app_missing_img.png index 27e366bbc..0bb16e5d8 100644 Binary files a/Flow.Launcher/Images/app_missing_img.png and b/Flow.Launcher/Images/app_missing_img.png differ diff --git a/Flow.Launcher/Images/loading.png b/Flow.Launcher/Images/loading.png new file mode 100644 index 000000000..1600b5967 Binary files /dev/null and b/Flow.Launcher/Images/loading.png differ diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml index f196412d3..5c6a74fe4 100644 --- a/Flow.Launcher/Languages/da.xaml +++ b/Flow.Launcher/Languages/da.xaml @@ -1,5 +1,8 @@ - - + + Kunne ikke registrere genvejstast: {0} Kunne ikke starte {0} @@ -87,7 +90,7 @@ af Initaliseringstid: Søgetid: - | Version + Version Website Uninstall diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 01be5ebc8..d0bdfee9b 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -65,6 +65,8 @@ Changes minimum match score required for results. Search with Pinyin Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese. + Always Preview + Always open preview panel when Flow starts. Press F1 to toggle preview. Shadow effect is not allowed while current theme has blur effect enabled @@ -89,7 +91,7 @@ by Init time: Query time: - | Version + Version Website Uninstall diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml index c87841693..eae8f7c1f 100644 --- a/Flow.Launcher/Languages/es-419.xaml +++ b/Flow.Launcher/Languages/es-419.xaml @@ -1,5 +1,8 @@ - - + + Error al registrar la tecla de acceso directo: {0} No se pudo iniciar {0} @@ -87,7 +90,7 @@ por Tiempo de inicio: Tiempo de consulta: - | Versión + Versión Sitio web Uninstall diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml index 537152663..a974172b8 100644 --- a/Flow.Launcher/Languages/es.xaml +++ b/Flow.Launcher/Languages/es.xaml @@ -1,5 +1,8 @@ - - + + No se ha podido registrar el atajo de teclado: {0} No se ha podido iniciar {0} @@ -87,7 +90,7 @@ por Tiempo de inicio: Tiempo de consulta: - | Versión + Versión Sitio web Desinstalar diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml index 08ea382ae..efd1a9b13 100644 --- a/Flow.Launcher/Languages/fr.xaml +++ b/Flow.Launcher/Languages/fr.xaml @@ -1,5 +1,8 @@ - - + + Impossible d'enregistrer le raccourci clavier : {0} Impossible de lancer {0} @@ -87,7 +90,7 @@ by Chargement : Utilisation : - | Version + Version Website Désinstaller diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml index 0518c0da3..7a8b174c3 100644 --- a/Flow.Launcher/Languages/it.xaml +++ b/Flow.Launcher/Languages/it.xaml @@ -1,5 +1,8 @@ - - + + Impossibile salvare il tasto di scelta rapida: {0} Avvio fallito {0} @@ -87,7 +90,7 @@ da Tempo di avvio: Tempo ricerca: - | Versione + Versione Sito Web Disinstalla @@ -200,8 +203,8 @@ Una nuova versione {0} è disponibile, riavvia Flow Launcher per favore. Ricerca aggiornamenti fallita, per favore controlla la tua connessione e le eventuali impostazioni proxy per api.github.com. - Download degli aggiornamenti fallito, per favore controlla la tua connessione ed eventuali impostazioni proxy per github-cloud.s3.amazonaws.com, - oppure vai su https://github.com/Flow-Launcher/Flow.Launcher/releases per scaricare gli aggiornamenti manualmente. + Download degli aggiornamenti fallito, per favore controlla la tua connessione ed eventuali impostazioni proxy per github-cloud.s3.amazonaws.com, + oppure vai su https://github.com/Flow-Launcher/Flow.Launcher/releases per scaricare gli aggiornamenti manualmente. Note di rilascio Usage Tips diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml index a05d3681b..fcbf6e8e8 100644 --- a/Flow.Launcher/Languages/ja.xaml +++ b/Flow.Launcher/Languages/ja.xaml @@ -1,5 +1,8 @@ - - + + ホットキー「{0}」の登録に失敗しました {0}の起動に失敗しました @@ -87,7 +90,7 @@ by 初期化時間: クエリ時間: - | バージョン + バージョン ウェブサイト アンインストール @@ -250,7 +253,7 @@ アクションキーボードを指定しない場合、* を使用してください - + Press a custom hotkey to open Flow Laucher and input the specified query automatically. プレビュー ホットキーは使用できません。新しいホットキーを選択してください diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml index 071a1fc44..21bf8f087 100644 --- a/Flow.Launcher/Languages/ko.xaml +++ b/Flow.Launcher/Languages/ko.xaml @@ -1,5 +1,8 @@ - - + + 단축키 등록 실패: {0} {0}을 실행할 수 없습니다. @@ -87,7 +90,7 @@ 제작자 초기화 시간: 쿼리 시간: - | 버전 + 버전 웹사이트 제거 diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml index 0a45549eb..0c23baf7d 100644 --- a/Flow.Launcher/Languages/nb.xaml +++ b/Flow.Launcher/Languages/nb.xaml @@ -1,5 +1,8 @@ - - + + Failed to register hotkey: {0} Could not start {0} @@ -87,7 +90,7 @@ by Init time: Query time: - | Version + Version Website Uninstall diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml index dc24b5fe1..0131873ff 100644 --- a/Flow.Launcher/Languages/pl.xaml +++ b/Flow.Launcher/Languages/pl.xaml @@ -1,5 +1,8 @@ - - + + Nie udało się ustawić skrótu klawiszowego: {0} Nie udało się uruchomić: {0} @@ -87,7 +90,7 @@ by Czas ładowania: Czas zapytania: - | Version + Version Website Odinstalowywanie diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml index 1042b5d99..1dffe8918 100644 --- a/Flow.Launcher/Languages/pt-br.xaml +++ b/Flow.Launcher/Languages/pt-br.xaml @@ -1,5 +1,8 @@ - - + + Falha ao registrar atalho: {0} Não foi possível iniciar {0} @@ -87,7 +90,7 @@ by Tempo de inicialização: Tempo de consulta: - | Version + Version Website Desinstalar diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml index fedf7e57a..0ba6345c9 100644 --- a/Flow.Launcher/Languages/ru.xaml +++ b/Flow.Launcher/Languages/ru.xaml @@ -1,5 +1,8 @@ - - + + Регистрация хоткея {0} не удалась Не удалось запустить {0} @@ -87,7 +90,7 @@ by Инициализация: Запрос: - | Version + Version Website Удалить diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index 1990c5ee2..211036ab3 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -1,5 +1,8 @@ - - + + Nepodarilo sa registrovať klávesovú skratku {0} Nepodarilo sa spustiť {0} @@ -87,7 +90,7 @@ od Inicializácia: Trvanie dopytu: - | Verzia + Verzia Webstránka Odinštalovať @@ -292,7 +295,7 @@ Aktualizuje sa... Flow Launcher nedokázal presunúť používateľské údaje do aktualizovanej verzie. - Prosím, presuňte profilový priečinok data z {0} do {1} + Prosím, presuňte profilový priečinok data z {0} do {1} Nová aktualizácia Je dostupná nová verzia Flow Launchera {0} diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml index 471be8040..6626ac8fd 100644 --- a/Flow.Launcher/Languages/sr.xaml +++ b/Flow.Launcher/Languages/sr.xaml @@ -1,5 +1,8 @@ - - + + Neuspešno registrovana prečica: {0} Neuspešno pokretanje {0} @@ -87,7 +90,7 @@ by Vreme inicijalizacije: Vreme upita: - | Version + Version Website Uninstall @@ -200,7 +203,7 @@ Nove verzija {0} je dostupna, molim Vas ponovo pokrenite Flow Launcher. Neuspešna provera ažuriranja, molim Vas proverite vašu vezu i podešavanja za proksi prema api.github.com. - Neuspešno preuzimanje ažuriranja, molim Vas proverite vašu vezu i podešavanja za proksi prema github-cloud.s3.amazonaws.com, + Neuspešno preuzimanje ažuriranja, molim Vas proverite vašu vezu i podešavanja za proksi prema github-cloud.s3.amazonaws.com, ili posetite https://github.com/Flow-Launcher/Flow.Launcher/releases da preuzmete ažuriranja ručno. U novoj verziji diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml index 366a7ccbc..2750df6f5 100644 --- a/Flow.Launcher/Languages/uk-UA.xaml +++ b/Flow.Launcher/Languages/uk-UA.xaml @@ -1,5 +1,8 @@ - - + + Реєстрація хоткея {0} не вдалася Не вдалося запустити {0} @@ -87,7 +90,7 @@ за Ініціалізація: Запит: - | Версія + Версія Сайт Uninstall diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml index 0cf95ec4e..449be9919 100644 --- a/Flow.Launcher/Languages/zh-cn.xaml +++ b/Flow.Launcher/Languages/zh-cn.xaml @@ -1,5 +1,8 @@ - - + + 注册热键:{0} 失败 启动命令 {0} 失败 @@ -87,7 +90,7 @@ 出自 加载耗时: 查询耗时: - | 版本 + 版本 官方网站 卸载 @@ -200,7 +203,7 @@ 发现新版本 {0}, 请重启 Flow Launcher 下载更新失败,请检查您与 api.github.com 的连接状态或检查代理设置 - 下载更新失败,请检查您与 github-cloud.s3.amazonaws.com 的连接状态或检查代理设置, + 下载更新失败,请检查您与 github-cloud.s3.amazonaws.com 的连接状态或检查代理设置, 或访问 https://github.com/Flow-Launcher/Flow.Launcher/releases 手动下载更新 更新说明 diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml index 7f4a40929..b9ea5605d 100644 --- a/Flow.Launcher/Languages/zh-tw.xaml +++ b/Flow.Launcher/Languages/zh-tw.xaml @@ -1,5 +1,8 @@ - - + + 登錄快捷鍵:{0} 失敗 啟動命令 {0} 失敗 @@ -87,7 +90,7 @@ 作者 載入耗時: 查詢耗時: - | 版本 + 版本 官方網站 解除安裝 diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 49854ed81..baf96e01c 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -13,7 +13,6 @@ Title="Flow Launcher" MinWidth="{Binding MainWindowWidth, Mode=OneWay}" MaxWidth="{Binding MainWindowWidth, Mode=OneWay}" - d:DataContext="{d:DesignInstance vm:MainViewModel}" AllowDrop="True" AllowsTransparency="True" Background="Transparent" @@ -306,6 +305,7 @@ @@ -323,55 +323,151 @@ Y1="0" Y2="0" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index b802cb457..28c631d11 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -59,7 +59,7 @@ namespace Flow.Launcher _settings = settings; InitializeComponent(); - InitializePosition(); + InitializePosition(); animationSound.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav")); } @@ -106,6 +106,7 @@ namespace Flow.Launcher WindowsInteropHelper.DisableControlBox(this); InitProgressbarAnimation(); InitializePosition(); + PreviewReset(); // since the default main window visibility is visible // so we need set focus during startup QueryTextBox.Focus(); @@ -123,6 +124,7 @@ namespace Flow.Launcher animationSound.Play(); } UpdatePosition(); + PreviewReset(); Activate(); QueryTextBox.Focus(); _settings.ActivateTimes++; @@ -618,12 +620,45 @@ namespace Flow.Launcher } } break; + case Key.F1: + PreviewToggle(); + e.Handled = true; + break; + default: break; } } + public void PreviewReset() + { + if (_settings.AlwaysPreview == true) + { + ResultArea.SetValue(Grid.ColumnSpanProperty, 1); + Preview.Visibility = Visibility.Visible; + } + else + { + ResultArea.SetValue(Grid.ColumnSpanProperty, 2); + Preview.Visibility = Visibility.Collapsed; + } + } + public void PreviewToggle() + { + + if (Preview.Visibility == Visibility.Collapsed) + { + ResultArea.SetValue(Grid.ColumnSpanProperty, 1); + Preview.Visibility = Visibility.Visible; + } + else + { + ResultArea.SetValue(Grid.ColumnSpanProperty, 2); + Preview.Visibility = Visibility.Collapsed; + } + } + private void MoveQueryTextToEnd() { // QueryTextBox seems to be update with a DispatcherPriority as low as ContextIdle. diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml index 07897361c..451dc5344 100644 --- a/Flow.Launcher/Resources/CustomControlTemplate.xaml +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -3230,4 +3230,26 @@ + + + diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index d44830f52..b2b96aa00 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -58,6 +58,7 @@ diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index f7955dd22..5c3c12710 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -731,6 +731,22 @@ + + + + + + + + +  + + + + @@ -994,7 +1010,6 @@ TextAlignment="Left" /> - - - - - - - - - + FontSize="11" + Foreground="{DynamicResource PluginInfoColor}" + Text="|" /> + + + - + RequestNavigate="OnRequestNavigate" + Style="{DynamicResource HyperLinkBtnStyle}" + TextDecorations="None"> + - - + Style="{DynamicResource LinkBtnStyle}" + Text="" + ToolTip="{DynamicResource plugin_uninstall}" /> + Margin="10,0,5,0" + Style="{DynamicResource LinkBtnStyle}" + Text="" + ToolTip="{DynamicResource pluginDirectory}"> - + - - - - diff --git a/Flow.Launcher/Themes/Base.xaml b/Flow.Launcher/Themes/Base.xaml index 94740a730..c48da0bca 100644 --- a/Flow.Launcher/Themes/Base.xaml +++ b/Flow.Launcher/Themes/Base.xaml @@ -356,7 +356,23 @@ - @@ -384,7 +400,63 @@ + + + + + + + + + + + + diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml index 88c48afee..67a47f4cf 100644 --- a/Flow.Launcher/Themes/BlurBlack Darker.xaml +++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml @@ -37,7 +37,6 @@ x:Key="WindowBorderStyle" BasedOn="{StaticResource BaseWindowBorderStyle}" TargetType="{x:Type Border}"> - @@ -48,6 +47,15 @@ + + + + + + diff --git a/Flow.Launcher/Themes/BlurBlack.xaml b/Flow.Launcher/Themes/BlurBlack.xaml index f74578a74..0f1264292 100644 --- a/Flow.Launcher/Themes/BlurBlack.xaml +++ b/Flow.Launcher/Themes/BlurBlack.xaml @@ -45,6 +45,15 @@ + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/BlurWhite.xaml b/Flow.Launcher/Themes/BlurWhite.xaml index 2d42d49bc..4406724b8 100644 --- a/Flow.Launcher/Themes/BlurWhite.xaml +++ b/Flow.Launcher/Themes/BlurWhite.xaml @@ -155,4 +155,28 @@ + + + + diff --git a/Flow.Launcher/Themes/Bullet Light.xaml b/Flow.Launcher/Themes/Bullet Light.xaml index 0dc3b33d2..1f776a2ee 100644 --- a/Flow.Launcher/Themes/Bullet Light.xaml +++ b/Flow.Launcher/Themes/Bullet Light.xaml @@ -87,7 +87,7 @@ x:Key="SeparatorStyle" BasedOn="{StaticResource BaseSeparatorStyle}" TargetType="{x:Type Rectangle}"> - + @@ -156,6 +156,7 @@ + @@ -181,4 +182,28 @@ TargetType="{x:Type TextBlock}"> + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Circle Light.xaml b/Flow.Launcher/Themes/Circle Light.xaml index 7e14a29a6..e52e3a957 100644 --- a/Flow.Launcher/Themes/Circle Light.xaml +++ b/Flow.Launcher/Themes/Circle Light.xaml @@ -69,7 +69,7 @@ x:Key="SeparatorStyle" BasedOn="{StaticResource BaseSeparatorStyle}" TargetType="{x:Type Rectangle}"> - + @@ -163,4 +163,28 @@ TargetType="{x:Type TextBlock}"> - \ No newline at end of file + + + + + diff --git a/Flow.Launcher/Themes/Circle System.xaml b/Flow.Launcher/Themes/Circle System.xaml index b00f03e76..2b2ce7ca3 100644 --- a/Flow.Launcher/Themes/Circle System.xaml +++ b/Flow.Launcher/Themes/Circle System.xaml @@ -70,7 +70,7 @@ x:Key="SeparatorStyle" BasedOn="{StaticResource BaseSeparatorStyle}" TargetType="{x:Type Rectangle}"> - + @@ -164,4 +164,28 @@ TargetType="{x:Type TextBlock}"> + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Cyan Dark.xaml b/Flow.Launcher/Themes/Cyan Dark.xaml index c79044f00..60bc09002 100644 --- a/Flow.Launcher/Themes/Cyan Dark.xaml +++ b/Flow.Launcher/Themes/Cyan Dark.xaml @@ -164,7 +164,7 @@ 0 0 - 0 0 0 0 + 0 0 0 4 + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Darker Glass.xaml b/Flow.Launcher/Themes/Darker Glass.xaml index a33f98b09..89b6dfa01 100644 --- a/Flow.Launcher/Themes/Darker Glass.xaml +++ b/Flow.Launcher/Themes/Darker Glass.xaml @@ -5,7 +5,7 @@ - + 0 0 0 8 + + + + + diff --git a/Flow.Launcher/Themes/Darker.xaml b/Flow.Launcher/Themes/Darker.xaml new file mode 100644 index 000000000..d1abbe978 --- /dev/null +++ b/Flow.Launcher/Themes/Darker.xaml @@ -0,0 +1,100 @@ + + + + + 0 0 0 8 + + + + + + + + #4d4d4d + + + + + + diff --git a/Flow.Launcher/Themes/Discord Dark.xaml b/Flow.Launcher/Themes/Discord Dark.xaml index 74c1719c4..5315c7644 100644 --- a/Flow.Launcher/Themes/Discord Dark.xaml +++ b/Flow.Launcher/Themes/Discord Dark.xaml @@ -5,6 +5,7 @@ + 0 0 0 6 + + + + diff --git a/Flow.Launcher/Themes/Dracula.xaml b/Flow.Launcher/Themes/Dracula.xaml index c01b67c74..ce3350728 100644 --- a/Flow.Launcher/Themes/Dracula.xaml +++ b/Flow.Launcher/Themes/Dracula.xaml @@ -5,6 +5,7 @@ + 0 0 0 6 + + + + diff --git a/Flow.Launcher/Themes/Gray.xaml b/Flow.Launcher/Themes/Gray.xaml index eb8b48f43..d8d344e21 100644 --- a/Flow.Launcher/Themes/Gray.xaml +++ b/Flow.Launcher/Themes/Gray.xaml @@ -70,7 +70,7 @@ TargetType="{x:Type Rectangle}"> - + - \ No newline at end of file + + + + + + diff --git a/Flow.Launcher/Themes/League.xaml b/Flow.Launcher/Themes/League.xaml index 9f4a9a628..7fbe56187 100644 --- a/Flow.Launcher/Themes/League.xaml +++ b/Flow.Launcher/Themes/League.xaml @@ -137,4 +137,29 @@ TargetType="{x:Type TextBlock}"> + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Midnight.xaml b/Flow.Launcher/Themes/Midnight.xaml index b52fe87e1..91ff620d5 100644 --- a/Flow.Launcher/Themes/Midnight.xaml +++ b/Flow.Launcher/Themes/Midnight.xaml @@ -163,4 +163,29 @@ TargetType="{x:Type TextBlock}"> - \ No newline at end of file + + + + + diff --git a/Flow.Launcher/Themes/Nord Darker.xaml b/Flow.Launcher/Themes/Nord Darker.xaml index 840e44b3c..d9ddb3076 100644 --- a/Flow.Launcher/Themes/Nord Darker.xaml +++ b/Flow.Launcher/Themes/Nord Darker.xaml @@ -3,6 +3,7 @@ + 0 0 0 8 + + + + + diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml index 96dae2545..dc97e4320 100644 --- a/Flow.Launcher/Themes/Pink.xaml +++ b/Flow.Launcher/Themes/Pink.xaml @@ -2,6 +2,7 @@ + 0 0 0 4 + + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Sublime.xaml b/Flow.Launcher/Themes/Sublime.xaml index 417bd723e..6df69ad3e 100644 --- a/Flow.Launcher/Themes/Sublime.xaml +++ b/Flow.Launcher/Themes/Sublime.xaml @@ -5,6 +5,7 @@ + 0 0 0 8 + + + + diff --git a/Flow.Launcher/Themes/Ubuntu.xaml b/Flow.Launcher/Themes/Ubuntu.xaml index ea10c0e82..33f232699 100644 --- a/Flow.Launcher/Themes/Ubuntu.xaml +++ b/Flow.Launcher/Themes/Ubuntu.xaml @@ -169,7 +169,7 @@ 0 0 0 0 0 - 0 0 0 0 + 0 0 0 8 + + + + \ No newline at end of file diff --git a/Flow.Launcher/Themes/Win10Light.xaml b/Flow.Launcher/Themes/Win10Light.xaml index 12ba01f71..5f837bdb3 100644 --- a/Flow.Launcher/Themes/Win10Light.xaml +++ b/Flow.Launcher/Themes/Win10Light.xaml @@ -5,6 +5,7 @@ + 0 0 0 4 + + + + diff --git a/Flow.Launcher/Themes/Win11Dark.xaml b/Flow.Launcher/Themes/Win11Dark.xaml index 4660eae8f..5abb96cce 100644 --- a/Flow.Launcher/Themes/Win11Dark.xaml +++ b/Flow.Launcher/Themes/Win11Dark.xaml @@ -5,6 +5,7 @@ + 0 0 0 8 + + + + diff --git a/Flow.Launcher/Themes/Win11Light.xaml b/Flow.Launcher/Themes/Win11Light.xaml index 4c0769d4d..e2c37236c 100644 --- a/Flow.Launcher/Themes/Win11Light.xaml +++ b/Flow.Launcher/Themes/Win11Light.xaml @@ -5,6 +5,7 @@ + 0 0 0 8 + + + + diff --git a/Flow.Launcher/Themes/Win11System.xaml b/Flow.Launcher/Themes/Win11System.xaml index 42f0579a7..df09249be 100644 --- a/Flow.Launcher/Themes/Win11System.xaml +++ b/Flow.Launcher/Themes/Win11System.xaml @@ -6,6 +6,7 @@ + 0 0 0 8 + + + + diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 4db8e3df3..d1f8132da 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -803,7 +803,7 @@ namespace Flow.Launcher.ViewModel Action = _ => { _topMostRecord.AddOrUpdate(result); - App.API.ShowMsg("Success"); + App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success")); return false; } }; diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 9871ceb93..65ba657ba 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using System.Windows; using System.Windows.Media; using Flow.Launcher.Plugin; @@ -6,6 +6,7 @@ using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Core.Plugin; using System.Windows.Controls; using CommunityToolkit.Mvvm.Input; +using Flow.Launcher.Core.Resource; namespace Flow.Launcher.ViewModel { @@ -36,7 +37,7 @@ namespace Flow.Launcher.ViewModel { get { - if (_image == ImageLoader.DefaultImage) + if (_image == ImageLoader.MissingImage) LoadIconAsync(); return _image; @@ -69,11 +70,13 @@ namespace Flow.Launcher.ViewModel ? new Control() : settingProvider.CreateSettingPanel() : null; - private ImageSource _image = ImageLoader.DefaultImage; + private ImageSource _image = ImageLoader.MissingImage; public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed; public string InitilizaTime => PluginPair.Metadata.InitTime + "ms"; public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms"; + public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version; + public string InitAndQueryTime => InternationalizationManager.Instance.GetTranslation("plugin_init_time") + " " + PluginPair.Metadata.InitTime + "ms, " + InternationalizationManager.Instance.GetTranslation("plugin_query_time") + " " + PluginPair.Metadata.AvgQueryTime + "ms"; public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords); public int Priority => PluginPair.Metadata.Priority; diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 2d61f6cab..0fadeccdf 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -19,47 +19,49 @@ namespace Flow.Launcher.ViewModel public ResultViewModel(Result result, Settings settings) { - if (result != null) + Settings = settings; + + if (result == null) { - Result = result; + return; + } + Result = result; - if (Result.Glyph is { FontFamily: not null } glyph) + if (Result.Glyph is { FontFamily: not null } glyph) + { + // Checks if it's a system installed font, which does not require path to be provided. + if (glyph.FontFamily.EndsWith(".ttf") || glyph.FontFamily.EndsWith(".otf")) { - // Checks if it's a system installed font, which does not require path to be provided. - if (glyph.FontFamily.EndsWith(".ttf") || glyph.FontFamily.EndsWith(".otf")) + string fontFamilyPath = glyph.FontFamily; + + if (!Path.IsPathRooted(fontFamilyPath)) { - string fontFamilyPath = glyph.FontFamily; + fontFamilyPath = Path.Combine(Result.PluginDirectory, fontFamilyPath); + } - if (!Path.IsPathRooted(fontFamilyPath)) + if (fonts.ContainsKey(fontFamilyPath)) + { + Glyph = glyph with { - fontFamilyPath = Path.Combine(Result.PluginDirectory, fontFamilyPath); - } - - if (fonts.ContainsKey(fontFamilyPath)) - { - Glyph = glyph with - { - FontFamily = fonts[fontFamilyPath] - }; - } - else - { - fontCollection.AddFontFile(fontFamilyPath); - fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{fontCollection.Families[^1].Name}"; - Glyph = glyph with - { - FontFamily = fonts[fontFamilyPath] - }; - } + FontFamily = fonts[fontFamilyPath] + }; } else { - Glyph = glyph; + fontCollection.AddFontFile(fontFamilyPath); + fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{fontCollection.Families[^1].Name}"; + Glyph = glyph with + { + FontFamily = fonts[fontFamilyPath] + }; } } + else + { + Glyph = glyph; + } } - Settings = settings; } private Settings Settings { get; } @@ -67,6 +69,10 @@ namespace Flow.Launcher.ViewModel public Visibility ShowOpenResultHotkey => Settings.ShowOpenResultHotkey ? Visibility.Visible : Visibility.Collapsed; + public Visibility ShowDefaultPreview => Result.PreviewPanel == null ? Visibility.Visible : Visibility.Collapsed; + + public Visibility ShowCustomizedPreview => Result.PreviewPanel == null ? Visibility.Collapsed : Visibility.Visible; + public Visibility ShowIcon { get @@ -106,7 +112,7 @@ namespace Flow.Launcher.ViewModel if (!Settings.UseGlyphIcons && !ImgIconAvailable && GlyphAvailable) return Visibility.Visible; - return Settings.UseGlyphIcons && GlyphAvailable ? Visibility.Visible : Visibility.Hidden; + return Settings.UseGlyphIcons && GlyphAvailable ? Visibility.Visible : Visibility.Collapsed; } } @@ -125,8 +131,10 @@ namespace Flow.Launcher.ViewModel : Result.SubTitleToolTip; private volatile bool ImageLoaded; + private volatile bool PreviewImageLoaded; - private ImageSource image = ImageLoader.DefaultImage; + private ImageSource image = ImageLoader.LoadingImage; + private ImageSource previewImage = ImageLoader.LoadingImage; public ImageSource Image { @@ -143,37 +151,76 @@ namespace Flow.Launcher.ViewModel private set => image = value; } + public ImageSource PreviewImage + { + get + { + if (!PreviewImageLoaded) + { + PreviewImageLoaded = true; + _ = LoadPreviewImageAsync(); + } + + return previewImage; + } + private set => previewImage = value; + } + + /// + /// Determines if to use the full width of the preview panel + /// + public bool UseBigThumbnail => Result.Preview.IsMedia; + public GlyphInfo Glyph { get; set; } - private async Task LoadImageAsync() + private async Task LoadImageInternalAsync(string imagePath, Result.IconDelegate icon, bool loadFullImage) { - var imagePath = Result.IcoPath; - if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) + if (string.IsNullOrEmpty(imagePath) && icon != null) { try { - image = Result.Icon(); - return; + var image = await Task.Run(() => icon()).ConfigureAwait(false); + return image; } catch (Exception e) { Log.Exception( - $"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", + $"|ResultViewModel.LoadImageInternalAsync|IcoPath is empty and exception when calling IconDelegate for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e); } } - var loadFullImage = (Path.GetExtension(imagePath) ?? "").Equals(".url", StringComparison.OrdinalIgnoreCase); + return await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false); + } - if (ImageLoader.CacheContainImage(imagePath)) + private async Task LoadImageAsync() + { + var imagePath = Result.IcoPath; + var iconDelegate = Result.Icon; + if (ImageLoader.CacheContainImage(imagePath, false)) { - // will get here either when icoPath has value\icon delegate is null\when had exception in delegate - image = await ImageLoader.LoadAsync(imagePath, loadFullImage); - return; + image = await LoadImageInternalAsync(imagePath, iconDelegate, false).ConfigureAwait(false); } + else + { + // We need to modify the property not field here to trigger the OnPropertyChanged event + Image = await LoadImageInternalAsync(imagePath, iconDelegate, false).ConfigureAwait(false); + } + } - // We need to modify the property not field here to trigger the OnPropertyChanged event - Image = await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false); + private async Task LoadPreviewImageAsync() + { + var imagePath = string.IsNullOrEmpty(Result.Preview.PreviewImagePath) ? Result.IcoPath : Result.Preview.PreviewImagePath; + var iconDelegate = Result.Icon; + if (ImageLoader.CacheContainImage(imagePath, true)) + { + previewImage = await LoadImageInternalAsync(imagePath, iconDelegate, true).ConfigureAwait(false); + } + else + { + // We need to modify the property not field here to trigger the OnPropertyChanged event + PreviewImage = await LoadImageInternalAsync(imagePath, iconDelegate, true).ConfigureAwait(false); + } } public Result Result { get; } diff --git a/Flow.Launcher/WelcomeWindow.xaml b/Flow.Launcher/WelcomeWindow.xaml index d797a623b..c7820d436 100644 --- a/Flow.Launcher/WelcomeWindow.xaml +++ b/Flow.Launcher/WelcomeWindow.xaml @@ -7,13 +7,13 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ui="http://schemas.modernwpf.com/2019" Name="FlowWelcomeWindow" - Title="Welcome to Flow Launcher" - Activated="OnActivated" + Title="{DynamicResource Welcome_Page1_Title}" Width="550" Height="650" - MouseDown="window_MouseDown" + Activated="OnActivated" Background="{DynamicResource Color00B}" Foreground="{DynamicResource PopupTextColor}" + MouseDown="window_MouseDown" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> @@ -48,7 +48,7 @@ VerticalAlignment="Center" FontSize="12" Foreground="{DynamicResource Color05B}" - Text="Welcome to Flow Launcher" /> + Text="{DynamicResource Welcome_Page1_Title}" />