using System.ComponentModel; // Nicht gemergte Änderung aus Projekt "Pilz.UI (net8.0-windows)" // Vor: // Imports System.Windows.Forms // Imports System.Drawing // Nach: // Imports System.Drawing // Imports System.Windows.Forms namespace Pilz.UI.WinForms; public class Highlighter : Component { private Dictionary _Highlights = []; private Dictionary _HighlightOnFocus = []; protected override void Dispose(bool disposing) { if (_ContainerControl is not null) { _ContainerControl.SizeChanged -= ContainerControlSizeChanged; _ContainerControl.HandleCreated -= ContainerControlHandleCreated; } if (_HighlightPanel is not null && _HighlightPanel.Parent is null && !_HighlightPanel.IsDisposed) { _HighlightPanel.Dispose(); _HighlightPanel = null; } else { _HighlightPanel = null; } base.Dispose(disposing); } [DefaultValue(false)] [Localizable(true)] [Description("Indicates whether control is highlighted when it receives input focus.")] public bool GetHighlightOnFocus(Control c) { if (_HighlightOnFocus.ContainsKey(c)) return _HighlightOnFocus[c]; return false; } public void SetHighlightOnFocus(Control c, bool highlight) { if (c is null) throw new NullReferenceException(); if (_HighlightOnFocus.ContainsKey(c)) { if (!highlight) RemoveHighlightOnFocus(_HighlightOnFocus, c); return; } if (highlight) AddHighlightOnFocus(_HighlightOnFocus, c); } private void AddHighlightOnFocus(Dictionary highlightOnFocus, Control c) { c.Enter += ControlHighlightEnter; c.Leave += ControlHighlightLeave; c.VisibleChanged += ControlHighlightVisibleChanged; highlightOnFocus.Add(c, true); } private void ControlHighlightVisibleChanged(object sender, EventArgs e) { if (_HighlightPanel is not null && sender.Equals(_HighlightPanel.FocusHighlightControl)) UpdateHighlighterRegion(); } private void ControlHighlightLeave(object sender, EventArgs e) { if (_HighlightPanel is not null) _HighlightPanel.FocusHighlightControl = null; UpdateHighlighterRegion(); } private void ControlHighlightEnter(object sender, EventArgs e) { if (_HighlightPanel is not null) { if (!_HighlightPanel.Visible) _HighlightPanel.Visible = true; _HighlightPanel.BringToFront(); _HighlightPanel.FocusHighlightControl = (Control)sender; } UpdateHighlighterRegion(); } private void RemoveHighlightOnFocus(Dictionary highlightOnFocus, Control c) { c.Enter -= ControlHighlightEnter; c.Leave -= ControlHighlightLeave; c.VisibleChanged -= ControlHighlightVisibleChanged; highlightOnFocus.Remove(c); } [DefaultValue(eHighlightColor.None)] [Localizable(true)] [Description("Indicates the highlight color that is applied to the control.")] public eHighlightColor GetHighlightColor(Control c) { if (_Highlights.ContainsKey(c)) return _Highlights[c]; return eHighlightColor.None; } public void SetHighlightColor(Control c, eHighlightColor highlightColor) { if (_Highlights.ContainsKey(c)) { if (highlightColor == eHighlightColor.None) RemoveHighlight(_Highlights, c); else { var color = _Highlights[c]; RemoveHighlight(_Highlights, c); AddHighlight(_Highlights, c, highlightColor); } } else if (highlightColor != eHighlightColor.None) { AddHighlight(_Highlights, c, highlightColor); } } private Dictionary _TabControl2 = []; private Dictionary _ParentPanel = []; private void AddHighlight(Dictionary highlights, Control c, eHighlightColor highlightColor) { highlights.Add(c, highlightColor); c.LocationChanged += new EventHandler(ControlLocationChanged); c.SizeChanged += new EventHandler(ControlSizeChanged); c.VisibleChanged += new EventHandler(ControlVisibleChanged); if (_HighlightPanel is not null) { if (!_HighlightPanel.Visible) _HighlightPanel.Visible = true; _HighlightPanel.BringToFront(); } if (c.Parent is null) c.ParentChanged += ControlParentChanged; else { AddTabControlHandlers(c); } UpdateHighlighterRegion(); } private void ControlParentChanged(object sender, EventArgs e) { var c = (Control)sender; c.ParentChanged -= ControlParentChanged; AddTabControlHandlers(c); } private void AddTabControlHandlers(Control c) { var tab2 = GetParentControl(c, typeof(TabControl)) as TabControl; if (tab2 is not null) { if (_TabControl2.ContainsKey(tab2)) _TabControl2[tab2] = _TabControl2[tab2] + 1; else { _TabControl2.Add(tab2, 1); tab2.SelectedIndexChanged += WinFormsTabSelectedIndexChanged; } } else { var parentPanel = GetParentControl(c, typeof(Panel)) as Panel; if (parentPanel is not null) { if (_ParentPanel.ContainsKey(parentPanel)) _ParentPanel[parentPanel] = _ParentPanel[parentPanel] + 1; else { _ParentPanel.Add(parentPanel, 1); parentPanel.Resize += ParentPanelResized; parentPanel.LocationChanged += ParentPanelLocationChanged; } } } } private void ParentPanelLocationChanged(object sender, EventArgs e) { UpdateHighlights(); } private void ParentPanelResized(object sender, EventArgs e) { UpdateHighlights(); } private void WinFormsTabSelectedIndexChanged(object sender, EventArgs e) { UpdateHighlighterRegion(); } private Control GetParentControl(Control c, Type parentType) { var parent = c.Parent; while (parent is not null) { if (parentType.IsAssignableFrom(parent.GetType())) return parent; parent = parent.Parent; } return null; } private void ControlVisibleChanged(object sender, EventArgs e) { UpdateHighlighterRegion(); } private void ControlSizeChanged(object sender, EventArgs e) { UpdateHighlighterRegion(); } private void ControlLocationChanged(object sender, EventArgs e) { UpdateHighlighterRegion(); } private void UpdateHighlighterRegion() { if (_HighlightPanel is not null) _HighlightPanel.UpdateRegion(); } public void UpdateHighlights() { UpdateHighlighterRegion(); } private void RemoveHighlight(Dictionary highlights, Control c) { highlights.Remove(c); c.LocationChanged -= new EventHandler(ControlLocationChanged); c.SizeChanged -= new EventHandler(ControlSizeChanged); c.VisibleChanged -= new EventHandler(ControlVisibleChanged); var tab2 = GetParentControl(c, typeof(TabControl)) as TabControl; if (tab2 is not null) { if (_TabControl2.ContainsKey(tab2)) { if (_TabControl2[tab2] == 1) { _TabControl2.Remove(tab2); tab2.SelectedIndexChanged -= WinFormsTabSelectedIndexChanged; } else { _TabControl2[tab2] = _TabControl2[tab2] - 1; } } } else { var parentPanel = GetParentControl(c, typeof(Panel)) as Panel; if (parentPanel is not null) { if (_ParentPanel.ContainsKey(parentPanel)) { if (_ParentPanel[parentPanel] == 1) { _ParentPanel.Remove(parentPanel); parentPanel.LocationChanged -= ParentPanelLocationChanged; parentPanel.SizeChanged -= ParentPanelResized; } else { _ParentPanel[parentPanel] = _ParentPanel[parentPanel] - 1; } } } } UpdateHighlighterRegion(); } internal Dictionary Highlights { get { return _Highlights; } } private eHighlightColor _FocusHighlightColor = eHighlightColor.Blue; [DefaultValue(eHighlightColor.Blue)] [Category("Appearance")] [Description("Indicates the highlight focus color.")] [Localizable(true)] public eHighlightColor FocusHighlightColor { get { return _FocusHighlightColor; } set { _FocusHighlightColor = value; if (_HighlightPanel is not null) { _HighlightPanel.FocusHighlightColor = value; UpdateHighlighterRegion(); } } } private HighlightPanel _HighlightPanel = null; private Control _ContainerControl = null; [Description("Indicates container control highlighter is bound to. Should be set to parent form.")] [Category("Behavior")] public Control ContainerControl { get { return _ContainerControl; } set { if (DesignMode) { _ContainerControl = value; return; } if (!ReferenceEquals(_ContainerControl, value)) { if (_ContainerControl is not null) { _ContainerControl.SizeChanged -= ContainerControlSizeChanged; _ContainerControl.HandleCreated -= ContainerControlHandleCreated; if (_HighlightPanel is not null && ReferenceEquals(_HighlightPanel.Parent, _ContainerControl)) _ContainerControl.Controls.Remove(_HighlightPanel); } _ContainerControl = value; if (_ContainerControl is not null) { _HighlightPanel ??= new HighlightPanel(_Highlights) { FocusHighlightColor = _FocusHighlightColor, Margin = new Padding(0), Padding = new Padding(0), CustomHighlightColors = _CustomHighlightColors, Visible = false }; _ContainerControl.SizeChanged += ContainerControlSizeChanged; _ContainerControl.HandleCreated += ContainerControlHandleCreated; _ContainerControl.Controls.Add(_HighlightPanel); UpdateHighlightPanelBounds(); } } } } private void ContainerControlHandleCreated(object sender, EventArgs e) { if (_Highlights.Count > 0 && _HighlightPanel is not null && !_HighlightPanel.Visible) _HighlightPanel.Visible = true; } private void UpdateHighlightPanelBounds() { var bounds = new Rectangle(0, 0, _ContainerControl.ClientRectangle.Width, _ContainerControl.ClientRectangle.Height); if (_HighlightPanel is not null) { if (_HighlightPanel.Parent is Form) { var form = _HighlightPanel.Parent as Form; if (form.AutoSize) { bounds.X += form.Padding.Left; bounds.Y += form.Padding.Top; bounds.Width -= form.Padding.Horizontal; bounds.Height -= form.Padding.Vertical; } } if (_HighlightPanel.Bounds.Equals(bounds)) _HighlightPanel.UpdateRegion(); else { _HighlightPanel.Bounds = bounds; } _HighlightPanel.BringToFront(); } } private System.Windows.Forms.Timer _DelayTimer = null; private void ContainerControlSizeChanged(object sender, EventArgs e) { var form = sender as Form; if (form is not null) { if (_DelayTimer is null) { _DelayTimer = new() { Interval = 100 }; _DelayTimer.Tick += new EventHandler(DelayTimerTick); _DelayTimer.Start(); } return; } UpdateHighlightPanelBounds(); } private void DelayTimerTick(object sender, EventArgs e) { var timer = _DelayTimer; _DelayTimer = null; timer.Tick -= new EventHandler(DelayTimerTick); timer.Stop(); timer.Dispose(); UpdateHighlightPanelBounds(); } private Color[] _CustomHighlightColors = null; [Category("Appearance")] [Description("Array of colors used to render custom highlight color. Control expects 3 colors in array to be specified which define the highlight border.")] public Color[] CustomHighlightColors { get { return _CustomHighlightColors; } set { _CustomHighlightColors = value; if (_HighlightPanel is not null) { _HighlightPanel.CustomHighlightColors = _CustomHighlightColors; _HighlightPanel.Invalidate(); } } } } public enum eHighlightColor { None, Red, Blue, Green, Orange, Custom }