Skip to content

Commit 155f40b

Browse files
authored
Feature: Added support for changing backdrop material (#12534)
1 parent f1815df commit 155f40b

File tree

11 files changed

+211
-36
lines changed

11 files changed

+211
-36
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Microsoft.UI.Composition;
2+
using Microsoft.UI.Composition.SystemBackdrops;
3+
using Microsoft.UI.Xaml;
4+
using Microsoft.UI.Xaml.Media;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Diagnostics.CodeAnalysis;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
12+
namespace Files.App.Helpers
13+
{
14+
internal sealed class AppSystemBackdrop : SystemBackdrop
15+
{
16+
private bool isSecondaryWindow;
17+
private IUserSettingsService userSettingsService;
18+
private ISystemBackdropControllerWithTargets? controller;
19+
private ICompositionSupportsSystemBackdrop target;
20+
private XamlRoot root;
21+
22+
public AppSystemBackdrop(bool isSecondaryWindow = false)
23+
{
24+
this.isSecondaryWindow = isSecondaryWindow;
25+
userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
26+
userSettingsService.OnSettingChangedEvent += OnSettingChanged;
27+
}
28+
29+
[MemberNotNull(nameof(target), nameof(root))]
30+
protected override void OnTargetConnected(ICompositionSupportsSystemBackdrop connectedTarget, XamlRoot xamlRoot)
31+
{
32+
if (target is not null)
33+
throw new InvalidOperationException("AppSystemBackdrop cannot be used with more than one target");
34+
35+
base.OnTargetConnected(connectedTarget, xamlRoot);
36+
this.target = connectedTarget;
37+
this.root = xamlRoot;
38+
controller = GetSystemBackdropController(userSettingsService.AppearanceSettingsService.AppThemeBackdropMaterial);
39+
controller?.SetSystemBackdropConfiguration(GetDefaultSystemBackdropConfiguration(connectedTarget, xamlRoot));
40+
controller?.AddSystemBackdropTarget(connectedTarget);
41+
}
42+
43+
protected override void OnTargetDisconnected(ICompositionSupportsSystemBackdrop disconnectedTarget)
44+
{
45+
base.OnTargetDisconnected(disconnectedTarget);
46+
this.target = null!;
47+
this.root = null!;
48+
controller?.RemoveSystemBackdropTarget(disconnectedTarget);
49+
controller?.Dispose();
50+
userSettingsService.OnSettingChangedEvent -= OnSettingChanged;
51+
}
52+
53+
private void OnSettingChanged(object? sender, Shared.EventArguments.SettingChangedEventArgs e)
54+
{
55+
if (target is null)
56+
return;
57+
58+
switch (e.SettingName)
59+
{
60+
case nameof(IAppearanceSettingsService.AppThemeBackdropMaterial):
61+
controller?.RemoveAllSystemBackdropTargets();
62+
controller?.Dispose();
63+
var newController = GetSystemBackdropController((BackdropMaterialType)e.NewValue!);
64+
newController?.SetSystemBackdropConfiguration(GetDefaultSystemBackdropConfiguration(target, root));
65+
newController?.AddSystemBackdropTarget(target);
66+
controller = newController;
67+
break;
68+
}
69+
}
70+
71+
private ISystemBackdropControllerWithTargets? GetSystemBackdropController(BackdropMaterialType backdropType)
72+
{
73+
if (isSecondaryWindow && backdropType == BackdropMaterialType.MicaAlt)
74+
backdropType = BackdropMaterialType.Mica;
75+
76+
switch (backdropType)
77+
{
78+
case BackdropMaterialType.MicaAlt:
79+
return new MicaController()
80+
{
81+
Kind = MicaKind.BaseAlt
82+
};
83+
84+
case BackdropMaterialType.Mica:
85+
return new MicaController()
86+
{
87+
Kind = MicaKind.Base
88+
};
89+
90+
case BackdropMaterialType.Acrylic:
91+
return new DesktopAcrylicController();
92+
93+
default:
94+
return null;
95+
}
96+
}
97+
}
98+
}

src/Files.App/Helpers/FilePropertiesHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
115115
propertiesWindow.Width = 800;
116116
propertiesWindow.Height = 550;
117117
propertiesWindow.Content = frame;
118-
propertiesWindow.SystemBackdrop = new MicaBackdrop();
118+
propertiesWindow.SystemBackdrop = new AppSystemBackdrop(true);
119119

120120
var appWindow = propertiesWindow.AppWindow;
121121
appWindow.Title = "Properties".GetLocalizedResource();

src/Files.App/MainWindow.xaml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,4 @@
66
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
88
xmlns:winuiex="using:WinUIEx"
9-
mc:Ignorable="d">
10-
11-
<!-- Mica Alt -->
12-
<winuiex:WindowEx.Backdrop>
13-
<winuiex:MicaSystemBackdrop Kind="BaseAlt" />
14-
</winuiex:WindowEx.Backdrop>
15-
16-
</winuiex:WindowEx>
9+
mc:Ignorable="d" />

src/Files.App/MainWindow.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4+
using Files.App.ServicesImplementation.Settings;
45
using Files.App.UserControls.MultitaskingControl;
56
using Microsoft.UI;
7+
using Microsoft.UI.Composition.SystemBackdrops;
68
using Microsoft.UI.Windowing;
79
using Microsoft.UI.Xaml.Controls;
10+
using Microsoft.UI.Xaml.Media;
811
using Microsoft.UI.Xaml.Media.Animation;
912
using Microsoft.UI.Xaml.Navigation;
1013
using System.IO;
@@ -158,6 +161,9 @@ private Frame EnsureWindowIsInitialized()
158161
// just ensure that the window is active
159162
if (!(App.Window.Content is Frame rootFrame))
160163
{
164+
// Set system backdrop
165+
this.SystemBackdrop = new AppSystemBackdrop();
166+
161167
// Create a Frame to act as the navigation context and navigate to the first page
162168
rootFrame = new Frame();
163169
rootFrame.CacheSize = 1;

src/Files.App/ServicesImplementation/Settings/AppearanceSettingsService.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Files.Backend.Services.Settings;
66
using Files.Shared.EventArguments;
77
using Microsoft.AppCenter.Analytics;
8+
using Microsoft.UI.Composition.SystemBackdrops;
89
using System;
910

1011
namespace Files.App.ServicesImplementation.Settings
@@ -70,6 +71,13 @@ public String AppThemeFontFamily
7071
set => Set(value);
7172
}
7273

74+
/// <inheritdoc/>
75+
public BackdropMaterialType AppThemeBackdropMaterial
76+
{
77+
get => Get(BackdropMaterialType.MicaAlt);
78+
set => Set(value);
79+
}
80+
7381
protected override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e)
7482
{
7583
switch (e.SettingName)
@@ -79,6 +87,7 @@ protected override void RaiseOnSettingChangedEvent(object sender, SettingChanged
7987
case nameof(AppThemeAddressBarBackgroundColor):
8088
case nameof(AppThemeSidebarBackgroundColor):
8189
case nameof(AppThemeFileAreaBackgroundColor):
90+
case nameof(AppThemeBackdropMaterial):
8291
Analytics.TrackEvent($"Set {e.SettingName} to {e.NewValue}");
8392
break;
8493
}

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3344,4 +3344,19 @@
33443344
<value>(multiple values)</value>
33453345
<comment>Text indicating that multiple selected files have different metadata values.</comment>
33463346
</data>
3347+
<data name="Acrylic" xml:space="preserve">
3348+
<value>Acrylic</value>
3349+
</data>
3350+
<data name="Mica" xml:space="preserve">
3351+
<value>Mica</value>
3352+
</data>
3353+
<data name="MicaAlt" xml:space="preserve">
3354+
<value>Mica Alt</value>
3355+
</data>
3356+
<data name="BackdropMaterial" xml:space="preserve">
3357+
<value>Backdrop Material</value>
3358+
</data>
3359+
<data name="Solid" xml:space="preserve">
3360+
<value>Solid</value>
3361+
</data>
33473362
</root>

src/Files.App/ViewModels/Settings/AppearanceViewModel.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using CommunityToolkit.WinUI.Helpers;
55
using Files.Backend.Services;
6+
using Microsoft.UI.Composition.SystemBackdrops;
67
using Microsoft.UI.Xaml;
78

89
namespace Files.App.ViewModels.Settings
@@ -13,6 +14,7 @@ public class AppearanceViewModel : ObservableObject
1314
private readonly IResourcesService ResourcesService;
1415

1516
public List<string> Themes { get; private set; }
17+
public Dictionary<BackdropMaterialType, string> BackdropMaterialTypes { get; private set; } = new();
1618

1719
public ObservableCollection<AppThemeResourceItem> AppThemeResources { get; }
1820

@@ -28,6 +30,16 @@ public AppearanceViewModel(IUserSettingsService userSettingsService, IResourcesS
2830
"DarkTheme".GetLocalizedResource()
2931
};
3032

33+
// TODO: Re-add Solid and regular Mica when theming is revamped
34+
//BackdropMaterialTypes.Add(BackdropMaterialType.Solid, "Solid".GetLocalizedResource());
35+
36+
BackdropMaterialTypes.Add(BackdropMaterialType.Acrylic, "Acrylic".GetLocalizedResource());
37+
38+
//BackdropMaterialTypes.Add(BackdropMaterialType.Mica, "Mica".GetLocalizedResource());
39+
BackdropMaterialTypes.Add(BackdropMaterialType.MicaAlt, "MicaAlt".GetLocalizedResource());
40+
41+
selectedBackdropMaterial = BackdropMaterialTypes[UserSettingsService.AppearanceSettingsService.AppThemeBackdropMaterial];
42+
3143
AppThemeResources = AppThemeResourceFactory.AppThemeResources;
3244

3345
UpdateSelectedResource();
@@ -129,5 +141,19 @@ public string AppThemeBackgroundColor
129141
}
130142
}
131143
}
144+
145+
private string selectedBackdropMaterial;
146+
public string SelectedBackdropMaterial
147+
{
148+
get => selectedBackdropMaterial;
149+
set
150+
{
151+
if(SetProperty(ref selectedBackdropMaterial, value))
152+
{
153+
UserSettingsService.AppearanceSettingsService.AppThemeBackdropMaterial = BackdropMaterialTypes.First(e => e.Value == value).Key;
154+
}
155+
}
156+
}
157+
132158
}
133159
}

src/Files.App/Views/Settings/AppearancePage.xaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@
115115
SelectedIndex="{x:Bind ViewModel.SelectedThemeIndex, Mode=TwoWay}" />
116116
</local:SettingsBlockControl>
117117

118+
<!-- Backdrop Material -->
119+
<local:SettingsBlockControl Title="{helpers:ResourceString Name=BackdropMaterial}" HorizontalAlignment="Stretch">
120+
<local:SettingsBlockControl.Icon>
121+
<FontIcon Glyph="&#xEF1F;" />
122+
</local:SettingsBlockControl.Icon>
123+
<ComboBox
124+
AutomationProperties.Name="{helpers:ResourceString Name=BackdropMaterial}"
125+
ItemsSource="{x:Bind ViewModel.BackdropMaterialTypes.Values}"
126+
SelectedItem="{x:Bind ViewModel.SelectedBackdropMaterial, Mode=TwoWay}" />
127+
</local:SettingsBlockControl>
128+
118129
<!-- App Background -->
119130
<local:SettingsBlockControl
120131
Title="{helpers:ResourceString Name=Background}"

src/Files.App/Views/Settings/GeneralPage.xaml

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,33 +57,6 @@
5757
</ComboBox.ItemTemplate>
5858
</ComboBox>
5959
</local:SettingsBlockControl>
60-
<!-- Restart Teaching Tip -->
61-
<TeachingTip
62-
IsLightDismissEnabled="True"
63-
IsOpen="{x:Bind ViewModel.ShowRestartControl, Mode=TwoWay}"
64-
Subtitle="{helpers:ResourceString Name=RestartNotificationText/Text}"
65-
Target="{x:Bind AppLanguagesComboBox}">
66-
<StackPanel
67-
x:Name="ButtonsStackPanel"
68-
Padding="0,8,0,0"
69-
HorizontalAlignment="Right"
70-
Orientation="Horizontal"
71-
Spacing="8">
72-
73-
<Button
74-
x:Name="YesButton"
75-
MinWidth="140"
76-
Command="{x:Bind ViewModel.RestartCommand, Mode=OneWay}"
77-
Content="{helpers:ResourceString Name=Yes}"
78-
Style="{ThemeResource AccentButtonStyle}" />
79-
80-
<Button
81-
x:Name="NoButton"
82-
MinWidth="140"
83-
Command="{x:Bind ViewModel.CancelRestartCommand, Mode=OneWay}"
84-
Content="{helpers:ResourceString Name=No}" />
85-
</StackPanel>
86-
</TeachingTip>
8760

8861
<!-- Date settings -->
8962
<local:SettingsBlockControl
@@ -348,5 +321,33 @@
348321
Style="{StaticResource RightAlignedToggleSwitchStyle}" />
349322
</local:SettingsBlockControl>
350323
</StackPanel>
324+
325+
<!-- Restart Teaching Tip -->
326+
<TeachingTip
327+
IsLightDismissEnabled="True"
328+
IsOpen="{x:Bind ViewModel.ShowRestartControl, Mode=TwoWay}"
329+
Subtitle="{helpers:ResourceString Name=RestartNotificationText/Text}"
330+
Target="{x:Bind AppLanguagesComboBox}">
331+
<StackPanel
332+
x:Name="ButtonsStackPanel"
333+
Padding="0,8,0,0"
334+
HorizontalAlignment="Right"
335+
Orientation="Horizontal"
336+
Spacing="8">
337+
338+
<Button
339+
x:Name="YesButton"
340+
MinWidth="140"
341+
Command="{x:Bind ViewModel.RestartCommand, Mode=OneWay}"
342+
Content="{helpers:ResourceString Name=Yes}"
343+
Style="{ThemeResource AccentButtonStyle}" />
344+
345+
<Button
346+
x:Name="NoButton"
347+
MinWidth="140"
348+
Command="{x:Bind ViewModel.CancelRestartCommand, Mode=OneWay}"
349+
Content="{helpers:ResourceString Name=No}" />
350+
</StackPanel>
351+
</TeachingTip>
351352
</Grid>
352353
</Page>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Files.Backend.Enums
2+
{
3+
public enum BackdropMaterialType
4+
{
5+
Solid,
6+
Mica,
7+
MicaAlt,
8+
Acrylic
9+
}
10+
}

src/Files.Backend/Services/Settings/IAppearanceSettingsService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4+
using Files.Backend.Enums;
45
using System;
56
using System.ComponentModel;
67

@@ -51,5 +52,10 @@ public interface IAppearanceSettingsService : IBaseSettingsService, INotifyPrope
5152
/// Gets or sets a value for the app theme font family.
5253
/// </summary>
5354
String AppThemeFontFamily { get; set; }
55+
56+
/// <summary>
57+
/// Gets or sets a value for the theme system backdrop.
58+
/// </summary>
59+
BackdropMaterialType AppThemeBackdropMaterial { get; set; }
5460
}
5561
}

0 commit comments

Comments
 (0)