mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
[KOE-125] Added focused border to tree control
This commit is contained in:
parent
b17ebb2ec4
commit
008c27026d
@ -1,6 +1,6 @@
|
||||
/// Project : Kopano OL Extension
|
||||
///
|
||||
/// Copyright 2016 Kopano b.v.
|
||||
/// Copyright 2017 Kopano b.v.
|
||||
///
|
||||
/// This program is free software: you can redistribute it and/or modify
|
||||
/// it under the terms of the GNU Affero General Public License, version 3,
|
||||
@ -138,6 +138,13 @@ namespace Acacia.Controls
|
||||
set { _nodeIdent = value; Rerender(); }
|
||||
}
|
||||
|
||||
public int BorderThickness
|
||||
{
|
||||
get
|
||||
{
|
||||
return BorderStyle == BorderStyle.FixedSingle ? 1 : 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Images
|
||||
@ -416,6 +423,8 @@ namespace Acacia.Controls
|
||||
{
|
||||
if (newHighlight != _highlightNode || _highlightPart != newPart)
|
||||
{
|
||||
bool oldFocused = Focused;
|
||||
|
||||
KTreeNode old = _highlightNode;
|
||||
|
||||
if (newHighlight != null && !newHighlight.IsSelectable)
|
||||
@ -429,6 +438,10 @@ namespace Acacia.Controls
|
||||
_highlightPart = newPart;
|
||||
}
|
||||
|
||||
// Update the border if required
|
||||
if (oldFocused != Focused)
|
||||
RedrawBorder();
|
||||
|
||||
// Render old node without highlight
|
||||
if (old != null)
|
||||
Rerender(old);
|
||||
@ -612,21 +625,6 @@ namespace Acacia.Controls
|
||||
|
||||
#endregion
|
||||
|
||||
#region Columns
|
||||
// TODO
|
||||
/*
|
||||
private readonly TreeViewColumnCollection _columns;
|
||||
|
||||
[Category("Columns")]
|
||||
[Browsable(true)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public TreeViewColumnCollection Columns
|
||||
{
|
||||
get { return _columns; }
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rendering
|
||||
|
||||
private KTreeRenderer _renderer;
|
||||
@ -864,6 +862,10 @@ namespace Acacia.Controls
|
||||
e.Graphics.FillRectangle(SystemBrushes.Control,
|
||||
ClientSize.Width - VerticalScrollBarWidth, ClientSize.Height - HorizontalScrollBarHeight,
|
||||
VerticalScrollBarWidth, HorizontalScrollBarHeight);
|
||||
|
||||
// The scrollbars sometimes get lost, force a repaint
|
||||
_verticalScrollBar.Refresh();
|
||||
_horizontalScrollBar.Refresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -1081,20 +1083,69 @@ namespace Acacia.Controls
|
||||
|
||||
#endregion
|
||||
|
||||
#region Focus
|
||||
#region Border
|
||||
|
||||
public override bool Focused
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Focused || _highlightNode != null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnGotFocus(EventArgs e)
|
||||
{
|
||||
base.OnGotFocus(e);
|
||||
Invalidate();
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
protected override void OnLostFocus(EventArgs e)
|
||||
{
|
||||
base.OnLostFocus(e);
|
||||
Invalidate();
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
protected override void OnEnabledChanged(EventArgs e)
|
||||
{
|
||||
base.OnEnabledChanged(e);
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == (int)WM.NCPAINT)
|
||||
{
|
||||
IntPtr hDC = User32.GetWindowDC(m.HWnd);
|
||||
try
|
||||
{
|
||||
using (Graphics g = Graphics.FromHdc(hDC))
|
||||
{
|
||||
_renderer.RenderControlBorder(g, new Rectangle(0, 0, Width, Height));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
User32.ReleaseDC(m.HWnd, hDC);
|
||||
}
|
||||
return;
|
||||
}
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
private void RedrawBorder()
|
||||
{
|
||||
// Force NCPaint update
|
||||
User32.RedrawWindow(this.Handle, IntPtr.Zero, IntPtr.Zero,
|
||||
User32.RedrawWindowFlags.Frame | User32.RedrawWindowFlags.Invalidate);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Winforms Autogenerated
|
||||
@ -1111,56 +1162,5 @@ namespace Acacia.Controls
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disabled state
|
||||
|
||||
protected override void OnEnabledChanged(EventArgs e)
|
||||
{
|
||||
base.OnEnabledChanged(e);
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == (int)WM.NCPAINT)
|
||||
{
|
||||
WmNcPaint(ref m);
|
||||
return;
|
||||
}
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private void WmNcPaint(ref Message m)
|
||||
{
|
||||
if (BorderStyle == BorderStyle.None)
|
||||
return;
|
||||
|
||||
IntPtr hDC = User32.GetWindowDC(m.HWnd);
|
||||
try
|
||||
{
|
||||
using (Graphics g = Graphics.FromHdc(hDC))
|
||||
{
|
||||
_renderer.RenderControlBorder(g, new Rectangle(0, 0, Width, Height));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
User32.ReleaseDC(m.HWnd, hDC);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
RedrawBorder();
|
||||
}
|
||||
|
||||
private void RedrawBorder()
|
||||
{
|
||||
// Force NCPaint update
|
||||
User32.RedrawWindow(this.Handle, IntPtr.Zero, IntPtr.Zero,
|
||||
User32.RedrawWindowFlags.Frame | User32.RedrawWindowFlags.Invalidate /*| User32.RedrawWindowFlags.UpdateNow*/);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,8 @@ namespace Acacia.Controls
|
||||
Rectangle containerRect = dims.NodeRect;
|
||||
containerRect.X = _clientRect.X;
|
||||
containerRect.Width = Math.Max(_totalRect.Width, _clientRect.Width);
|
||||
// Overlap the rectangle with the control border, to prevent duplicate lines
|
||||
containerRect = containerRect.Expand(new Padding(_tree.BorderThickness));
|
||||
|
||||
// Selection background
|
||||
RenderNodeOutline(graphics, node, _tree.FullRowSelect ? containerRect : dims.NodeRect, highlight);
|
||||
|
@ -66,6 +66,11 @@ namespace Acacia.Controls
|
||||
private readonly VisualStyleRenderer _treeViewGlyphHotClosed = new VisualStyleRenderer(TREEVIEW, 4, 1);
|
||||
private readonly VisualStyleRenderer _treeViewGlyphHotOpened = new VisualStyleRenderer(TREEVIEW, 4, 2);
|
||||
|
||||
// We use the combo box styles for the outline
|
||||
private readonly VisualStyleRenderer _treeViewBorderNormal = new VisualStyleRenderer("COMBOBOX", 4, 1);
|
||||
private readonly VisualStyleRenderer _treeViewBorderFocus = new VisualStyleRenderer("COMBOBOX", 4, 2);
|
||||
private readonly VisualStyleRenderer _treeViewBorderDisabled = new VisualStyleRenderer("COMBOBOX", 4, 4);
|
||||
|
||||
private Size? _glyphSize;
|
||||
|
||||
protected override Size GetExpanderSize(Graphics graphics, KTreeNode node)
|
||||
@ -124,8 +129,10 @@ namespace Acacia.Controls
|
||||
protected override void RenderNodeOutline(Graphics graphics, KTreeNode node, Rectangle rect, KTreeNodeMeasurements.Part? highlight)
|
||||
{
|
||||
// Draw one pixel too far, to overlap top and bottom borders for a continuous selection
|
||||
|
||||
Rectangle highlightRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + 1);
|
||||
// If full-row selecting, compensate for shifted rectangle.
|
||||
if (_tree.FullRowSelect)
|
||||
highlightRect.Height -= 2 * _tree.BorderThickness;
|
||||
if (_tree.ActiveNode == node && _tree.Focused)
|
||||
{
|
||||
if (node.IsSelected)
|
||||
@ -148,11 +155,20 @@ namespace Acacia.Controls
|
||||
|
||||
public override void RenderControlBorder(Graphics graphics, Rectangle rect)
|
||||
{
|
||||
Color color = (_tree.Enabled ? _treeViewItemNormal : _treeViewItemDisabled).GetColor(ColorProperty.BorderColor);
|
||||
using (Pen pen = new Pen(_tree.Enabled ? Color.Black : SystemColors.GrayText))
|
||||
VisualStyleRenderer style;
|
||||
if (_tree.Enabled)
|
||||
{
|
||||
graphics.DrawRectangle(pen, new Rectangle(rect.X, rect.Y, rect.Width - 1, rect.Height - 1));
|
||||
}
|
||||
if (_tree.Focused)
|
||||
style = _treeViewBorderFocus;
|
||||
else
|
||||
style = _treeViewBorderNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
style = _treeViewBorderDisabled;
|
||||
}
|
||||
|
||||
style.DrawBackground(graphics, rect, graphics.ClipBounds.ToRectangle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,11 @@ namespace Acacia.Controls
|
||||
return new Point(_this.Left, _this.Top);
|
||||
}
|
||||
|
||||
public static Rectangle ToRectangle(this RectangleF _this)
|
||||
{
|
||||
return new Rectangle((int)_this.X, (int)_this.Y, (int)_this.Width, (int)_this.Height);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/// Copyright 2016 Kopano b.v.
|
||||
/// Copyright 2017 Kopano b.v.
|
||||
///
|
||||
/// This program is free software: you can redistribute it and/or modify
|
||||
/// it under the terms of the GNU Affero General Public License, version 3,
|
||||
|
Loading…
x
Reference in New Issue
Block a user