Files

131 lines
5.1 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.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);
}
}
}