Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/Files.App.Controls/ThemedIcon/Data/ThemedIconColorType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Controls
{
/// <summary>
/// Defines the IconColorTypes for <see cref="ThemedIcon"/> which sets the visual state
/// to use the correct brush values which match system signal colors.
/// </summary>
public enum ThemedIconColorType
{
None,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Normal. Default Value.
/// </summary>
Normal,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Critical.
/// </summary>
Critical,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Caution.
/// </summary>
Caution,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Success.
/// </summary>
Success,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Neutral.
/// </summary>
Neutral,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Accent.
/// </summary>
Accent,

/// <summary>
/// Icon color type of <see cref="ThemedIcon"/> is Custom. Used in combination
/// with the IconColor and Foreground brushes.
/// </summary>
Custom
}
}
28 changes: 28 additions & 0 deletions src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayerType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Controls
{
/// <summary>
/// Defines LayerTypes for <see cref="ThemedIcon"/>.
/// </summary>
public enum ThemedIconLayerType
{
/// <summary>
/// The LayerType uses the Base color. Default state.
/// </summary>
Base,
/// <summary>
/// The LayerType uses the Alt color.
/// </summary>
Alt,
/// <summary>
/// The LayerType uses an Accented color.
/// </summary>
Accent,
/// <summary>
/// The LayerType uses a contrasting color for the Accented color.
/// </summary>
AccentContrast,
}
}
12 changes: 12 additions & 0 deletions src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Controls
{
/// <summary>
/// A collection of Layers for the ThemedIcon's Layered IconType
/// </summary>
public sealed class ThemedIconLayers : List<ThemedIconLayer>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Controls
{
/// <summary>
/// Defines IconTypes for <see cref="ThemedIcon"/>.
/// </summary>
public enum ToggleBehaviors
{
/// <summary>
/// Auto enables the ThemedIcon to listen to owner control states.
/// </summary>
Auto,

/// <summary>
/// On will always use the ThemedIcon's Toggle state
/// </summary>
On,

/// <summary>
/// Off will not use the ThemedIcon's Toggle state
/// </summary>
Off,
}
}
21 changes: 21 additions & 0 deletions src/Files.App.Controls/ThemedIcon/Data/ThemedIconTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Controls
{
/// <summary>
/// Defines IconTypes for <see cref="ThemedIcon"/>.
/// </summary>
public enum ThemedIconTypes
{
/// <summary>
/// Icon type of <see cref="ThemedIcon"/> is Outline.
/// </summary>
Outline,

/// <summary>
/// Icon type of <see cref="ThemedIcon"/> is Layered.
/// </summary>
Layered,
}
}
118 changes: 57 additions & 61 deletions src/Files.App.Controls/ThemedIcon/ThemedIcon.Consts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,65 @@

namespace Files.App.Controls
{
// Template Parts
[TemplatePart(Name = FilledPathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = OutlinePathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = LayeredPathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = LayeredPathCanvas, Type = typeof(Canvas))]

// Icon Type Visual States
[TemplateVisualState(Name = OutlineTypeStateName, GroupName = IconTypeStateGroupName)]
[TemplateVisualState(Name = LayeredTypeStateName, GroupName = IconTypeStateGroupName)]
[TemplateVisualState(Name = FilledTypeStateName, GroupName = IconTypeStateGroupName)]
// Template Parts
[TemplatePart(Name = FilledPathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = OutlinePathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = LayeredPathIconViewBox, Type = typeof(Viewbox))]
[TemplatePart(Name = LayeredPathCanvas, Type = typeof(Canvas))]
// Icon Type Visual States
[TemplateVisualState(Name = OutlineTypeStateName, GroupName = IconTypeStateGroupName)]
[TemplateVisualState(Name = LayeredTypeStateName, GroupName = IconTypeStateGroupName)]
[TemplateVisualState(Name = FilledTypeStateName, GroupName = IconTypeStateGroupName)]
// Icon Color Visual States
[TemplateVisualState(Name = NormalStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CriticalStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CautionStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = SuccessStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = NeutralStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = AccentStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CustomColorStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = ToggleStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = DisabledColorStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = DisabledToggleColorStateName, GroupName = IconColorStateGroupName)]
// Icon IsEnabled Visual States
[TemplateVisualState(Name = EnabledStateName, GroupName = EnabledStateGroupName)]
[TemplateVisualState(Name = DisabledStateName, GroupName = EnabledStateGroupName)]
public partial class ThemedIcon
{
// Visual State Group Names
internal const string IconTypeStateGroupName = "IconTypeStates";
internal const string IconColorStateGroupName = "IconColorStates";
internal const string EnabledStateGroupName = "EnabledStates";

// Icon Color Visual States
[TemplateVisualState(Name = NormalStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CriticalStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CautionStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = SuccessStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = NeutralStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = AccentStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = CustomColorStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = ToggleStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = DisabledColorStateName, GroupName = IconColorStateGroupName)]
[TemplateVisualState(Name = DisabledToggleColorStateName, GroupName = IconColorStateGroupName)]
// "Icon Type" Visual State Names
internal const string OutlineTypeStateName = "Outline";
internal const string FilledTypeStateName = "Filled";
internal const string LayeredTypeStateName = "Layered";

// Icon IsEnabled Visual States
[TemplateVisualState(Name = EnabledStateName, GroupName = EnabledStateGroupName)]
[TemplateVisualState(Name = DisabledStateName, GroupName = EnabledStateGroupName)]
// "Icon State" Visual State Names
internal const string NormalStateName = "Normal";
internal const string CriticalStateName = "Critical";
internal const string CautionStateName = "Caution";
internal const string SuccessStateName = "Success";
internal const string NeutralStateName = "Neutral";
internal const string AccentStateName = "Accent";
internal const string CustomColorStateName = "Custom";
internal const string ToggleStateName = "Toggle";
internal const string DisabledColorStateName = "DisabledColor";
internal const string DisabledToggleColorStateName = "DisabledToggleColor";

public partial class ThemedIcon
{
// Visual State Group Names
internal const string IconTypeStateGroupName = "IconTypeStates";
internal const string IconColorStateGroupName = "IconColorStates";
internal const string EnabledStateGroupName = "EnabledStates";
// "Enabled" Visual State Names
internal const string EnabledStateName = "Enabled";
internal const string DisabledStateName = "Disabled";

// "Icon Type" Visual State Names
internal const string OutlineTypeStateName = "Outline";
internal const string FilledTypeStateName = "Filled";
internal const string LayeredTypeStateName = "Layered";
// ViewBox Controls
internal const string FilledPathIconViewBox = "PART_FilledIconViewBox";
internal const string OutlinePathIconViewBox = "PART_OutlineIconViewBox";
internal const string LayeredPathIconViewBox = "PART_LayeredIconViewBox";
internal const string LayeredPathCanvas = "PART_LayerCanvas";

// "Icon State" Visual State Names
internal const string NormalStateName = "Normal";
internal const string CriticalStateName = "Critical";
internal const string CautionStateName = "Caution";
internal const string SuccessStateName = "Success";
internal const string NeutralStateName = "Neutral";
internal const string AccentStateName = "Accent";
internal const string CustomColorStateName = "Custom";
internal const string ToggleStateName = "Toggle";
internal const string DisabledColorStateName = "DisabledColor";
internal const string DisabledToggleColorStateName = "DisabledToggleColor";

// "Enabled" Visual State Names
internal const string EnabledStateName = "Enabled";
internal const string DisabledStateName = "Disabled";

// ViewBox Controls
internal const string FilledPathIconViewBox = "PART_FilledIconViewBox";
internal const string OutlinePathIconViewBox = "PART_OutlineIconViewBox";
internal const string LayeredPathIconViewBox = "PART_LayeredIconViewBox";
internal const string LayeredPathCanvas = "PART_LayerCanvas";

// Path Controls
internal const string FilledIconPath = "PART_FilledPath";
internal const string OutlineIconPath = "PART_OutlinePath";
}
}
// Path Controls
internal const string FilledIconPath = "PART_FilledPath";
internal const string OutlineIconPath = "PART_OutlinePath";
}
}
62 changes: 62 additions & 0 deletions src/Files.App.Controls/ThemedIcon/ThemedIcon.Owner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;

namespace Files.App.Controls
{
public partial class ThemedIcon
{
private bool _isOwnerToggled;
private bool _isOwnerEnabled;

private Control? ownerControl = null;
private ToggleButton? ownerToggleButton = null;

private void FindOwnerControlStates()
{
if (this.FindAscendant<ToggleButton>() is ToggleButton toggleButton)
{
ownerToggleButton = toggleButton;

// IsChecked/IsToggled change aware
ownerToggleButton.Checked += OwnerControl_IsCheckedChanged;
ownerToggleButton.Unchecked += OwnerControl_IsCheckedChanged;
_isOwnerToggled = ownerToggleButton.IsChecked is true;
}

if (this.FindAscendant<Control>() is Control control)
{
ownerControl = control;

// IsEnabled change aware
ownerControl.IsEnabledChanged += OwnerControl_IsEnabledChanged;
_isOwnerEnabled = ownerControl.IsEnabled;

UpdateVisualStates();
}
}

private void OwnerControl_IsCheckedChanged(object sender, RoutedEventArgs e)
{
if (ownerToggleButton is null)
return;

_isOwnerToggled = ownerToggleButton.IsChecked is true;
UpdateVisualStates();

}

private void OwnerControl_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (ownerControl is null)
return;

_isOwnerEnabled = ownerControl.IsEnabled;
UpdateVisualStates();
}
}
}
Loading