diff --git a/.editorconfig b/.editorconfig index eaeb81ba..1237dead 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 25-09-2023 +# Version: 1.0.1 +# Updated: 03-06-2024 # Location: Root # Distribution: DotNet8 # Inspired by: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options @@ -464,10 +464,45 @@ dotnet_diagnostic.MA0048.severity = error # https://github.com/atc-net dotnet_diagnostic.CA1014.severity = none # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/CA1014.md dotnet_diagnostic.CA1068.severity = error # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/CA1068.md dotnet_diagnostic.CA1305.severity = error +dotnet_diagnostic.CA1510.severity = suggestion # Use ArgumentNullException throw helper +dotnet_diagnostic.CA1511.severity = suggestion # Use ArgumentException throw helper +dotnet_diagnostic.CA1512.severity = suggestion # Use ArgumentOutOfRangeException throw helper +dotnet_diagnostic.CA1513.severity = suggestion # Use ObjectDisposedException throw helper +dotnet_diagnostic.CA1514.severity = error # Avoid redundant length argument dotnet_diagnostic.CA1707.severity = error # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/CA1707.md dotnet_diagnostic.CA1812.severity = none dotnet_diagnostic.CA1822.severity = suggestion +dotnet_diagnostic.CA1849.severity = error # Call async methods when in an async method +dotnet_diagnostic.CA1854.severity = suggestion # Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method +dotnet_diagnostic.CA1855.severity = suggestion # Prefer 'Clear' over 'Fill' +dotnet_diagnostic.CA1856.severity = error # Incorrect usage of ConstantExpected attribute +dotnet_diagnostic.CA1857.severity = suggestion # A constant is expected for the parameter +dotnet_diagnostic.CA1858.severity = suggestion # Use 'StartsWith' instead of 'IndexOf' +dotnet_diagnostic.CA1859.severity = suggestion # Use concrete types when possible for improved performance +dotnet_diagnostic.CA1860.severity = suggestion # Avoid using 'Enumerable.Any()' extension method +dotnet_diagnostic.CA1861.severity = suggestion # Avoid constant arrays as arguments +dotnet_diagnostic.CA1862.severity = error # Use the 'StringComparison' method overloads to perform case-insensitive string comparisons +dotnet_diagnostic.CA1863.severity = suggestion # Use 'CompositeFormat' +dotnet_diagnostic.CA1864.severity = suggestion # Prefer the 'IDictionary.TryAdd(TKey, TValue)' method +dotnet_diagnostic.CA1865.severity = suggestion # Use char overload +dotnet_diagnostic.CA1866.severity = suggestion # Use char overload +dotnet_diagnostic.CA1867.severity = suggestion # Use char overload +dotnet_diagnostic.CA1868.severity = suggestion # Unnecessary call to 'Contains(item)' +dotnet_diagnostic.CA1869.severity = suggestion # Cache and reuse 'JsonSerializerOptions' instances +dotnet_diagnostic.CA1870.severity = suggestion # Use a cached 'SearchValues' instance dotnet_diagnostic.CA2007.severity = suggestion # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/CA2007.md +dotnet_diagnostic.CA2017.severity = error # Parameter count mismatch +dotnet_diagnostic.CA2018.severity = error # The count argument to Buffer.BlockCopy should specify the number of bytes to copy +dotnet_diagnostic.CA2019.severity = error # ThreadStatic fields should not use inline initialization +dotnet_diagnostic.CA2021.severity = error # Don't call Enumerable.Cast or Enumerable.OfType with incompatible types +dotnet_diagnostic.CA2250.severity = suggestion # Use ThrowIfCancellationRequested +dotnet_diagnostic.CA2252.severity = suggestion # Opt-in to preview features should be used with caution +dotnet_diagnostic.CA2253.severity = error # Named placeholders should not be numeric values +dotnet_diagnostic.CA2254.severity = suggestion # Template should be a static expression +dotnet_diagnostic.CA2255.severity = suggestion # The ModuleInitializer attribute should not be used in libraries +dotnet_diagnostic.CA2259.severity = error # Ensure ThreadStatic is only used with static fields +dotnet_diagnostic.CA2260.severity = error # Implement generic math interfaces correctly +dotnet_diagnostic.CA2261.severity = error # Do not use ConfigureAwaitOptions.SuppressThrowing with Task dotnet_diagnostic.IDE0005.severity = warning # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/IDE0005.md dotnet_diagnostic.IDE0058.severity = none # https://github.com/atc-net/atc-coding-rules/blob/main/documentation/CodeAnalyzersRules/MicrosoftCodeAnalysis/IDE0058.md diff --git a/Directory.Build.props b/Directory.Build.props index f7b74544..30732a45 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,10 +45,10 @@ - + - + \ No newline at end of file diff --git a/sample/.editorconfig b/sample/.editorconfig index 325a0c97..f252e0e6 100644 --- a/sample/.editorconfig +++ b/sample/.editorconfig @@ -41,6 +41,11 @@ # StyleCop # https://github.com/DotNetAnalyzers/StyleCopAnalyzers +# SonarAnalyzer.CSharp +# https://rules.sonarsource.com/csharp + +dotnet_diagnostic.S1075.severity = none # Refactor your code not to use hardcoded absolute paths or URIs + ########################################## # Custom - Code Analyzers Rules diff --git a/sample/Atc.Wpf.Sample/.editorconfig b/sample/Atc.Wpf.Sample/.editorconfig index 821094ee..93ca8326 100644 --- a/sample/Atc.Wpf.Sample/.editorconfig +++ b/sample/Atc.Wpf.Sample/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/sample/Atc.Wpf.Sample/Atc.Wpf.Sample.csproj b/sample/Atc.Wpf.Sample/Atc.Wpf.Sample.csproj index 7f847246..9ded6d6f 100644 --- a/sample/Atc.Wpf.Sample/Atc.Wpf.Sample.csproj +++ b/sample/Atc.Wpf.Sample/Atc.Wpf.Sample.csproj @@ -50,7 +50,7 @@ - + diff --git a/sample/Atc.Wpf.Sample/SamplesWpf/Controls/Inputs/RichTextBoxExView.xaml b/sample/Atc.Wpf.Sample/SamplesWpfControls/BaseControls/RichTextBoxExView.xaml similarity index 97% rename from sample/Atc.Wpf.Sample/SamplesWpf/Controls/Inputs/RichTextBoxExView.xaml rename to sample/Atc.Wpf.Sample/SamplesWpfControls/BaseControls/RichTextBoxExView.xaml index bbf0fa7e..eabf91b0 100644 --- a/sample/Atc.Wpf.Sample/SamplesWpf/Controls/Inputs/RichTextBoxExView.xaml +++ b/sample/Atc.Wpf.Sample/SamplesWpfControls/BaseControls/RichTextBoxExView.xaml @@ -1,5 +1,5 @@ /// Interaction logic for RichTextBoxExView. diff --git a/sample/Atc.Wpf.Sample/SamplesWpfControlsTreeView.xaml b/sample/Atc.Wpf.Sample/SamplesWpfControlsTreeView.xaml index 04f7724d..398d65ca 100644 --- a/sample/Atc.Wpf.Sample/SamplesWpfControlsTreeView.xaml +++ b/sample/Atc.Wpf.Sample/SamplesWpfControlsTreeView.xaml @@ -60,7 +60,7 @@ Header="ColorPicker" IsExpanded="True" SamplePath="BaseControls.ColorPickerView" /> - + diff --git a/sample/Atc.Wpf.Sample/SamplesWpfTreeView.xaml b/sample/Atc.Wpf.Sample/SamplesWpfTreeView.xaml index 3af60824..a30ae640 100644 --- a/sample/Atc.Wpf.Sample/SamplesWpfTreeView.xaml +++ b/sample/Atc.Wpf.Sample/SamplesWpfTreeView.xaml @@ -14,10 +14,6 @@ - - - - diff --git a/src/Atc.Wpf.Controls.Sample/.editorconfig b/src/Atc.Wpf.Controls.Sample/.editorconfig index 821094ee..93ca8326 100644 --- a/src/Atc.Wpf.Controls.Sample/.editorconfig +++ b/src/Atc.Wpf.Controls.Sample/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/src/Atc.Wpf.Controls.Sample/Atc.Wpf.Controls.Sample.csproj b/src/Atc.Wpf.Controls.Sample/Atc.Wpf.Controls.Sample.csproj index 075c3886..ec8661d4 100644 --- a/src/Atc.Wpf.Controls.Sample/Atc.Wpf.Controls.Sample.csproj +++ b/src/Atc.Wpf.Controls.Sample/Atc.Wpf.Controls.Sample.csproj @@ -10,11 +10,12 @@ - + + diff --git a/src/Atc.Wpf.Controls/.editorconfig b/src/Atc.Wpf.Controls/.editorconfig index 821094ee..93ca8326 100644 --- a/src/Atc.Wpf.Controls/.editorconfig +++ b/src/Atc.Wpf.Controls/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/src/Atc.Wpf.Controls/AssemblyInfo.cs b/src/Atc.Wpf.Controls/AssemblyInfo.cs index d935820f..3de39f8d 100644 --- a/src/Atc.Wpf.Controls/AssemblyInfo.cs +++ b/src/Atc.Wpf.Controls/AssemblyInfo.cs @@ -2,11 +2,11 @@ [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] [assembly: XmlnsPrefix("https://github.com/atc-net/atc-wpf/tree/main/schemas", "atc")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.BaseControls")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Dialogs")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.LabelControls")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Layouts")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Notifications")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Progressing")] -[assembly: XmlnsDefinition(@"https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Viewers")] \ No newline at end of file +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.BaseControls")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Dialogs")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.LabelControls")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Layouts")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Notifications")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Progressing")] +[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Viewers")] \ No newline at end of file diff --git a/src/Atc.Wpf.Controls/Atc.Wpf.Controls.csproj b/src/Atc.Wpf.Controls/Atc.Wpf.Controls.csproj index 6f1b8f52..8b93ff15 100644 --- a/src/Atc.Wpf.Controls/Atc.Wpf.Controls.csproj +++ b/src/Atc.Wpf.Controls/Atc.Wpf.Controls.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Atc.Wpf/Controls/Inputs/RichTextBoxEx.cs b/src/Atc.Wpf.Controls/BaseControls/RichTextBoxEx.cs similarity index 72% rename from src/Atc.Wpf/Controls/Inputs/RichTextBoxEx.cs rename to src/Atc.Wpf.Controls/BaseControls/RichTextBoxEx.cs index 89d336cb..e1619f35 100644 --- a/src/Atc.Wpf/Controls/Inputs/RichTextBoxEx.cs +++ b/src/Atc.Wpf.Controls/BaseControls/RichTextBoxEx.cs @@ -1,11 +1,20 @@ -namespace Atc.Wpf.Controls.Inputs; +namespace Atc.Wpf.Controls.BaseControls; /// -/// RichTextBoxEx is a extension of the . +/// RichTextBoxEx is an extension of the . /// [SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "OK.")] public class RichTextBoxEx : RichTextBox { + public static readonly DependencyProperty ThemeModeProperty = DependencyProperty.Register( + nameof(ThemeMode), + typeof(ThemeMode), + typeof(RichTextBoxEx), + new FrameworkPropertyMetadata( + ThemeMode.Light, + FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, + OnThemeModeChanged)); + /// /// The text property. /// @@ -40,6 +49,22 @@ public class RichTextBoxEx : RichTextBox /// public RichTextBoxEx() { + var contextMenu = new ContextMenu(); + var copyMenuItem = new MenuItem + { + Header = Miscellaneous.CopyToClipboard, + Icon = new SvgImage + { + Width = 16, + Height = 16, + Source = "/Atc.Wpf.Controls;component/Resources/Icons/clipboard.svg", + }, + }; + copyMenuItem.Click += OnCopyToClipboardClick; + contextMenu.Items.Add(copyMenuItem); + ContextMenu = contextMenu; + + ThemeManager.Current.ThemeChanged += OnThemeChanged; } /// @@ -51,6 +76,18 @@ public RichTextBoxEx(FlowDocument document) { } + /// + /// Gets or sets the text. + /// + /// + /// The text. + /// + public ThemeMode ThemeMode + { + get => (ThemeMode)GetValue(ThemeModeProperty); + set => SetValue(ThemeModeProperty, value); + } + /// /// Gets or sets the text. /// @@ -140,11 +177,33 @@ protected override void OnTextChanged( UpdateTextFromDocument(); } - /// - /// Called when [text property changed]. - /// - /// The dependency object. - /// The instance containing the event data. + private void OnCopyToClipboardClick( + object sender, + RoutedEventArgs e) + => Clipboard.SetText(Text); + + private void OnThemeChanged( + object? sender, + ThemeChangedEventArgs e) + { + if (Enum.TryParse(e.NewTheme.BaseColorScheme, ignoreCase: false, out var themeModeValue)) + { + ThemeMode = themeModeValue; + } + } + + private static void OnThemeModeChanged( + DependencyObject d, + DependencyPropertyChangedEventArgs e) + { + if (d is not RichTextBoxEx richTextBoxEx) + { + return; + } + + richTextBoxEx.UpdateDocumentFromText(); + } + private static void OnTextChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -157,11 +216,6 @@ private static void OnTextChanged( richTextBoxEx.UpdateDocumentFromText(); } - /// - /// Coerces the text property. - /// - /// The dependency object. - /// The value. private static object CoerceText( DependencyObject d, object? value) @@ -169,11 +223,6 @@ private static object CoerceText( return value ?? string.Empty; } - /// - /// Called when [text formatter property changed]. - /// - /// The dependency object. - /// The instance containing the event data. private static void OnTextFormatterChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -188,9 +237,6 @@ private static void OnTextFormatterChanged( (ITextFormatter)e.NewValue); } - /// - /// Updates the text from document. - /// private void UpdateTextFromDocument() { if (preventTextUpdate) @@ -203,9 +249,6 @@ private void UpdateTextFromDocument() preventDocumentUpdate = false; } - /// - /// Updates the document from text. - /// private void UpdateDocumentFromText() { if (preventDocumentUpdate) @@ -214,7 +257,7 @@ private void UpdateDocumentFromText() } preventTextUpdate = true; - TextFormatter.SetText(Document, Text); + TextFormatter.SetText(Document, Text, ThemeMode); preventTextUpdate = false; } } \ No newline at end of file diff --git a/src/Atc.Wpf.Controls/GlobalUsings.cs b/src/Atc.Wpf.Controls/GlobalUsings.cs index 79763b41..19edf50c 100644 --- a/src/Atc.Wpf.Controls/GlobalUsings.cs +++ b/src/Atc.Wpf.Controls/GlobalUsings.cs @@ -41,6 +41,7 @@ global using Atc.Wpf.Controls.BaseControls.Internal; global using Atc.Wpf.Controls.ColorControls.Internal; global using Atc.Wpf.Controls.Dialogs; +global using Atc.Wpf.Controls.Documents.TextFormatters; global using Atc.Wpf.Controls.LabelControls; global using Atc.Wpf.Controls.LabelControls.Abstractions; global using Atc.Wpf.Controls.LabelControls.Enums; diff --git a/src/Atc.Wpf.FontIcons/.editorconfig b/src/Atc.Wpf.FontIcons/.editorconfig index 821094ee..93ca8326 100644 --- a/src/Atc.Wpf.FontIcons/.editorconfig +++ b/src/Atc.Wpf.FontIcons/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/src/Atc.Wpf.Theming/.editorconfig b/src/Atc.Wpf.Theming/.editorconfig index 821094ee..93ca8326 100644 --- a/src/Atc.Wpf.Theming/.editorconfig +++ b/src/Atc.Wpf.Theming/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/src/Atc.Wpf.Theming/Atc.Wpf.Theming.csproj b/src/Atc.Wpf.Theming/Atc.Wpf.Theming.csproj index 910f8289..6204ee9c 100644 --- a/src/Atc.Wpf.Theming/Atc.Wpf.Theming.csproj +++ b/src/Atc.Wpf.Theming/Atc.Wpf.Theming.csproj @@ -25,13 +25,13 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Atc.Wpf.Theming/Controls/Windows/WindowSettings.cs b/src/Atc.Wpf.Theming/Controls/Windows/WindowSettings.cs index a8d9ac55..95558a29 100644 --- a/src/Atc.Wpf.Theming/Controls/Windows/WindowSettings.cs +++ b/src/Atc.Wpf.Theming/Controls/Windows/WindowSettings.cs @@ -21,8 +21,8 @@ internal WINDOWPLACEMENT ToWindowPlacement() { length = (uint)Marshal.SizeOf(), showCmd = (SHOW_WINDOW_CMD)showCmd, - ptMinPosition = new POINT { x = (int)minPosition.X, y = (int)minPosition.Y }, - ptMaxPosition = new POINT { x = (int)maxPosition.X, y = (int)maxPosition.Y }, + ptMinPosition = new System.Drawing.Point { X = (int)minPosition.X, Y = (int)minPosition.Y }, + ptMaxPosition = new System.Drawing.Point { X = (int)maxPosition.X, Y = (int)maxPosition.Y }, rcNormalPosition = new RECT { left = (int)normalPosition.X, @@ -38,8 +38,8 @@ internal static WindowPlacementSetting FromWindowPlacement(WINDOWPLACEMENT windo return new WindowPlacementSetting { showCmd = (uint)windowPlacement.showCmd, - minPosition = new Point(windowPlacement.ptMinPosition.x, windowPlacement.ptMinPosition.y), - maxPosition = new Point(windowPlacement.ptMaxPosition.x, windowPlacement.ptMaxPosition.y), + minPosition = new Point(windowPlacement.ptMinPosition.X, windowPlacement.ptMinPosition.Y), + maxPosition = new Point(windowPlacement.ptMaxPosition.X, windowPlacement.ptMaxPosition.Y), normalPosition = new Rect( windowPlacement.rcNormalPosition.left, windowPlacement.rcNormalPosition.top, diff --git a/src/Atc.Wpf/.editorconfig b/src/Atc.Wpf/.editorconfig index 821094ee..93ca8326 100644 --- a/src/Atc.Wpf/.editorconfig +++ b/src/Atc.Wpf/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/src/Atc.Wpf/AssemblyInfo.cs b/src/Atc.Wpf/AssemblyInfo.cs index e2926d48..69325b9b 100644 --- a/src/Atc.Wpf/AssemblyInfo.cs +++ b/src/Atc.Wpf/AssemblyInfo.cs @@ -2,7 +2,6 @@ [assembly: XmlnsPrefix("https://github.com/atc-net/atc-wpf/tree/main/schemas", "atc")] [assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls")] -[assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Inputs")] [assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Layouts")] [assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Media")] [assembly: XmlnsDefinition("https://github.com/atc-net/atc-wpf/tree/main/schemas", "Atc.Wpf.Controls.Selectors")] diff --git a/src/Atc.Wpf/Atc.Wpf.csproj b/src/Atc.Wpf/Atc.Wpf.csproj index 2bcc7666..f99e5e2d 100644 --- a/src/Atc.Wpf/Atc.Wpf.csproj +++ b/src/Atc.Wpf/Atc.Wpf.csproj @@ -1007,7 +1007,7 @@ - + diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/ITextFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/ITextFormatter.cs index 73687452..35357449 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/ITextFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/ITextFormatter.cs @@ -17,5 +17,6 @@ public interface ITextFormatter /// /// The document. /// The text. - void SetText(FlowDocument document, string text); + /// The ThemeMode. + void SetText(FlowDocument document, string text, ThemeMode themeMode); } \ No newline at end of file diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/PlainTextFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/PlainTextFormatter.cs index 1bbb0d4a..786040c4 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/PlainTextFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/PlainTextFormatter.cs @@ -22,7 +22,8 @@ public string GetText(FlowDocument document) /// /// The document. /// The text. - public void SetText(FlowDocument document, string text) + /// The ThemeMode. + public void SetText(FlowDocument document, string text, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(document); diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/RtfFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/RtfFormatter.cs index 25f91d7c..9164f9ba 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/RtfFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/RtfFormatter.cs @@ -25,8 +25,9 @@ public string GetText(FlowDocument document) /// /// The document. /// The text. + /// The ThemeMode. /// Data provided is not in the correct RTF format. - public void SetText(FlowDocument document, string text) + public void SetText(FlowDocument document, string text, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(document); diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/CSharpFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/CSharpFormatter.cs index 271af7bc..7980fdae 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/CSharpFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/CSharpFormatter.cs @@ -27,14 +27,15 @@ public string GetText(FlowDocument document) /// /// The document. /// The text. - public void SetText(FlowDocument document, string text) + /// The ThemeMode. + public void SetText(FlowDocument document, string text, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(document); document.Blocks.Clear(); document.SetCurrentValue(FlowDocument.PageWidthProperty, 2500D); var cSharp = new CSharp(); - var p = cSharp.FormatCode(text); + var p = cSharp.FormatCode(text, themeMode); document.Blocks.Add(p); } } \ No newline at end of file diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Code.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Code.cs index e4b29cca..1d0e9775 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Code.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Code.cs @@ -99,9 +99,10 @@ protected Code() /// /// The resulting from a /// single regular expression match. + /// The ThemeMode. /// A string containing the HTML code fragment. [SuppressMessage("Design", "MA0051:Method is too long", Justification = "OK.")] - protected override string MatchEval(Match match) + protected override string MatchEval(Match match, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(match); @@ -125,7 +126,10 @@ protected override string MatchEval(Match match) { var run = new Run(sb.ToString()) { - Foreground = new SolidColorBrush(Color.FromRgb(0, 128, 0)), + Foreground = new SolidColorBrush( + themeMode == ThemeMode.Light + ? Color.FromRgb(0, 128, 0) + : Color.FromRgb(87, 166, 74)), }; CodeParagraphGlobal.Add(run); @@ -139,7 +143,10 @@ protected override string MatchEval(Match match) { var run = new Run(match.ToString()) { - Foreground = new SolidColorBrush(Color.FromRgb(0, 96, 128)), + Foreground = new SolidColorBrush( + themeMode == ThemeMode.Light + ? Color.FromRgb(179, 90, 45) + : Color.FromRgb(214, 157, 133)), }; CodeParagraphGlobal.Add(run); @@ -151,7 +158,7 @@ protected override string MatchEval(Match match) { var run = new Run(match.ToString()) { - Foreground = new SolidColorBrush(Color.FromRgb(204, 102, 51)), + Foreground = new SolidColorBrush(Color.FromRgb(155, 155, 143)), }; CodeParagraphGlobal.Add(run); @@ -163,7 +170,10 @@ protected override string MatchEval(Match match) { var run = new Run(match.ToString()) { - Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 255)), + Foreground = new SolidColorBrush( + themeMode == ThemeMode.Light + ? Color.FromRgb(0, 0, 255) + : Color.FromRgb(86, 156, 214)), }; CodeParagraphGlobal.Add(run); diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Source.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Source.cs index 07af5d25..97fef496 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Source.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/Format/Source.cs @@ -8,7 +8,7 @@ namespace Atc.Wpf.Controls.Documents.TextFormatters.SourceCode.Format; /// /// /// -/// To display the formatted code on your web site, the web page must +/// To display the formatted code on your website, the web page must /// refer to a stylesheet that defines the formatting for the different /// CSS classes generated by CSharpFormat: /// .csharpcode, pre, .rem, .kwrd, .str, .op, .preproc, .alt, .lnum. @@ -78,12 +78,13 @@ protected Source() /// Transforms a source code string to HTML 4.01. /// /// The source. + /// The ThemeMode. /// /// A string containing the HTML formatted code. /// - public Paragraph FormatCode(string source) + public Paragraph FormatCode(string source, ThemeMode themeMode) { - return FormatCodeHelper(source); + return FormatCodeHelper(source, themeMode); } /// @@ -92,15 +93,16 @@ public Paragraph FormatCode(string source) /// /// The resulting from a /// single regular expression match. + /// The ThemeMode. /// A string containing the HTML code fragment. - protected abstract string MatchEval(Match match); + protected abstract string MatchEval(Match match, ThemeMode themeMode); - private Paragraph FormatCodeHelper(string source) + private Paragraph FormatCodeHelper(string source, ThemeMode themeMode) { var codeParagraph = new Paragraph(); var sb = new StringBuilder(source); - source = CodeRegex.Replace(sb.ToString(), MatchEval); - string[] characters = { "::::::" }; + source = CodeRegex.Replace(sb.ToString(), match => MatchEval(match, themeMode)); + string[] characters = ["::::::"]; var split = source.Split(characters, StringSplitOptions.None); var currentChunk = 0; diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/XamlFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/XamlFormatter.cs index 1343f66f..b1aa5e08 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/XamlFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/SourceCode/XamlFormatter.cs @@ -1,4 +1,5 @@ // ReSharper disable UnusedMethodReturnValue.Global +// ReSharper disable SwitchStatementMissingSomeEnumCasesNoDefault namespace Atc.Wpf.Controls.Documents.TextFormatters.SourceCode; /// @@ -16,8 +17,9 @@ public class XamlFormatter : ITextFormatter /// /// The xaml text. /// The target document. + /// The ThemeMode. /// The flowDocument. - public static FlowDocument ColorizeXaml(string xamlText, FlowDocument targetDoc) + public static FlowDocument ColorizeXaml(string xamlText, FlowDocument targetDoc, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(xamlText); ArgumentNullException.ThrowIfNull(targetDoc); @@ -33,7 +35,9 @@ public static FlowDocument ColorizeXaml(string xamlText, FlowDocument targetDoc) { var tokenText = xamlText.Substring(position, token.Length); tokenTexts.Add(tokenText); - var color = ColorForToken(token); + var color = themeMode == ThemeMode.Light + ? LightColorForToken(token) + : DarkColorForToken(token); colors.Add(color); position += token.Length; } @@ -72,18 +76,19 @@ public string GetText(FlowDocument document) /// /// The document. /// The text. - public void SetText(FlowDocument document, string text) + /// The ThemeMode. + public void SetText(FlowDocument document, string text, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(document); document.Blocks.Clear(); document.SetCurrentValue(FlowDocument.PageWidthProperty, 2500D); - ColorizeXaml(text, document); + ColorizeXaml(text, document, themeMode); } - private static Color ColorForToken(XmlToken token) + private static Color LightColorForToken(XmlToken token) { - var color = Color.FromRgb(0, 0, 0); + var color = Color.FromRgb(231, 84, 128); switch (token.Kind) { case XmlTokenKind.Open: @@ -116,4 +121,40 @@ private static Color ColorForToken(XmlToken token) return color; } + + private static Color DarkColorForToken(XmlToken token) + { + var color = Color.FromRgb(231, 84, 128); + switch (token.Kind) + { + case XmlTokenKind.Open: + case XmlTokenKind.OpenClose: + case XmlTokenKind.Close: + case XmlTokenKind.SelfClose: + case XmlTokenKind.CommentBegin: + case XmlTokenKind.CommentEnd: + case XmlTokenKind.CDataBegin: + case XmlTokenKind.CDataEnd: + case XmlTokenKind.Equals: + case XmlTokenKind.OpenProcessingInstruction: + case XmlTokenKind.CloseProcessingInstruction: + case XmlTokenKind.AttributeValue: + color = Color.FromRgb(86, 156, 214); + break; + case XmlTokenKind.ElementName: + color = Color.FromRgb(255, 255, 255); + break; + case XmlTokenKind.TextContent: + break; + case XmlTokenKind.AttributeName: + case XmlTokenKind.Entity: + color = Color.FromRgb(146, 202, 244); + break; + case XmlTokenKind.CommentText: + color = Color.FromRgb(87, 166, 74); + break; + } + + return color; + } } \ No newline at end of file diff --git a/src/Atc.Wpf/Controls/Documents/TextFormatters/XamlFormatter.cs b/src/Atc.Wpf/Controls/Documents/TextFormatters/XamlFormatter.cs index 83740a1d..171b64d7 100644 --- a/src/Atc.Wpf/Controls/Documents/TextFormatters/XamlFormatter.cs +++ b/src/Atc.Wpf/Controls/Documents/TextFormatters/XamlFormatter.cs @@ -25,8 +25,9 @@ public string GetText(FlowDocument document) /// /// The document. /// The text. + /// The ThemeMode. /// Data provided is not in the correct Xaml format. - public void SetText(FlowDocument document, string text) + public void SetText(FlowDocument document, string text, ThemeMode themeMode) { ArgumentNullException.ThrowIfNull(document); diff --git a/src/Atc.Wpf/Enums/ThemeMode.cs b/src/Atc.Wpf/Enums/ThemeMode.cs new file mode 100644 index 00000000..c8e0d3d5 --- /dev/null +++ b/src/Atc.Wpf/Enums/ThemeMode.cs @@ -0,0 +1,8 @@ +// ReSharper disable once CheckNamespace +namespace Atc.Wpf; + +public enum ThemeMode +{ + Light, + Dark, +} \ No newline at end of file diff --git a/src/Atc.Wpf/GlobalUsings.cs b/src/Atc.Wpf/GlobalUsings.cs index 7c655879..92b4ffc6 100644 --- a/src/Atc.Wpf/GlobalUsings.cs +++ b/src/Atc.Wpf/GlobalUsings.cs @@ -41,7 +41,6 @@ global using Atc.Wpf; global using Atc.Wpf.Collections; global using Atc.Wpf.Command; -global using Atc.Wpf.Controls.Documents.TextFormatters; global using Atc.Wpf.Controls.Documents.TextFormatters.SourceCode.Format; global using Atc.Wpf.Controls.Media; global using Atc.Wpf.Controls.Media.W3cSvg; diff --git a/src/Atc.Wpf/Mvvm/MainWindowViewModelBase.cs b/src/Atc.Wpf/Mvvm/MainWindowViewModelBase.cs index 33d94881..0b2b4c27 100644 --- a/src/Atc.Wpf/Mvvm/MainWindowViewModelBase.cs +++ b/src/Atc.Wpf/Mvvm/MainWindowViewModelBase.cs @@ -10,6 +10,11 @@ public WindowState WindowState get => windowState; set { + if (windowState == value) + { + return; + } + windowState = value; RaisePropertyChanged(); } @@ -23,7 +28,12 @@ public void OnLoaded( object sender, RoutedEventArgs e) { - // Method intentionally left empty. + if (sender is FrameworkElement frameworkElement && + (frameworkElement.Width >= SystemParameters.PrimaryScreenWidth || + frameworkElement.Height >= SystemParameters.PrimaryScreenHeight)) + { + WindowState = WindowState.Maximized; + } } /// diff --git a/src/Atc.Wpf/Mvvm/ViewModelBase.cs b/src/Atc.Wpf/Mvvm/ViewModelBase.cs index 712774de..e50118d3 100644 --- a/src/Atc.Wpf/Mvvm/ViewModelBase.cs +++ b/src/Atc.Wpf/Mvvm/ViewModelBase.cs @@ -38,6 +38,11 @@ public bool IsEnable get => isEnable; set { + if (isEnable == value) + { + return; + } + isEnable = value; RaisePropertyChanged(); } @@ -65,6 +70,11 @@ public bool IsBusy get => isBusy; set { + if (isBusy == value) + { + return; + } + isBusy = value; RaisePropertyChanged(); } @@ -76,6 +86,11 @@ public bool IsDirty get => isDirty; set { + if (isDirty == value) + { + return; + } + isDirty = value; RaisePropertyChanged(); } @@ -87,6 +102,11 @@ public bool IsSelected get => isSelected; set { + if (isSelected == value) + { + return; + } + isSelected = value; RaisePropertyChanged(); } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f516744f..bce62e19 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -54,7 +54,7 @@ - + diff --git a/test/Atc.Wpf.Controls.Tests/Atc.Wpf.Controls.Tests.csproj b/test/Atc.Wpf.Controls.Tests/Atc.Wpf.Controls.Tests.csproj index 44e6f315..d95e0bfa 100644 --- a/test/Atc.Wpf.Controls.Tests/Atc.Wpf.Controls.Tests.csproj +++ b/test/Atc.Wpf.Controls.Tests/Atc.Wpf.Controls.Tests.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Atc.Wpf.Tests/Atc.Wpf.Tests.csproj b/test/Atc.Wpf.Tests/Atc.Wpf.Tests.csproj index c868a8c8..0ffe71cc 100644 --- a/test/Atc.Wpf.Tests/Atc.Wpf.Tests.csproj +++ b/test/Atc.Wpf.Tests/Atc.Wpf.Tests.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Atc.Wpf.Theming.Tests/Atc.Wpf.Theming.Tests.csproj b/test/Atc.Wpf.Theming.Tests/Atc.Wpf.Theming.Tests.csproj index 151d3edb..ab8d43d0 100644 --- a/test/Atc.Wpf.Theming.Tests/Atc.Wpf.Theming.Tests.csproj +++ b/test/Atc.Wpf.Theming.Tests/Atc.Wpf.Theming.Tests.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tool/Atc.Wpf.Generator.FontIconResources/.editorconfig b/tool/Atc.Wpf.Generator.FontIconResources/.editorconfig index 821094ee..93ca8326 100644 --- a/tool/Atc.Wpf.Generator.FontIconResources/.editorconfig +++ b/tool/Atc.Wpf.Generator.FontIconResources/.editorconfig @@ -1,6 +1,6 @@ # ATC coding rules - https://github.com/atc-net/atc-coding-rules -# Version: 1.0.0 -# Updated: 27-03-2024 +# Version: 1.0.1 +# Updated: 06-06-2024 # Location: wpf # Distribution: Frameworks @@ -12,6 +12,9 @@ dotnet_diagnostic.MA0004.severity = error # Use Task.ConfigureAwait(false) https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md dotnet_diagnostic.MA0048.severity = none # To support partial classes - File will not match type name. +dotnet_diagnostic.CA2227.severity = none # Change property to be read-only by removing the property setter - https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2227 + + ########################################## # Custom - Code Analyzers Rules ########################################## \ No newline at end of file diff --git a/tool/Atc.Wpf.Generator.FontIconResources/Atc.Wpf.Generator.FontIconResources.csproj b/tool/Atc.Wpf.Generator.FontIconResources/Atc.Wpf.Generator.FontIconResources.csproj index 253e1350..881989e5 100644 --- a/tool/Atc.Wpf.Generator.FontIconResources/Atc.Wpf.Generator.FontIconResources.csproj +++ b/tool/Atc.Wpf.Generator.FontIconResources/Atc.Wpf.Generator.FontIconResources.csproj @@ -8,7 +8,7 @@ - + NU1701