Files
DP44/enriched-qwen3-coder-next/Common/DTS.CommonCore/Themes.md
2026-04-17 14:55:32 -04:00

89 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- Common/DTS.CommonCore/Themes/CommonStyles.xaml.cs
- Common/DTS.CommonCore/Themes/BrushesAndColors.cs
generated_at: "2026-04-16T02:17:03.753064+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "0e615cefd8a8a763"
---
# Themes
## Documentation: `DTS.Common` Theme & Style Utilities
---
### 1. Purpose
This module provides shared, reusable styling infrastructure for the applications UI, specifically focusing on two concerns: (1) centralized access to theme-defined `Brush` and `Color` resources via static properties with caching to avoid repeated resource lookups, and (2) a centralized event handler for tooltip events that publishes help text via Prisms `IEventAggregator`. It serves as a single source of truth for visual styling constants, decoupling UI components from explicit resource key strings and enabling consistent theming across the application. The module does *not* define styles itself but consumes them from external resource dictionaries (e.g., `brushes.xaml` and implicit theme dictionaries).
---
### 2. Public Interface
#### `CommonStyles` (partial class, non-static)
- **`void ToolTipEventHandler(object sender, ToolTipEventArgs e)`**
Marks the tooltip event as handled (`e.Handled = true`) and publishes a `HelpTextEventArg` instance (containing the original `sender` and `ToolTipEventArgs`) to the `HelpTextEvent` via the `IEventAggregator`. This enables decoupled help-text display logic elsewhere in the application.
#### `BrushesAndColors` (abstract, non-instantiable)
A static utility class exposing ~40 read-only properties returning cached `Brush` or `Color` resources. All properties follow the naming pattern `Brush_*` or `Color_*`. Key examples:
- **`Brush_ApplicationTileExport`** → `SolidColorBrush`
- **`Brush_ApplicationStatus_Failed`** → `SolidColorBrush`
- **`Brush_Dimmed_Text`** → `SolidColorBrush`
- **`Brush_Table_AlternatingRowBackground`** → `SolidColorBrush`
- **`Brush_FlatControlPressedBackground`** → `Brush`
- **`Brush_Transparent`** → `Brush` (created on-demand as `new SolidColorBrush(Colors.Transparent)`)
- **`Brush_Error`**, **`Brush_Warning`**, **`Brush_Attention`**, **`Brush_NoError`** → `SolidColorBrush`
- **`Brush_Realtime_OSC_SELECTED`**, **`Brush_Realtime_METER_UNSELECTED`**, etc. → `Brush`
- **`Brush_ApplicationStatusPowerRed`**, **`Brush_ApplicationStatusPowerYellow`**, **`Brush_ApplicationStatusPowerGreen`** → `SolidColorBrush`
- **`Color_ActionBackground`**, **`Color_ItemForeground`**, etc. → `Color` (not cached; fetched fresh each call)
> **Note**: Properties are implemented with lazy initialization and caching (where applicable). The `BrushesAndColors` class is `abstract` to prevent instantiation.
---
### 3. Invariants
- **Resource Availability**: All `Brush`/`Color` resources must be defined in the applications resource dictionaries (e.g., `Themes/brushes.xaml` or merged dictionaries). If a resource is missing, `Application.Current.FindResource(...)` will throw a `ResourceReferenceKeyNotFoundException` at runtime (not caught in the source).
- **Immutability**: All retrieved `Brush` instances are frozen (`Freeze()`) to make them immutable and thread-safe for rendering. This is enforced via `.Freeze()` after retrieval.
- **Caching Semantics**:
- Most `Brush` properties cache their value in a private static field and reuse it on subsequent calls.
- `Color` properties do *not* cache; they call `Application.Current.FindResource(...)` every time.
- The `_resourceDictionary` field is shared across all resource lookups that fall back to `brushes.xaml`, but is only initialized on first use for those specific properties.
- **Null Safety**: Some properties guard against null resources (e.g., `Brush_FlatControlDisabledForeground`, `Brush_ApplicationStatus_Waiting`) and return `null` if the resource is missing. Others do not (e.g., `Brush_Error`), risking exceptions.
---
### 4. Dependencies
#### External Dependencies (Imports/Usings)
- **`System.Windows`** → WPF core types (`Application`, `ResourceDictionary`, `Brush`, `SolidColorBrush`, `Colors`).
- **`System.Windows.Controls`** → `ToolTipEventArgs`.
- **`Microsoft.Practices.ServiceLocation`** → `ServiceLocator.Current`.
- **`Microsoft.Practices.Prism.Events`** → `IEventAggregator`, `IEvent`.
- **`DTS.Common.Events`** → `HelpTextEvent`, `HelpTextEventArg` (consumed but not defined here).
#### Internal Dependencies
- **`DTS.Common.Events.HelpTextEvent`** and **`HelpTextEventArg`** must be defined elsewhere in `DTS.Common.Events`.
- **`Themes/brushes.xaml`** → Required resource dictionary for fallback lookups (used by `Brush_NoError`, `Brush_Error`, `Brush_Warning`, `Brush_Attention`).
- **Application-level resource dictionaries** → Must define all referenced resource keys (e.g., `"Brush_ApplicationStatus_Failed"`, `"Color_ActionBackground"`, etc.).
#### Consumers (Inferred)
- Any UI component needing consistent styling (e.g., tiles, tables, status indicators) likely references `BrushesAndColors` properties directly in XAML or code-behind.
- Any component needing help-text support on tooltips likely subscribes to `HelpTextEvent` and attaches `CommonStyles.ToolTipEventHandler` to tooltip events.
---
### 5. Gotchas
- **Theme Switching Incompatibility**: As noted in the `BrushesAndColors` XML doc comment, static caching means brushes may become stale if the theme changes at runtime (e.g., via dynamic resource dictionary replacement). The comment suggests this is currently non-issue because themes are not actively used.
- **Inconsistent Caching Strategy**: `Color` properties do *not* cache, while most `Brush` properties do. This is likely unintentional and could lead to repeated resource lookups for colors.
- **Typo in Resource Key**: In `Brush_ApplicationStatus_Failed_SystemProcess`, the resource key is `"Brush_ApplicationStauts_Failed_SystemProcess"` (missing "a" in "Status"). This may cause runtime failures if the key is misspelled in the XAML resource dictionary.
- **Null Handling Inconsistency**: Some properties (e.g., `Brush_FlatControlDisabledForeground`) return `null` if the resource is missing; others (e.g., `Brush_Error`) do not check for null after `FindResource`, risking exceptions.
- **Double Initialization Risk in `Brush_Warning`**: The `Brush_Warning` property incorrectly assigns to `_brushError` instead of `_brushWarning` in its getter (`_brushError = ...`). This is a bug: it overwrites the `_brushError` cache and returns the warning brush as `_brushError`, while `_brushWarning` remains `null`.
- **Thread Safety**: While frozen brushes are thread-safe, the lazy initialization logic (e.g., `if (null == _brush_X) ...`) is *not* thread-safe. Concurrent access during first initialization could result in multiple lookups or race conditions.
- **Hardcoded Resource Paths**: The fallback `ResourceDictionary` for `Brush_NoError`, `Brush_Error`, etc., uses a hardcoded pack URI (`/DTS.Common;component/Themes/brushes.xaml`). This assumes the dictionary is embedded as a resource in the `DTS.Common` assembly.
> **None identified from source alone** — *except where explicitly called out above.*