From 0f6bef64b08ca1152496f6694145b7e14cea02c9 Mon Sep 17 00:00:00 2001 From: Giduac Date: Mon, 16 Dec 2024 13:16:13 +0100 Subject: [PATCH] 1908-V100-KDGV-Column-indicator-image-class Adds the KryptonDataGridViewCellIndicatorImage.cs file and class --- .../KryptonDataGridViewCellIndicatorImage.cs | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.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..758dd1d2e --- /dev/null +++ b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonDataGridViewCellIndicatorImage.cs @@ -0,0 +1,187 @@ +#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; + // Concurrency lock + private ReaderWriterLockSlim _rwls; + // 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; + _rwls = new(); + + 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); + } + } + } + } + + public virtual Image? Image + { + get + { + _rwls.EnterReadLock(); + Image? image = _image; + _rwls.ExitReadLock(); + + return 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) + { + _rwls.EnterWriteLock(); + + // Probably the case used most, so first to check. + _image = KryptonManager.CurrentGlobalPalette.GetGalleryButtonImage(_paletteRibbonGalleryButton, _paletteState)!; + ResizeCellIndicatorImage(); + + _rwls.ExitWriteLock(); + } + else if (DataGridView is KryptonDataGridView dataGridView) + { + _rwls.EnterWriteLock(); + + 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(); + + _rwls.ExitWriteLock(); + } + } + + /// + /// 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 + } +}