mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Expand GeneralSettingsPage with ~25 settings using FluentAvalonia SettingsExpander
- Add Card, ExCard, CardGroup custom controls for settings pages - Update GeneralSettingsViewModel with new properties: - Startup: UseLogonTaskForStartup, HideOnStartup - Behavior: HideNotifyIcon, IgnoreHotkeysOnFullscreen, AlwaysPreview - Updates: AutoUpdates, AutoUpdatePlugins - Search: SearchPrecision, LastQueryMode, SearchDelay - Home: ShowHomePage, ShowHistoryResults, MaxHistoryResults - Misc: AutoRestart, ShowWarning, AlwaysStartEn, ShouldUsePinyin - Rewrite GeneralSettingsPage.axaml using SettingsExpander pattern - Update migration checklist to ~35-40% progress
This commit is contained in:
parent
8a99881799
commit
1d945654c1
9 changed files with 1087 additions and 90 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Flow.Launcher Avalonia Migration Checklist
|
||||
|
||||
> **Overall Progress: ~30-35%**
|
||||
> **Overall Progress: ~35-40%**
|
||||
> Last Updated: January 2026
|
||||
|
||||
---
|
||||
|
|
@ -48,44 +48,53 @@
|
|||
## 2. Settings Pages
|
||||
|
||||
### 2.1 General Settings (`SettingsPaneGeneral.xaml` - 538 lines)
|
||||
**Avalonia: 71 lines (~13%)**
|
||||
**Avalonia: ~270 lines (~50%)**
|
||||
|
||||
| Setting | Status | Binding Property |
|
||||
|---------|--------|------------------|
|
||||
| **Startup Section** |
|
||||
| Start on system startup | :x: Missing | `StartFlowLauncherOnSystemStartup` |
|
||||
| Use logon task | :x: Missing | `UseLogonTaskForStartup` |
|
||||
| Hide on startup | :x: Missing | `Settings.HideOnStartup` |
|
||||
| Start on system startup | :white_check_mark: Done | `StartOnStartup` |
|
||||
| Use logon task | :white_check_mark: Done | `UseLogonTaskForStartup` |
|
||||
| Hide on startup | :white_check_mark: Done | `HideOnStartup` |
|
||||
| **Behavior Section** |
|
||||
| Hide when lose focus | :x: Missing | `Settings.HideWhenDeactivated` |
|
||||
| Hide notify icon | :x: Missing | `Settings.HideNotifyIcon` |
|
||||
| Show at topmost | :x: Missing | `Settings.ShowAtTopmost` |
|
||||
| Hide when lose focus | :white_check_mark: Done | `HideWhenDeactivated` |
|
||||
| Hide notify icon | :white_check_mark: Done | `HideNotifyIcon` |
|
||||
| Show at topmost | :white_check_mark: Done | `ShowAtTopmost` |
|
||||
| Ignore hotkeys on fullscreen | :white_check_mark: Done | `IgnoreHotkeysOnFullscreen` |
|
||||
| Always preview | :white_check_mark: Done | `AlwaysPreview` |
|
||||
| **Position Section** |
|
||||
| Search window position | :x: Missing | `Settings.SearchWindowScreen` |
|
||||
| Search window position | :white_check_mark: Done | `SelectedSearchWindowScreen` |
|
||||
| Search window align | :white_check_mark: Done | `SelectedSearchWindowAlign` |
|
||||
| Custom position X/Y | :x: Missing | `Settings.CustomWindowLeft/Top` |
|
||||
| Remember last position | :x: Missing | `Settings.RememberLastLaunchLocation` |
|
||||
| **Search Section** |
|
||||
| Max results shown | :x: Missing | `Settings.MaxResultsToShow` |
|
||||
| Clear input on close | :x: Missing | `Settings.ClearInputOnLaunch` |
|
||||
| Auto-complete text | :white_check_mark: Done | `Settings.AutoCompleteText` |
|
||||
| Keep search text | :x: Missing | `Settings.KeepMaxResults` |
|
||||
| Query search precision | :x: Missing | `Settings.QuerySearchPrecision` |
|
||||
| **Input Section** |
|
||||
| Always start English mode | :x: Missing | `Settings.AlwaysStartEn` |
|
||||
| First search delay | :x: Missing | `Settings.FirstSearchDelay` |
|
||||
| Input delay | :x: Missing | `Settings.InputDelay` |
|
||||
| **Language Section** |
|
||||
| Language selector | :white_check_mark: Done | `Settings.Language` |
|
||||
| Query search precision | :white_check_mark: Done | `SelectedSearchPrecision` |
|
||||
| Last query mode | :white_check_mark: Done | `SelectedLastQueryMode` |
|
||||
| Search delay toggle | :white_check_mark: Done | `SearchQueryResultsWithDelay` |
|
||||
| Search delay time | :white_check_mark: Done | `SearchDelayTime` |
|
||||
| **Home Page Section** |
|
||||
| Show home page | :white_check_mark: Done | `ShowHomePage` |
|
||||
| History results for home | :white_check_mark: Done | `ShowHistoryResultsForHomePage` |
|
||||
| History results count | :white_check_mark: Done | `MaxHistoryResultsToShow` |
|
||||
| **Updates Section** |
|
||||
| Auto-update interval | :x: Missing | `Settings.UpdateCheckInterval` |
|
||||
| Check for updates | :x: Missing | `UpdateApp` command |
|
||||
| **Advanced Section** |
|
||||
| Python directory | :x: Missing | `Settings.PluginSettings.PythonExecutablePath` |
|
||||
| Node directory | :x: Missing | `Settings.PluginSettings.NodeExecutablePath` |
|
||||
| Plugin directory | :x: Missing | `Settings.PluginSettings.PluginDirectory` |
|
||||
| Auto updates | :white_check_mark: Done | `AutoUpdates` |
|
||||
| Auto update plugins | :white_check_mark: Done | `AutoUpdatePlugins` |
|
||||
| **Miscellaneous** |
|
||||
| Auto restart after changing | :white_check_mark: Done | `AutoRestartAfterChanging` |
|
||||
| Show unknown source warning | :white_check_mark: Done | `ShowUnknownSourceWarning` |
|
||||
| Always start English | :white_check_mark: Done | `AlwaysStartEn` |
|
||||
| Use Pinyin | :white_check_mark: Done | `ShouldUsePinyin` |
|
||||
| **Language Section** |
|
||||
| Language selector | :white_check_mark: Done | `SelectedLanguage` |
|
||||
| **Paths** |
|
||||
| Python directory | :white_check_mark: Done | `PythonPath` (display + select) |
|
||||
| Node directory | :white_check_mark: Done | `NodePath` (display + select) |
|
||||
| **Not Yet Implemented** |
|
||||
| Select browser | :x: Missing | Opens `SelectBrowserWindow` |
|
||||
| Select file manager | :x: Missing | Opens `SelectFileManagerWindow` |
|
||||
| Portable mode | :x: Missing | `Settings.ShouldUsePinyin` |
|
||||
| Portable mode | :x: Missing | Toggle |
|
||||
| Dialog jump settings | :x: Missing | ExCard with nested options |
|
||||
| Double pinyin settings | :x: Missing | ExCard with schema selector |
|
||||
| Korean IME settings | :x: Missing | ExCard with registry toggle |
|
||||
|
||||
### 2.2 Theme Settings (`SettingsPaneTheme.xaml` - 803 lines)
|
||||
**Avalonia: 66 lines (~8%)**
|
||||
|
|
@ -192,7 +201,7 @@
|
|||
| Open logs folder | :x: Missing | Button |
|
||||
| Open settings folder | :x: Missing | Button |
|
||||
|
||||
**Settings Progress: 312/2609 lines (~12%)**
|
||||
**Settings Progress: ~550/2609 lines (~21%)**
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -200,9 +209,9 @@
|
|||
|
||||
| Control | WPF File | Status | Description |
|
||||
|---------|----------|--------|-------------|
|
||||
| Card | `Card.xaml.cs` | :x: Missing | Settings card with icon, title, subtitle |
|
||||
| ExCard | `ExCard.xaml.cs` | :x: Missing | Expandable card with nested content |
|
||||
| CardGroup | `CardGroup.xaml.cs` | :x: Missing | Groups cards with rounded corners |
|
||||
| Card | `Card.xaml.cs` | :white_check_mark: Done | Settings card with icon, title, subtitle |
|
||||
| ExCard | `ExCard.xaml.cs` | :white_check_mark: Done | Expandable card with nested content |
|
||||
| CardGroup | `CardGroup.xaml.cs` | :white_check_mark: Done | Groups cards with rounded corners |
|
||||
| InfoBar | `InfoBar.xaml.cs` | :x: Missing | Information/warning banner |
|
||||
| HyperLink | `HyperLink.xaml.cs` | :x: Missing | Clickable link control |
|
||||
| HotkeyDisplay | `HotkeyDisplay.xaml.cs` | :x: Missing | Displays hotkey as key badges |
|
||||
|
|
@ -210,7 +219,9 @@
|
|||
| InstalledPluginDisplayKeyword | `InstalledPluginDisplayKeyword.xaml.cs` | :x: Missing | Keyword badge |
|
||||
| InstalledPluginDisplayBottomData | `InstalledPluginDisplayBottomData.xaml.cs` | :x: Missing | Plugin metadata footer |
|
||||
|
||||
**Progress: 0/9 (0%)**
|
||||
**Progress: 3/9 (33%)**
|
||||
|
||||
> Note: Using FluentAvalonia's `SettingsExpander` for most settings pages instead of custom Card controls.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -222,6 +233,7 @@
|
|||
| ResultsViewModel | ~200 | ~150 | :white_check_mark: 75% | Core functionality done |
|
||||
| ResultViewModel | ~300 | ~200 | :white_check_mark: 67% | Basic display done |
|
||||
| SettingWindowViewModel | ~100 | ~50 | :yellow_circle: 50% | Navigation works |
|
||||
| GeneralSettingsViewModel | ~100 | ~400 | :white_check_mark: 95% | Most settings implemented |
|
||||
| PluginViewModel | ~150 | ~30 | :yellow_circle: 20% | Basic list only |
|
||||
| PluginStoreItemViewModel | ~100 | 0 | :x: 0% | Not started |
|
||||
| WelcomeViewModel | ~80 | 0 | :x: 0% | Not started |
|
||||
|
|
@ -375,8 +387,8 @@
|
|||
### High Priority (Core UX)
|
||||
1. [ ] **HighlightTextConverter** - Search match highlighting
|
||||
2. [ ] **History cycling** - Up/Down arrow through history
|
||||
3. [ ] **GeneralSettingsPage** - Essential settings (startup, behavior)
|
||||
4. [ ] **Card/ExCard controls** - Required for all settings pages
|
||||
3. [x] **GeneralSettingsPage** - Essential settings (startup, behavior) - DONE
|
||||
4. [x] **Card/ExCard controls** - Required for all settings pages - DONE (using FluentAvalonia SettingsExpander)
|
||||
5. [ ] **Hide on focus loss** - Expected behavior
|
||||
|
||||
### Medium Priority (Feature Completeness)
|
||||
|
|
@ -429,10 +441,13 @@ Flow.Launcher.Avalonia/
|
|||
│ ├── PreviewPanel.axaml
|
||||
│ ├── Controls/
|
||||
│ │ ├── HotkeyControl.axaml
|
||||
│ │ └── HotkeyRecorderDialog.axaml
|
||||
│ │ ├── HotkeyRecorderDialog.axaml
|
||||
│ │ ├── Card.axaml (+ .cs)
|
||||
│ │ ├── ExCard.axaml (+ .cs)
|
||||
│ │ └── CardGroup.axaml (+ .cs)
|
||||
│ └── SettingPages/
|
||||
│ ├── SettingsWindow.axaml
|
||||
│ ├── GeneralSettingsPage.axaml (71 lines)
|
||||
│ ├── GeneralSettingsPage.axaml (~270 lines)
|
||||
│ ├── ThemeSettingsPage.axaml (66 lines)
|
||||
│ ├── HotkeySettingsPage.axaml (26 lines)
|
||||
│ ├── PluginsSettingsPage.axaml (47 lines)
|
||||
|
|
@ -440,7 +455,9 @@ Flow.Launcher.Avalonia/
|
|||
│ └── AboutSettingsPage.axaml (25 lines)
|
||||
├── ViewModel/
|
||||
│ ├── MainViewModel.cs (~420 lines)
|
||||
│ └── SettingPages/*.cs
|
||||
│ ├── SettingPages/
|
||||
│ │ └── GeneralSettingsViewModel.cs (~400 lines)
|
||||
│ └── ...
|
||||
├── Helper/ (4 files)
|
||||
├── Converters/ (3 files)
|
||||
└── Themes/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ using CommunityToolkit.Mvvm.Input;
|
|||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using Flow.Launcher.Plugin.SharedModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AvaloniaI18n = Flow.Launcher.Avalonia.Resource.Internationalization;
|
||||
|
|
@ -22,8 +24,16 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
_i18n = Ioc.Default.GetRequiredService<AvaloniaI18n>();
|
||||
|
||||
LoadLanguages();
|
||||
LoadSearchWindowOptions();
|
||||
LoadSearchPrecisionOptions();
|
||||
LoadLastQueryModeOptions();
|
||||
}
|
||||
|
||||
// Direct access to settings for bindings
|
||||
public Flow.Launcher.Infrastructure.UserSettings.Settings Settings => _settings;
|
||||
|
||||
#region Languages
|
||||
|
||||
[ObservableProperty]
|
||||
private List<Language> _languages = new();
|
||||
|
||||
|
|
@ -41,6 +51,10 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Startup Settings
|
||||
|
||||
public bool StartOnStartup
|
||||
{
|
||||
get => _settings.StartFlowLauncherOnSystemStartup;
|
||||
|
|
@ -51,6 +65,30 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
}
|
||||
}
|
||||
|
||||
public bool UseLogonTaskForStartup
|
||||
{
|
||||
get => _settings.UseLogonTaskForStartup;
|
||||
set
|
||||
{
|
||||
_settings.UseLogonTaskForStartup = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideOnStartup
|
||||
{
|
||||
get => _settings.HideOnStartup;
|
||||
set
|
||||
{
|
||||
_settings.HideOnStartup = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Behavior Settings
|
||||
|
||||
public bool HideWhenDeactivated
|
||||
{
|
||||
get => _settings.HideWhenDeactivated;
|
||||
|
|
@ -61,6 +99,16 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
}
|
||||
}
|
||||
|
||||
public bool HideNotifyIcon
|
||||
{
|
||||
get => _settings.HideNotifyIcon;
|
||||
set
|
||||
{
|
||||
_settings.HideNotifyIcon = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAtTopmost
|
||||
{
|
||||
get => _settings.ShowAtTopmost;
|
||||
|
|
@ -71,6 +119,212 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
}
|
||||
}
|
||||
|
||||
public bool IgnoreHotkeysOnFullscreen
|
||||
{
|
||||
get => _settings.IgnoreHotkeysOnFullscreen;
|
||||
set
|
||||
{
|
||||
_settings.IgnoreHotkeysOnFullscreen = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AlwaysPreview
|
||||
{
|
||||
get => _settings.AlwaysPreview;
|
||||
set
|
||||
{
|
||||
_settings.AlwaysPreview = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Update Settings
|
||||
|
||||
public bool AutoUpdates
|
||||
{
|
||||
get => _settings.AutoUpdates;
|
||||
set
|
||||
{
|
||||
_settings.AutoUpdates = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoUpdatePlugins
|
||||
{
|
||||
get => _settings.AutoUpdatePlugins;
|
||||
set
|
||||
{
|
||||
_settings.AutoUpdatePlugins = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Search Window Position
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EnumDisplayItem<SearchWindowScreens>> _searchWindowScreens = new();
|
||||
|
||||
public SearchWindowScreens SelectedSearchWindowScreen
|
||||
{
|
||||
get => _settings.SearchWindowScreen;
|
||||
set
|
||||
{
|
||||
_settings.SearchWindowScreen = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EnumDisplayItem<SearchWindowAligns>> _searchWindowAligns = new();
|
||||
|
||||
public SearchWindowAligns SelectedSearchWindowAlign
|
||||
{
|
||||
get => _settings.SearchWindowAlign;
|
||||
set
|
||||
{
|
||||
_settings.SearchWindowAlign = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Query Settings
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EnumDisplayItem<SearchPrecisionScore>> _searchPrecisionScores = new();
|
||||
|
||||
public SearchPrecisionScore SelectedSearchPrecision
|
||||
{
|
||||
get => _settings.QuerySearchPrecision;
|
||||
set
|
||||
{
|
||||
_settings.QuerySearchPrecision = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EnumDisplayItem<LastQueryMode>> _lastQueryModes = new();
|
||||
|
||||
public LastQueryMode SelectedLastQueryMode
|
||||
{
|
||||
get => _settings.LastQueryMode;
|
||||
set
|
||||
{
|
||||
_settings.LastQueryMode = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool SearchQueryResultsWithDelay
|
||||
{
|
||||
get => _settings.SearchQueryResultsWithDelay;
|
||||
set
|
||||
{
|
||||
_settings.SearchQueryResultsWithDelay = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int SearchDelayTime
|
||||
{
|
||||
get => _settings.SearchDelayTime;
|
||||
set
|
||||
{
|
||||
_settings.SearchDelayTime = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Home Page Settings
|
||||
|
||||
public bool ShowHomePage
|
||||
{
|
||||
get => _settings.ShowHomePage;
|
||||
set
|
||||
{
|
||||
_settings.ShowHomePage = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowHistoryResultsForHomePage
|
||||
{
|
||||
get => _settings.ShowHistoryResultsForHomePage;
|
||||
set
|
||||
{
|
||||
_settings.ShowHistoryResultsForHomePage = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxHistoryResultsToShow
|
||||
{
|
||||
get => _settings.MaxHistoryResultsToShowForHomePage;
|
||||
set
|
||||
{
|
||||
_settings.MaxHistoryResultsToShowForHomePage = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Miscellaneous Settings
|
||||
|
||||
public bool AutoRestartAfterChanging
|
||||
{
|
||||
get => _settings.AutoRestartAfterChanging;
|
||||
set
|
||||
{
|
||||
_settings.AutoRestartAfterChanging = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowUnknownSourceWarning
|
||||
{
|
||||
get => _settings.ShowUnknownSourceWarning;
|
||||
set
|
||||
{
|
||||
_settings.ShowUnknownSourceWarning = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AlwaysStartEn
|
||||
{
|
||||
get => _settings.AlwaysStartEn;
|
||||
set
|
||||
{
|
||||
_settings.AlwaysStartEn = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldUsePinyin
|
||||
{
|
||||
get => _settings.ShouldUsePinyin;
|
||||
set
|
||||
{
|
||||
_settings.ShouldUsePinyin = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Paths
|
||||
|
||||
public string PythonPath => _settings.PluginSettings.PythonExecutablePath ?? "Not set";
|
||||
public string NodePath => _settings.PluginSettings.NodeExecutablePath ?? "Not set";
|
||||
|
||||
|
|
@ -88,6 +342,10 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load Options
|
||||
|
||||
private void LoadLanguages()
|
||||
{
|
||||
// Minimal set of languages for now, can be expanded by loading from directory later
|
||||
|
|
@ -100,4 +358,42 @@ public partial class GeneralSettingsViewModel : ObservableObject
|
|||
new Language("ja", "日本語")
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadSearchWindowOptions()
|
||||
{
|
||||
SearchWindowScreens = new ObservableCollection<EnumDisplayItem<SearchWindowScreens>>(
|
||||
Enum.GetValues<SearchWindowScreens>().Select(v => new EnumDisplayItem<SearchWindowScreens>(v, v.ToString())));
|
||||
|
||||
SearchWindowAligns = new ObservableCollection<EnumDisplayItem<SearchWindowAligns>>(
|
||||
Enum.GetValues<SearchWindowAligns>().Select(v => new EnumDisplayItem<SearchWindowAligns>(v, v.ToString())));
|
||||
}
|
||||
|
||||
private void LoadSearchPrecisionOptions()
|
||||
{
|
||||
SearchPrecisionScores = new ObservableCollection<EnumDisplayItem<SearchPrecisionScore>>(
|
||||
Enum.GetValues<SearchPrecisionScore>().Select(v => new EnumDisplayItem<SearchPrecisionScore>(v, v.ToString())));
|
||||
}
|
||||
|
||||
private void LoadLastQueryModeOptions()
|
||||
{
|
||||
LastQueryModes = new ObservableCollection<EnumDisplayItem<LastQueryMode>>(
|
||||
Enum.GetValues<LastQueryMode>().Select(v => new EnumDisplayItem<LastQueryMode>(v, v.ToString())));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for displaying enum values in ComboBoxes
|
||||
/// </summary>
|
||||
public class EnumDisplayItem<T> where T : Enum
|
||||
{
|
||||
public T Value { get; }
|
||||
public string Display { get; }
|
||||
|
||||
public EnumDisplayItem(T value, string display)
|
||||
{
|
||||
Value = value;
|
||||
Display = display;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
235
Flow.Launcher.Avalonia/Views/Controls/Card.axaml
Normal file
235
Flow.Launcher.Avalonia/Views/Controls/Card.axaml
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Flow.Launcher.Avalonia.Views.Controls"
|
||||
x:Class="Flow.Launcher.Avalonia.Views.Controls.Card"
|
||||
x:DataType="controls:Card"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Styles>
|
||||
<!-- Default Card Style -->
|
||||
<Style Selector="controls|Card">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:Card">
|
||||
<Border x:Name="CardBorder"
|
||||
Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
MinHeight="68"
|
||||
Padding="0,15"
|
||||
Margin="0,4,0,0">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<!-- Icon -->
|
||||
<TextBlock x:Name="IconText"
|
||||
Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="24,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
|
||||
<!-- Spacer when no icon -->
|
||||
<Border Grid.Column="0"
|
||||
Width="24"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNullOrEmpty}}" />
|
||||
|
||||
<!-- Title and Subtitle -->
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Content (right side) -->
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Inside Card Style (nested inside ExCard) -->
|
||||
<Style Selector="controls|Card.inside">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:Card">
|
||||
<Border Background="Transparent"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,0"
|
||||
MinHeight="68"
|
||||
Padding="0,15">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="24,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
<Border Grid.Column="0" Width="24"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNullOrEmpty}}" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- InsideFit Card Style (nested with extra padding) -->
|
||||
<Style Selector="controls|Card.insidefit">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:Card">
|
||||
<Border Background="Transparent"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,0"
|
||||
MinHeight="68"
|
||||
Padding="35,15,26,15">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- First/Middle/Last styles for CardGroup -->
|
||||
<Style Selector="controls|Card.first, controls|Card.middle, controls|Card.last">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:Card">
|
||||
<Border Background="Transparent"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
MinHeight="68"
|
||||
Padding="0,15">
|
||||
<Border.Styles>
|
||||
<Style Selector="Border">
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
</Border.Styles>
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="24,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
<Border Grid.Column="0" Width="24"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNullOrEmpty}}" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style Selector="controls|Card.middle, controls|Card.last">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:Card">
|
||||
<Border Background="Transparent"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,0"
|
||||
MinHeight="68"
|
||||
Padding="0,15">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="24,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
<Border Grid.Column="0" Width="24"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNullOrEmpty}}" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
</UserControl>
|
||||
46
Flow.Launcher.Avalonia/Views/Controls/Card.axaml.cs
Normal file
46
Flow.Launcher.Avalonia/Views/Controls/Card.axaml.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Flow.Launcher.Avalonia.Views.Controls
|
||||
{
|
||||
public partial class Card : ContentControl
|
||||
{
|
||||
public static readonly StyledProperty<string> TitleProperty =
|
||||
AvaloniaProperty.Register<Card, string>(nameof(Title), string.Empty);
|
||||
|
||||
public static readonly StyledProperty<string> SubProperty =
|
||||
AvaloniaProperty.Register<Card, string>(nameof(Sub), string.Empty);
|
||||
|
||||
public static readonly StyledProperty<string> IconProperty =
|
||||
AvaloniaProperty.Register<Card, string>(nameof(Icon), string.Empty);
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => GetValue(TitleProperty);
|
||||
set => SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
public string Sub
|
||||
{
|
||||
get => GetValue(SubProperty);
|
||||
set => SetValue(SubProperty, value);
|
||||
}
|
||||
|
||||
public string Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public Card()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Flow.Launcher.Avalonia/Views/Controls/CardGroup.axaml
Normal file
30
Flow.Launcher.Avalonia/Views/Controls/CardGroup.axaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Flow.Launcher.Avalonia.Views.Controls"
|
||||
x:Class="Flow.Launcher.Avalonia.Views.Controls.CardGroup"
|
||||
x:DataType="controls:CardGroup"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Styles>
|
||||
<Style Selector="controls|CardGroup">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:CardGroup">
|
||||
<Border Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5">
|
||||
<ItemsPresenter ItemsPanel="{TemplateBinding ItemsPanel}" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
<Setter Property="ItemsPanel">
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical" />
|
||||
</ItemsPanelTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
</UserControl>
|
||||
18
Flow.Launcher.Avalonia/Views/Controls/CardGroup.axaml.cs
Normal file
18
Flow.Launcher.Avalonia/Views/Controls/CardGroup.axaml.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Flow.Launcher.Avalonia.Views.Controls
|
||||
{
|
||||
public partial class CardGroup : ItemsControl
|
||||
{
|
||||
public CardGroup()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Flow.Launcher.Avalonia/Views/Controls/ExCard.axaml
Normal file
78
Flow.Launcher.Avalonia/Views/Controls/ExCard.axaml
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Flow.Launcher.Avalonia.Views.Controls"
|
||||
x:Class="Flow.Launcher.Avalonia.Views.Controls.ExCard"
|
||||
x:DataType="controls:ExCard"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Styles>
|
||||
<Style Selector="controls|ExCard">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="controls:ExCard">
|
||||
<Expander x:Name="CardExpander"
|
||||
IsExpanded="{TemplateBinding IsExpanded, Mode=TwoWay}"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Expander.Styles>
|
||||
<Style Selector="Expander">
|
||||
<Setter Property="Background" Value="{DynamicResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
<Style Selector="Expander /template/ ToggleButton#ExpanderHeader">
|
||||
<Setter Property="MinHeight" Value="68" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
</Expander.Styles>
|
||||
|
||||
<Expander.Header>
|
||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto" Margin="0,12">
|
||||
<!-- Icon -->
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{TemplateBinding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="24,0,16,0"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
<Border Grid.Column="0" Width="24"
|
||||
IsVisible="{TemplateBinding Icon, Converter={x:Static StringConverters.IsNullOrEmpty}}" />
|
||||
|
||||
<!-- Title and Subtitle -->
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center" Margin="0,0,14,0">
|
||||
<TextBlock Text="{TemplateBinding Title}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock Text="{TemplateBinding Sub}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Padding="0,0,24,0"
|
||||
IsVisible="{TemplateBinding Sub, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Side Content (e.g., toggle switch) -->
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding SideContent}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,14,0" />
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
|
||||
<!-- Expandable Content -->
|
||||
<ContentPresenter Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="0" />
|
||||
</Expander>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
</UserControl>
|
||||
64
Flow.Launcher.Avalonia/Views/Controls/ExCard.axaml.cs
Normal file
64
Flow.Launcher.Avalonia/Views/Controls/ExCard.axaml.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Flow.Launcher.Avalonia.Views.Controls
|
||||
{
|
||||
public partial class ExCard : ContentControl
|
||||
{
|
||||
public static readonly StyledProperty<string> TitleProperty =
|
||||
AvaloniaProperty.Register<ExCard, string>(nameof(Title), string.Empty);
|
||||
|
||||
public static readonly StyledProperty<string> SubProperty =
|
||||
AvaloniaProperty.Register<ExCard, string>(nameof(Sub), string.Empty);
|
||||
|
||||
public static readonly StyledProperty<string> IconProperty =
|
||||
AvaloniaProperty.Register<ExCard, string>(nameof(Icon), string.Empty);
|
||||
|
||||
public static readonly StyledProperty<object?> SideContentProperty =
|
||||
AvaloniaProperty.Register<ExCard, object?>(nameof(SideContent));
|
||||
|
||||
public static readonly StyledProperty<bool> IsExpandedProperty =
|
||||
AvaloniaProperty.Register<ExCard, bool>(nameof(IsExpanded), false);
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => GetValue(TitleProperty);
|
||||
set => SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
public string Sub
|
||||
{
|
||||
get => GetValue(SubProperty);
|
||||
set => SetValue(SubProperty, value);
|
||||
}
|
||||
|
||||
public string Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public object? SideContent
|
||||
{
|
||||
get => GetValue(SideContentProperty);
|
||||
set => SetValue(SideContentProperty, value);
|
||||
}
|
||||
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => GetValue(IsExpandedProperty);
|
||||
set => SetValue(IsExpandedProperty, value);
|
||||
}
|
||||
|
||||
public ExCard()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,66 +6,279 @@
|
|||
xmlns:vm="using:Flow.Launcher.Avalonia.ViewModel.SettingPages"
|
||||
xmlns:i18n="using:Flow.Launcher.Avalonia.Resource"
|
||||
xmlns:core="using:Flow.Launcher.Core.Resource"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:userSettings="using:Flow.Launcher.Infrastructure.UserSettings"
|
||||
xmlns:sharedModels="using:Flow.Launcher.Plugin.SharedModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="1200"
|
||||
x:Class="Flow.Launcher.Avalonia.Views.SettingPages.GeneralSettingsPage"
|
||||
x:DataType="vm:GeneralSettingsViewModel">
|
||||
|
||||
<StackPanel Spacing="20">
|
||||
<TextBlock Text="{i18n:Localize general}" FontSize="28" FontWeight="SemiBold" />
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="4" Margin="0,18,25,30">
|
||||
<TextBlock Text="{i18n:Localize general}" FontSize="28" FontWeight="SemiBold" Margin="0,0,0,8" />
|
||||
|
||||
<!-- Language Selection -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize language}"
|
||||
IconSource="Earth">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox ItemsSource="{Binding Languages}"
|
||||
SelectedItem="{Binding SelectedLanguage}"
|
||||
MinWidth="200">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="core:Language">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Start on System Startup with nested option -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize startFlowLauncherOnSystemStartup}"
|
||||
IconSource="Power"
|
||||
IsExpanded="False">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding StartOnStartup}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize useLogonTaskForStartup}"
|
||||
Description="{i18n:Localize useLogonTaskForStartupTooltip}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding UseLogonTaskForStartup}" />
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Startup Settings -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize startFlowLauncherOnSystemStartup}"
|
||||
IconSource="Save">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding StartOnStartup}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Hide on Startup -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize hideOnStartup}"
|
||||
Description="{i18n:Localize hideOnStartupToolTip}"
|
||||
IconSource="Hide">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding HideOnStartup}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Behavior Settings -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize hideFlowLauncherWhenLoseFocus}"
|
||||
IconSource="Hide">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding HideWhenDeactivated}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Hide when lose focus -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize hideFlowLauncherWhenLoseFocus}"
|
||||
IconSource="Hide">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding HideWhenDeactivated}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<ui:SettingsExpander Header="{i18n:Localize showAtTopmost}"
|
||||
IconSource="Up">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShowAtTopmost}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Hide Notify Icon -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize hideNotifyIcon}"
|
||||
Description="{i18n:Localize hideNotifyIconToolTip}"
|
||||
IconSource="Hide">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding HideNotifyIcon}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Python & Node Paths -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize pythonFilePath}"
|
||||
Description="{Binding PythonPath}">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button Content="{i18n:Localize select}" Command="{Binding SelectPythonCommand}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Show at Topmost -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize showAtTopmost}"
|
||||
Description="{i18n:Localize showAtTopmostToolTip}"
|
||||
IconSource="Up">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShowAtTopmost}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<ui:SettingsExpander Header="{i18n:Localize nodeFilePath}"
|
||||
Description="{Binding NodePath}">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button Content="{i18n:Localize select}" Command="{Binding SelectNodeCommand}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
<!-- Search Window Position -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize SearchWindowPosition}"
|
||||
IconSource="MoveUp"
|
||||
IsExpanded="False">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox ItemsSource="{Binding SearchWindowScreens}"
|
||||
SelectedItem="{Binding SelectedSearchWindowScreen, Mode=TwoWay}"
|
||||
MinWidth="200">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:EnumDisplayItem`1">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize SearchWindowAlign}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ComboBox ItemsSource="{Binding SearchWindowAligns}"
|
||||
SelectedItem="{Binding SelectedSearchWindowAlign, Mode=TwoWay}"
|
||||
MinWidth="160">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:EnumDisplayItem`1">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
<!-- Ignore Hotkeys on Fullscreen -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize ignoreHotkeysOnFullscreen}"
|
||||
Description="{i18n:Localize ignoreHotkeysOnFullscreenToolTip}"
|
||||
IconSource="Keyboard">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding IgnoreHotkeysOnFullscreen}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Always Preview -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize AlwaysPreview}"
|
||||
IconSource="PreviewLink">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding AlwaysPreview}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Auto Updates -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize autoUpdates}"
|
||||
Description="{i18n:Localize autoUpdatesTooltip}"
|
||||
IconSource="Sync">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding AutoUpdates}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Auto Update Plugins -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize autoUpdatePlugins}"
|
||||
Description="{i18n:Localize autoUpdatePluginsToolTip}"
|
||||
IconSource="Sync">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding AutoUpdatePlugins}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Query Search Settings -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize querySearchPrecision}"
|
||||
Description="{i18n:Localize querySearchPrecisionToolTip}"
|
||||
IconSource="Find"
|
||||
IsExpanded="False">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox ItemsSource="{Binding SearchPrecisionScores}"
|
||||
SelectedItem="{Binding SelectedSearchPrecision, Mode=TwoWay}"
|
||||
MinWidth="150">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:EnumDisplayItem`1">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize lastQueryMode}"
|
||||
Description="{i18n:Localize lastQueryModeToolTip}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ComboBox ItemsSource="{Binding LastQueryModes}"
|
||||
SelectedItem="{Binding SelectedLastQueryMode, Mode=TwoWay}"
|
||||
MinWidth="180">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:EnumDisplayItem`1">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Search Delay -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize searchDelay}"
|
||||
Description="{i18n:Localize searchDelayToolTip}"
|
||||
IconSource="Clock"
|
||||
IsExpanded="False">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding SearchQueryResultsWithDelay}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize searchDelayTime}"
|
||||
Description="{i18n:Localize searchDelayTimeToolTip}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ui:NumberBox Value="{Binding SearchDelayTime}"
|
||||
Minimum="0"
|
||||
Maximum="1000"
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Compact"
|
||||
Width="120" />
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Home Page Settings -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize homePage}"
|
||||
Description="{i18n:Localize homePageToolTip}"
|
||||
IconSource="Home"
|
||||
IsExpanded="False">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShowHomePage}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize historyResultsForHomePage}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShowHistoryResultsForHomePage}" />
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
<ui:SettingsExpanderItem Content="{i18n:Localize historyResultsCountForHomePage}">
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ui:NumberBox Value="{Binding MaxHistoryResultsToShow}"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
SmallChange="5"
|
||||
SpinButtonPlacementMode="Compact"
|
||||
Width="120" />
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Auto Restart After Changing -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize autoRestartAfterChanging}"
|
||||
Description="{i18n:Localize autoRestartAfterChangingToolTip}"
|
||||
IconSource="Refresh">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding AutoRestartAfterChanging}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Show Unknown Source Warning -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize showUnknownSourceWarning}"
|
||||
Description="{i18n:Localize showUnknownSourceWarningToolTip}"
|
||||
IconSource="Important">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShowUnknownSourceWarning}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Always Start English -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize typingStartEn}"
|
||||
Description="{i18n:Localize typingStartEnTooltip}"
|
||||
IconSource="Keyboard">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding AlwaysStartEn}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Use Pinyin -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize ShouldUsePinyin}"
|
||||
Description="{i18n:Localize ShouldUsePinyinToolTip}"
|
||||
IconSource="Character">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch IsChecked="{Binding ShouldUsePinyin}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Python Path -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize pythonFilePath}"
|
||||
Description="{Binding PythonPath}"
|
||||
IconSource="Code">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button Content="{i18n:Localize select}" Command="{Binding SelectPythonCommand}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Node Path -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize nodeFilePath}"
|
||||
Description="{Binding NodePath}"
|
||||
IconSource="Code">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button Content="{i18n:Localize select}" Command="{Binding SelectNodeCommand}" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
<!-- Language Selection -->
|
||||
<ui:SettingsExpander Header="{i18n:Localize language}"
|
||||
IconSource="Globe">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox ItemsSource="{Binding Languages}"
|
||||
SelectedItem="{Binding SelectedLanguage}"
|
||||
MinWidth="200">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="core:Language">
|
||||
<TextBlock Text="{Binding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
|
|
|
|||
Loading…
Reference in a new issue