From f00952b10a6be76b4397d5d4c2d5985f0bb28795 Mon Sep 17 00:00:00 2001 From: Giduac Date: Thu, 26 Dec 2024 09:30:27 +0100 Subject: [PATCH] 1908-V95-KDGV-Column-indicator-image-class-KryptonDataGridViewUtilities Adds KryptonDataGridViewCellIndicatorImage.cs Adds KryptonDataGridViewUtilities.cs --- .../KryptonDataGridViewCellIndicatorImage.cs | 169 ++++++++++++++++++ .../KryptonDataGridViewUtilities.cs | 76 ++++++++ 2 files changed, 245 insertions(+) create mode 100644 Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.cs create mode 100644 Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewUtilities.cs diff --git a/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.cs b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.cs new file mode 100644 index 000000000..b4ef53300 --- /dev/null +++ b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.cs @@ -0,0 +1,169 @@ +#region BSD License +/* + * New BSD 3-Clause License (https://github.com/Krypton-Suite/Standard-Toolkit/blob/master/LICENSE) + * Modifications by Peter Wagner (aka Wagnerp), Simon Coghlan (aka Smurf-IV), Giduac & Ahmed Abdelhameed et al. 2017 - 2025. All rights reserved. + * + */ +#endregion + +namespace Krypton.Toolkit +{ + /// + /// This class is used within advanved columns that make use of embedded controls. + /// + [ToolboxItem(false)] + internal class KryptonDataGridViewCellIndicatorImage : IDisposable + { + #region Fields + // Cell indicator image + private Image? _image = null; + // Size of the image which is always square + private int _size; + // Datagridview the column belongs to. + private KryptonDataGridView? _dataGridView; + // State of disposal + private bool _disposed = false; + + // type and state of the image + private PaletteRibbonGalleryButton _paletteRibbonGalleryButton = PaletteRibbonGalleryButton.Down; + private PaletteState _paletteState = PaletteState.Normal; + #endregion Fields + + #region Identity + /// + /// Default constructor. + /// + /// The image size in pixels. Which will always be used to square the image. Default is 14. + public KryptonDataGridViewCellIndicatorImage(int imageSize = 14) + { + _size = imageSize; + + UpdateCellIndicatorImage(true); + KryptonManager.GlobalPaletteChanged += OnKryptonManagerGlobalPaletteChanged; + } + #endregion Identity + + #region Public + /// + /// Reference to the column's DataGridView.
+ /// Set this property via the column's 'protected override void OnDataGridViewChanged()'. + ///
+ public KryptonDataGridView? DataGridView + { + get => _dataGridView; + + set + { + if (_dataGridView != value) + { + if (_dataGridView is not null) + { + _dataGridView.PaletteChanged -= OnDataGridViewPaletteChanged; + } + + _dataGridView = value; + + if (_dataGridView is not null) + { + _dataGridView.PaletteChanged += OnDataGridViewPaletteChanged; + UpdateCellIndicatorImage(false); + } + } + } + } + + /// + /// Cell indicator image. + /// + public virtual Image? Image => _image; + + /// > + public void Dispose() + { + Dispose(true); + } + + /// + public void Dispose(bool disposing) + { + // If the column is disposed at runtime the eventhandlers need to unsubscribe from the grid and kmananger + try + { + if (!_disposed && disposing) + { + // Since the DataGridView property is controlled internally, + // use the cached reference to unsubscribe from the event + if (_dataGridView is not null) + { + _dataGridView.PaletteChanged -= OnDataGridViewPaletteChanged; + } + + KryptonManager.GlobalPaletteChanged -= OnKryptonManagerGlobalPaletteChanged; + _dataGridView = null; + + _disposed = true; + } + } + catch { } + } + #endregion Public + + #region Private + /// + /// Subscribe this handler to: KryptonDataGridView.PaletteChanged + /// + /// Not used. + /// Not used. + private void OnDataGridViewPaletteChanged(object? sender, EventArgs e) => UpdateCellIndicatorImage(false); + + /// + /// Subscribe this handler to: KryptonManager.GlobalPaletteChanged + /// + /// Not used. + /// Not used. + private void OnKryptonManagerGlobalPaletteChanged(object? sender, EventArgs e) => UpdateCellIndicatorImage(true); + + /// + /// Updates the cell indicator image based on the source from where the theme change originated. + /// + /// True if KryptonManager fired the theme change, otherwise from KryptonDataGridView. + private void UpdateCellIndicatorImage(bool updateFromKryptonManager) + { + if (updateFromKryptonManager) + { + // Probably the case used most, so first to check. + _image = KryptonManager.CurrentGlobalPalette.GetGalleryButtonImage(_paletteRibbonGalleryButton, _paletteState)!; + ResizeCellIndicatorImage(); + } + else if (DataGridView is KryptonDataGridView dataGridView) + { + if (dataGridView.Palette is not null && dataGridView.PaletteMode == PaletteMode.Custom) + { + // The grid has a custom palette instance assigned to it and PaletteMode is Custom + _image = dataGridView.Palette.GetGalleryButtonImage(_paletteRibbonGalleryButton, _paletteState); + } + else + { + // Fetch through KryptonManager using the locally set palette mode + _image = KryptonManager + .GetPaletteForMode(dataGridView.PaletteMode) + .GetGalleryButtonImage(_paletteRibbonGalleryButton, _paletteState)!; + } + + ResizeCellIndicatorImage(); + } + } + + /// + /// This method may only be used by UpdateCellIndicatorImage() + /// + private void ResizeCellIndicatorImage() + { + if (_image is not null && (_image.Width != _size || _image.Height != _size)) + { + _image = new Bitmap(_image, _size, _size); + } + } + #endregion Private + } +} diff --git a/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewUtilities.cs b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewUtilities.cs new file mode 100644 index 000000000..304cf966d --- /dev/null +++ b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewUtilities.cs @@ -0,0 +1,76 @@ +#region BSD License +/* + * New BSD 3-Clause License (https://github.com/Krypton-Suite/Standard-Toolkit/blob/master/LICENSE) + * Modifications by Peter Wagner (aka Wagnerp), Simon Coghlan (aka Smurf-IV), Giduac & Ahmed Abdelhameed et al. 2024 - 2025. All rights reserved. + * + */ +#endregion + +namespace Krypton.Toolkit +{ + + internal class KryptonDataGridViewUtilities + { + internal static class TextFormatFlagsCellStyleAlignments + { + // Calculate these once for use in ComputeTextFormatFlagsForCellStyleAlignment() + private const TextFormatFlags baseMask = TextFormatFlags.NoPrefix | TextFormatFlags.PreserveGraphicsClipping; + + internal const TextFormatFlags TopLeft_RightToLeft = baseMask | TextFormatFlags.Top | TextFormatFlags.Right | TextFormatFlags.RightToLeft; + internal const TextFormatFlags TopLeft_LeftToRight = baseMask | TextFormatFlags.Top | TextFormatFlags.Left; + internal const TextFormatFlags TopCenter = baseMask | TextFormatFlags.Top | TextFormatFlags.HorizontalCenter; + internal const TextFormatFlags TopRight_RightToLeft = baseMask | TextFormatFlags.Top | TextFormatFlags.Left | TextFormatFlags.RightToLeft; + internal const TextFormatFlags TopRight_LeftToRight = baseMask | TextFormatFlags.Top | TextFormatFlags.Right; + + internal const TextFormatFlags MiddleLeft_RightToLeft = baseMask | TextFormatFlags.VerticalCenter | TextFormatFlags.Right | TextFormatFlags.RightToLeft; + internal const TextFormatFlags MiddleLeft_LeftToRight = baseMask | TextFormatFlags.VerticalCenter | TextFormatFlags.Left; + internal const TextFormatFlags MiddleCenter = baseMask | TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter; + internal const TextFormatFlags MiddleRight_RightToLeft = baseMask | TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.RightToLeft; + internal const TextFormatFlags MiddleRight_LeftToRight = baseMask | TextFormatFlags.VerticalCenter | TextFormatFlags.Right; + + internal const TextFormatFlags BottomLeft_RightToLeft = baseMask | TextFormatFlags.Bottom | TextFormatFlags.Right | TextFormatFlags.RightToLeft; + internal const TextFormatFlags BottomLeft_LeftToRight = baseMask | TextFormatFlags.Bottom | TextFormatFlags.Left; + internal const TextFormatFlags BottomCenter = baseMask | TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter; + internal const TextFormatFlags BottomRight_RightToLeft = baseMask | TextFormatFlags.Bottom | TextFormatFlags.Left | TextFormatFlags.RightToLeft; + internal const TextFormatFlags BottomRight_Lefttoright = baseMask | TextFormatFlags.Bottom | TextFormatFlags.Right; + + internal const TextFormatFlags DefaultAlignment = baseMask | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter; + } + + internal static TextFormatFlags ComputeTextFormatFlagsForCellStyleAlignment( + bool rightToLeft, + DataGridViewContentAlignment alignment, + DataGridViewTriState wrapMode) + { + // This routine has been copied from the dotnet winforms project and slightly rewritten to reduce computing masks + // Licensed to the .NET Foundation under one or more agreements. + // The .NET Foundation licenses this file to you under the MIT license. + TextFormatFlags tff = alignment switch + { + DataGridViewContentAlignment.TopLeft when rightToLeft => TextFormatFlagsCellStyleAlignments.TopLeft_RightToLeft, + DataGridViewContentAlignment.TopLeft when !rightToLeft => TextFormatFlagsCellStyleAlignments.TopLeft_LeftToRight, + DataGridViewContentAlignment.TopCenter => TextFormatFlagsCellStyleAlignments.TopCenter, + DataGridViewContentAlignment.TopRight when rightToLeft => TextFormatFlagsCellStyleAlignments.TopRight_RightToLeft, + DataGridViewContentAlignment.TopRight when !rightToLeft => TextFormatFlagsCellStyleAlignments.TopRight_LeftToRight, + + DataGridViewContentAlignment.MiddleLeft when rightToLeft => TextFormatFlagsCellStyleAlignments.MiddleLeft_RightToLeft, + DataGridViewContentAlignment.MiddleLeft when !rightToLeft => TextFormatFlagsCellStyleAlignments.MiddleLeft_LeftToRight, + DataGridViewContentAlignment.MiddleCenter => TextFormatFlagsCellStyleAlignments.MiddleCenter, + DataGridViewContentAlignment.MiddleRight when rightToLeft => TextFormatFlagsCellStyleAlignments.MiddleRight_RightToLeft, + DataGridViewContentAlignment.MiddleRight when !rightToLeft => TextFormatFlagsCellStyleAlignments.MiddleRight_LeftToRight, + + DataGridViewContentAlignment.BottomLeft when rightToLeft => TextFormatFlagsCellStyleAlignments.BottomLeft_RightToLeft, + DataGridViewContentAlignment.BottomLeft when !rightToLeft => TextFormatFlagsCellStyleAlignments.BottomLeft_LeftToRight, + DataGridViewContentAlignment.BottomCenter => TextFormatFlagsCellStyleAlignments.BottomCenter, + DataGridViewContentAlignment.BottomRight when rightToLeft => TextFormatFlagsCellStyleAlignments.BottomRight_RightToLeft, + DataGridViewContentAlignment.BottomRight when !rightToLeft => TextFormatFlagsCellStyleAlignments.BottomRight_Lefttoright, + _ => TextFormatFlagsCellStyleAlignments.DefaultAlignment + }; + + return tff | (wrapMode == DataGridViewTriState.False + ? TextFormatFlags.SingleLine + : TextFormatFlags.WordBreak); + + } + } +}