188 lines
7.4 KiB
C#
188 lines
7.4 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Drawing;
|
||
using System.Windows.Forms;
|
||
|
||
namespace FontPreview
|
||
{
|
||
/// <summary>
|
||
/// 字体对比对话框。
|
||
/// 模式一(showList=true):把已加入对比列表的多个字体纵向滚动排列,同一文字/字号并排渲染。
|
||
/// 模式二(showList=false):从全部字体里选两个下拉框对比。
|
||
/// </summary>
|
||
public class CompareDialog : Form
|
||
{
|
||
private List<FontItem> items;
|
||
private bool listMode;
|
||
private ComboBox cboA;
|
||
private ComboBox cboB;
|
||
private TextBox txtText;
|
||
private NumericUpDown numSize;
|
||
private PictureBox picA;
|
||
private PictureBox picB;
|
||
private Label lblNameA;
|
||
private Label lblNameB;
|
||
private Panel scrollPanel;
|
||
private List<PictureBox> listPics = new List<PictureBox>();
|
||
private List<Label> listNames = new List<Label>();
|
||
private List<RoundPanel> listCards = new List<RoundPanel>();
|
||
private Action<string> installCallback;
|
||
|
||
public CompareDialog(List<FontItem> items, bool showList, Action<string> installCallback = null)
|
||
{
|
||
this.installCallback = installCallback;
|
||
this.items = items;
|
||
this.listMode = showList;
|
||
Text = listMode ? "字体多字体对比(已加入 " + items.Count + " 个)" : "字体并排对比";
|
||
FormBorderStyle = FormBorderStyle.SizableToolWindow;
|
||
StartPosition = FormStartPosition.CenterParent;
|
||
ClientSize = new Size(820, 600);
|
||
Font = new Font("Microsoft YaHei UI", 9f);
|
||
MinimumSize = new Size(620, 460);
|
||
|
||
// 顶部:文字 + 字号 + 渲染
|
||
Label lt = new Label { Text = "文字:", Location = new Point(12, 15), Size = new Size(44, 20) };
|
||
txtText = new TextBox { Location = new Point(62, 12), Size = new Size(560, 24), Text = "永字八法 横平竖直 你好世界 ABC 0123" };
|
||
Label ls = new Label { Text = "字号:", Location = new Point(632, 15), Size = new Size(40, 20) };
|
||
numSize = new NumericUpDown { Location = new Point(676, 12), Size = new Size(60, 24), Minimum = 12, Maximum = 120, Value = 36 };
|
||
Button btnGo = new Button { Text = "渲染", Location = new Point(744, 11), Size = new Size(58, 26) };
|
||
btnGo.Click += OnRender;
|
||
numSize.ValueChanged += OnRender;
|
||
txtText.Leave += delegate { OnRender(null, null); };
|
||
txtText.KeyDown += delegate (object s, KeyEventArgs k) { if (k.KeyCode == Keys.Enter) { OnRender(null, null); k.SuppressKeyPress = true; } };
|
||
Controls.Add(lt); Controls.Add(txtText); Controls.Add(ls); Controls.Add(numSize); Controls.Add(btnGo);
|
||
|
||
if (listMode)
|
||
{
|
||
scrollPanel = new Panel { Location = new Point(12, 44), Size = new Size(790, 544), AutoScroll = true, BackColor = Color.White };
|
||
Controls.Add(scrollPanel);
|
||
RebuildList();
|
||
}
|
||
else
|
||
{
|
||
Label la = new Label { Text = "字体 A:", Location = new Point(12, 48), Size = new Size(50, 20) };
|
||
cboA = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Location = new Point(62, 45), Size = new Size(360, 24) };
|
||
Label lb = new Label { Text = "字体 B:", Location = new Point(430, 48), Size = new Size(50, 20) };
|
||
cboB = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Location = new Point(480, 45), Size = new Size(268, 24) };
|
||
foreach (FontItem it in items)
|
||
{
|
||
string s = it.DisplayName + " —— " + it.Name;
|
||
cboA.Items.Add(s);
|
||
cboB.Items.Add(s);
|
||
}
|
||
if (cboA.Items.Count > 0) cboA.SelectedIndex = 0;
|
||
if (cboB.Items.Count > 1) cboB.SelectedIndex = 1; else if (cboB.Items.Count > 0) cboB.SelectedIndex = 0;
|
||
lblNameA = new Label { Location = new Point(12, 82), Size = new Size(776, 18), ForeColor = Color.DimGray };
|
||
lblNameB = new Label { Location = new Point(12, 282), Size = new Size(776, 18), ForeColor = Color.DimGray };
|
||
picA = new PictureBox { Location = new Point(12, 102), Size = new Size(776, 176), BackColor = Color.FromArgb(242, 244, 247), SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle };
|
||
picB = new PictureBox { Location = new Point(12, 302), Size = new Size(776, 176), BackColor = Color.FromArgb(242, 244, 247), SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle };
|
||
Controls.Add(la); Controls.Add(cboA);
|
||
Controls.Add(lb); Controls.Add(cboB);
|
||
Controls.Add(lblNameA); Controls.Add(lblNameB);
|
||
Controls.Add(picA); Controls.Add(picB);
|
||
}
|
||
|
||
Shown += delegate { OnRender(null, null); };
|
||
}
|
||
|
||
private void RebuildList()
|
||
{
|
||
scrollPanel.Controls.Clear();
|
||
listPics.Clear();
|
||
listNames.Clear();
|
||
listCards.Clear();
|
||
int w = scrollPanel.ClientSize.Width - 24;
|
||
if (w < 400) w = 400;
|
||
for (int i = 0; i < items.Count; i++)
|
||
{
|
||
FontItem it = items[i];
|
||
RoundPanel card = UiTheme.CreateCard(w, 180);
|
||
Panel accent = UiTheme.CreateAccentBar(14, 16);
|
||
Label name = UiTheme.CreateCardTitle(it.DisplayName, 26, 12, w - 44);
|
||
PictureBox pic = UiTheme.CreatePreviewBox(18, 46, w - 36, 120);
|
||
// 右键:以快捷方式安装
|
||
ContextMenuStrip cm = new ContextMenuStrip();
|
||
ToolStripMenuItem miInstall = new ToolStripMenuItem("以快捷方式安装(复制到左侧目录)");
|
||
miInstall.Click += delegate
|
||
{
|
||
if (installCallback != null) installCallback(it.Path);
|
||
};
|
||
cm.Items.Add(miInstall);
|
||
card.ContextMenuStrip = cm;
|
||
pic.ContextMenuStrip = cm;
|
||
name.ContextMenuStrip = cm;
|
||
// 左键复制字体名
|
||
card.Cursor = Cursors.Hand;
|
||
EventHandler copyClick = delegate { try { Clipboard.SetText(it.Name); } catch { } };
|
||
card.MouseClick += (MouseEventHandler)delegate (object s, MouseEventArgs e) { if (e.Button == MouseButtons.Left) copyClick(s, e); };
|
||
pic.MouseClick += (MouseEventHandler)delegate (object s, MouseEventArgs e) { if (e.Button == MouseButtons.Left) copyClick(s, e); };
|
||
name.MouseClick += (MouseEventHandler)delegate (object s, MouseEventArgs e) { if (e.Button == MouseButtons.Left) copyClick(s, e); };
|
||
card.Controls.Add(accent);
|
||
card.Controls.Add(name);
|
||
card.Controls.Add(pic);
|
||
scrollPanel.Controls.Add(card);
|
||
listCards.Add(card);
|
||
listNames.Add(name);
|
||
listPics.Add(pic);
|
||
}
|
||
}
|
||
|
||
private void OnRender(object sender, EventArgs e)
|
||
{
|
||
if (listMode)
|
||
{
|
||
for (int i = 0; i < items.Count; i++)
|
||
{
|
||
RenderOne(i, listPics[i], listNames[i]);
|
||
}
|
||
LayoutList();
|
||
}
|
||
else
|
||
{
|
||
RenderOne(cboA.SelectedIndex, picA, lblNameA);
|
||
RenderOne(cboB.SelectedIndex, picB, lblNameB);
|
||
}
|
||
}
|
||
|
||
// 按每张图片实际高度重排卡片纵向位置
|
||
private void LayoutList()
|
||
{
|
||
int y = 8;
|
||
int w = scrollPanel.ClientSize.Width - 24;
|
||
if (w < 400) w = 400;
|
||
for (int i = 0; i < listCards.Count; i++)
|
||
{
|
||
int h = (listPics[i].Image != null) ? listPics[i].Image.Height : 120;
|
||
if (h > 400) h = 400;
|
||
if (h < 60) h = 60;
|
||
listCards[i].Width = w;
|
||
listCards[i].Height = 46 + h + 10;
|
||
listCards[i].Top = y;
|
||
listCards[i].Left = 8;
|
||
listPics[i].Height = h;
|
||
y += listCards[i].Height + 12;
|
||
}
|
||
}
|
||
|
||
private void RenderOne(int idx, PictureBox pic, Label nameLbl)
|
||
{
|
||
if (idx < 0 || idx >= items.Count) return;
|
||
FontItem it = items[idx];
|
||
bool failed;
|
||
Bitmap bmp = Worker.RenderFont(it.Path, it.Name, txtText.Text, (int)numSize.Value, Color.Black, Color.White, out failed);
|
||
nameLbl.Text = it.DisplayName;
|
||
if (bmp != null)
|
||
{
|
||
// 新图画好后再一次性替换旧图,避免中间空白闪烁
|
||
Bitmap old = (Bitmap)pic.Image;
|
||
pic.Image = bmp;
|
||
if (old != null) old.Dispose();
|
||
}
|
||
else
|
||
{
|
||
nameLbl.Text = it.DisplayName + "(渲染失败)";
|
||
}
|
||
}
|
||
}
|
||
}
|