Scale TreeViewAdv elements based on DPI

TreeViewAdv assumed a standard 96 DPI display. This commit fixes some
problems on high DPI displays, including some problems mentioned in
OHM issue 830.

- column header height
- checkboxes
- icons
- indentation
This commit is contained in:
David Wilhelm 2017-08-10 12:34:05 -07:00 committed by Michael Möller
parent 1cd85881e8
commit e2099a034d
5 changed files with 73 additions and 10 deletions

View File

@ -46,7 +46,9 @@ namespace Aga.Controls.Tree.NodeControls
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
{
return new Size(ImageSize, ImageSize);
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
int scaledY = node.Tree.GetScaledSize(ImageSize);
return new Size(scaledX, scaledY);
}
public override void Draw(TreeNodeAdv node, DrawContext context)
@ -56,13 +58,15 @@ namespace Aga.Controls.Tree.NodeControls
if (Application.RenderWithVisualStyles)
{
VisualStyleRenderer renderer;
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
int scaledY = node.Tree.GetScaledSize(ImageSize);
if (state == CheckState.Indeterminate)
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.MixedNormal);
else if (state == CheckState.Checked)
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.CheckedNormal);
else
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.UncheckedNormal);
renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, ImageSize, ImageSize));
renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, scaledX, scaledY));
}
else
{

View File

@ -19,10 +19,16 @@ namespace Aga.Controls.Tree.NodeControls
{
Image image = GetIcon(node);
if (image != null)
return image.Size;
{
int scaledX = node.Tree.GetScaledSize(image.Size.Width, false);
int scaledY = node.Tree.GetScaledSize(image.Size.Height);
return new Size(scaledX, scaledY); ;
}
else
{
return Size.Empty;
}
}
public override void Draw(TreeNodeAdv node, DrawContext context)

View File

@ -46,7 +46,9 @@ namespace Aga.Controls.Tree.NodeControls
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
{
return new Size(Width, Width);
int scaledX = node.Tree.GetScaledSize(Width, false);
int scaledY = node.Tree.GetScaledSize(Width);
return new Size(scaledX, scaledY);
}
public override void Draw(TreeNodeAdv node, DrawContext context)
@ -54,7 +56,9 @@ namespace Aga.Controls.Tree.NodeControls
if (node.CanExpand)
{
Rectangle r = context.Bounds;
int dy = (int)Math.Round((float)(r.Height - ImageSize) / 2);
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
int scaledY = node.Tree.GetScaledSize(ImageSize);
int dy = (int)Math.Round((float)(r.Height - scaledY) / 2);
if (Application.RenderWithVisualStyles)
{
VisualStyleRenderer renderer;
@ -62,7 +66,7 @@ namespace Aga.Controls.Tree.NodeControls
renderer = OpenedRenderer;
else
renderer = ClosedRenderer;
renderer.DrawBackground(context.Graphics, new Rectangle(r.X, r.Y + dy, ImageSize, ImageSize));
renderer.DrawBackground(context.Graphics, new Rectangle(r.X, r.Y + dy, scaledX, scaledY));
}
else
{

View File

@ -259,8 +259,9 @@ namespace Aga.Controls.Tree
while (curNode != _root && curNode != null)
{
int level = curNode.Level;
int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
int scaledIndent = node.Tree.GetScaledSize(_indent, false);
int x = (level - 1) * scaledIndent + NodePlusMinus.ImageSize / 2 + LeftMargin;
int width = node.Tree.GetScaledSize(NodePlusMinus.Width - NodePlusMinus.ImageSize / 2, false);
int y = rowRect.Y;
int y2 = y + rowRect.Height;

View File

@ -42,6 +42,11 @@ namespace Aga.Controls.Tree
private List<TreeNodeAdv> _expandingNodes = new List<TreeNodeAdv>();
private AbortableThreadPool _threadPool = new AbortableThreadPool();
private float dpiX;
private float dpiY;
private float dpiXscale = 1;
private float dpiYscale = 1;
#region Public Events
[Category("Action")]
@ -204,6 +209,7 @@ namespace Aga.Controls.Tree
public TreeViewAdv()
{
InitializeComponent();
SetDPI();
SetStyle(ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint
| ControlStyles.OptimizedDoubleBuffer
@ -216,6 +222,7 @@ namespace Aga.Controls.Tree
_columnHeaderHeight = 20;
else
_columnHeaderHeight = 17;
_columnHeaderHeight = GetScaledSize(_columnHeaderHeight);
//BorderStyle = BorderStyle.Fixed3D;
_hScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
@ -245,6 +252,46 @@ namespace Aga.Controls.Tree
ExpandingIcon.IconChanged += ExpandingIconChanged;
}
public void SetDPI()
{
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx
const int _default_dpi = 96;
Graphics g = this.CreateGraphics();
try
{
this.dpiX = g.DpiX;
this.dpiY = g.DpiY;
}
finally
{
g.Dispose();
}
if (dpiX > 0)
{
this.dpiXscale = dpiX / _default_dpi;
}
if (dpiY > 0)
{
this.dpiYscale = dpiY / _default_dpi;
}
}
public int GetScaledSize(int size, bool useY = true)
{
int scaledsize = size;
if (useY && this.dpiYscale > 1)
{
scaledsize = (int)(this.dpiYscale * size);
}
else if (this.dpiXscale > 1)
{
scaledsize = (int)(this.dpiXscale * size);
}
return scaledsize;
}
void ExpandingIconChanged(object sender, EventArgs e)
{
if (IsHandleCreated && !IsDisposed)
@ -543,11 +590,12 @@ namespace Aga.Controls.Tree
if (node == null)
yield break;
int scaledIndent = node.Tree.GetScaledSize(_indent, false);
int y = rowRect.Y;
int x = (node.Level - 1) * _indent + LeftMargin;
int x = (node.Level - 1) * scaledIndent + LeftMargin;
int width = 0;
if (node.Row == 0 && ShiftFirstNode)
x -= _indent;
x -= scaledIndent;
Rectangle rect = Rectangle.Empty;
if (ShowPlusMinus)