From 02950244d4d070175f5f88527e20f9847290d270 Mon Sep 17 00:00:00 2001 From: davidkallesen Date: Fri, 8 May 2026 12:54:27 +0200 Subject: [PATCH 1/3] fix(theming): replace VSM with ControlTemplate.Triggers on ToolBar ToggleButton style CommonStates and CheckStates VisualStateGroups both animated Border.Background.Color, so MouseOver overwrote Checked's color and the empty Normal state never restored it on mouse-leave. This caused the Checked appearance to disappear on hover and made the initial-checked state unreliable on first render. Replaces the colliding VSM animations with ControlTemplate.Triggers plus a MultiTrigger for the IsChecked + IsMouseOver combination. Triggers compose deterministically and fix both symptoms across every ToolBar ToggleButton/CheckBox/RadioButton in the library. --- .../Styles/BaseControls/ToolBar.xaml | 71 +++++++------------ 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/src/Atc.Wpf.Theming/Styles/BaseControls/ToolBar.xaml b/src/Atc.Wpf.Theming/Styles/BaseControls/ToolBar.xaml index d8f8e7b6..dae46430 100644 --- a/src/Atc.Wpf.Theming/Styles/BaseControls/ToolBar.xaml +++ b/src/Atc.Wpf.Theming/Styles/BaseControls/ToolBar.xaml @@ -16,53 +16,32 @@ HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + From e95f33e7618fc773427dbfec08b0b364c3dc721b Mon Sep 17 00:00:00 2001 From: davidkallesen Date: Fri, 8 May 2026 12:54:37 +0200 Subject: [PATCH 2/3] docs(terminalviewer): add keyboard shortcuts section to readme Documents the 11 shortcuts wired in TerminalViewer.xaml's UserControl.InputBindings (Ctrl+F/L/S/G/P, F3, Shift+F3, Esc, Ctrl++/=, Ctrl+-, Ctrl+0) so consumers can discover them without reading the XAML. --- .../Viewers/TerminalViewer_Readme.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Atc.Wpf.Components/Viewers/TerminalViewer_Readme.md b/src/Atc.Wpf.Components/Viewers/TerminalViewer_Readme.md index d9a4641f..1c2ce9a3 100644 --- a/src/Atc.Wpf.Components/Viewers/TerminalViewer_Readme.md +++ b/src/Atc.Wpf.Components/Viewers/TerminalViewer_Readme.md @@ -73,6 +73,26 @@ terminalViewer.Terms3 = new List { "TRACE", "VERBOSE" }; | `CopyToClipboardCommand` | Copy all terminal content to clipboard | | `ClearScreenCommand` | Clear all terminal output | +## ⌨️ Keyboard Shortcuts + +Shortcuts fire when the `TerminalViewer` (or any of its descendants) has keyboard focus. They are wired via `UserControl.InputBindings` in the control's XAML, so they require no setup by the host. + +| Shortcut | Action | +|----------|--------| +| `Ctrl+F` | Focus the search box | +| `Ctrl+L` | Clear the screen | +| `Ctrl+S` | Export visible content to `.txt` / `.log` | +| `Ctrl+G` | Jump back to the live tail (when detached) | +| `Ctrl+P` | Pause / resume incoming lines | +| `F3` | Jump to next search match | +| `Shift+F3` | Jump to previous search match | +| `Esc` | Clear the current search | +| `Ctrl++` / `Ctrl+=` | Zoom in (font size) | +| `Ctrl+-` | Zoom out (font size) | +| `Ctrl+0` | Reset zoom to default | + +The zoom shortcuts accept both the main keyboard row and the numeric keypad (`Ctrl+NumPad +`, `Ctrl+NumPad -`, `Ctrl+NumPad 0`). + ## 📝 Notes - Data arrives via messenger events (`TerminalReceivedDataEventArgs`) From e1995683ec5e8353c35f1b99006d2b248a3bd9f1 Mon Sep 17 00:00:00 2001 From: davidkallesen Date: Fri, 8 May 2026 12:55:35 +0200 Subject: [PATCH 3/3] refactor(resources): reorganize resx files using feature-cohesion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inventory showed ~80% of keys in Atc.Wpf.Controls/Resources/Miscellaneous.resx were referenced by exactly one consumer assembly. They were feature-specific strings that just happened to live in the central pool. Reorganize the 99 keys + Word.resx (160 keys) so each string lives with the feature that owns it, and only truly cross-cutting strings stay central. Phase 1 — Move Word.resx to Atc.Wpf foundation * Word.{resx,da-DK.resx,de-DE.resx,Designer.cs} moved from Atc.Wpf.Controls/Resources to Atc.Wpf/Resources (namespace Atc.Wpf.Resources) * All consumer ResxName= and Word.X references updated; global using added where needed * Cleans up 'Atc.Wpf.Controls.Resources' from Forms global using (no longer needed there) Phase 2 — Pull feature strings down to feature assemblies * Atc.Wpf.UndoRedo/Resources/Miscellaneous.resx (new, 4 keys: UndoAll, RedoAll, ClearHistory, MarkSaved) * Atc.Wpf.Forms/Resources/Miscellaneous.resx (new, 7 keys: Font*, TimeZone) * Atc.Wpf.Components/Resources/TerminalViewer.resx (new, 22 keys: TerminalViewer + Zoom + Export*) * Atc.Wpf.Components/Resources/JsonViewer.resx (new, 10 keys: JsonType*, errors) * Atc.Wpf.Components/Resources/DualListSelector.resx (new, 12 keys: Move*, Filter, ItemCount*) * Atc.Wpf.Components/Resources/Miscellaneous.resx (new, 12 keys: AppMonitor + Print + Flyout + shared) * FieldIsRequired removed from Atc.Wpf.Controls Misc (already in Atc.Wpf.Forms/Validations.resx) Phase 3 — Slim shared keys up to Atc.Wpf * Atc.Wpf/Resources/Miscellaneous.resx (new, 16 truly shared keys: ApplicationSettings, PleaseWait, SelectFile, CopyAllToClipboard, etc.) * Atc.Wpf.Controls/Resources/Miscellaneous.resx slimmed to 11 Controls-specific keys (Color picker + Pixel/Thickness) C# disambiguation pattern (matches existing ThemingMiscellaneous convention) * File-level using aliases (SharedMisc, ControlsMiscellaneous, FormsMiscellaneous, ComponentsMisc, TerminalViewerStrings, JsonViewerStrings, DualListSelectorStrings) where multiple Miscellaneous classes are in scope * XAML always uses fully-qualified ResxName; xmlns:resources mappings adjusted per file Incidental fixes * da-DK Cancel: 'Fortryd' -> 'Annuller' (Word.resx; 'Fortryd' is the Undo translation) * de-DE Locked: 'Verschlossen' -> 'Gesperrt' (better for UI control state) * de-DE Redo: 'Redo' -> 'Wiederherstellen' (was untranslated English) * da-DK Minute: 'Minute' -> 'Minut' (was English typo) * Atc.Wpf.Network/Resources: added StartIpExample, EndIpExample, PortsExample (replaces hardcoded watermarks in NetworkScannerSettingsView) Build: full Release (warnings-as-errors), 0/0. Tests: 1908 passing. --- .../Atc.Wpf.Components.csproj | 74 ++ .../BasicApplicationSettingsDialogBox.xaml | 5 +- ...icApplicationSettingsDialogBoxViewModel.cs | 6 +- src/Atc.Wpf.Components/Flyouts/Flyout.xaml | 7 +- src/Atc.Wpf.Components/GlobalUsings.cs | 2 +- .../Monitoring/ApplicationMonitorView.xaml | 28 +- .../Monitoring/ApplicationMonitorViewModel.cs | 8 +- .../Printing/PrintPreviewWindow.xaml | 13 +- .../Progressing/BusyIndicatorManager.cs | 2 +- .../Resources/DualListSelector.Designer.cs | 171 +++++ .../Resources/DualListSelector.da-DK.resx | 97 +++ .../Resources/DualListSelector.de-DE.resx | 97 +++ .../Resources/DualListSelector.resx | 97 +++ .../Resources/JsonViewer.Designer.cs | 154 ++++ .../Resources/JsonViewer.da-DK.resx | 92 +++ .../Resources/JsonViewer.de-DE.resx | 92 +++ .../Resources/JsonViewer.resx | 92 +++ .../Resources/Miscellaneous.Designer.cs | 172 +++++ .../Resources/Miscellaneous.da-DK.resx | 98 +++ .../Resources/Miscellaneous.de-DE.resx | 98 +++ .../Resources/Miscellaneous.resx | 98 +++ .../Resources/TerminalViewer.Designer.cs | 262 +++++++ .../Resources/TerminalViewer.da-DK.resx | 128 ++++ .../Resources/TerminalViewer.de-DE.resx | 128 ++++ .../Resources/TerminalViewer.resx | 128 ++++ .../Selectors/DualListSelector.cs | 10 +- .../Selectors/DualListSelector.xaml | 44 +- .../BasicApplicationSettingsView.xaml | 2 +- .../Viewers/JsonViewer.xaml | 30 +- .../Viewers/JsonViewer.xaml.cs | 9 +- .../Viewers/TerminalViewer.xaml | 43 +- .../Viewers/TerminalViewer.xaml.cs | 9 +- .../Zoom/ZoomBrowserView.xaml | 10 +- src/Atc.Wpf.Controls/Atc.Wpf.Controls.csproj | 15 - src/Atc.Wpf.Controls/GlobalUsings.cs | 1 + src/Atc.Wpf.Controls/Inputs/PixelSizeBox.xaml | 5 +- src/Atc.Wpf.Controls/Inputs/RichTextBoxEx.cs | 4 +- src/Atc.Wpf.Controls/Inputs/ThicknessBox.xaml | 9 +- .../Pickers/DirectoryPicker.xaml.cs | 4 +- .../Pickers/FilePicker.xaml.cs | 4 +- .../Progressing/BusyOverlay.cs | 4 +- .../Progressing/BusyOverlay.xaml | 4 +- .../Resources/Miscellaneous.Designer.cs | 713 +----------------- .../Resources/Miscellaneous.da-DK.resx | 251 +----- .../Resources/Miscellaneous.de-DE.resx | 251 +----- .../Resources/Miscellaneous.resx | 251 +----- src/Atc.Wpf.Forms/Atc.Wpf.Forms.csproj | 15 + .../BaseControls/ClockPanelPicker.xaml | 4 +- .../BaseControls/FontPicker.xaml | 4 +- .../Dialogs/ColorPickerDialogBox.xaml.cs | 4 +- .../Dialogs/DialogBoxSettings.cs | 10 +- .../Dialogs/FontPickerDialogBox.xaml.cs | 4 +- .../FontEditing/AdvancedFontPicker.xaml | 62 +- src/Atc.Wpf.Forms/GlobalUsings.cs | 2 +- src/Atc.Wpf.Forms/LabelTextInfo.xaml | 4 +- src/Atc.Wpf.Forms/LabelTextInfo.xaml.cs | 4 +- src/Atc.Wpf.Forms/LabelTimeZonePicker.xaml | 2 +- .../Resources/Miscellaneous.Designer.cs | 126 ++++ .../Resources/Miscellaneous.da-DK.resx | 82 ++ .../Resources/Miscellaneous.de-DE.resx | 82 ++ .../Resources/Miscellaneous.resx | 82 ++ .../Selectors/LabelCountrySelector.xaml.cs | 6 +- .../Selectors/LabelFontFamilySelector.xaml.cs | 8 +- .../Selectors/LabelLanguageSelector.xaml.cs | 6 +- .../LabelWellKnownColorSelector.xaml.cs | 6 +- .../Resources/Resources.Designer.cs | 29 +- .../Resources/Resources.da-DK.resx | 9 + .../Resources/Resources.de-DE.resx | 9 + src/Atc.Wpf.Network/Resources/Resources.resx | 9 + .../Scanner/NetworkScannerSettingsView.xaml | 6 +- src/Atc.Wpf.UndoRedo/Atc.Wpf.UndoRedo.csproj | 23 + src/Atc.Wpf.UndoRedo/GlobalUsings.cs | 1 - .../Resources/Miscellaneous.Designer.cs | 99 +++ .../Resources/Miscellaneous.da-DK.resx | 132 ++++ .../Resources/Miscellaneous.de-DE.resx | 132 ++++ .../Resources/Miscellaneous.resx | 132 ++++ src/Atc.Wpf.UndoRedo/UndoRedoHistoryView.xaml | 12 +- .../UndoRedoHistoryViewModel.cs | 4 +- src/Atc.Wpf/Atc.Wpf.csproj | 34 + .../Resources/Miscellaneous.Designer.cs | 207 +++++ .../Resources/Miscellaneous.da-DK.resx | 109 +++ .../Resources/Miscellaneous.de-DE.resx | 109 +++ src/Atc.Wpf/Resources/Miscellaneous.resx | 109 +++ .../Resources/Word.Designer.cs | 159 +++- .../Resources/Word.da-DK.resx | 39 + .../Resources/Word.de-DE.resx | 43 +- .../Resources/Word.resx | 39 + 87 files changed, 4142 insertions(+), 1638 deletions(-) create mode 100644 src/Atc.Wpf.Components/Resources/DualListSelector.Designer.cs create mode 100644 src/Atc.Wpf.Components/Resources/DualListSelector.da-DK.resx create mode 100644 src/Atc.Wpf.Components/Resources/DualListSelector.de-DE.resx create mode 100644 src/Atc.Wpf.Components/Resources/DualListSelector.resx create mode 100644 src/Atc.Wpf.Components/Resources/JsonViewer.Designer.cs create mode 100644 src/Atc.Wpf.Components/Resources/JsonViewer.da-DK.resx create mode 100644 src/Atc.Wpf.Components/Resources/JsonViewer.de-DE.resx create mode 100644 src/Atc.Wpf.Components/Resources/JsonViewer.resx create mode 100644 src/Atc.Wpf.Components/Resources/Miscellaneous.Designer.cs create mode 100644 src/Atc.Wpf.Components/Resources/Miscellaneous.da-DK.resx create mode 100644 src/Atc.Wpf.Components/Resources/Miscellaneous.de-DE.resx create mode 100644 src/Atc.Wpf.Components/Resources/Miscellaneous.resx create mode 100644 src/Atc.Wpf.Components/Resources/TerminalViewer.Designer.cs create mode 100644 src/Atc.Wpf.Components/Resources/TerminalViewer.da-DK.resx create mode 100644 src/Atc.Wpf.Components/Resources/TerminalViewer.de-DE.resx create mode 100644 src/Atc.Wpf.Components/Resources/TerminalViewer.resx create mode 100644 src/Atc.Wpf.Forms/Resources/Miscellaneous.Designer.cs create mode 100644 src/Atc.Wpf.Forms/Resources/Miscellaneous.da-DK.resx create mode 100644 src/Atc.Wpf.Forms/Resources/Miscellaneous.de-DE.resx create mode 100644 src/Atc.Wpf.Forms/Resources/Miscellaneous.resx create mode 100644 src/Atc.Wpf.UndoRedo/Resources/Miscellaneous.Designer.cs create mode 100644 src/Atc.Wpf.UndoRedo/Resources/Miscellaneous.da-DK.resx create mode 100644 src/Atc.Wpf.UndoRedo/Resources/Miscellaneous.de-DE.resx create mode 100644 src/Atc.Wpf.UndoRedo/Resources/Miscellaneous.resx create mode 100644 src/Atc.Wpf/Resources/Miscellaneous.Designer.cs create mode 100644 src/Atc.Wpf/Resources/Miscellaneous.da-DK.resx create mode 100644 src/Atc.Wpf/Resources/Miscellaneous.de-DE.resx create mode 100644 src/Atc.Wpf/Resources/Miscellaneous.resx rename src/{Atc.Wpf.Controls => Atc.Wpf}/Resources/Word.Designer.cs (91%) rename src/{Atc.Wpf.Controls => Atc.Wpf}/Resources/Word.da-DK.resx (94%) rename src/{Atc.Wpf.Controls => Atc.Wpf}/Resources/Word.de-DE.resx (93%) rename src/{Atc.Wpf.Controls => Atc.Wpf}/Resources/Word.resx (94%) diff --git a/src/Atc.Wpf.Components/Atc.Wpf.Components.csproj b/src/Atc.Wpf.Components/Atc.Wpf.Components.csproj index 4e9995d8..22b1504b 100644 --- a/src/Atc.Wpf.Components/Atc.Wpf.Components.csproj +++ b/src/Atc.Wpf.Components/Atc.Wpf.Components.csproj @@ -57,4 +57,78 @@ + + + DualListSelector.resx + True + True + + + JsonViewer.resx + True + True + + + Miscellaneous.resx + True + True + + + TerminalViewer.resx + True + True + + + + + + Designer + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + DualListSelector.Designer.cs + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + JsonViewer.Designer.cs + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + Miscellaneous.Designer.cs + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + Designer + PublicResXFileCodeGenerator + + + TerminalViewer.Designer.cs + PublicResXFileCodeGenerator + + + \ No newline at end of file diff --git a/src/Atc.Wpf.Components/Dialogs/BasicApplicationSettingsDialogBox.xaml b/src/Atc.Wpf.Components/Dialogs/BasicApplicationSettingsDialogBox.xaml index 99b24bb0..d7213213 100644 --- a/src/Atc.Wpf.Components/Dialogs/BasicApplicationSettingsDialogBox.xaml +++ b/src/Atc.Wpf.Components/Dialogs/BasicApplicationSettingsDialogBox.xaml @@ -3,6 +3,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:atc="https://github.com/atc-net/atc-wpf/tree/main/schemas" + xmlns:atcTranslation="https://github.com/atc-net/atc-wpf/tree/main/schemas/translations" xmlns:atcValueConverters="https://github.com/atc-net/atc-wpf/tree/main/schemas/value-converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:dialogs="clr-namespace:Atc.Wpf.Theming.Themes.Dialogs;assembly=Atc.Wpf.Theming" @@ -51,7 +52,7 @@ Background="{DynamicResource AtcApps.Brushes.ThemeBackground}" Command="{Binding Path=OkCommand}" CommandParameter="{Binding ElementName=DialogApplicationSettings}" - Content="OK" + Content="{atcTranslation:Resx ResxName=Atc.Wpf.Resources.Word, Key=Ok}" Foreground="{DynamicResource AtcApps.Brushes.Text}" IsDefault="True" /> @@ -34,13 +34,13 @@ Height="16" Margin="1,1,0,0" Source="pack://application:,,,/Atc.Wpf.Components;component/Resources/Images/scrollrefresh.png" - ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Controls.Resources.Miscellaneous, + ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Resources.Word, Key=Auto}" /> @@ -78,7 +78,7 @@ Height="16" Margin="1,1,0,0" Source="pack://application:,,,/Atc.Wpf.Components;component/Resources/Images/error.png" - ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Controls.Resources.Miscellaneous, + ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Resources.Word, Key=Errors}" /> @@ -88,7 +88,7 @@ Height="16" Margin="1,1,0,0" Source="pack://application:,,,/Atc.Wpf.Components;component/Resources/Images/warning.png" - ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Controls.Resources.Miscellaneous, + ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Resources.Word, Key=Warnings}" /> @@ -98,7 +98,7 @@ Height="16" Margin="1,1,0,0" Source="pack://application:,,,/Atc.Wpf.Components;component/Resources/Images/information.png" - ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Controls.Resources.Miscellaneous, + ToolTip="{atcTranslation:Resx ResxName=Atc.Wpf.Resources.Word, Key=Information}" /> @@ -115,7 +115,7 @@