| | | 1 | | namespace Allyaria.Theming.Helpers; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Represents a navigational context for resolving theming relationships across components, states, and style types in |
| | | 5 | | /// Allyaria theming engine. |
| | | 6 | | /// </summary> |
| | | 7 | | /// <remarks> |
| | | 8 | | /// <para> |
| | | 9 | | /// <see cref="ThemeNavigator" /> is used to describe combinations of component types, visual states, and theme |
| | | 10 | | /// variations. It provides fluent methods for building specific navigation contexts for theme updates, typically |
| | | 11 | | /// consumed by <see cref="ThemeUpdater" />. |
| | | 12 | | /// </para> |
| | | 13 | | /// <para> |
| | | 14 | | /// The static <see cref="Initialize" /> member provides an empty baseline instance that can be progressively |
| | | 15 | | /// specialized using the <c>Set*</c> methods. |
| | | 16 | | /// </para> |
| | | 17 | | /// </remarks> |
| | | 18 | | public readonly record struct ThemeNavigator( |
| | 12672 | 19 | | IReadOnlyList<ComponentType> ComponentTypes, |
| | 12615 | 20 | | IReadOnlyList<ThemeType> ThemeTypes, |
| | 13369 | 21 | | IReadOnlyList<ComponentState> ComponentStates, |
| | 25434 | 22 | | IReadOnlyList<StyleType> StyleTypes |
| | | 23 | | ) |
| | | 24 | | { |
| | | 25 | | /// <summary> |
| | | 26 | | /// Gets a base instance of <see cref="ThemeNavigator" /> with all internal lists initialized and empty. |
| | | 27 | | /// </summary> |
| | 1 | 28 | | public static readonly ThemeNavigator Initialize = new( |
| | 1 | 29 | | ComponentTypes: BuildList<ComponentType>(), |
| | 1 | 30 | | ThemeTypes: BuildList<ThemeType>(), |
| | 1 | 31 | | ComponentStates: BuildList<ComponentState>(), |
| | 1 | 32 | | StyleTypes: BuildList<StyleType>() |
| | 1 | 33 | | ); |
| | | 34 | | |
| | | 35 | | /// <summary> |
| | | 36 | | /// Builds a typed list of enum values, validating that the provided type is one of the supported theming enums ( |
| | | 37 | | /// <see cref="ComponentType" />, <see cref="ThemeType" />, <see cref="ComponentState" />, or <see cref="StyleType" |
| | | 38 | | /// </summary> |
| | | 39 | | /// <typeparam name="TEnum">The enum type to populate.</typeparam> |
| | | 40 | | /// <param name="items">The enum values to include in the list.</param> |
| | | 41 | | /// <returns>A new list containing the provided items, or an empty list if none were provided.</returns> |
| | | 42 | | /// <exception cref="AryArgumentException">Thrown if an unsupported enum type is used.</exception> |
| | | 43 | | private static List<TEnum> BuildList<TEnum>(params TEnum[] items) |
| | | 44 | | where TEnum : Enum |
| | | 45 | | { |
| | 26005 | 46 | | if (items.Length is 0) |
| | | 47 | | { |
| | 5 | 48 | | return new List<TEnum>(); |
| | | 49 | | } |
| | | 50 | | |
| | 26000 | 51 | | if (!(items[0] is ComponentState or ComponentType or ThemeType or StyleType)) |
| | | 52 | | { |
| | | 53 | | // Code Coverage: This is unreachable through all public methods. |
| | 0 | 54 | | throw new AryArgumentException(message: "Invalid enum type", argName: nameof(items)); |
| | | 55 | | } |
| | | 56 | | |
| | 26000 | 57 | | var list = new List<TEnum>(capacity: items.Length); |
| | 26000 | 58 | | list.AddRange(collection: items); |
| | | 59 | | |
| | 26000 | 60 | | return list; |
| | | 61 | | } |
| | | 62 | | |
| | | 63 | | /// <summary> |
| | | 64 | | /// Sets all component states except <see cref="ComponentState.Hidden" /> and <see cref="ComponentState.ReadOnly" /> |
| | | 65 | | /// </summary> |
| | | 66 | | /// <returns>A new <see cref="ThemeNavigator" /> instance with all interactive component states selected.</returns> |
| | | 67 | | public ThemeNavigator SetAllComponentStates() |
| | | 68 | | { |
| | 944 | 69 | | var states = Enum.GetValues<ComponentState>().ToList(); |
| | 944 | 70 | | states.Remove(item: ComponentState.Hidden); |
| | 944 | 71 | | states.Remove(item: ComponentState.ReadOnly); |
| | | 72 | | |
| | 944 | 73 | | return SetComponentStates(items: states.ToArray()); |
| | | 74 | | } |
| | | 75 | | |
| | | 76 | | /// <summary>Sets all available component types.</summary> |
| | | 77 | | /// <returns>A new <see cref="ThemeNavigator" /> with all <see cref="ComponentType" /> values applied.</returns> |
| | 1 | 78 | | public ThemeNavigator SetAllComponentTypes() => SetComponentTypes(items: Enum.GetValues<ComponentType>()); |
| | | 79 | | |
| | | 80 | | /// <summary>Sets all available style types.</summary> |
| | | 81 | | /// <returns>A new <see cref="ThemeNavigator" /> with all <see cref="StyleType" /> values applied.</returns> |
| | 1 | 82 | | public ThemeNavigator SetAllStyleTypes() => SetStyleTypes(items: Enum.GetValues<StyleType>()); |
| | | 83 | | |
| | | 84 | | /// <summary>Sets the component states for this navigator.</summary> |
| | | 85 | | /// <param name="items">An array of <see cref="ComponentState" /> values to include.</param> |
| | | 86 | | /// <returns>A new <see cref="ThemeNavigator" /> with the specified component states.</returns> |
| | | 87 | | public ThemeNavigator SetComponentStates(params ComponentState[] items) |
| | 6521 | 88 | | => this with |
| | 6521 | 89 | | { |
| | 6521 | 90 | | ComponentStates = BuildList(items: items) |
| | 6521 | 91 | | }; |
| | | 92 | | |
| | | 93 | | /// <summary>Sets the component types for this navigator.</summary> |
| | | 94 | | /// <param name="items">An array of <see cref="ComponentType" /> values to include.</param> |
| | | 95 | | /// <returns>A new <see cref="ThemeNavigator" /> with the specified component types.</returns> |
| | | 96 | | public ThemeNavigator SetComponentTypes(params ComponentType[] items) |
| | 6502 | 97 | | => this with |
| | 6502 | 98 | | { |
| | 6502 | 99 | | ComponentTypes = BuildList(items: items) |
| | 6502 | 100 | | }; |
| | | 101 | | |
| | | 102 | | /// <summary>Configures this navigator for high-contrast or standard light/dark theme variants.</summary> |
| | | 103 | | /// <param name="isHighContrast">Whether high-contrast themes should be targeted.</param> |
| | | 104 | | /// <returns>A new <see cref="ThemeNavigator" /> configured for the specified contrast context.</returns> |
| | | 105 | | internal ThemeNavigator SetContrastThemeTypes(bool isHighContrast) |
| | 945 | 106 | | => isHighContrast |
| | 945 | 107 | | ? SetThemeTypes(ThemeType.HighContrastLight, ThemeType.HighContrastDark) |
| | 945 | 108 | | : SetThemeTypes(ThemeType.Light, ThemeType.Dark); |
| | | 109 | | |
| | | 110 | | /// <summary>Sets the style types for this navigator.</summary> |
| | | 111 | | /// <param name="items">An array of <see cref="StyleType" /> values to include.</param> |
| | | 112 | | /// <returns>A new <see cref="ThemeNavigator" /> with the specified style types.</returns> |
| | | 113 | | public ThemeNavigator SetStyleTypes(params StyleType[] items) |
| | 6466 | 114 | | => this with |
| | 6466 | 115 | | { |
| | 6466 | 116 | | StyleTypes = BuildList(items: items) |
| | 6466 | 117 | | }; |
| | | 118 | | |
| | | 119 | | /// <summary> |
| | | 120 | | /// Sets the specific theme type to navigate, validating that system and high-contrast variants are excluded. |
| | | 121 | | /// </summary> |
| | | 122 | | /// <param name="themeType">The <see cref="ThemeType" /> to target.</param> |
| | | 123 | | /// <returns>A new <see cref="ThemeNavigator" /> configured with the specified theme type.</returns> |
| | | 124 | | /// <exception cref="AryArgumentException">Thrown if the specified theme type is invalid for this context.</exceptio |
| | | 125 | | public ThemeNavigator SetThemeType(ThemeType themeType) |
| | 26 | 126 | | => themeType is ThemeType.System or ThemeType.HighContrastDark or ThemeType.HighContrastLight |
| | 26 | 127 | | ? throw new AryArgumentException(message: "Invalid theme type", argName: nameof(themeType)) |
| | 26 | 128 | | : SetThemeTypes(items: themeType); |
| | | 129 | | |
| | | 130 | | /// <summary>Sets the theme types for this navigator.</summary> |
| | | 131 | | /// <param name="items">An array of <see cref="ThemeType" /> values to include.</param> |
| | | 132 | | /// <returns>A new <see cref="ThemeNavigator" /> configured with the specified theme types.</returns> |
| | | 133 | | internal ThemeNavigator SetThemeTypes(params ThemeType[] items) |
| | 6512 | 134 | | => this with |
| | 6512 | 135 | | { |
| | 6512 | 136 | | ThemeTypes = BuildList(items: items) |
| | 6512 | 137 | | }; |
| | | 138 | | } |