-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
384 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
using BlueprintExplorer.Properties; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Drawing; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using System.Windows.Forms; | ||
|
||
namespace BlueprintExplorer | ||
{ | ||
internal class BubbleLabel : Control | ||
{ | ||
|
||
private SolidBrush _ForeBrush; | ||
|
||
private bool _Marquee; | ||
|
||
private float _MarqueePos; | ||
|
||
private static Timer _MarqueeTimer; | ||
|
||
public string OverrideText | ||
{ | ||
get => _OverrideText; | ||
set | ||
{ | ||
_OverrideText = value; | ||
Invalidate(); | ||
} | ||
|
||
} | ||
public string Text2 | ||
{ | ||
get => _Text2; | ||
set | ||
{ | ||
_Text2 = value; | ||
InvalidateFragments(value, secondaryFragments); | ||
Invalidate(); | ||
} | ||
|
||
} | ||
|
||
public BubbleLabel() | ||
{ | ||
if (_MarqueeTimer == null) | ||
{ | ||
_MarqueeTimer = new(); | ||
_MarqueeTimer.Interval = 16; | ||
_MarqueeTimer.Start(); | ||
} | ||
|
||
_MarqueeTimer.Tick += OnMarqueeTick; | ||
|
||
DoubleBuffered = true; | ||
} | ||
|
||
private void OnMarqueeTick(object sender, EventArgs e) | ||
{ | ||
if (!_Marquee) return; | ||
|
||
_MarqueePos += 4; | ||
|
||
Invalidate(); | ||
} | ||
|
||
public bool Marquee | ||
{ | ||
get { return _Marquee; } | ||
set | ||
{ | ||
_Marquee = value; | ||
_MarqueePos = 18; | ||
Invalidate(); | ||
} | ||
} | ||
|
||
interface IFragment | ||
{ | ||
SizeF Render(Graphics g, BubbleLabel label); | ||
} | ||
|
||
class TextFragment : IFragment | ||
{ | ||
public string Text = ""; | ||
|
||
public SizeF Render(Graphics g, BubbleLabel label) | ||
{ | ||
if (Text?.Length == 0) return SizeF.Empty; | ||
|
||
TextRenderer.DrawText(g, Text, label.Font, new Point((int)g.Transform.OffsetX, 0), label.ForeColor); | ||
return g.MeasureString(Text, label.Font); | ||
} | ||
} | ||
|
||
class KeyFragment : IFragment | ||
{ | ||
public string Key = ""; | ||
|
||
private bool Meta => Key is "ctrl" or "shift" or "return" or "alt" or "enter"; | ||
|
||
public SizeF Render(Graphics g, BubbleLabel label) | ||
{ | ||
int ratio = Meta ? 2 : 1; | ||
int height = label.Height - 2; | ||
int width = (int)(ratio * height); | ||
|
||
var pen = new Pen(label._ForeBrush, 3); | ||
|
||
float stringWidth = g.MeasureString(Key, label.Font).Width; | ||
|
||
float c = width / 2 - stringWidth / 2; | ||
|
||
g.DrawRectangle(pen, 0, 1, width, height); | ||
g.DrawString(Key, label.Font, label._ForeBrush, new PointF(c, 1)); | ||
|
||
return new SizeF(width, height); | ||
|
||
} | ||
} | ||
|
||
class ImageFragment : IFragment | ||
{ | ||
public Image img; | ||
|
||
public SizeF Render(Graphics g, BubbleLabel label) | ||
{ | ||
if (img == null) return SizeF.Empty; | ||
|
||
float ratio = img.Width / (float)img.Height; | ||
int height = label.Height - 2; | ||
int width = (int)(ratio * height); | ||
|
||
|
||
g.DrawImage(img, new Rectangle(0, 0, width, height)); | ||
return new SizeF(width, height); | ||
} | ||
} | ||
|
||
protected override void OnForeColorChanged(EventArgs e) | ||
{ | ||
base.OnForeColorChanged(e); | ||
_ForeBrush = new(ForeColor); | ||
} | ||
|
||
private List<IFragment> primaryFragments = new(); | ||
private List<IFragment> secondaryFragments = new(); | ||
private string _OverrideText; | ||
private string _Text2; | ||
|
||
private void InvalidateFragments(string template, List<IFragment> fragments) | ||
{ | ||
var rawFragments = TemplateRunner.Iterate(template); | ||
|
||
fragments.Clear(); | ||
foreach (var raw in rawFragments) | ||
{ | ||
if (raw.IsError) | ||
{ | ||
fragments.Add(new TextFragment() { Text = "ERROR:<" + raw.Raw + ">" }); | ||
continue; | ||
} | ||
|
||
if (!raw.IsVariable) | ||
{ | ||
fragments.Add(new TextFragment() { Text = raw.Raw }); | ||
} | ||
else | ||
{ | ||
if (raw.Object == "key") | ||
{ | ||
fragments.Add(new KeyFragment() { Key = raw.Property }); | ||
continue; | ||
} | ||
|
||
//object obj = null; | ||
//if (obj is Bitmap img) | ||
//{ | ||
// fragments.Add(new ImageFragment() { img = img }); | ||
|
||
//} | ||
} | ||
} | ||
|
||
Invalidate(); | ||
|
||
} | ||
|
||
protected override void OnTextChanged(EventArgs e) | ||
{ | ||
base.OnTextChanged(e); | ||
InvalidateFragments(Text, primaryFragments); | ||
} | ||
|
||
private StringFormat _StringFormat; | ||
|
||
protected override void OnPaintBackground(PaintEventArgs pevent) | ||
{ | ||
pevent.Graphics.Clear(BackColor); | ||
} | ||
|
||
protected override void OnPaint(PaintEventArgs e) | ||
{ | ||
_ForeBrush ??= new(ForeColor); | ||
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; | ||
|
||
//_StringFormat = new StringFormat | ||
//{ | ||
// FormatFlags = StringFormatFlags.NoWrap | ||
//}; | ||
|
||
if (_Marquee) | ||
{ | ||
e.Graphics.TranslateTransform(_MarqueePos, 0); | ||
} | ||
|
||
if (_OverrideText != null) | ||
{ | ||
e.Graphics.DrawString(_OverrideText, Font, _ForeBrush, PointF.Empty); | ||
return; | ||
} | ||
|
||
|
||
foreach (var frag in primaryFragments) | ||
{ | ||
var advance = frag.Render(e.Graphics, this); | ||
e.Graphics.TranslateTransform(advance.Width, 0); | ||
} | ||
foreach (var frag in secondaryFragments) | ||
{ | ||
var advance = frag.Render(e.Graphics, this); | ||
e.Graphics.TranslateTransform(advance.Width, 0); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.