mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
CmdPal: Transparent window (#45159)
## Summary This PR adds: - Backdrop material customization - Alongside acrylic, the following options are now available: - Transparent background - Mica background - Background material opacity - Lets you control how transparent the background is ## Pictures? Pictures! <img width="1491" height="928" alt="image" src="https://github.com/user-attachments/assets/ff4e9e06-fcf1-4f05-bc0a-fb70dc4f39be" /> https://github.com/user-attachments/assets/84e83279-afab-481e-b904-f054318c5d2f <img width="977" height="628" alt="image" src="https://github.com/user-attachments/assets/241a228d-af3f-448a-94a6-0a282218bd8c" /> ## PR Checklist - [x] Closes: #44197 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
@@ -288,7 +288,6 @@ internal sealed partial class BlurImageControl : Control
|
||||
_effectBrush?.Dispose();
|
||||
_effectBrush = effectFactory.CreateBrush();
|
||||
|
||||
// Set initial source
|
||||
if (ImageSource is not null)
|
||||
{
|
||||
_imageBrush ??= _compositor.CreateSurfaceBrush();
|
||||
|
||||
@@ -16,24 +16,38 @@
|
||||
CornerRadius="8"
|
||||
Translation="0,0,8">
|
||||
<Grid>
|
||||
<!-- Clear style: SolidColorBrush with computed alpha (window backdrop) -->
|
||||
<Border
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
Visibility="{x:Bind h:BindTransformers.NegateVisibility(ShowBackgroundImage), Mode=OneWay}">
|
||||
Visibility="{x:Bind ClearVisibility, Mode=OneWay}">
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="{x:Bind EffectiveClearColor, Mode=OneWay}" />
|
||||
</Border.Background>
|
||||
</Border>
|
||||
<!-- Acrylic/Mica style: AcrylicBrush with effective opacity (window backdrop) -->
|
||||
<Border
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
Visibility="{x:Bind AcrylicVisibility, Mode=OneWay}">
|
||||
<Border.Background>
|
||||
<AcrylicBrush
|
||||
FallbackColor="{x:Bind PreviewBackgroundColor, Mode=OneWay}"
|
||||
TintColor="{x:Bind PreviewBackgroundColor, Mode=OneWay}"
|
||||
TintOpacity="{x:Bind PreviewBackgroundOpacity, Mode=OneWay}" />
|
||||
TintOpacity="{x:Bind PreviewEffectiveOpacity, Mode=OneWay}" />
|
||||
</Border.Background>
|
||||
</Border>
|
||||
<!-- Background image (inside window, on top of backdrop) -->
|
||||
<local:BlurImageControl
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BlurAmount="{x:Bind PreviewBackgroundImageBlurAmount, Mode=OneWay}"
|
||||
ImageBrightness="{x:Bind PreviewBackgroundImageBrightness, Mode=OneWay}"
|
||||
ImageOpacity="{x:Bind PreviewBackgroundImageOpacity, Mode=OneWay}"
|
||||
ImageSource="{x:Bind PreviewBackgroundImageSource, Mode=OneWay}"
|
||||
ImageStretch="{x:Bind ToStretch(PreviewBackgroundImageFit), Mode=OneWay}"
|
||||
IsHitTestVisible="False"
|
||||
|
||||
@@ -12,13 +12,11 @@ namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class CommandPalettePreview : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty PreviewBackgroundOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(0d));
|
||||
public static readonly DependencyProperty PreviewBackgroundColorProperty = DependencyProperty.Register(nameof(PreviewBackgroundColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color), OnBackdropPropertyChanged));
|
||||
|
||||
public static readonly DependencyProperty PreviewBackgroundColorProperty = DependencyProperty.Register(nameof(PreviewBackgroundColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color)));
|
||||
public static readonly DependencyProperty PreviewBackgroundImageSourceProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageSource), typeof(ImageSource), typeof(CommandPalettePreview), new PropertyMetadata(null, OnBackgroundImageSourceChanged));
|
||||
|
||||
public static readonly DependencyProperty PreviewBackgroundImageSourceProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageSource), typeof(ImageSource), typeof(CommandPalettePreview), new PropertyMetadata(null, PropertyChangedCallback));
|
||||
|
||||
public static readonly DependencyProperty PreviewBackgroundImageOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageOpacity), typeof(int), typeof(CommandPalettePreview), new PropertyMetadata(0));
|
||||
public static readonly DependencyProperty PreviewBackgroundImageOpacityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(1.0));
|
||||
|
||||
public static readonly DependencyProperty PreviewBackgroundImageFitProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageFit), typeof(BackgroundImageFit), typeof(CommandPalettePreview), new PropertyMetadata(default(BackgroundImageFit)));
|
||||
|
||||
@@ -30,7 +28,18 @@ public sealed partial class CommandPalettePreview : UserControl
|
||||
|
||||
public static readonly DependencyProperty PreviewBackgroundImageTintIntensityProperty = DependencyProperty.Register(nameof(PreviewBackgroundImageTintIntensity), typeof(int), typeof(CommandPalettePreview), new PropertyMetadata(0));
|
||||
|
||||
public static readonly DependencyProperty ShowBackgroundImageProperty = DependencyProperty.Register(nameof(ShowBackgroundImage), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed));
|
||||
public static readonly DependencyProperty ShowBackgroundImageProperty = DependencyProperty.Register(nameof(ShowBackgroundImage), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed, OnVisibilityPropertyChanged));
|
||||
|
||||
public static readonly DependencyProperty PreviewBackdropStyleProperty = DependencyProperty.Register(nameof(PreviewBackdropStyle), typeof(BackdropStyle?), typeof(CommandPalettePreview), new PropertyMetadata(null, OnVisibilityPropertyChanged));
|
||||
|
||||
public static readonly DependencyProperty PreviewEffectiveOpacityProperty = DependencyProperty.Register(nameof(PreviewEffectiveOpacity), typeof(double), typeof(CommandPalettePreview), new PropertyMetadata(1.0, OnBackdropPropertyChanged));
|
||||
|
||||
// Computed read-only dependency properties
|
||||
public static readonly DependencyProperty EffectiveClearColorProperty = DependencyProperty.Register(nameof(EffectiveClearColor), typeof(Color), typeof(CommandPalettePreview), new PropertyMetadata(default(Color)));
|
||||
|
||||
public static readonly DependencyProperty AcrylicVisibilityProperty = DependencyProperty.Register(nameof(AcrylicVisibility), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Visible));
|
||||
|
||||
public static readonly DependencyProperty ClearVisibilityProperty = DependencyProperty.Register(nameof(ClearVisibility), typeof(Visibility), typeof(CommandPalettePreview), new PropertyMetadata(Visibility.Collapsed));
|
||||
|
||||
public BackgroundImageFit PreviewBackgroundImageFit
|
||||
{
|
||||
@@ -38,12 +47,6 @@ public sealed partial class CommandPalettePreview : UserControl
|
||||
set { SetValue(PreviewBackgroundImageFitProperty, value); }
|
||||
}
|
||||
|
||||
public double PreviewBackgroundOpacity
|
||||
{
|
||||
get { return (double)GetValue(PreviewBackgroundOpacityProperty); }
|
||||
set { SetValue(PreviewBackgroundOpacityProperty, value); }
|
||||
}
|
||||
|
||||
public Color PreviewBackgroundColor
|
||||
{
|
||||
get { return (Color)GetValue(PreviewBackgroundColorProperty); }
|
||||
@@ -56,10 +59,10 @@ public sealed partial class CommandPalettePreview : UserControl
|
||||
set { SetValue(PreviewBackgroundImageSourceProperty, value); }
|
||||
}
|
||||
|
||||
public int PreviewBackgroundImageOpacity
|
||||
public double PreviewBackgroundImageOpacity
|
||||
{
|
||||
get { return (int)GetValue(PreviewBackgroundImageOpacityProperty); }
|
||||
set { SetValue(PreviewBackgroundImageOpacityProperty, value); }
|
||||
get => (double)GetValue(PreviewBackgroundImageOpacityProperty);
|
||||
set => SetValue(PreviewBackgroundImageOpacityProperty, value);
|
||||
}
|
||||
|
||||
public double PreviewBackgroundImageBrightness
|
||||
@@ -92,12 +95,48 @@ public sealed partial class CommandPalettePreview : UserControl
|
||||
set => SetValue(ShowBackgroundImageProperty, value);
|
||||
}
|
||||
|
||||
public BackdropStyle? PreviewBackdropStyle
|
||||
{
|
||||
get => (BackdropStyle?)GetValue(PreviewBackdropStyleProperty);
|
||||
set => SetValue(PreviewBackdropStyleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the effective opacity for the backdrop, pre-computed by the theme provider.
|
||||
/// For Acrylic style: used directly as TintOpacity.
|
||||
/// For Clear style: used to compute the alpha channel of the solid color.
|
||||
/// </summary>
|
||||
public double PreviewEffectiveOpacity
|
||||
{
|
||||
get => (double)GetValue(PreviewEffectiveOpacityProperty);
|
||||
set => SetValue(PreviewEffectiveOpacityProperty, value);
|
||||
}
|
||||
|
||||
// Computed read-only properties
|
||||
public Color EffectiveClearColor
|
||||
{
|
||||
get => (Color)GetValue(EffectiveClearColorProperty);
|
||||
private set => SetValue(EffectiveClearColorProperty, value);
|
||||
}
|
||||
|
||||
public Visibility AcrylicVisibility
|
||||
{
|
||||
get => (Visibility)GetValue(AcrylicVisibilityProperty);
|
||||
private set => SetValue(AcrylicVisibilityProperty, value);
|
||||
}
|
||||
|
||||
public Visibility ClearVisibility
|
||||
{
|
||||
get => (Visibility)GetValue(ClearVisibilityProperty);
|
||||
private set => SetValue(ClearVisibilityProperty, value);
|
||||
}
|
||||
|
||||
public CommandPalettePreview()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
private static void OnBackgroundImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is not CommandPalettePreview preview)
|
||||
{
|
||||
@@ -107,7 +146,46 @@ public sealed partial class CommandPalettePreview : UserControl
|
||||
preview.ShowBackgroundImage = e.NewValue is ImageSource ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private double ToOpacity(int value) => value / 100.0;
|
||||
private static void OnBackdropPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is not CommandPalettePreview preview)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
preview.UpdateComputedClearColor();
|
||||
}
|
||||
|
||||
private static void OnVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is not CommandPalettePreview preview)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
preview.UpdateComputedVisibilityProperties();
|
||||
preview.UpdateComputedClearColor();
|
||||
}
|
||||
|
||||
private void UpdateComputedClearColor()
|
||||
{
|
||||
EffectiveClearColor = Color.FromArgb(
|
||||
(byte)(PreviewEffectiveOpacity * 255),
|
||||
PreviewBackgroundColor.R,
|
||||
PreviewBackgroundColor.G,
|
||||
PreviewBackgroundColor.B);
|
||||
}
|
||||
|
||||
private void UpdateComputedVisibilityProperties()
|
||||
{
|
||||
var config = BackdropStyles.Get(PreviewBackdropStyle ?? BackdropStyle.Acrylic);
|
||||
|
||||
// Show backdrop effect based on style (on top of any background image)
|
||||
AcrylicVisibility = config.PreviewBrush == PreviewBrushKind.Acrylic
|
||||
? Visibility.Visible : Visibility.Collapsed;
|
||||
ClearVisibility = config.PreviewBrush == PreviewBrushKind.Solid
|
||||
? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private double ToTintIntensity(int value) => value / 100.0;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
VerticalAlignment="Stretch"
|
||||
BlurAmount="{x:Bind ViewModel.BackgroundImageBlurAmount, Mode=OneWay}"
|
||||
ImageBrightness="{x:Bind ViewModel.BackgroundImageBrightness, Mode=OneWay}"
|
||||
ImageOpacity="{x:Bind ViewModel.BackgroundImageOpacity, Mode=OneWay}"
|
||||
ImageOpacity="{x:Bind ViewModel.EffectiveImageOpacity, Mode=OneWay}"
|
||||
ImageSource="{x:Bind ViewModel.BackgroundImageSource, Mode=OneWay}"
|
||||
ImageStretch="{x:Bind ViewModel.BackgroundImageStretch, Mode=OneWay}"
|
||||
IsHitTestVisible="False"
|
||||
|
||||
@@ -31,6 +31,7 @@ using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
using Windows.System;
|
||||
using Windows.UI;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Graphics.Dwm;
|
||||
@@ -80,7 +81,9 @@ public sealed partial class MainWindow : WindowEx,
|
||||
private int _sessionErrorCount;
|
||||
|
||||
private DesktopAcrylicController? _acrylicController;
|
||||
private MicaController? _micaController;
|
||||
private SystemBackdropConfiguration? _configurationSource;
|
||||
private bool _isUpdatingBackdrop;
|
||||
private TimeSpan _autoGoHomeInterval = Timeout.InfiniteTimeSpan;
|
||||
|
||||
private WindowPosition _currentWindowPosition = new();
|
||||
@@ -109,7 +112,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
|
||||
}
|
||||
|
||||
SetAcrylic();
|
||||
InitializeBackdropSupport();
|
||||
|
||||
_hiddenOwnerBehavior.ShowInTaskbar(this, Debugger.IsAttached);
|
||||
|
||||
@@ -158,7 +161,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
App.Current.Services.GetService<SettingsModel>()!.SettingsChanged += SettingsChangedHandler;
|
||||
|
||||
// Make sure that we update the acrylic theme when the OS theme changes
|
||||
RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateAcrylic);
|
||||
RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateBackdrop);
|
||||
|
||||
// Hardcoding event name to avoid bringing in the PowerToys.interop dependency. Event name must match CMDPAL_SHOW_EVENT from shared_constants.h
|
||||
NativeEventWaiter.WaitForEventLoop("Local\\PowerToysCmdPal-ShowEvent-62336fcd-8611-4023-9b30-091a6af4cc5a", () =>
|
||||
@@ -185,7 +188,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
|
||||
private void ThemeServiceOnThemeChanged(object? sender, ThemeChangedEventArgs e)
|
||||
{
|
||||
UpdateAcrylic();
|
||||
UpdateBackdrop();
|
||||
}
|
||||
|
||||
private static void LocalKeyboardListener_OnKeyPressed(object? sender, LocalKeyboardListenerKeyPressedEventArgs e)
|
||||
@@ -280,48 +283,170 @@ public sealed partial class MainWindow : WindowEx,
|
||||
_autoGoHomeTimer.Interval = _autoGoHomeInterval;
|
||||
}
|
||||
|
||||
private void SetAcrylic()
|
||||
private void InitializeBackdropSupport()
|
||||
{
|
||||
if (DesktopAcrylicController.IsSupported())
|
||||
if (DesktopAcrylicController.IsSupported() || MicaController.IsSupported())
|
||||
{
|
||||
// Hooking up the policy object.
|
||||
_configurationSource = new SystemBackdropConfiguration
|
||||
{
|
||||
// Initial configuration state.
|
||||
IsInputActive = true,
|
||||
};
|
||||
UpdateAcrylic();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAcrylic()
|
||||
private void UpdateBackdrop()
|
||||
{
|
||||
// Prevent re-entrance when backdrop changes trigger ActualThemeChanged
|
||||
if (_isUpdatingBackdrop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isUpdatingBackdrop = true;
|
||||
|
||||
var backdrop = _themeService.Current.BackdropParameters;
|
||||
var isImageMode = ViewModel.ShowBackgroundImage;
|
||||
var config = BackdropStyles.Get(backdrop.Style);
|
||||
|
||||
try
|
||||
{
|
||||
if (_acrylicController != null)
|
||||
switch (config.ControllerKind)
|
||||
{
|
||||
_acrylicController.RemoveAllSystemBackdropTargets();
|
||||
_acrylicController.Dispose();
|
||||
case BackdropControllerKind.Solid:
|
||||
CleanupBackdropControllers();
|
||||
var tintColor = Color.FromArgb(
|
||||
(byte)(backdrop.EffectiveOpacity * 255),
|
||||
backdrop.TintColor.R,
|
||||
backdrop.TintColor.G,
|
||||
backdrop.TintColor.B);
|
||||
SetupTransparentBackdrop(tintColor);
|
||||
break;
|
||||
|
||||
case BackdropControllerKind.Mica:
|
||||
case BackdropControllerKind.MicaAlt:
|
||||
SetupMica(backdrop, isImageMode, config.ControllerKind);
|
||||
break;
|
||||
|
||||
case BackdropControllerKind.Acrylic:
|
||||
case BackdropControllerKind.AcrylicThin:
|
||||
default:
|
||||
SetupDesktopAcrylic(backdrop, isImageMode, config.ControllerKind);
|
||||
break;
|
||||
}
|
||||
|
||||
var backdrop = _themeService.Current.BackdropParameters;
|
||||
_acrylicController = new DesktopAcrylicController
|
||||
{
|
||||
TintColor = backdrop.TintColor,
|
||||
TintOpacity = backdrop.TintOpacity,
|
||||
FallbackColor = backdrop.FallbackColor,
|
||||
LuminosityOpacity = backdrop.LuminosityOpacity,
|
||||
};
|
||||
|
||||
// Enable the system backdrop.
|
||||
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
|
||||
_acrylicController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
|
||||
_acrylicController.SetSystemBackdropConfiguration(_configurationSource);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Failed to update backdrop", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isUpdatingBackdrop = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupTransparentBackdrop(Color tintColor)
|
||||
{
|
||||
if (SystemBackdrop is TransparentTintBackdrop existingBackdrop)
|
||||
{
|
||||
existingBackdrop.TintColor = tintColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemBackdrop = new TransparentTintBackdrop { TintColor = tintColor };
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupBackdropControllers()
|
||||
{
|
||||
if (_acrylicController is not null)
|
||||
{
|
||||
_acrylicController.RemoveAllSystemBackdropTargets();
|
||||
_acrylicController.Dispose();
|
||||
_acrylicController = null;
|
||||
}
|
||||
|
||||
if (_micaController is not null)
|
||||
{
|
||||
_micaController.RemoveAllSystemBackdropTargets();
|
||||
_micaController.Dispose();
|
||||
_micaController = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupDesktopAcrylic(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind)
|
||||
{
|
||||
CleanupBackdropControllers();
|
||||
|
||||
// Fall back to solid color if acrylic not supported
|
||||
if (_configurationSource is null || !DesktopAcrylicController.IsSupported())
|
||||
{
|
||||
SetupTransparentBackdrop(backdrop.FallbackColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// DesktopAcrylicController and SystemBackdrop can't be active simultaneously
|
||||
SystemBackdrop = null;
|
||||
|
||||
// Image mode: no tint here, BlurImageControl handles it (avoids double-tinting)
|
||||
var effectiveTintOpacity = isImageMode
|
||||
? 0.0f
|
||||
: backdrop.EffectiveOpacity;
|
||||
|
||||
_acrylicController = new DesktopAcrylicController
|
||||
{
|
||||
Kind = kind == BackdropControllerKind.AcrylicThin
|
||||
? DesktopAcrylicKind.Thin
|
||||
: DesktopAcrylicKind.Default,
|
||||
TintColor = backdrop.TintColor,
|
||||
TintOpacity = effectiveTintOpacity,
|
||||
FallbackColor = backdrop.FallbackColor,
|
||||
LuminosityOpacity = backdrop.EffectiveLuminosityOpacity,
|
||||
};
|
||||
|
||||
// Requires "using WinRT;" for Window.As<>()
|
||||
_acrylicController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
|
||||
_acrylicController.SetSystemBackdropConfiguration(_configurationSource);
|
||||
}
|
||||
|
||||
private void SetupMica(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind)
|
||||
{
|
||||
CleanupBackdropControllers();
|
||||
|
||||
// Fall back to solid color if Mica not supported
|
||||
if (_configurationSource is null || !MicaController.IsSupported())
|
||||
{
|
||||
SetupTransparentBackdrop(backdrop.FallbackColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// MicaController and SystemBackdrop can't be active simultaneously
|
||||
SystemBackdrop = null;
|
||||
_configurationSource.Theme = _themeService.Current.Theme == ElementTheme.Dark
|
||||
? SystemBackdropTheme.Dark
|
||||
: SystemBackdropTheme.Light;
|
||||
|
||||
var hasColorization = _themeService.Current.HasColorization || isImageMode;
|
||||
|
||||
_micaController = new MicaController
|
||||
{
|
||||
Kind = kind == BackdropControllerKind.MicaAlt
|
||||
? MicaKind.BaseAlt
|
||||
: MicaKind.Base,
|
||||
};
|
||||
|
||||
// Only set tint properties when colorization is active
|
||||
// Otherwise let system handle light/dark theme defaults automatically
|
||||
if (hasColorization)
|
||||
{
|
||||
// Image mode: no tint here, BlurImageControl handles it (avoids double-tinting)
|
||||
_micaController.TintColor = backdrop.TintColor;
|
||||
_micaController.TintOpacity = isImageMode ? 0.0f : backdrop.EffectiveOpacity;
|
||||
_micaController.FallbackColor = backdrop.FallbackColor;
|
||||
_micaController.LuminosityOpacity = backdrop.EffectiveLuminosityOpacity;
|
||||
}
|
||||
|
||||
_micaController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
|
||||
_micaController.SetSystemBackdropConfiguration(_configurationSource);
|
||||
}
|
||||
|
||||
private void ShowHwnd(IntPtr hwndValue, MonitorBehavior target)
|
||||
@@ -637,12 +762,8 @@ public sealed partial class MainWindow : WindowEx,
|
||||
|
||||
private void DisposeAcrylic()
|
||||
{
|
||||
if (_acrylicController is not null)
|
||||
{
|
||||
_acrylicController.Dispose();
|
||||
_acrylicController = null!;
|
||||
_configurationSource = null!;
|
||||
}
|
||||
CleanupBackdropControllers();
|
||||
_configurationSource = null!;
|
||||
}
|
||||
|
||||
// Updates our window s.t. the top of the window is draggable.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using CommunityToolkit.WinUI.Helpers;
|
||||
using Microsoft.CmdPal.UI.Helpers;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.UI;
|
||||
@@ -34,7 +35,7 @@ internal sealed class ColorfulThemeProvider : IThemeProvider
|
||||
_uiSettings = uiSettings;
|
||||
}
|
||||
|
||||
public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context)
|
||||
public BackdropParameters GetBackdropParameters(ThemeContext context)
|
||||
{
|
||||
var isLight = context.Theme == ElementTheme.Light ||
|
||||
(context.Theme == ElementTheme.Default &&
|
||||
@@ -53,7 +54,26 @@ internal sealed class ColorfulThemeProvider : IThemeProvider
|
||||
var colorIntensity = isLight ? 0.6f * colorIntensityUser : colorIntensityUser;
|
||||
var effectiveBgColor = ColorBlender.Blend(baseColor, blended, colorIntensity);
|
||||
|
||||
return new AcrylicBackdropParameters(effectiveBgColor, effectiveBgColor, 0.8f, 0.8f);
|
||||
var transparencyMode = context.BackdropStyle ?? BackdropStyle.Acrylic;
|
||||
var config = BackdropStyles.Get(transparencyMode);
|
||||
|
||||
// For colorful theme, boost tint opacity to show color better through blur
|
||||
// But not for styles with fixed opacity (Mica) - they handle their own opacity
|
||||
var baseTintOpacity = config.ControllerKind == BackdropControllerKind.Solid || !config.SupportsOpacity
|
||||
? (float?)null // Use default
|
||||
: Math.Max(config.BaseTintOpacity, 0.8f);
|
||||
|
||||
var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity, baseTintOpacity);
|
||||
var effectiveLuminosityOpacity = config.SupportsOpacity
|
||||
? config.BaseLuminosityOpacity * context.BackdropOpacity
|
||||
: config.BaseLuminosityOpacity;
|
||||
|
||||
return new BackdropParameters(
|
||||
TintColor: effectiveBgColor,
|
||||
FallbackColor: effectiveBgColor,
|
||||
EffectiveOpacity: effectiveOpacity,
|
||||
EffectiveLuminosityOpacity: effectiveLuminosityOpacity,
|
||||
Style: transparencyMode);
|
||||
}
|
||||
|
||||
private static class ColorBlender
|
||||
|
||||
@@ -8,14 +8,14 @@ using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
namespace Microsoft.CmdPal.UI.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Provides theme identification, resource path resolution, and creation of acrylic
|
||||
/// backdrop parameters based on the current <see cref="ThemeContext"/>.
|
||||
/// Provides theme identification, resource path resolution, and creation of backdrop
|
||||
/// parameters based on the current <see cref="ThemeContext"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implementations should expose a stable <see cref="ThemeKey"/> and a valid XAML resource
|
||||
/// dictionary path via <see cref="ResourcePath"/>. The
|
||||
/// <see cref="GetAcrylicBackdrop(ThemeContext)"/> method computes
|
||||
/// <see cref="AcrylicBackdropParameters"/> using the supplied theme context.
|
||||
/// <see cref="GetBackdropParameters(ThemeContext)"/> method computes
|
||||
/// <see cref="BackdropParameters"/> using the supplied theme context.
|
||||
/// </remarks>
|
||||
internal interface IThemeProvider
|
||||
{
|
||||
@@ -30,9 +30,9 @@ internal interface IThemeProvider
|
||||
string ResourcePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates acrylic backdrop parameters based on the provided theme context.
|
||||
/// Creates backdrop parameters based on the provided theme context.
|
||||
/// </summary>
|
||||
/// <param name="context">The current theme context, including theme, tint, and optional background details.</param>
|
||||
/// <returns>The computed <see cref="AcrylicBackdropParameters"/> for the backdrop.</returns>
|
||||
AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context);
|
||||
/// <param name="context">The current theme context, including theme, tint, transparency mode, and optional background details.</param>
|
||||
/// <returns>The computed <see cref="BackdropParameters"/> for the backdrop.</returns>
|
||||
BackdropParameters GetBackdropParameters(ThemeContext context);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.UI;
|
||||
@@ -28,16 +29,28 @@ internal sealed class NormalThemeProvider : IThemeProvider
|
||||
|
||||
public string ResourcePath => "ms-appx:///Styles/Theme.Normal.xaml";
|
||||
|
||||
public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context)
|
||||
public BackdropParameters GetBackdropParameters(ThemeContext context)
|
||||
{
|
||||
var isLight = context.Theme == ElementTheme.Light ||
|
||||
(context.Theme == ElementTheme.Default &&
|
||||
_uiSettings.GetColorValue(UIColorType.Background).R > 128);
|
||||
|
||||
return new AcrylicBackdropParameters(
|
||||
var backdropStyle = context.BackdropStyle ?? BackdropStyle.Acrylic;
|
||||
var config = BackdropStyles.Get(backdropStyle);
|
||||
|
||||
// Apply light/dark theme adjustment to luminosity
|
||||
var baseLuminosityOpacity = isLight
|
||||
? config.BaseLuminosityOpacity
|
||||
: Math.Min(config.BaseLuminosityOpacity + 0.06f, 1.0f);
|
||||
|
||||
var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity);
|
||||
var effectiveLuminosityOpacity = baseLuminosityOpacity * context.BackdropOpacity;
|
||||
|
||||
return new BackdropParameters(
|
||||
TintColor: isLight ? LightBaseColor : DarkBaseColor,
|
||||
FallbackColor: isLight ? LightBaseColor : DarkBaseColor,
|
||||
TintOpacity: 0.5f,
|
||||
LuminosityOpacity: isLight ? 0.9f : 0.96f);
|
||||
EffectiveOpacity: effectiveOpacity,
|
||||
EffectiveLuminosityOpacity: effectiveLuminosityOpacity,
|
||||
Style: backdropStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Input parameters for theme computation, passed to theme providers.
|
||||
/// </summary>
|
||||
internal sealed record ThemeContext
|
||||
{
|
||||
public ElementTheme Theme { get; init; }
|
||||
@@ -21,4 +25,8 @@ internal sealed record ThemeContext
|
||||
public double BackgroundImageOpacity { get; init; }
|
||||
|
||||
public int? ColorIntensity { get; init; }
|
||||
|
||||
public BackdropStyle? BackdropStyle { get; init; }
|
||||
|
||||
public float BackdropOpacity { get; init; } = 1.0f;
|
||||
}
|
||||
|
||||
@@ -72,10 +72,13 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
|
||||
}
|
||||
|
||||
// provider selection
|
||||
var intensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100);
|
||||
IThemeProvider provider = intensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image
|
||||
? _colorfulThemeProvider
|
||||
: _normalThemeProvider;
|
||||
var themeColorIntensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100);
|
||||
var imageTintIntensity = Math.Clamp(_settings.BackgroundImageTintIntensity, 0, 100);
|
||||
var effectiveColorIntensity = _settings.ColorizationMode == ColorizationMode.Image
|
||||
? imageTintIntensity
|
||||
: themeColorIntensity;
|
||||
|
||||
IThemeProvider provider = UseColorfulProvider(effectiveColorIntensity) ? _colorfulThemeProvider : _normalThemeProvider;
|
||||
|
||||
// Calculate values
|
||||
var tint = _settings.ColorizationMode switch
|
||||
@@ -96,32 +99,39 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
|
||||
};
|
||||
var opacity = Math.Clamp(_settings.BackgroundImageOpacity, 0, 100) / 100.0;
|
||||
|
||||
// create context and offload to actual theme provider
|
||||
// create input and offload to actual theme provider
|
||||
var context = new ThemeContext
|
||||
{
|
||||
Tint = tint,
|
||||
ColorIntensity = intensity,
|
||||
ColorIntensity = effectiveColorIntensity,
|
||||
Theme = effectiveTheme,
|
||||
BackgroundImageSource = imageSource,
|
||||
BackgroundImageStretch = stretch,
|
||||
BackgroundImageOpacity = opacity,
|
||||
BackdropStyle = _settings.BackdropStyle,
|
||||
BackdropOpacity = Math.Clamp(_settings.BackdropOpacity, 0, 100) / 100f,
|
||||
};
|
||||
var backdrop = provider.GetAcrylicBackdrop(context);
|
||||
var backdrop = provider.GetBackdropParameters(context);
|
||||
var blur = _settings.BackgroundImageBlurAmount;
|
||||
var brightness = _settings.BackgroundImageBrightness;
|
||||
|
||||
// Create public snapshot (no provider!)
|
||||
var hasColorization = effectiveColorIntensity > 0
|
||||
&& _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image;
|
||||
|
||||
var snapshot = new ThemeSnapshot
|
||||
{
|
||||
Tint = tint,
|
||||
TintIntensity = intensity / 100f,
|
||||
TintIntensity = effectiveColorIntensity / 100f,
|
||||
Theme = effectiveTheme,
|
||||
BackgroundImageSource = imageSource,
|
||||
BackgroundImageStretch = stretch,
|
||||
BackgroundImageOpacity = opacity,
|
||||
BackdropParameters = backdrop,
|
||||
BackdropOpacity = context.BackdropOpacity,
|
||||
BlurAmount = blur,
|
||||
BackgroundBrightness = brightness / 100f,
|
||||
HasColorization = hasColorization,
|
||||
};
|
||||
|
||||
// Bundle with provider for internal use
|
||||
@@ -138,6 +148,12 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
|
||||
ThemeChanged?.Invoke(this, new ThemeChangedEventArgs());
|
||||
}
|
||||
|
||||
private bool UseColorfulProvider(int effectiveColorIntensity)
|
||||
{
|
||||
return _settings.ColorizationMode == ColorizationMode.Image
|
||||
|| (effectiveColorIntensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor);
|
||||
}
|
||||
|
||||
private static BitmapImage? LoadImageSafe(string? path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
@@ -195,13 +211,15 @@ internal sealed partial class ThemeService : IThemeService, IDisposable
|
||||
{
|
||||
Tint = Colors.Transparent,
|
||||
Theme = ElementTheme.Light,
|
||||
BackdropParameters = new AcrylicBackdropParameters(Colors.Black, Colors.Black, 0.5f, 0.5f),
|
||||
BackdropParameters = new BackdropParameters(Colors.Black, Colors.Black, EffectiveOpacity: 0.5f, EffectiveLuminosityOpacity: 0.5f),
|
||||
BackdropOpacity = 1.0f,
|
||||
BackgroundImageOpacity = 1,
|
||||
BackgroundImageSource = null,
|
||||
BackgroundImageStretch = Stretch.Fill,
|
||||
BlurAmount = 0,
|
||||
TintIntensity = 1.0f,
|
||||
BackgroundBrightness = 0,
|
||||
HasColorization = false,
|
||||
},
|
||||
Provider = _normalThemeProvider,
|
||||
};
|
||||
|
||||
@@ -22,18 +22,50 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<ptControls:ScreenPreview Margin="0,0,0,16" HorizontalAlignment="Left">
|
||||
<ptControls:CommandPalettePreview
|
||||
PreviewBackgroundColor="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintColor, Mode=OneWay}"
|
||||
PreviewBackgroundImageBlurAmount="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBlurAmount, Mode=OneWay}"
|
||||
PreviewBackgroundImageBrightness="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBrightness, Mode=OneWay}"
|
||||
PreviewBackgroundImageFit="{x:Bind ViewModel.Appearance.BackgroundImageFit, Mode=OneWay}"
|
||||
PreviewBackgroundImageSource="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageSource, Mode=OneWay}"
|
||||
PreviewBackgroundImageTint="{x:Bind ViewModel.Appearance.EffectiveThemeColor, Mode=OneWay}"
|
||||
PreviewBackgroundImageTintIntensity="{x:Bind ViewModel.Appearance.ColorIntensity, Mode=OneWay}"
|
||||
PreviewBackgroundOpacity="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintOpacity, Mode=OneWay}"
|
||||
RequestedTheme="{x:Bind ViewModel.Appearance.EffectiveTheme, Mode=OneWay}" />
|
||||
</ptControls:ScreenPreview>
|
||||
<StackPanel
|
||||
Margin="0,0,0,16"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Horizontal"
|
||||
Spacing="16">
|
||||
<ptControls:ScreenPreview>
|
||||
<ptControls:CommandPalettePreview
|
||||
PreviewBackdropStyle="{x:Bind ViewModel.Appearance.EffectiveBackdropStyle, Mode=OneWay}"
|
||||
PreviewBackgroundColor="{x:Bind ViewModel.Appearance.EffectiveBackdrop.TintColor, Mode=OneWay}"
|
||||
PreviewBackgroundImageBlurAmount="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBlurAmount, Mode=OneWay}"
|
||||
PreviewBackgroundImageBrightness="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageBrightness, Mode=OneWay}"
|
||||
PreviewBackgroundImageFit="{x:Bind ViewModel.Appearance.BackgroundImageFit, Mode=OneWay}"
|
||||
PreviewBackgroundImageOpacity="{x:Bind ViewModel.Appearance.EffectiveImageOpacity, Mode=OneWay}"
|
||||
PreviewBackgroundImageSource="{x:Bind ViewModel.Appearance.EffectiveBackgroundImageSource, Mode=OneWay}"
|
||||
PreviewBackgroundImageTint="{x:Bind ViewModel.Appearance.EffectiveThemeColor, Mode=OneWay}"
|
||||
PreviewBackgroundImageTintIntensity="{x:Bind ViewModel.Appearance.EffectiveTintIntensity, Mode=OneWay}"
|
||||
PreviewEffectiveOpacity="{x:Bind ViewModel.Appearance.EffectiveBackdrop.EffectiveOpacity, Mode=OneWay}"
|
||||
RequestedTheme="{x:Bind ViewModel.Appearance.EffectiveTheme, Mode=OneWay}" />
|
||||
</ptControls:ScreenPreview>
|
||||
<StackPanel VerticalAlignment="Bottom" Spacing="8">
|
||||
<Button
|
||||
x:Uid="Settings_AppearancePage_OpenCommandPaletteButton"
|
||||
MinWidth="200"
|
||||
HorizontalContentAlignment="Left"
|
||||
Click="OpenCommandPalette_Click"
|
||||
Style="{StaticResource SubtleButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
<TextBlock x:Uid="Settings_AppearancePage_OpenCommandPaletteButton_Text" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button
|
||||
x:Uid="Settings_AppearancePage_ResetAppearanceButton"
|
||||
MinWidth="200"
|
||||
HorizontalContentAlignment="Left"
|
||||
Command="{x:Bind ViewModel.Appearance.ResetAppearanceSettingsCommand}"
|
||||
Style="{StaticResource SubtleButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
<TextBlock x:Uid="Settings_AppearancePage_ResetAppearanceButton_Text" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_AppTheme_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.Appearance.ThemeIndex, Mode=TwoWay}">
|
||||
@@ -62,19 +94,67 @@
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="Settings_GeneralPage_BackdropStyle_SettingsCard"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsExpanded="{x:Bind ViewModel.Appearance.IsBackdropOpacityVisible, Mode=OneWay}">
|
||||
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.Appearance.BackdropStyleIndex, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Acrylic" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Transparent" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_Mica" />
|
||||
<!-- Hidden: preview not working well, kept to preserve index mapping -->
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_AcrylicThin" Visibility="Collapsed" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_BackdropStyle_MicaAlt" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<!-- Mica description (no opacity control) -->
|
||||
<controls:SettingsCard
|
||||
x:Uid="Settings_GeneralPage_MicaBackdrop_SettingsCard"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
ContentAlignment="Vertical"
|
||||
Visibility="{x:Bind ViewModel.Appearance.IsMicaBackdropDescriptionVisible, Mode=OneWay}">
|
||||
<TextBlock
|
||||
x:Uid="Settings_GeneralPage_MicaBackdrop_DescriptionTextBlock"
|
||||
Margin="24"
|
||||
HorizontalAlignment="Stretch"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
HorizontalTextAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</controls:SettingsCard>
|
||||
<!-- Opacity slider (for non-Mica styles) -->
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackdropOpacity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsBackdropOpacityVisible, Mode=OneWay}">
|
||||
<Slider
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
StepFrequency="1"
|
||||
Value="{x:Bind ViewModel.Appearance.BackdropOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="Settings_GeneralPage_Background_SettingsExpander"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.Appearance.IsBackgroundSettingsEnabled, Mode=OneWay}"
|
||||
IsExpanded="{x:Bind ViewModel.Appearance.IsColorizationDetailsExpanded, Mode=TwoWay}">
|
||||
<ComboBox
|
||||
x:Uid="Settings_GeneralPage_ColorizationMode"
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind ViewModel.Appearance.ColorizationModeIndex, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_None" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_WindowsAccent" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_CustomColor" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_Image" />
|
||||
</ComboBox>
|
||||
<Grid>
|
||||
<ComboBox
|
||||
x:Uid="Settings_GeneralPage_ColorizationMode"
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind ViewModel.Appearance.ColorizationModeIndex, Mode=TwoWay}"
|
||||
Visibility="{x:Bind ViewModel.Appearance.IsBackgroundSettingsEnabled, Mode=OneWay}">
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_None" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_WindowsAccent" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_CustomColor" />
|
||||
<ComboBoxItem x:Uid="Settings_GeneralPage_ColorizationMode_Image" />
|
||||
</ComboBox>
|
||||
<TextBlock
|
||||
x:Uid="Settings_GeneralPage_Background_NotAvailable"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Visibility="{x:Bind ViewModel.Appearance.IsBackgroundNotAvailableVisible, Mode=OneWay}" />
|
||||
</Grid>
|
||||
<controls:SettingsExpander.Items>
|
||||
<!-- none -->
|
||||
<controls:SettingsCard
|
||||
@@ -155,7 +235,7 @@
|
||||
PaletteColors="{x:Bind ViewModel.Appearance.Swatches}"
|
||||
SelectedColor="{x:Bind ViewModel.Appearance.ThemeColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsCustomTintIntensityVisible, Mode=OneWay}">
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsColorIntensityVisible, Mode=OneWay}">
|
||||
<Slider
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
Maximum="100"
|
||||
@@ -163,9 +243,17 @@
|
||||
StepFrequency="1"
|
||||
Value="{x:Bind ViewModel.Appearance.ColorIntensity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_ImageTintIntensity_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsImageTintIntensityVisible, Mode=OneWay}">
|
||||
<Slider
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
StepFrequency="1"
|
||||
Value="{x:Bind ViewModel.Appearance.BackgroundImageTintIntensity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Reset background image properties -->
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundImage_ResetProperties_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsBackgroundControlsVisible, Mode=OneWay}">
|
||||
<!-- Reset appearance properties -->
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_BackgroundImage_ResetProperties_SettingsCard" Visibility="{x:Bind ViewModel.Appearance.IsResetButtonVisible, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<Button x:Uid="Settings_GeneralPage_Background_ResetImagePropertiesButton" Command="{x:Bind ViewModel.Appearance.ResetBackgroundImagePropertiesCommand}" />
|
||||
</StackPanel>
|
||||
|
||||
@@ -3,8 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.Events;
|
||||
using Microsoft.CmdPal.UI.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI;
|
||||
@@ -12,6 +17,7 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Documents;
|
||||
using Microsoft.Windows.Storage.Pickers;
|
||||
using Windows.Win32.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Settings;
|
||||
|
||||
@@ -86,4 +92,9 @@ public sealed partial class AppearancePage : Page
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OpenCommandPalette_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<HotkeySummonMessage>(new(string.Empty, HWND.Null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -577,6 +577,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="Settings_GeneralPage_BackgroundTintIntensity_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Color intensity</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ImageTintIntensity_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Color intensity</value>
|
||||
</data>
|
||||
<data name="OptionalColorPickerButton_UnsetTextBlock.Text" xml:space="preserve">
|
||||
<value>Choose color</value>
|
||||
</data>
|
||||
@@ -668,7 +671,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<value>Background image</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_NoBackground_DescriptionTextBlock.Text" xml:space="preserve">
|
||||
<value>No settings</value>
|
||||
<value>No additional settings are available.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_Background_SettingsExpander.Header" xml:space="preserve">
|
||||
<value>Background</value>
|
||||
@@ -676,6 +679,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="Settings_GeneralPage_Background_SettingsExpander.Description" xml:space="preserve">
|
||||
<value>Choose a custom background color or image</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_Background_NotAvailable.Text" xml:space="preserve">
|
||||
<value>Not available with Mica</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_WindowsAccentColor_SettingsCard.Header" xml:space="preserve">
|
||||
<value>System accent color</value>
|
||||
</data>
|
||||
@@ -692,7 +698,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<value>Restore defaults</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_Background_ResetImagePropertiesButton.Content" xml:space="preserve">
|
||||
<value>Reset</value>
|
||||
<value>Reset image settings</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_WindowsAccentColor_SettingsCard_Description1.Text" xml:space="preserve">
|
||||
<value>Change the system accent in Windows Settings:</value>
|
||||
@@ -727,4 +733,45 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="Settings_GeneralPage_VersionNo" xml:space="preserve">
|
||||
<value>Version {0}</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropOpacity_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Opacity</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Material</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Select the visual material used for the window background</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_Acrylic.Content" xml:space="preserve">
|
||||
<value>Acrylic (default)</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_Transparent.Content" xml:space="preserve">
|
||||
<value>Transparent</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_Mica.Content" xml:space="preserve">
|
||||
<value>Mica</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_AcrylicThin.Content" xml:space="preserve">
|
||||
<value>Thin Acrylic</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackdropStyle_MicaAlt.Content" xml:space="preserve">
|
||||
<value>Mica Alt</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_MicaBackdrop_DescriptionTextBlock.Text" xml:space="preserve">
|
||||
<value>Mica automatically adapts to your desktop wallpaper. Custom backgrounds and opacity settings are not available for this material.</value>
|
||||
</data>
|
||||
<data name="Settings_AppearancePage_OpenCommandPaletteButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Open Command Palette</value>
|
||||
<comment>Button to open the Command Palette window to preview appearance changes</comment>
|
||||
</data>
|
||||
<data name="Settings_AppearancePage_OpenCommandPaletteButton_Text.Text" xml:space="preserve">
|
||||
<value>Open Command Palette</value>
|
||||
</data>
|
||||
<data name="Settings_AppearancePage_ResetAppearanceButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Reset appearance settings</value>
|
||||
<comment>Button to reset all appearance settings to their default values</comment>
|
||||
</data>
|
||||
<data name="Settings_AppearancePage_ResetAppearanceButton_Text.Text" xml:space="preserve">
|
||||
<value>Reset to defaults</value>
|
||||
</data>
|
||||
</root>
|
||||
Reference in New Issue
Block a user