131 lines
5.1 KiB
C#
131 lines
5.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Drawing;
|
||
using System.Drawing.Drawing2D;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Windows.Forms;
|
||
|
||
namespace AccompanyingAssistant {
|
||
public class BubbleForm : Form {
|
||
private string _message = "";
|
||
private int cornerRadius = 12;
|
||
private int tailHeight = 10;
|
||
private Color bubbleColor = Color.FromArgb(255, 255, 230);
|
||
private Color borderColor = Color.FromArgb(220, 220, 200);
|
||
private Font messageFont = new Font("微软雅黑", 9);
|
||
|
||
public string Message {
|
||
get { return _message; }
|
||
set {
|
||
_message = value;
|
||
CalculateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
public BubbleForm() {
|
||
this.FormBorderStyle = FormBorderStyle.None;
|
||
this.ShowInTaskbar = false;
|
||
this.StartPosition = FormStartPosition.Manual;
|
||
this.Padding = new Padding(12, 12, 12, 12 + tailHeight);
|
||
this.BackColor = Color.Magenta;
|
||
this.TransparencyKey = Color.Magenta;
|
||
this.DoubleBuffered = true;
|
||
|
||
// 初始大小
|
||
this.Size = new Size(200, 100);
|
||
|
||
// 添加关闭按钮
|
||
var closeButton = new Button();
|
||
closeButton.Text = "×";
|
||
closeButton.FlatStyle = FlatStyle.Flat;
|
||
closeButton.FlatAppearance.BorderSize = 0;
|
||
closeButton.BackColor = Color.Transparent;
|
||
closeButton.ForeColor = Color.Gray;
|
||
closeButton.Font = new Font("Arial", 8, FontStyle.Bold);
|
||
closeButton.Size = new Size(20, 20);
|
||
closeButton.Location = new Point(this.Width - closeButton.Width - 5, 5);
|
||
closeButton.Click += (s, e) => this.Hide();
|
||
this.Controls.Add(closeButton);
|
||
}
|
||
public void UpdateSize() {
|
||
CalculateSize();
|
||
}
|
||
|
||
private void CalculateSize() {
|
||
using (Graphics g = this.CreateGraphics()) {
|
||
// 增加最大宽度限制,防止气泡过宽
|
||
int maxWidth = Screen.PrimaryScreen.WorkingArea.Width / 3;
|
||
SizeF textSize = g.MeasureString(_message, messageFont, maxWidth);
|
||
|
||
int newWidth = (int)Math.Max(150, Math.Min(maxWidth, textSize.Width + this.Padding.Horizontal));
|
||
int newHeight = (int)(textSize.Height + this.Padding.Vertical);
|
||
|
||
this.Size = new Size(newWidth, newHeight);
|
||
|
||
if (this.Controls.Count > 0) {
|
||
this.Controls[0].Location = new Point(this.Width - 25, 5);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
protected override void OnPaint(PaintEventArgs e) {
|
||
base.OnPaint(e);
|
||
Graphics g = e.Graphics;
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
|
||
// 创建气泡路径
|
||
GraphicsPath path = new GraphicsPath();
|
||
Rectangle mainRect = new Rectangle(0, 0, this.Width, this.Height - tailHeight);
|
||
|
||
// 绘制圆角矩形主体
|
||
path.AddArc(mainRect.X, mainRect.Y, cornerRadius, cornerRadius, 180, 90);
|
||
path.AddArc(mainRect.X + mainRect.Width - cornerRadius, mainRect.Y, cornerRadius, cornerRadius, 270, 90);
|
||
path.AddArc(mainRect.X + mainRect.Width - cornerRadius, mainRect.Y + mainRect.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90);
|
||
|
||
// 添加尾巴
|
||
int tailWidth = 20;
|
||
int tailX = this.Width / 2 - tailWidth / 2;
|
||
path.AddLine(mainRect.X + mainRect.Width - cornerRadius, mainRect.Y + mainRect.Height, tailX + tailWidth, mainRect.Y + mainRect.Height);
|
||
path.AddLine(tailX + tailWidth, mainRect.Y + mainRect.Height, this.Width / 2, this.Height);
|
||
path.AddLine(this.Width / 2, this.Height, tailX, mainRect.Y + mainRect.Height);
|
||
path.AddLine(tailX, mainRect.Y + mainRect.Height, mainRect.X + cornerRadius, mainRect.Y + mainRect.Height);
|
||
|
||
path.AddArc(mainRect.X, mainRect.Y + mainRect.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90);
|
||
|
||
// 填充气泡
|
||
using (Brush bubbleBrush = new SolidBrush(bubbleColor)) {
|
||
g.FillPath(bubbleBrush, path);
|
||
}
|
||
|
||
// 绘制边框
|
||
using (Pen borderPen = new Pen(borderColor, 1)) {
|
||
g.DrawPath(borderPen, path);
|
||
}
|
||
|
||
// 绘制文本
|
||
using (Brush textBrush = new SolidBrush(Color.Black)) {
|
||
g.DrawString(_message, messageFont, textBrush,
|
||
new RectangleF(
|
||
this.Padding.Left,
|
||
this.Padding.Top,
|
||
this.Width - this.Padding.Horizontal,
|
||
this.Height - this.Padding.Vertical));
|
||
}
|
||
}
|
||
|
||
private void InitializeComponent() {
|
||
this.SuspendLayout();
|
||
//
|
||
// BubbleForm
|
||
//
|
||
this.ClientSize = new System.Drawing.Size(284, 261);
|
||
this.Name = "BubbleForm";
|
||
this.ResumeLayout(false);
|
||
|
||
}
|
||
}
|
||
}
|