Files
font-preview/FontPreview/CompareDialog.cs
T

188 lines
7.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 + "(渲染失败)";
}
}
}
}