Skip to content

Commit e2099a0

Browse files
dwilhelmmoellerm
authored andcommitted
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
1 parent 1cd8588 commit e2099a0

5 files changed

Lines changed: 73 additions & 10 deletions

File tree

External/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ public NodeCheckBox(string propertyName)
4646

4747
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
4848
{
49-
return new Size(ImageSize, ImageSize);
49+
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
50+
int scaledY = node.Tree.GetScaledSize(ImageSize);
51+
return new Size(scaledX, scaledY);
5052
}
5153

5254
public override void Draw(TreeNodeAdv node, DrawContext context)
@@ -56,13 +58,15 @@ public override void Draw(TreeNodeAdv node, DrawContext context)
5658
if (Application.RenderWithVisualStyles)
5759
{
5860
VisualStyleRenderer renderer;
61+
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
62+
int scaledY = node.Tree.GetScaledSize(ImageSize);
5963
if (state == CheckState.Indeterminate)
6064
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.MixedNormal);
6165
else if (state == CheckState.Checked)
6266
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.CheckedNormal);
6367
else
6468
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.UncheckedNormal);
65-
renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, ImageSize, ImageSize));
69+
renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, scaledX, scaledY));
6670
}
6771
else
6872
{

External/Aga.Controls/Tree/NodeControls/NodeIcon.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
1919
{
2020
Image image = GetIcon(node);
2121
if (image != null)
22-
return image.Size;
22+
{
23+
int scaledX = node.Tree.GetScaledSize(image.Size.Width, false);
24+
int scaledY = node.Tree.GetScaledSize(image.Size.Height);
25+
return new Size(scaledX, scaledY); ;
26+
}
2327
else
28+
{
2429
return Size.Empty;
30+
}
2531
}
2632

2733

External/Aga.Controls/Tree/NodeControls/NodePlusMinus.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,27 @@ public NodePlusMinus()
4646

4747
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
4848
{
49-
return new Size(Width, Width);
49+
int scaledX = node.Tree.GetScaledSize(Width, false);
50+
int scaledY = node.Tree.GetScaledSize(Width);
51+
return new Size(scaledX, scaledY);
5052
}
5153

5254
public override void Draw(TreeNodeAdv node, DrawContext context)
5355
{
5456
if (node.CanExpand)
5557
{
5658
Rectangle r = context.Bounds;
57-
int dy = (int)Math.Round((float)(r.Height - ImageSize) / 2);
59+
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
60+
int scaledY = node.Tree.GetScaledSize(ImageSize);
61+
int dy = (int)Math.Round((float)(r.Height - scaledY) / 2);
5862
if (Application.RenderWithVisualStyles)
5963
{
6064
VisualStyleRenderer renderer;
6165
if (node.IsExpanded)
6266
renderer = OpenedRenderer;
6367
else
6468
renderer = ClosedRenderer;
65-
renderer.DrawBackground(context.Graphics, new Rectangle(r.X, r.Y + dy, ImageSize, ImageSize));
69+
renderer.DrawBackground(context.Graphics, new Rectangle(r.X, r.Y + dy, scaledX, scaledY));
6670
}
6771
else
6872
{

External/Aga.Controls/Tree/TreeViewAdv.Draw.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,9 @@ private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
259259
while (curNode != _root && curNode != null)
260260
{
261261
int level = curNode.Level;
262-
int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
263-
int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
262+
int scaledIndent = node.Tree.GetScaledSize(_indent, false);
263+
int x = (level - 1) * scaledIndent + NodePlusMinus.ImageSize / 2 + LeftMargin;
264+
int width = node.Tree.GetScaledSize(NodePlusMinus.Width - NodePlusMinus.ImageSize / 2, false);
264265
int y = rowRect.Y;
265266
int y2 = y + rowRect.Height;
266267

External/Aga.Controls/Tree/TreeViewAdv.cs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public partial class TreeViewAdv : Control
4242
private List<TreeNodeAdv> _expandingNodes = new List<TreeNodeAdv>();
4343
private AbortableThreadPool _threadPool = new AbortableThreadPool();
4444

45+
private float dpiX;
46+
private float dpiY;
47+
private float dpiXscale = 1;
48+
private float dpiYscale = 1;
49+
4550
#region Public Events
4651

4752
[Category("Action")]
@@ -204,6 +209,7 @@ protected virtual void OnDropNodeValidating(Point point, ref TreeNodeAdv node)
204209
public TreeViewAdv()
205210
{
206211
InitializeComponent();
212+
SetDPI();
207213
SetStyle(ControlStyles.AllPaintingInWmPaint
208214
| ControlStyles.UserPaint
209215
| ControlStyles.OptimizedDoubleBuffer
@@ -216,6 +222,7 @@ public TreeViewAdv()
216222
_columnHeaderHeight = 20;
217223
else
218224
_columnHeaderHeight = 17;
225+
_columnHeaderHeight = GetScaledSize(_columnHeaderHeight);
219226

220227
//BorderStyle = BorderStyle.Fixed3D;
221228
_hScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
@@ -245,6 +252,46 @@ public TreeViewAdv()
245252
ExpandingIcon.IconChanged += ExpandingIconChanged;
246253
}
247254

255+
public void SetDPI()
256+
{
257+
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx
258+
const int _default_dpi = 96;
259+
Graphics g = this.CreateGraphics();
260+
261+
try
262+
{
263+
this.dpiX = g.DpiX;
264+
this.dpiY = g.DpiY;
265+
}
266+
finally
267+
{
268+
g.Dispose();
269+
}
270+
if (dpiX > 0)
271+
{
272+
this.dpiXscale = dpiX / _default_dpi;
273+
}
274+
if (dpiY > 0)
275+
{
276+
this.dpiYscale = dpiY / _default_dpi;
277+
}
278+
}
279+
280+
public int GetScaledSize(int size, bool useY = true)
281+
{
282+
int scaledsize = size;
283+
284+
if (useY && this.dpiYscale > 1)
285+
{
286+
scaledsize = (int)(this.dpiYscale * size);
287+
}
288+
else if (this.dpiXscale > 1)
289+
{
290+
scaledsize = (int)(this.dpiXscale * size);
291+
}
292+
return scaledsize;
293+
}
294+
248295
void ExpandingIconChanged(object sender, EventArgs e)
249296
{
250297
if (IsHandleCreated && !IsDisposed)
@@ -543,11 +590,12 @@ internal IEnumerable<NodeControlInfo> GetNodeControls(TreeNodeAdv node, Rectangl
543590
if (node == null)
544591
yield break;
545592

593+
int scaledIndent = node.Tree.GetScaledSize(_indent, false);
546594
int y = rowRect.Y;
547-
int x = (node.Level - 1) * _indent + LeftMargin;
595+
int x = (node.Level - 1) * scaledIndent + LeftMargin;
548596
int width = 0;
549597
if (node.Row == 0 && ShiftFirstNode)
550-
x -= _indent;
598+
x -= scaledIndent;
551599
Rectangle rect = Rectangle.Empty;
552600

553601
if (ShowPlusMinus)

0 commit comments

Comments
 (0)