* 全部SunnyUI控件支持DPI自适应缩放。

This commit is contained in:
Sunny 2021-11-18 19:14:35 +08:00
parent ebfef9c105
commit 88d608a946
49 changed files with 423 additions and 224 deletions

Binary file not shown.

Binary file not shown.

View File

@ -24,6 +24,7 @@
private void uiButton1_Click(object sender, System.EventArgs e) private void uiButton1_Click(object sender, System.EventArgs e)
{ {
btn = new UIButton(); btn = new UIButton();
btn.SetDPIScale();
btn.Text = "Button" + index++.ToString("D2"); btn.Text = "Button" + index++.ToString("D2");
//btn.Click += Btn_Click; //btn.Click += Btn_Click;

View File

@ -1,7 +1,7 @@
using Sunny.UI; using Sunny.UI;
using System.Windows.Forms; using System.Windows.Forms;
namespace SunnyUI.VIP.Demo namespace Sunny.UI.Demo
{ {
public partial class FSplitContainer : UIPage public partial class FSplitContainer : UIPage
{ {

View File

@ -1,5 +1,5 @@
 
namespace SunnyUI.VIP.Demo namespace Sunny.UI.Demo
{ {
partial class FSplitContainer partial class FSplitContainer
{ {

View File

@ -1,5 +1,4 @@
using SunnyUI.VIP.Demo; using System;
using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;

View File

@ -485,18 +485,20 @@ namespace Sunny.UI
} }
} }
using Font tmp = SubFont.DPIScaleFont();
if (Option.XAxis.AxisLabel.Show) if (Option.XAxis.AxisLabel.Show)
{ {
float start = DrawOrigin.X + DrawBarWidth / 2.0f; float start = DrawOrigin.X + DrawBarWidth / 2.0f;
foreach (var data in Option.XAxis.Data) foreach (var data in Option.XAxis.Data)
{ {
SizeF sf = g.MeasureString(data, SubFont); SizeF sf = g.MeasureString(data, tmp);
g.DrawString(data, SubFont, ForeColor, start - sf.Width / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length); g.DrawString(data, tmp, ForeColor, start - sf.Width / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length);
start += DrawBarWidth; start += DrawBarWidth;
} }
SizeF sfname = g.MeasureString(Option.XAxis.Name, SubFont); SizeF sfname = g.MeasureString(Option.XAxis.Name, tmp);
g.DrawString(Option.XAxis.Name, SubFont, ForeColor, DrawOrigin.X + (DrawSize.Width - sfname.Width) / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length + sfname.Height); g.DrawString(Option.XAxis.Name, tmp, ForeColor, DrawOrigin.X + (DrawSize.Width - sfname.Width) / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length + sfname.Height);
} }
if (Option.YAxis.AxisTick.Show) if (Option.YAxis.AxisTick.Show)
@ -545,16 +547,16 @@ namespace Sunny.UI
for (int i = YAxisStart; i <= YAxisEnd; i++) for (int i = YAxisStart; i <= YAxisEnd; i++)
{ {
string label = Option.YAxis.AxisLabel.GetLabel(i * YAxisInterval, idx); string label = Option.YAxis.AxisLabel.GetLabel(i * YAxisInterval, idx);
SizeF sf = g.MeasureString(label, SubFont); SizeF sf = g.MeasureString(label, tmp);
wmax = Math.Max(wmax, sf.Width); wmax = Math.Max(wmax, sf.Width);
g.DrawString(label, SubFont, ForeColor, DrawOrigin.X - Option.YAxis.AxisTick.Length - sf.Width, start - sf.Height / 2.0f); g.DrawString(label, tmp, ForeColor, DrawOrigin.X - Option.YAxis.AxisTick.Length - sf.Width, start - sf.Height / 2.0f);
start -= DrawBarHeight; start -= DrawBarHeight;
} }
SizeF sfname = g.MeasureString(Option.YAxis.Name, SubFont); SizeF sfname = g.MeasureString(Option.YAxis.Name, tmp);
int x = (int)(DrawOrigin.X - Option.YAxis.AxisTick.Length - wmax - sfname.Height); int x = (int)(DrawOrigin.X - Option.YAxis.AxisTick.Length - wmax - sfname.Height);
int y = (int)(Option.Grid.Top + (DrawSize.Height - sfname.Width) / 2); int y = (int)(Option.Grid.Top + (DrawSize.Height - sfname.Width) / 2);
g.DrawString(Option.YAxis.Name, SubFont, ForeColor, new Point(x, y), g.DrawString(Option.YAxis.Name, tmp, ForeColor, new Point(x, y),
new StringFormat() { Alignment = StringAlignment.Center }, 270); new StringFormat() { Alignment = StringAlignment.Center }, 270);
} }
} }
@ -573,14 +575,15 @@ namespace Sunny.UI
g.DrawLine(pn, DrawOrigin.X, pos, Width - Option.Grid.Right, pos); g.DrawLine(pn, DrawOrigin.X, pos, Width - Option.Grid.Right, pos);
} }
SizeF sf = g.MeasureString(line.Name, SubFont); using Font tmp = SubFont.DPIScaleFont();
SizeF sf = g.MeasureString(line.Name, tmp);
if (line.Left == UILeftAlignment.Left) if (line.Left == UILeftAlignment.Left)
g.DrawString(line.Name, SubFont, line.Color, DrawOrigin.X + 4, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, DrawOrigin.X + 4, pos - 2 - sf.Height);
if (line.Left == UILeftAlignment.Center) if (line.Left == UILeftAlignment.Center)
g.DrawString(line.Name, SubFont, line.Color, DrawOrigin.X + (Width - Option.Grid.Left - Option.Grid.Right - sf.Width) / 2, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, DrawOrigin.X + (Width - Option.Grid.Left - Option.Grid.Right - sf.Width) / 2, pos - 2 - sf.Height);
if (line.Left == UILeftAlignment.Right) if (line.Left == UILeftAlignment.Right)
g.DrawString(line.Name, SubFont, line.Color, Width - sf.Width - 4 - Option.Grid.Right, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, Width - sf.Width - 4 - Option.Grid.Right, pos - 2 - sf.Height);
} }
} }
@ -599,7 +602,8 @@ namespace Sunny.UI
for (int i = 0; i < Option.XAxis.Data.Count; i++) for (int i = 0; i < Option.XAxis.Data.Count; i++)
{ {
Bars[0][i].Size = g.MeasureString(Bars[0][i].Tips, SubFont); using Font tmp = SubFont.DPIScaleFont();
Bars[0][i].Size = g.MeasureString(Bars[0][i].Tips, tmp);
} }
} }

View File

@ -171,7 +171,7 @@ namespace Sunny.UI
base.OnPaint(e); base.OnPaint(e);
if (tip != null && !tip.Font.Equals(legendFont)) if (tip != null && !tip.Font.Equals(legendFont))
{ {
tip.Font = legendFont; tip.Font = legendFont.DPIScaleFont();
} }
DrawOption(e.Graphics); DrawOption(e.Graphics);
@ -246,7 +246,8 @@ namespace Sunny.UI
g.DrawString(title.Text, Font, ChartStyle.ForeColor, left, top); g.DrawString(title.Text, Font, ChartStyle.ForeColor, left, top);
SizeF sfs = g.MeasureString(title.SubText, SubFont); using Font tmp = SubFont.DPIScaleFont();
SizeF sfs = g.MeasureString(title.SubText, tmp);
switch (title.Left) switch (title.Left)
{ {
case UILeftAlignment.Left: left = TextInterval; break; case UILeftAlignment.Left: left = TextInterval; break;
@ -260,7 +261,7 @@ namespace Sunny.UI
case UITopAlignment.Bottom: top = top - sf.Height; break; case UITopAlignment.Bottom: top = top - sf.Height; break;
} }
g.DrawString(title.SubText, SubFont, ChartStyle.ForeColor, left, top); g.DrawString(title.SubText, tmp, ChartStyle.ForeColor, left, top);
} }
protected void DrawLegend(Graphics g, UILegend legend) protected void DrawLegend(Graphics g, UILegend legend)
@ -272,9 +273,10 @@ namespace Sunny.UI
float maxWidth = 0; float maxWidth = 0;
float oneHeight = 0; float oneHeight = 0;
using Font tmp = LegendFont.DPIScaleFont();
foreach (var data in legend.Data) foreach (var data in legend.Data)
{ {
SizeF sf = g.MeasureString(data, LegendFont); SizeF sf = g.MeasureString(data, tmp);
totalHeight += sf.Height; totalHeight += sf.Height;
totalWidth += sf.Width; totalWidth += sf.Width;
totalWidth += 20; totalWidth += 20;
@ -313,7 +315,7 @@ namespace Sunny.UI
for (int i = 0; i < legend.DataCount; i++) for (int i = 0; i < legend.DataCount; i++)
{ {
var data = legend.Data[i]; var data = legend.Data[i];
SizeF sf = g.MeasureString(data, LegendFont); SizeF sf = g.MeasureString(data, tmp);
Color color = ChartStyle.GetColor(i); Color color = ChartStyle.GetColor(i);
if (legend.Colors.Count > 0 && i >= 0 && i < legend.Colors.Count) if (legend.Colors.Count > 0 && i >= 0 && i < legend.Colors.Count)
@ -322,7 +324,7 @@ namespace Sunny.UI
if (legend.Orient == UIOrient.Horizontal) if (legend.Orient == UIOrient.Horizontal)
{ {
g.FillRoundRectangle(color, (int)startLeft, (int)top + 1, 18, (int)oneHeight - 2, 5); g.FillRoundRectangle(color, (int)startLeft, (int)top + 1, 18, (int)oneHeight - 2, 5);
g.DrawString(data, LegendFont, color, startLeft + 20, top); g.DrawString(data, tmp, color, startLeft + 20, top);
startLeft += 22; startLeft += 22;
startLeft += sf.Width; startLeft += sf.Width;
} }
@ -330,7 +332,7 @@ namespace Sunny.UI
if (legend.Orient == UIOrient.Vertical) if (legend.Orient == UIOrient.Vertical)
{ {
g.FillRoundRectangle(color, (int)left, (int)startTop + 1, 18, (int)oneHeight - 2, 5); g.FillRoundRectangle(color, (int)left, (int)startTop + 1, 18, (int)oneHeight - 2, 5);
g.DrawString(data, LegendFont, color, left + 20, startTop); g.DrawString(data, tmp, color, left + 20, startTop);
startTop += oneHeight; startTop += oneHeight;
} }
} }

View File

@ -142,7 +142,7 @@ namespace Sunny.UI
private void DrawSeries(Graphics g, List<UIDoughnutSeries> series) private void DrawSeries(Graphics g, List<UIDoughnutSeries> series)
{ {
if (series == null || series.Count == 0) return; if (series == null || series.Count == 0) return;
using Font tmp = LegendFont.DPIScaleFont();
for (int pieIndex = 0; pieIndex < series.Count; pieIndex++) for (int pieIndex = 0; pieIndex < series.Count; pieIndex++)
{ {
var pie = series[pieIndex]; var pie = series[pieIndex];
@ -159,7 +159,7 @@ namespace Sunny.UI
else else
g.FillFan(color, angle.Center, angle.Inner, angle.Outer, angle.Start - 90, angle.Sweep); g.FillFan(color, angle.Center, angle.Inner, angle.Outer, angle.Start - 90, angle.Sweep);
Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, LegendFont); Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, tmp);
if (pie.Label.Show && ActiveAzIndex == azIndex) if (pie.Label.Show && ActiveAzIndex == azIndex)
{ {

View File

@ -217,7 +217,7 @@ namespace Sunny.UI
} }
if (XScale == null || YScale == null) return; if (XScale == null || YScale == null) return;
using Font tmp = SubFont.DPIScaleFont();
//X Tick //X Tick
if (Option.XAxis.AxisTick.Show) if (Option.XAxis.AxisTick.Show)
{ {
@ -245,8 +245,8 @@ namespace Sunny.UI
label = XLabels[i].ToString("F" + Option.XAxis.AxisLabel.DecimalCount); label = XLabels[i].ToString("F" + Option.XAxis.AxisLabel.DecimalCount);
} }
SizeF sf = g.MeasureString(label, SubFont); SizeF sf = g.MeasureString(label, tmp);
g.DrawString(label, SubFont, ForeColor, x - sf.Width / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length); g.DrawString(label, tmp, ForeColor, x - sf.Width / 2.0f, DrawOrigin.Y + Option.XAxis.AxisTick.Length);
} }
if (x.Equals(DrawOrigin.X)) continue; if (x.Equals(DrawOrigin.X)) continue;
@ -260,8 +260,8 @@ namespace Sunny.UI
} }
} }
SizeF sfName = g.MeasureString(Option.XAxis.Name, SubFont); SizeF sfName = g.MeasureString(Option.XAxis.Name, tmp);
g.DrawString(Option.XAxis.Name, SubFont, ForeColor, g.DrawString(Option.XAxis.Name, tmp, ForeColor,
DrawOrigin.X + (DrawSize.Width - sfName.Width) / 2.0f, DrawOrigin.X + (DrawSize.Width - sfName.Width) / 2.0f,
DrawOrigin.Y + Option.XAxis.AxisTick.Length + sfName.Height); DrawOrigin.Y + Option.XAxis.AxisTick.Length + sfName.Height);
} }
@ -279,9 +279,9 @@ namespace Sunny.UI
if (Option.YAxis.AxisLabel.Show) if (Option.YAxis.AxisLabel.Show)
{ {
string label = YLabels[i].ToString(YScale.Format); string label = YLabels[i].ToString(YScale.Format);
SizeF sf = g.MeasureString(label, SubFont); SizeF sf = g.MeasureString(label, tmp);
widthMax = Math.Max(widthMax, sf.Width); widthMax = Math.Max(widthMax, sf.Width);
g.DrawString(label, SubFont, ForeColor, DrawOrigin.X - Option.YAxis.AxisTick.Length - sf.Width, y - sf.Height / 2.0f); g.DrawString(label, tmp, ForeColor, DrawOrigin.X - Option.YAxis.AxisTick.Length - sf.Width, y - sf.Height / 2.0f);
} }
if (y.Equals(DrawOrigin.Y)) continue; if (y.Equals(DrawOrigin.Y)) continue;
@ -295,10 +295,10 @@ namespace Sunny.UI
} }
} }
SizeF sfName = g.MeasureString(Option.YAxis.Name, SubFont); SizeF sfName = g.MeasureString(Option.YAxis.Name, tmp);
float xx = DrawOrigin.X - Option.YAxis.AxisTick.Length - widthMax - sfName.Height / 2.0f; float xx = DrawOrigin.X - Option.YAxis.AxisTick.Length - widthMax - sfName.Height / 2.0f;
float yy = Option.Grid.Top + DrawSize.Height / 2.0f; float yy = Option.Grid.Top + DrawSize.Height / 2.0f;
g.DrawStringRotateAtCenter(Option.YAxis.Name, SubFont, ForeColor, new PointF(xx, yy), 270); g.DrawStringRotateAtCenter(Option.YAxis.Name, tmp, ForeColor, new PointF(xx, yy), 270);
} }
} }
@ -534,7 +534,7 @@ namespace Sunny.UI
private void DrawAxisScales(Graphics g) private void DrawAxisScales(Graphics g)
{ {
if (YScale == null) return; if (YScale == null) return;
using Font tmp = SubFont.DPIScaleFont();
foreach (var line in Option.YAxisScaleLines) foreach (var line in Option.YAxisScaleLines)
{ {
float pos = YScale.CalcYPixel(line.Value, DrawOrigin.Y, DrawSize.Height); float pos = YScale.CalcYPixel(line.Value, DrawOrigin.Y, DrawSize.Height);
@ -545,14 +545,15 @@ namespace Sunny.UI
g.DrawLine(pn, DrawOrigin.X + 1, pos, Width - Option.Grid.Right - 1, pos); g.DrawLine(pn, DrawOrigin.X + 1, pos, Width - Option.Grid.Right - 1, pos);
} }
SizeF sf = g.MeasureString(line.Name, SubFont);
SizeF sf = g.MeasureString(line.Name, tmp);
if (line.Left == UILeftAlignment.Left) if (line.Left == UILeftAlignment.Left)
g.DrawString(line.Name, SubFont, line.Color, DrawOrigin.X + 4, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, DrawOrigin.X + 4, pos - 2 - sf.Height);
if (line.Left == UILeftAlignment.Center) if (line.Left == UILeftAlignment.Center)
g.DrawString(line.Name, SubFont, line.Color, DrawOrigin.X + (Width - Option.Grid.Left - Option.Grid.Right - sf.Width) / 2, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, DrawOrigin.X + (Width - Option.Grid.Left - Option.Grid.Right - sf.Width) / 2, pos - 2 - sf.Height);
if (line.Left == UILeftAlignment.Right) if (line.Left == UILeftAlignment.Right)
g.DrawString(line.Name, SubFont, line.Color, Width - sf.Width - 4 - Option.Grid.Right, pos - 2 - sf.Height); g.DrawString(line.Name, tmp, line.Color, Width - sf.Width - 4 - Option.Grid.Right, pos - 2 - sf.Height);
} }
int idx = 0; int idx = 0;
@ -566,7 +567,7 @@ namespace Sunny.UI
g.DrawLine(pn, pos, DrawOrigin.Y - 1, pos, Option.Grid.Top + 1); g.DrawLine(pn, pos, DrawOrigin.Y - 1, pos, Option.Grid.Top + 1);
} }
SizeF sf = g.MeasureString(line.Name, SubFont); SizeF sf = g.MeasureString(line.Name, tmp);
float x = pos - sf.Width; float x = pos - sf.Width;
if (x < Option.Grid.Left) x = pos + 2; if (x < Option.Grid.Left) x = pos + 2;
float y = Option.Grid.Top + 4 + sf.Height * idx; float y = Option.Grid.Top + 4 + sf.Height * idx;
@ -577,7 +578,7 @@ namespace Sunny.UI
} }
idx++; idx++;
g.DrawString(line.Name, SubFont, line.Color, x, y); g.DrawString(line.Name, tmp, line.Color, x, y);
} }
} }
@ -668,7 +669,8 @@ namespace Sunny.UI
{ {
using (Graphics g = this.CreateGraphics()) using (Graphics g = this.CreateGraphics())
{ {
SizeF sf = g.MeasureString(sb.ToString(), SubFont); using Font tmp = SubFont.DPIScaleFont();
SizeF sf = g.MeasureString(sb.ToString(), tmp);
tip.Size = new Size((int)sf.Width + 4, (int)sf.Height + 4); tip.Size = new Size((int)sf.Width + 4, (int)sf.Height + 4);
} }

View File

@ -158,6 +158,7 @@ namespace Sunny.UI
{ {
var pie = series[pieIndex]; var pie = series[pieIndex];
RectangleF rect = GetSeriesRect(pie); RectangleF rect = GetSeriesRect(pie);
using Font tmp = LegendFont.DPIScaleFont();
for (int azIndex = 0; azIndex < pie.Data.Count; azIndex++) for (int azIndex = 0; azIndex < pie.Data.Count; azIndex++)
{ {
Color color = ChartStyle.GetColor(azIndex); Color color = ChartStyle.GetColor(azIndex);
@ -165,7 +166,7 @@ namespace Sunny.UI
if (data.StyleCustomMode) color = data.Color; if (data.StyleCustomMode) color = data.Color;
RectangleF rectx = new RectangleF(rect.X - 10, rect.Y - 10, rect.Width + 20, rect.Width + 20); RectangleF rectx = new RectangleF(rect.X - 10, rect.Y - 10, rect.Width + 20, rect.Width + 20);
g.FillPie(color, (ActivePieIndex == pieIndex && ActiveAzIndex == azIndex) ? rectx : rect, Angles[pieIndex][azIndex].Start - 90, Angles[pieIndex][azIndex].Sweep); g.FillPie(color, (ActivePieIndex == pieIndex && ActiveAzIndex == azIndex) ? rectx : rect, Angles[pieIndex][azIndex].Start - 90, Angles[pieIndex][azIndex].Sweep);
Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, LegendFont); Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, tmp);
if (pie.Label.Show) if (pie.Label.Show)
{ {

View File

@ -323,11 +323,11 @@ namespace Sunny.UI
return control.CreateGraphics().DpiX / 96.0f; return control.CreateGraphics().DpiX / 96.0f;
} }
public static Font DPIScaleFont(this Control control) // public static Font DPIScaleFont(this Control control)
{ // {
return new Font(control.Font.FontFamily, control.Font.Size / control.DPIScale(), // return new Font(control.Font.FontFamily, control.Font.Size / control.DPIScale(),
control.Font.Style, control.Font.Unit, control.Font.GdiCharSet); // control.Font.Style, control.Font.Unit, control.Font.GdiCharSet);
} // }
public static Font DPIScaleFont(this Control control, Font font) public static Font DPIScaleFont(this Control control, Font font)
{ {
@ -335,11 +335,22 @@ namespace Sunny.UI
font.Style, font.Unit, font.GdiCharSet); font.Style, font.Unit, font.GdiCharSet);
} }
public static Font DPIScaleFont(this Font font)
{
using Control control = new();
return new Font(font.FontFamily, font.Size / control.DPIScale(),
font.Style, font.Unit, font.GdiCharSet);
}
public static void SetDPIScaleFont(this Control control) public static void SetDPIScaleFont(this Control control)
{ {
if (!control.DPIScale().Equals(1)) if (!control.DPIScale().Equals(1))
{ {
control.Font = control.DPIScaleFont(); if (control is IStyleInterface ctrl)
{
if (!ctrl.IsScaled)
control.Font = control.DPIScaleFont(control.Font);
}
} }
} }
@ -349,7 +360,15 @@ namespace Sunny.UI
foreach (Control con in control.Controls) foreach (Control con in control.Controls)
{ {
list.Add(con); list.Add(con);
if (con is IToolTip) continue;
if (con is UITextBox) continue;
if (con is UIDropControl) continue;
if (con is UIListBox) continue;
if (con is UIImageListBox) continue;
if (con is UIPagination) continue;
if (con is UIRichTextBox) continue;
if (con is UITreeView) continue;
if (con is UINavBar) continue;
if (con.Controls.Count > 0) if (con.Controls.Count > 0)
{ {

View File

@ -22,6 +22,8 @@
using Microsoft.Win32; using Microsoft.Win32;
using System; using System;
#pragma warning disable CA1416 // 验证平台兼容性
namespace Sunny.UI namespace Sunny.UI
{ {
public static class UEnvironment public static class UEnvironment

View File

@ -39,7 +39,7 @@ namespace Sunny.UI
public static class UIMessageTip public static class UIMessageTip
{ {
//默认字体。当样式中的Font==null时用该字体替换 //默认字体。当样式中的Font==null时用该字体替换
static readonly Font DefaultFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 12); static readonly Font DefaultFont = UIFontColor.Font;
//文本格式。用于测量和绘制 //文本格式。用于测量和绘制
static readonly StringFormat DefStringFormat = StringFormat.GenericTypographic; static readonly StringFormat DefStringFormat = StringFormat.GenericTypographic;
@ -301,6 +301,8 @@ namespace Sunny.UI
var size = Size.Empty; var size = Size.Empty;
var iconBounds = Rectangle.Empty; var iconBounds = Rectangle.Empty;
var textBounds = Rectangle.Empty; var textBounds = Rectangle.Empty;
Font font = style.TextFont ?? DefaultFont;
using Font tmp = font.DPIScaleFont();
if (style.Icon != null) if (style.Icon != null)
{ {
@ -317,7 +319,7 @@ namespace Sunny.UI
textBounds.X += style.IconSpacing; textBounds.X += style.IconSpacing;
} }
textBounds.Size = Size.Truncate(GraphicsUtils.MeasureString(text, style.TextFont ?? DefaultFont, 0, DefStringFormat)); textBounds.Size = Size.Truncate(GraphicsUtils.MeasureString(text, tmp, 0, DefStringFormat));
size.Width += textBounds.Width; size.Width += textBounds.Width;
if (size.Height < textBounds.Height) if (size.Height < textBounds.Height)
@ -330,6 +332,7 @@ namespace Sunny.UI
} }
textBounds.Offset(style.TextOffset); textBounds.Offset(style.TextOffset);
} }
size += style.Padding.Size; size += style.Padding.Size;
iconBounds.Offset(style.Padding.Left, style.Padding.Top); iconBounds.Offset(style.Padding.Left, style.Padding.Top);
textBounds.Offset(style.Padding.Left, style.Padding.Top); textBounds.Offset(style.Padding.Left, style.Padding.Top);
@ -370,7 +373,7 @@ namespace Sunny.UI
{ {
textBrush = new SolidBrush(style.TextColor); textBrush = new SolidBrush(style.TextColor);
//DEBUG: g.DrawRectangle(new Border(Color.Red){ Width=1, Direction= Direction.Inner}.Pen, textBounds); //DEBUG: g.DrawRectangle(new Border(Color.Red){ Width=1, Direction= Direction.Inner}.Pen, textBounds);
g.DrawString(text, style.TextFont ?? DefaultFont, textBrush, textBounds.Location, DefStringFormat); g.DrawString(text, tmp, textBrush, textBounds.Location, DefStringFormat);
} }
g.Flush(FlushIntention.Sync); g.Flush(FlushIntention.Sync);
@ -617,7 +620,7 @@ namespace Sunny.UI
Width = 2 Width = 2
}; };
IconSpacing = 5; IconSpacing = 5;
TextFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 12); TextFont = UIFontColor.Font;
var fontName = TextFont.Name; var fontName = TextFont.Name;
if (fontName == "宋体") { TextOffset = new Point(1, 1); } if (fontName == "宋体") { TextOffset = new Point(1, 1); }
TextColor = Color.Black; TextColor = Color.Black;

View File

@ -11,6 +11,30 @@ namespace Sunny.UI
Translate(); Translate();
} }
public override void SetDPIScale()
{
if (!IsScaled)
{
m_opacitySlider.SetDPIScaleFont();
m_colorBar.SetDPIScaleFont();
foreach (var label in this.GetControls<UILabel>())
{
label.SetDPIScaleFont();
}
foreach (var label in this.GetControls<UITextBox>())
{
label.SetDPIScaleFont();
}
btnOK.SetDPIScaleFont();
btnCancel.SetDPIScaleFont();
}
base.SetDPIScale();
}
public void Translate() public void Translate()
{ {
btnOK.Text = UILocalize.OK; btnOK.Text = UILocalize.OK;

View File

@ -21,6 +21,20 @@ namespace Sunny.UI
Translate(); Translate();
} }
public override void SetDPIScale()
{
if (!IsScaled)
{
edtFilter.SetDPIScaleFont();
btnSearch.SetDPIScaleFont();
btnClear.SetDPIScaleFont();
btnOK.SetDPIScaleFont();
btnCancel.SetDPIScaleFont();
}
base.SetDPIScale();
}
public void Translate() public void Translate()
{ {
btnOK.Text = UILocalize.OK; btnOK.Text = UILocalize.OK;

View File

@ -11,6 +11,17 @@ namespace Sunny.UI
public UITreeView TreeView => treeView; public UITreeView TreeView => treeView;
public override void SetDPIScale()
{
if (!IsScaled)
{
btnOK.SetDPIScaleFont();
btnCancel.SetDPIScaleFont();
}
base.SetDPIScale();
}
[DefaultValue(false)] [DefaultValue(false)]
public bool CheckBoxes public bool CheckBoxes
{ {

View File

@ -326,6 +326,16 @@ namespace Sunny.UI
Translate(); Translate();
} }
public override void SetDPIScale()
{
if (!IsScaled)
{
TopPanel.SetDPIScaleFont();
}
base.SetDPIScale();
}
public void Translate() public void Translate()
{ {
months.Clear(); months.Clear();
@ -711,7 +721,7 @@ namespace Sunny.UI
if (ShowToday) if (ShowToday)
{ {
using (Font SubFont = new Font("微软雅黑", 10.5f)) using (Font SubFont = new Font("微软雅黑", 10.5f / this.DPIScale()))
{ {
e.Graphics.FillRectangle(p3.FillColor, p3.Width - width * 4 + 1, p3.Height - height + 1, width * 4 - 2, height - 2); e.Graphics.FillRectangle(p3.FillColor, p3.Width - width * 4 + 1, p3.Height - height + 1, width * 4 - 2, height - 2);
e.Graphics.FillRoundRectangle(PrimaryColor, new Rectangle(p3.Width - width * 4 + 6, p3.Height - height + 3, 8, height - 10), 3); e.Graphics.FillRoundRectangle(PrimaryColor, new Rectangle(p3.Width - width * 4 + 6, p3.Height - height + 3, 8, height - 10), 3);

View File

@ -732,6 +732,24 @@ namespace Sunny.UI
Translate(); Translate();
} }
public override void SetDPIScale()
{
if (!IsScaled)
{
TopPanel.SetDPIScaleFont();
foreach (var label in this.GetControls<UILabel>())
{
label.SetDPIScaleFont();
}
btnOK.SetDPIScaleFont();
btnCancel.SetDPIScaleFont();
}
base.SetDPIScale();
}
public void Translate() public void Translate()
{ {
months.Clear(); months.Clear();
@ -1238,7 +1256,7 @@ namespace Sunny.UI
if (ShowToday) if (ShowToday)
{ {
using (Font SubFont = new Font("微软雅黑", 10.5f)) using (Font SubFont = new Font("微软雅黑", 10.5f / this.DPIScale()))
{ {
e.Graphics.FillRectangle(p3.FillColor, p3.Width - width * 4 + 1, p3.Height - height + 1, width * 4 - 2, height - 2); e.Graphics.FillRectangle(p3.FillColor, p3.Width - width * 4 + 1, p3.Height - height + 1, width * 4 - 2, height - 2);
e.Graphics.FillRoundRectangle(PrimaryColor, new Rectangle((int)(p3.Width - width * 4 + 6), p3.Height - height + 3, 8, height - 10), 3); e.Graphics.FillRoundRectangle(PrimaryColor, new Rectangle((int)(p3.Width - width * 4 + 6), p3.Height - height + 3, 8, height - 10), 3);

View File

@ -438,6 +438,22 @@ namespace Sunny.UI
btnCancel.Text = UILocalize.Cancel; btnCancel.Text = UILocalize.Cancel;
} }
public override void SetDPIScale()
{
if (!IsScaled)
{
foreach (var label in this.GetControls<UILabel>())
{
label.SetDPIScaleFont();
}
btnOK.SetDPIScaleFont();
btnCancel.SetDPIScaleFont();
}
base.SetDPIScale();
}
private void UITimeItem_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) private void UITimeItem_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{ {
if (e.Delta < 0) if (e.Delta < 0)

View File

@ -182,13 +182,14 @@ namespace Sunny.UI
if (Enabled && ShowTips && !string.IsNullOrEmpty(TipsText)) if (Enabled && ShowTips && !string.IsNullOrEmpty(TipsText))
{ {
using Font tmpFont = TipsFont.DPIScaleFont();
e.Graphics.SetHighQuality(); e.Graphics.SetHighQuality();
SizeF sf = e.Graphics.MeasureString(TipsText, TipsFont); SizeF sf = e.Graphics.MeasureString(TipsText, tmpFont);
float sfMax = Math.Max(sf.Width, sf.Height); float sfMax = Math.Max(sf.Width, sf.Height);
float x = Width - 1 - 2 - sfMax; float x = Width - 1 - 2 - sfMax;
float y = 1 + 1; float y = 1 + 1;
e.Graphics.FillEllipse(TipsColor, x, y, sfMax, sfMax); e.Graphics.FillEllipse(TipsColor, x, y, sfMax, sfMax);
e.Graphics.DrawString(TipsText, TipsFont, TipsForeColor, x + sfMax / 2.0f - sf.Width / 2.0f, y + sfMax / 2.0f - sf.Height / 2.0f); e.Graphics.DrawString(TipsText, tmpFont, TipsForeColor, x + sfMax / 2.0f - sf.Width / 2.0f, y + sfMax / 2.0f - sf.Height / 2.0f);
} }
if (Focused && ShowFocusLine) if (Focused && ShowFocusLine)

View File

@ -111,14 +111,12 @@ namespace Sunny.UI
for (int i = 0; i < Items.Count; i++) for (int i = 0; i < Items.Count; i++)
{ {
UICheckBox box = new UICheckBox UICheckBox box = new UICheckBox();
{ box.BackColor = Color.Transparent;
BackColor = Color.Transparent, box.Font = Font;
Font = Font, box.Parent = this;
Parent = this, box.Tag = i;
Tag = i, box.Style = Style;
Style = Style
};
box.ValueChanged += Box_ValueChanged; box.ValueChanged += Box_ValueChanged;
boxes.Add(box); boxes.Add(box);
@ -207,23 +205,6 @@ namespace Sunny.UI
return false; return false;
} }
//[Browsable(false)]
//public List<string> SelectedItems
//{
// get
// {
// List<string> items = new List<string>();
// foreach (var checkBox in boxes)
// {
// if (checkBox.Checked)
// items.Add(checkBox.Text);
// }
// return items;
// }
//}
[Browsable(false)] [Browsable(false)]
public List<object> SelectedItems public List<object> SelectedItems
{ {
@ -313,15 +294,6 @@ namespace Sunny.UI
} }
} }
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
foreach (var box in boxes)
{
box.Font = Font;
}
}
/// <summary> /// <summary>
/// 全部选择 /// 全部选择
/// </summary> /// </summary>

View File

@ -66,6 +66,7 @@ namespace Sunny.UI
{ {
item.SelectedColor = Value; item.SelectedColor = Value;
item.Translate(); item.Translate();
item.SetDPIScale();
ItemForm.Show(this); ItemForm.Show(this);
} }

View File

@ -53,6 +53,7 @@ namespace Sunny.UI
item.ShowFilter = ShowFilter; item.ShowFilter = ShowFilter;
ItemForm.Size = ItemSize; ItemForm.Size = ItemSize;
item.ShowButtons = true; item.ShowButtons = true;
item.SetDPIScale();
item.Translate(); item.Translate();
ItemForm.Show(this); ItemForm.Show(this);
} }

View File

@ -178,6 +178,7 @@ namespace Sunny.UI
item.TreeView.ExpandAll(); item.TreeView.ExpandAll();
item.CanSelectRootNode = CanSelectRootNode; item.CanSelectRootNode = CanSelectRootNode;
item.Translate(); item.Translate();
item.SetDPIScale();
ItemForm.Show(this); ItemForm.Show(this);
} }

View File

@ -39,7 +39,7 @@ namespace Sunny.UI
} }
[Browsable(false)] [Browsable(false)]
public bool IsScaled { get; private set; } public bool IsScaled { get; set; }
public void SetDPIScale() public void SetDPIScale()
{ {
@ -50,6 +50,15 @@ namespace Sunny.UI
} }
} }
protected override void OnOpening(CancelEventArgs e)
{
base.OnOpening(e);
if (!IsScaled && UIStyles.DPIScale)
{
SetDPIScale();
}
}
/// <summary> /// <summary>
/// 自定义主题风格 /// 自定义主题风格
/// </summary> /// </summary>

View File

@ -46,9 +46,9 @@ namespace Sunny.UI
} }
[Browsable(false)] [Browsable(false)]
public bool IsScaled { get; private set; } public bool IsScaled { get; set; }
public void SetDPIScale() public virtual void SetDPIScale()
{ {
if (!IsScaled) if (!IsScaled)
{ {

View File

@ -157,6 +157,7 @@ namespace Sunny.UI
item.ShowToday = ShowToday; item.ShowToday = ShowToday;
item.PrimaryColor = RectColor; item.PrimaryColor = RectColor;
item.Translate(); item.Translate();
item.SetDPIScale();
ItemForm.Show(this); ItemForm.Show(this);
} }

View File

@ -63,7 +63,6 @@ namespace Sunny.UI
[Description("日期输入时,显示今日按钮"), Category("SunnyUI")] [Description("日期输入时,显示今日按钮"), Category("SunnyUI")]
public bool ShowToday { get; set; } public bool ShowToday { get; set; }
public UIDatetimePicker() public UIDatetimePicker()
{ {
InitializeComponent(); InitializeComponent();
@ -153,6 +152,7 @@ namespace Sunny.UI
item.ShowToday = ShowToday; item.ShowToday = ShowToday;
item.PrimaryColor = RectColor; item.PrimaryColor = RectColor;
item.Translate(); item.Translate();
item.SetDPIScale();
ItemForm.Show(this); ItemForm.Show(this);
} }

View File

@ -89,8 +89,18 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
if (pnlValue != null) pnlValue.Font = Font;
if (edit != null) edit.Font = Font; if (pnlValue != null)
{
pnlValue.IsScaled = true;
pnlValue.Font = Font;
}
if (edit != null)
{
edit.IsScaled = true;
edit.Font = Font;
}
} }
public event OnValueChanged ValueChanged; public event OnValueChanged ValueChanged;

View File

@ -49,6 +49,18 @@ namespace Sunny.UI
JoinEvents(true); JoinEvents(true);
} }
[Browsable(false)]
public bool IsScaled { get; set; }
public void SetDPIScale()
{
if (!IsScaled)
{
this.SetDPIScaleFont();
IsScaled = true;
}
}
private string watermark; private string watermark;
[DefaultValue(null)] [DefaultValue(null)]

View File

@ -29,7 +29,7 @@ namespace Sunny.UI
/// <summary> /// <summary>
/// 图像按钮 /// 图像按钮
/// </summary> /// </summary>
public sealed class UIImageButton : PictureBox public sealed class UIImageButton : PictureBox, IStyleInterface
{ {
private bool IsPress; private bool IsPress;
private bool IsHover; private bool IsHover;
@ -43,6 +43,16 @@ namespace Sunny.UI
private ContentAlignment textAlign = ContentAlignment.MiddleCenter; private ContentAlignment textAlign = ContentAlignment.MiddleCenter;
private Color foreColor = UIFontColor.Primary; private Color foreColor = UIFontColor.Primary;
/// <summary>
/// 主题样式
/// </summary>
[DefaultValue(UIStyle.Blue), Description("主题样式"), Category("SunnyUI")]
public UIStyle Style
{
get => _style;
set => SetStyle(value);
}
/// <summary> /// <summary>
/// Tag字符串 /// Tag字符串
/// </summary> /// </summary>
@ -50,6 +60,31 @@ namespace Sunny.UI
[Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")] [Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")]
public string TagString { get; set; } public string TagString { get; set; }
public void SetStyleColor(UIBaseStyle uiColor)
{
ForeColor = uiColor.LabelForeColor;
Invalidate();
}
public void SetStyle(UIStyle style)
{
UIBaseStyle uiColor = UIStyles.GetStyleColor(style);
if (!uiColor.IsCustom()) SetStyleColor(uiColor);
_style = style;
}
private UIStyle _style = UIStyle.Blue;
public bool IsScaled { get; private set; }
public void SetDPIScale()
{
if (!IsScaled)
{
this.SetDPIScaleFont();
IsScaled = true;
}
}
[Category("SunnyUI")] [Category("SunnyUI")]
[Description("按钮文字")] [Description("按钮文字")]
[Browsable(true)] [Browsable(true)]
@ -134,6 +169,13 @@ namespace Sunny.UI
base.Font = UIFontColor.Font; base.Font = UIFontColor.Font;
} }
/// <summary>
/// 自定义主题风格
/// </summary>
[DefaultValue(false)]
[Description("获取或设置可以自定义主题风格"), Category("SunnyUI")]
public bool StyleCustomMode { get; set; }
public string Version { get; } public string Version { get; }
/// <summary> /// <summary>

View File

@ -119,6 +119,7 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
listbox.IsScaled = true;
listbox.Font = Font; listbox.Font = Font;
} }
@ -369,7 +370,7 @@ namespace Sunny.UI
} }
[Browsable(false)] [Browsable(false)]
public bool IsScaled { get; private set; } public bool IsScaled { get; set; }
public void SetDPIScale() public void SetDPIScale()
{ {

View File

@ -105,8 +105,18 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
if (pnlValue != null) pnlValue.Font = Font;
if (edit != null) edit.Font = Font; if (pnlValue != null)
{
pnlValue.IsScaled = true;
pnlValue.Font = Font;
}
if (edit != null)
{
edit.IsScaled = true;
edit.Font = Font;
}
} }
private int step = 1; private int step = 1;

View File

@ -322,6 +322,7 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
listbox.IsScaled = true;
listbox.Font = Font; listbox.Font = Font;
} }
@ -606,7 +607,7 @@ namespace Sunny.UI
public string TagString { get; set; } public string TagString { get; set; }
[Browsable(false)] [Browsable(false)]
public bool IsScaled { get; private set; } public bool IsScaled { get; set; }
public void SetDPIScale() public void SetDPIScale()
{ {

View File

@ -112,12 +112,6 @@ namespace Sunny.UI
MenuHelper.Clear(); MenuHelper.Clear();
} }
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
if (NavBarMenu != null) NavBarMenu.Font = Font;
}
[DefaultValue(null)] [DefaultValue(null)]
[Description("关联的TabControl"), Category("SunnyUI")] [Description("关联的TabControl"), Category("SunnyUI")]
public UITabControl TabControl { get; set; } public UITabControl TabControl { get; set; }
@ -334,6 +328,23 @@ namespace Sunny.UI
set => NavBarMenu.ImageList = value; set => NavBarMenu.ImageList = value;
} }
private Font dropMenuFont = UIFontColor.Font;
/// <summary>
/// 标题字体
/// </summary>
[Description("标题字体"), Category("SunnyUI")]
[DefaultValue(typeof(Font), "微软雅黑, 12pt")]
public Font DropMenuFont
{
get => dropMenuFont;
set
{
dropMenuFont = value;
Invalidate();
}
}
private StringAlignment nodeAlignment = StringAlignment.Far; private StringAlignment nodeAlignment = StringAlignment.Far;
[DefaultValue(StringAlignment.Far)] [DefaultValue(StringAlignment.Far)]
@ -599,6 +610,8 @@ namespace Sunny.UI
NavBarMenu.Style = UIStyles.Style; NavBarMenu.Style = UIStyles.Style;
NavBarMenu.Items.Clear(); NavBarMenu.Items.Clear();
NavBarMenu.ImageList = ImageList; NavBarMenu.ImageList = ImageList;
NavBarMenu.IsScaled = false;
NavBarMenu.Font = DropMenuFont;
foreach (TreeNode node in Nodes[SelectedIndex].Nodes) foreach (TreeNode node in Nodes[SelectedIndex].Nodes)
{ {
ToolStripMenuItem item = new ToolStripMenuItem(node.Text) { Tag = node }; ToolStripMenuItem item = new ToolStripMenuItem(node.Text) { Tag = node };

View File

@ -623,24 +623,28 @@ namespace Sunny.UI
if (ShowTips && MenuHelper.GetTipsText(e.Node).IsValid() && TreeNodeSymbols.NotContainsKey(e.Node)) if (ShowTips && MenuHelper.GetTipsText(e.Node).IsValid() && TreeNodeSymbols.NotContainsKey(e.Node))
{ {
SizeF tipsSize = e.Graphics.MeasureString(MenuHelper.GetTipsText(e.Node), TipsFont); var tmpFont = this.DPIScaleFont(TipsFont);
SizeF tipsSize = e.Graphics.MeasureString(MenuHelper.GetTipsText(e.Node), tmpFont);
float sfMax = Math.Max(tipsSize.Width, tipsSize.Height) + 1; float sfMax = Math.Max(tipsSize.Width, tipsSize.Height) + 1;
float tipsLeft = Width - (ScrollBarVisible ? 50 : 30) - 6 - sfMax; float tipsLeft = Width - (ScrollBarVisible ? ScrollBarInfo.VerticalScrollBarWidth() : 0) - sfMax - sfMax;
float tipsTop = e.Bounds.Y + (ItemHeight - sfMax) / 2; float tipsTop = e.Bounds.Y + (ItemHeight - sfMax) / 2;
if (MenuHelper[e.Node] != null) if (MenuHelper[e.Node] != null)
{ {
using StringFormat alignment = GDI.SetAlignment();
if (MenuHelper[e.Node].TipsCustom) if (MenuHelper[e.Node].TipsCustom)
{ {
e.Graphics.FillEllipse(MenuHelper[e.Node].TipsBackColor, tipsLeft, tipsTop, sfMax, sfMax); e.Graphics.FillEllipse(MenuHelper[e.Node].TipsBackColor, tipsLeft, tipsTop, sfMax, sfMax);
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TipsFont, MenuHelper[e.Node].TipsForeColor, tipsLeft + sfMax / 2.0f - tipsSize.Width / 2.0f, tipsTop + 1 + sfMax / 2.0f - tipsSize.Height / 2.0f); e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), tmpFont, MenuHelper[e.Node].TipsForeColor, new RectangleF(tipsLeft, tipsTop, sfMax, sfMax), alignment);
} }
else else
{ {
e.Graphics.FillEllipse(TipsColor, tipsLeft, tipsTop, sfMax, sfMax); e.Graphics.FillEllipse(TipsColor, tipsLeft, tipsTop, sfMax, sfMax);
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TipsFont, TipsForeColor, tipsLeft + sfMax / 2.0f - tipsSize.Width / 2.0f, tipsTop + 1 + sfMax / 2.0f - tipsSize.Height / 2.0f); e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), tmpFont, TipsForeColor, new RectangleF(tipsLeft, tipsTop, sfMax, sfMax), alignment);
} }
} }
tmpFont.Dispose();
} }
} }
} }

View File

@ -123,11 +123,14 @@ namespace Sunny.UI
b16.Text = UILocalize.Next; b16.Text = UILocalize.Next;
btnSelect.Text = UILocalize.SelectTitle; btnSelect.Text = UILocalize.SelectTitle;
SizeF sf = b0.CreateGraphics().MeasureString(b0.Text, b0.Font); using (Font tmpFont = this.DPIScaleFont(b0.Font))
{
SizeF sf = b0.CreateGraphics().MeasureString(b0.Text, tmpFont);
b0.Width = b0.SymbolSize + (int)sf.Width + 10; b0.Width = b0.SymbolSize + (int)sf.Width + 10;
sf = b16.CreateGraphics().MeasureString(b16.Text, b16.Font); sf = b16.CreateGraphics().MeasureString(b16.Text, tmpFont);
b16.Width = b16.SymbolSize + (int)sf.Width + 10; b16.Width = b16.SymbolSize + (int)sf.Width + 10;
}
btnSelect.Width = (int)btnSelect.CreateGraphics().MeasureString(btnSelect.Text, btnSelect.Font).Width + 16; btnSelect.Width = (int)btnSelect.CreateGraphics().MeasureString(btnSelect.Text, btnSelect.Font).Width + 16;

View File

@ -53,9 +53,9 @@ namespace Sunny.UI
} }
[Browsable(false)] [Browsable(false)]
public bool IsScaled { get; private set; } public bool IsScaled { get; set; }
public void SetDPIScale() public virtual void SetDPIScale()
{ {
if (!IsScaled) if (!IsScaled)
{ {

View File

@ -250,14 +250,5 @@ namespace Sunny.UI
Invalidate(); Invalidate();
} }
} }
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
foreach (var button in buttons)
{
button.Font = Font;
}
}
} }
} }

View File

@ -262,6 +262,8 @@ namespace Sunny.UI
public void SetScrollInfo() public void SetScrollInfo()
{ {
bar.Width = ScrollBarInfo.VerticalScrollBarWidth() + 1;
bar.Left = Width - bar.Width - 1;
if (bar == null) if (bar == null)
{ {
return; return;
@ -284,7 +286,7 @@ namespace Sunny.UI
private void SizeChange() private void SizeChange()
{ {
bar.Top = 2; bar.Top = 2;
bar.Width = ScrollBarInfo.VerticalScrollBarWidth(); bar.Width = ScrollBarInfo.VerticalScrollBarWidth() + 1;
bar.Left = Width - bar.Width - 1; bar.Left = Width - bar.Width - 1;
bar.Height = Height - 4; bar.Height = Height - 4;
bar.BringToFront(); bar.BringToFront();

View File

@ -464,6 +464,7 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
edit.IsScaled = true;
edit.Font = Font; edit.Font = Font;
CalcEditHeight(); CalcEditHeight();
SizeChange(); SizeChange();

View File

@ -149,6 +149,7 @@ namespace Sunny.UI
{ {
item.Time = Value; item.Time = Value;
item.Translate(); item.Translate();
item.SetDPIScale();
ItemForm.Show(this); ItemForm.Show(this);
} }
} }

View File

@ -204,13 +204,16 @@ namespace Sunny.UI
var bmp = new Bitmap(e.ToolTipSize.Width, e.ToolTipSize.Height); var bmp = new Bitmap(e.ToolTipSize.Width, e.ToolTipSize.Height);
var g = Graphics.FromImage(bmp); var g = Graphics.FromImage(bmp);
int symbolWidth = tooltip.Symbol > 0 ? tooltip.SymbolSize : 0; int symbolWidth = tooltip.Symbol > 0 ? tooltip.SymbolSize : 0;
Font tmpTitleFont = TitleFont.DPIScaleFont();
Font tmpFont = Font.DPIScaleFont();
SizeF titleSize = new SizeF(0, 0); SizeF titleSize = new SizeF(0, 0);
if (tooltip.Title.IsValid()) if (tooltip.Title.IsValid())
{ {
titleSize = g.MeasureString(tooltip.Title, TitleFont); titleSize = g.MeasureString(tooltip.Title, tmpTitleFont);
} }
SizeF textSize = g.MeasureString(tooltip.Description, Font); SizeF textSize = g.MeasureString(tooltip.Description, tmpFont);
int allWidth = (int)Math.Max(textSize.Width, titleSize.Width) + 10; int allWidth = (int)Math.Max(textSize.Width, titleSize.Width) + 10;
if (symbolWidth > 0) allWidth = allWidth + symbolWidth + 5; if (symbolWidth > 0) allWidth = allWidth + symbolWidth + 5;
int allHeight = titleSize.Height > 0 ? int allHeight = titleSize.Height > 0 ?
@ -218,6 +221,9 @@ namespace Sunny.UI
(int)textSize.Height + 10; (int)textSize.Height + 10;
e.ToolTipSize = new Size(allWidth, allHeight); e.ToolTipSize = new Size(allWidth, allHeight);
bmp.Dispose(); bmp.Dispose();
tmpTitleFont.Dispose();
tmpFont.Dispose();
} }
} }
} }
@ -225,6 +231,9 @@ namespace Sunny.UI
private void ToolTipExDraw(object sender, DrawToolTipEventArgs e) private void ToolTipExDraw(object sender, DrawToolTipEventArgs e)
{ {
Font tmpTitleFont = TitleFont.DPIScaleFont();
Font tmpFont = Font.DPIScaleFont();
if (ToolTipControls.ContainsKey(e.AssociatedControl)) if (ToolTipControls.ContainsKey(e.AssociatedControl))
{ {
var tooltip = ToolTipControls[e.AssociatedControl]; var tooltip = ToolTipControls[e.AssociatedControl];
@ -244,10 +253,10 @@ namespace Sunny.UI
{ {
if (tooltip.Title.IsValid()) if (tooltip.Title.IsValid())
{ {
titleSize = e.Graphics.MeasureString(tooltip.Title, TitleFont); titleSize = e.Graphics.MeasureString(tooltip.Title, tmpTitleFont);
} }
e.Graphics.DrawString(tooltip.Title, TitleFont, ForeColor, e.Graphics.DrawString(tooltip.Title, tmpTitleFont, ForeColor,
tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5, 5); tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5, 5);
} }
@ -258,14 +267,17 @@ namespace Sunny.UI
e.Bounds.Width - 5, 5 + titleSize.Height + 3); e.Bounds.Width - 5, 5 + titleSize.Height + 3);
} }
e.Graphics.DrawString(e.ToolTipText, Font, ForeColor, e.Graphics.DrawString(e.ToolTipText, tmpFont, ForeColor,
tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5, tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5,
titleSize.Height > 0 ? 10 + titleSize.Height : 5); titleSize.Height > 0 ? 10 + titleSize.Height : 5);
} }
else else
{ {
e.Graphics.DrawString(e.ToolTipText, e.Font, ForeColor, 0, 0); e.Graphics.DrawString(e.ToolTipText, tmpFont, ForeColor, 0, 0);
} }
tmpTitleFont.Dispose();
tmpFont.Dispose();
} }
public class ToolTipControl : ISymbol public class ToolTipControl : ISymbol

View File

@ -533,7 +533,11 @@ namespace Sunny.UI
protected override void OnFontChanged(EventArgs e) protected override void OnFontChanged(EventArgs e)
{ {
base.OnFontChanged(e); base.OnFontChanged(e);
if (view != null) view.Font = Font; if (view != null)
{
view.IsScaled = true;
view.Font = Font;
}
} }
protected override void OnMouseWheel(MouseEventArgs e) protected override void OnMouseWheel(MouseEventArgs e)
@ -660,6 +664,18 @@ namespace Sunny.UI
base.DoubleBuffered = true; base.DoubleBuffered = true;
} }
[Browsable(false)]
public bool IsScaled { get; set; }
public void SetDPIScale()
{
if (!IsScaled)
{
this.SetDPIScaleFont();
IsScaled = true;
}
}
[DefaultValue(typeof(Color), "155, 200, 255")] [DefaultValue(typeof(Color), "155, 200, 255")]
public Color HoverColor { get; set; } = Color.FromArgb(155, 200, 255); public Color HoverColor { get; set; } = Color.FromArgb(155, 200, 255);

View File

@ -29,7 +29,6 @@
* 2021-08-17: V3.0.8 IFrame接口 * 2021-08-17: V3.0.8 IFrame接口
******************************************************************************/ ******************************************************************************/
using Sunny.UI.Win32;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@ -82,7 +81,7 @@ namespace Sunny.UI
if (!this.DPIScale().Equals(1)) if (!this.DPIScale().Equals(1))
{ {
this.TitleFont = this.DPIScaleFont(this.TitleFont); TitleFont = this.DPIScaleFont(TitleFont);
} }
foreach (Control control in this.GetAllDPIScaleControls()) foreach (Control control in this.GetAllDPIScaleControls())

View File

@ -40,6 +40,29 @@ namespace Sunny.UI
{ {
public sealed partial class UINotifier : Form public sealed partial class UINotifier : Form
{ {
[Browsable(false)]
public bool IsScaled { get; private set; }
public void SetDPIScale()
{
if (!IsScaled && UIStyles.DPIScale)
{
this.SetDPIScaleFont();
noteTitle.Font = noteTitle.DPIScaleFont(noteTitle.Font);
noteContent.Font = noteContent.DPIScaleFont(noteContent.Font);
noteDate.Font = noteDate.DPIScaleFont(noteDate.Font);
foreach (Control control in this.GetAllDPIScaleControls())
{
control.SetDPIScaleFont();
}
IsScaled = true;
}
}
#region GLOBALS #region GLOBALS
private class NoteLocation // Helper class to handle Note position private class NoteLocation // Helper class to handle Note position
@ -362,6 +385,7 @@ namespace Sunny.UI
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
private void onMenuClick(object sender, EventArgs e) private void onMenuClick(object sender, EventArgs e)
{ {
closeAllToolStripMenuItem.Font = menu.DPIScaleFont(menu.Font);
menu.Show(buttonMenu, new Point(0, buttonMenu.Height)); menu.Show(buttonMenu, new Point(0, buttonMenu.Height));
} }
@ -479,6 +503,7 @@ namespace Sunny.UI
isDialog, isDialog,
timeout, timeout,
inApp); inApp);
not.SetDPIScale();
not.Show(); // Show the note not.Show(); // Show the note
if (not.Timeout >= 500) // Start auto close timer (if any) if (not.Timeout >= 500) // Start auto close timer (if any)
@ -614,6 +639,7 @@ namespace Sunny.UI
} }
UINotifier note = new UINotifier(content, type, title, true); // Instantiate the UINotifier form UINotifier note = new UINotifier(content, type, title, true); // Instantiate the UINotifier form
note.SetDPIScale();
note.backDialogStyle = backDialogStyle; note.backDialogStyle = backDialogStyle;
switch (note.backDialogStyle) switch (note.backDialogStyle)

View File

@ -48,7 +48,7 @@
// //
// noteContent // noteContent
// //
this.noteContent.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.noteContent.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.noteContent.Image = global::Sunny.UI.Properties.Resources.notifier; this.noteContent.Image = global::Sunny.UI.Properties.Resources.notifier;
this.noteContent.Location = new System.Drawing.Point(43, 30); this.noteContent.Location = new System.Drawing.Point(43, 30);
this.noteContent.Name = "noteContent"; this.noteContent.Name = "noteContent";
@ -60,11 +60,11 @@
// noteDate // noteDate
// //
this.noteDate.AutoSize = true; this.noteDate.AutoSize = true;
this.noteDate.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.noteDate.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.noteDate.Image = global::Sunny.UI.Properties.Resources.notifier; this.noteDate.Image = global::Sunny.UI.Properties.Resources.notifier;
this.noteDate.Location = new System.Drawing.Point(11, 103); this.noteDate.Location = new System.Drawing.Point(11, 97);
this.noteDate.Name = "noteDate"; this.noteDate.Name = "noteDate";
this.noteDate.Size = new System.Drawing.Size(13, 9); this.noteDate.Size = new System.Drawing.Size(18, 15);
this.noteDate.TabIndex = 4; this.noteDate.TabIndex = 4;
this.noteDate.Text = "- -"; this.noteDate.Text = "- -";
// //
@ -72,7 +72,7 @@
// //
this.buttonClose.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(140)))), ((int)(((byte)(230))))); this.buttonClose.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(140)))), ((int)(((byte)(230)))));
this.buttonClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; this.buttonClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.buttonClose.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.buttonClose.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.buttonClose.ForeColor = System.Drawing.Color.White; this.buttonClose.ForeColor = System.Drawing.Color.White;
this.buttonClose.Location = new System.Drawing.Point(256, 2); this.buttonClose.Location = new System.Drawing.Point(256, 2);
this.buttonClose.Name = "buttonClose"; this.buttonClose.Name = "buttonClose";
@ -98,23 +98,24 @@
// //
// menu // menu
// //
this.menu.ImageScalingSize = new System.Drawing.Size(24, 24);
this.menu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeAllToolStripMenuItem}); this.closeAllToolStripMenuItem});
this.menu.Name = "menu"; this.menu.Name = "menu";
this.menu.Size = new System.Drawing.Size(120, 26); this.menu.Size = new System.Drawing.Size(146, 34);
// //
// closeAllToolStripMenuItem // closeAllToolStripMenuItem
// //
this.closeAllToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.closeAllToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.closeAllToolStripMenuItem.Name = "closeAllToolStripMenuItem"; this.closeAllToolStripMenuItem.Name = "closeAllToolStripMenuItem";
this.closeAllToolStripMenuItem.Size = new System.Drawing.Size(119, 22); this.closeAllToolStripMenuItem.Size = new System.Drawing.Size(145, 30);
this.closeAllToolStripMenuItem.Text = "Close All"; this.closeAllToolStripMenuItem.Text = "Close All";
this.closeAllToolStripMenuItem.Click += new System.EventHandler(this.onMenuCloseAllClick); this.closeAllToolStripMenuItem.Click += new System.EventHandler(this.onMenuCloseAllClick);
// //
// noteTitle // noteTitle
// //
this.noteTitle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(140)))), ((int)(((byte)(230))))); this.noteTitle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(140)))), ((int)(((byte)(230)))));
this.noteTitle.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.noteTitle.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.noteTitle.ForeColor = System.Drawing.Color.White; this.noteTitle.ForeColor = System.Drawing.Color.White;
this.noteTitle.Location = new System.Drawing.Point(2, 2); this.noteTitle.Location = new System.Drawing.Point(2, 2);
this.noteTitle.Name = "noteTitle"; this.noteTitle.Name = "noteTitle";
@ -126,11 +127,11 @@
// idLabel // idLabel
// //
this.idLabel.AutoSize = true; this.idLabel.AutoSize = true;
this.idLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.idLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.idLabel.Image = global::Sunny.UI.Properties.Resources.notifier; this.idLabel.Image = global::Sunny.UI.Properties.Resources.notifier;
this.idLabel.Location = new System.Drawing.Point(296, 103); this.idLabel.Location = new System.Drawing.Point(296, 103);
this.idLabel.Name = "idLabel"; this.idLabel.Name = "idLabel";
this.idLabel.Size = new System.Drawing.Size(21, 9); this.idLabel.Size = new System.Drawing.Size(35, 15);
this.idLabel.TabIndex = 7; this.idLabel.TabIndex = 7;
this.idLabel.Text = "0000"; this.idLabel.Text = "0000";
this.idLabel.Visible = false; this.idLabel.Visible = false;
@ -138,8 +139,10 @@
// icon // icon
// //
this.icon.BackColor = System.Drawing.Color.White; this.icon.BackColor = System.Drawing.Color.White;
this.icon.Font = new System.Drawing.Font("微软雅黑", 12F); this.icon.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.icon.IsScaled = false;
this.icon.Location = new System.Drawing.Point(10, 51); this.icon.Location = new System.Drawing.Point(10, 51);
this.icon.MinimumSize = new System.Drawing.Size(1, 1);
this.icon.Name = "icon"; this.icon.Name = "icon";
this.icon.Padding = new System.Windows.Forms.Padding(40, 0, 0, 0); this.icon.Padding = new System.Windows.Forms.Padding(40, 0, 0, 0);
this.icon.Size = new System.Drawing.Size(32, 30); this.icon.Size = new System.Drawing.Size(32, 30);

View File

@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <root>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">