diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs index 4debde0..a4b3d1d 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs @@ -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 } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs index 436cfbc..21c274c 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs @@ -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); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRendererVisualStyles.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRendererVisualStyles.cs index 0769696..8a325f5 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRendererVisualStyles.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRendererVisualStyles.cs @@ -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()); } } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs index 07ad8be..8b980d2 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs @@ -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 } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs index bbf8edf..9f7e722 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs @@ -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,