536 lines
16 KiB
C#
536 lines
16 KiB
C#
using System;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.Drawing.Drawing2D;
|
||
using System.Drawing.Text;
|
||
using System.Windows.Forms;
|
||
|
||
namespace hKursu
|
||
{
|
||
public class hLabel : Control
|
||
{
|
||
private string _text = "";
|
||
private Font _font = new Font("Segoe UI", 9F);
|
||
private Color _foreColor = Color.Black;
|
||
private Color _shadowColor = Color.Gray;
|
||
private int _shadowOffset = 2;
|
||
private ContentAlignment _textAlign = ContentAlignment.TopLeft;
|
||
private bool _autoSize = true;
|
||
private int _maxWidth = 200;
|
||
private TextRenderingHint _textRenderingHint = TextRenderingHint.AntiAliasGridFit;
|
||
|
||
// Kontur özellikleri
|
||
private bool _drawOutline = false;
|
||
private Color _outlineColor = Color.Black;
|
||
private float _outlineWidth = 1.0f;
|
||
|
||
// 3D efekt özellikleri
|
||
private TextEffect _textEffect = TextEffect.None;
|
||
private Color _bevelHighlight = Color.White;
|
||
private Color _bevelShadow = Color.Gray;
|
||
private int _bevelDepth = 1;
|
||
|
||
public enum TextEffect
|
||
{
|
||
None,
|
||
Bevel,
|
||
Emboss,
|
||
Engrave
|
||
}
|
||
public hLabel()
|
||
{
|
||
SetStyle(ControlStyles.SupportsTransparentBackColor |
|
||
ControlStyles.AllPaintingInWmPaint |
|
||
ControlStyles.UserPaint |
|
||
ControlStyles.ResizeRedraw |
|
||
ControlStyles.OptimizedDoubleBuffer, true);
|
||
|
||
BackColor = Color.Transparent;
|
||
Size = new Size(200, 50); // Varsayılan boyut
|
||
UpdateSize();
|
||
}
|
||
|
||
// Properties
|
||
[Browsable(true)]
|
||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||
public override string Text
|
||
{
|
||
get { return _text; }
|
||
set
|
||
{
|
||
_text = value ?? "";
|
||
UpdateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
public override Font Font
|
||
{
|
||
get { return _font; }
|
||
set
|
||
{
|
||
_font = value ?? new Font("Segoe UI", 9F);
|
||
UpdateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
public override Color ForeColor
|
||
{
|
||
get { return _foreColor; }
|
||
set
|
||
{
|
||
_foreColor = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Gölge rengi")]
|
||
public Color ShadowColor
|
||
{
|
||
get { return _shadowColor; }
|
||
set
|
||
{
|
||
_shadowColor = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Gölge uzaklığı")]
|
||
public int ShadowOffset
|
||
{
|
||
get { return _shadowOffset; }
|
||
set
|
||
{
|
||
_shadowOffset = Math.Max(0, value);
|
||
UpdateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
public ContentAlignment TextAlign
|
||
{
|
||
get { return _textAlign; }
|
||
set
|
||
{
|
||
_textAlign = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Layout")]
|
||
public override bool AutoSize
|
||
{
|
||
get { return _autoSize; }
|
||
set
|
||
{
|
||
_autoSize = value;
|
||
if (_autoSize) UpdateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Layout")]
|
||
[Description("Maksimum genişlik")]
|
||
public int MaxWidth
|
||
{
|
||
get { return _maxWidth; }
|
||
set
|
||
{
|
||
_maxWidth = Math.Max(10, value);
|
||
UpdateSize();
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Yazı tipi kalitesi")]
|
||
public TextRenderingHint TextQuality
|
||
{
|
||
get { return _textRenderingHint; }
|
||
set
|
||
{
|
||
_textRenderingHint = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
// Kontur Properties
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Kontur çizgisi çiz")]
|
||
public bool DrawOutline
|
||
{
|
||
get { return _drawOutline; }
|
||
set
|
||
{
|
||
_drawOutline = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Kontur rengi")]
|
||
public Color OutlineColor
|
||
{
|
||
get { return _outlineColor; }
|
||
set
|
||
{
|
||
_outlineColor = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Kontur kalınlığı")]
|
||
public float OutlineWidth
|
||
{
|
||
get { return _outlineWidth; }
|
||
set
|
||
{
|
||
_outlineWidth = Math.Max(0.1f, value);
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
// 3D Efekt Properties
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("3D metin efekti")]
|
||
public TextEffect Effect
|
||
{
|
||
get { return _textEffect; }
|
||
set
|
||
{
|
||
_textEffect = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Bevel aydınlatma rengi")]
|
||
public Color BevelHighlight
|
||
{
|
||
get { return _bevelHighlight; }
|
||
set
|
||
{
|
||
_bevelHighlight = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Bevel gölge rengi")]
|
||
public Color BevelShadow
|
||
{
|
||
get { return _bevelShadow; }
|
||
set
|
||
{
|
||
_bevelShadow = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
[Browsable(true)]
|
||
[Category("Appearance")]
|
||
[Description("Bevel derinliği")]
|
||
public int BevelDepth
|
||
{
|
||
get { return _bevelDepth; }
|
||
set
|
||
{
|
||
_bevelDepth = Math.Max(1, value);
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
// Ana çizim metodu
|
||
protected override void OnPaint(PaintEventArgs e)
|
||
{
|
||
if (string.IsNullOrEmpty(_text))
|
||
return;
|
||
|
||
Graphics g = e.Graphics;
|
||
|
||
// Yazı tipi kalitesi ayarları
|
||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||
g.TextRenderingHint = _textRenderingHint;
|
||
|
||
Rectangle textBounds = GetTextBounds();
|
||
|
||
// 3D efektler
|
||
if (_textEffect != TextEffect.None)
|
||
{
|
||
Draw3DText(g, textBounds);
|
||
}
|
||
|
||
// Gölge efekti çiz (sadece efekt yoksa)
|
||
if (_shadowOffset > 0 && _textEffect == TextEffect.None)
|
||
{
|
||
Rectangle shadowBounds = new Rectangle(
|
||
textBounds.X + _shadowOffset,
|
||
textBounds.Y + _shadowOffset,
|
||
textBounds.Width,
|
||
textBounds.Height);
|
||
|
||
using (SolidBrush shadowBrush = new SolidBrush(_shadowColor))
|
||
{
|
||
DrawWrappedText(g, _text, _font, shadowBrush, shadowBounds, false);
|
||
}
|
||
}
|
||
|
||
// Ana metin çiz
|
||
using (SolidBrush textBrush = new SolidBrush(_foreColor))
|
||
{
|
||
DrawWrappedText(g, _text, _font, textBrush, textBounds, _drawOutline);
|
||
}
|
||
}
|
||
|
||
// 3D efekt çizimi
|
||
private void Draw3DText(Graphics g, Rectangle bounds)
|
||
{
|
||
switch (_textEffect)
|
||
{
|
||
case TextEffect.Bevel:
|
||
DrawBevelText(g, bounds);
|
||
break;
|
||
case TextEffect.Emboss:
|
||
DrawEmbossText(g, bounds);
|
||
break;
|
||
case TextEffect.Engrave:
|
||
DrawEngraveText(g, bounds);
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void DrawBevelText(Graphics g, Rectangle bounds)
|
||
{
|
||
// Highlight (sol üst)
|
||
Rectangle highlightBounds = new Rectangle(
|
||
bounds.X - _bevelDepth, bounds.Y - _bevelDepth,
|
||
bounds.Width, bounds.Height);
|
||
using (SolidBrush highlightBrush = new SolidBrush(_bevelHighlight))
|
||
{
|
||
DrawWrappedText(g, _text, _font, highlightBrush, highlightBounds, false);
|
||
}
|
||
|
||
// Shadow (sağ alt)
|
||
Rectangle shadowBounds = new Rectangle(
|
||
bounds.X + _bevelDepth, bounds.Y + _bevelDepth,
|
||
bounds.Width, bounds.Height);
|
||
using (SolidBrush shadowBrush = new SolidBrush(_bevelShadow))
|
||
{
|
||
DrawWrappedText(g, _text, _font, shadowBrush, shadowBounds, false);
|
||
}
|
||
}
|
||
|
||
private void DrawEmbossText(Graphics g, Rectangle bounds)
|
||
{
|
||
// Koyu gölge (sol üst)
|
||
Rectangle darkBounds = new Rectangle(
|
||
bounds.X - _bevelDepth, bounds.Y - _bevelDepth,
|
||
bounds.Width, bounds.Height);
|
||
using (SolidBrush darkBrush = new SolidBrush(_bevelShadow))
|
||
{
|
||
DrawWrappedText(g, _text, _font, darkBrush, darkBounds, false);
|
||
}
|
||
|
||
// Açık highlight (sağ alt)
|
||
Rectangle lightBounds = new Rectangle(
|
||
bounds.X + _bevelDepth, bounds.Y + _bevelDepth,
|
||
bounds.Width, bounds.Height);
|
||
using (SolidBrush lightBrush = new SolidBrush(_bevelHighlight))
|
||
{
|
||
DrawWrappedText(g, _text, _font, lightBrush, lightBounds, false);
|
||
}
|
||
}
|
||
|
||
private void DrawEngraveText(Graphics g, Rectangle bounds)
|
||
{
|
||
// Açık gölge (sol üst)
|
||
Rectangle lightBounds = new Rectangle(
|
||
bounds.X - _bevelDepth, bounds.Y - _bevelDepth,
|
||
bounds.Width, bounds.Height);
|
||
using (SolidBrush lightBrush = new SolidBrush(_bevelHighlight))
|
||
{
|
||
DrawWrappedText(g, _text, _font, lightBrush, lightBounds, false); // false
|
||
}
|
||
|
||
// Ana metin koyu renkte
|
||
_foreColor = Color.FromArgb(128, _foreColor);
|
||
}
|
||
|
||
// Metin sarma ve çizim
|
||
private void DrawWrappedText(Graphics g, string text, Font font, Brush brush, Rectangle bounds, bool drawOutline)
|
||
{
|
||
StringFormat sf = GetStringFormat();
|
||
|
||
if (drawOutline && _outlineWidth > 0)
|
||
{
|
||
// Kontur çizmek için GraphicsPath kullan
|
||
using (GraphicsPath path = new GraphicsPath())
|
||
{
|
||
path.AddString(text, font.FontFamily, (int)font.Style,
|
||
g.DpiY * font.Size / 72, bounds, sf);
|
||
|
||
// Kontur çiz
|
||
using (Pen outlinePen = new Pen(_outlineColor, _outlineWidth))
|
||
{
|
||
outlinePen.LineJoin = LineJoin.Round;
|
||
g.DrawPath(outlinePen, path);
|
||
}
|
||
|
||
// İçini doldur
|
||
g.FillPath(brush, path);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
g.DrawString(text, font, brush, bounds, sf);
|
||
}
|
||
|
||
sf.Dispose();
|
||
}
|
||
|
||
// Metin hizalama formatı
|
||
private StringFormat GetStringFormat()
|
||
{
|
||
StringFormat sf = new StringFormat();
|
||
sf.FormatFlags = StringFormatFlags.LineLimit;
|
||
sf.Trimming = StringTrimming.Word;
|
||
|
||
// Yatay hizalama
|
||
switch (_textAlign)
|
||
{
|
||
case ContentAlignment.TopLeft:
|
||
case ContentAlignment.MiddleLeft:
|
||
case ContentAlignment.BottomLeft:
|
||
sf.Alignment = StringAlignment.Near;
|
||
break;
|
||
case ContentAlignment.TopCenter:
|
||
case ContentAlignment.MiddleCenter:
|
||
case ContentAlignment.BottomCenter:
|
||
sf.Alignment = StringAlignment.Center;
|
||
break;
|
||
case ContentAlignment.TopRight:
|
||
case ContentAlignment.MiddleRight:
|
||
case ContentAlignment.BottomRight:
|
||
sf.Alignment = StringAlignment.Far;
|
||
break;
|
||
}
|
||
|
||
// Dikey hizalama
|
||
switch (_textAlign)
|
||
{
|
||
case ContentAlignment.TopLeft:
|
||
case ContentAlignment.TopCenter:
|
||
case ContentAlignment.TopRight:
|
||
sf.LineAlignment = StringAlignment.Near;
|
||
break;
|
||
case ContentAlignment.MiddleLeft:
|
||
case ContentAlignment.MiddleCenter:
|
||
case ContentAlignment.MiddleRight:
|
||
sf.LineAlignment = StringAlignment.Center;
|
||
break;
|
||
case ContentAlignment.BottomLeft:
|
||
case ContentAlignment.BottomCenter:
|
||
case ContentAlignment.BottomRight:
|
||
sf.LineAlignment = StringAlignment.Far;
|
||
break;
|
||
}
|
||
|
||
return sf;
|
||
}
|
||
|
||
// Metin sınırlarını hesapla
|
||
private Rectangle GetTextBounds()
|
||
{
|
||
int availableWidth = _autoSize ? _maxWidth : Width;
|
||
int extraSpace = Math.Max(_shadowOffset, _bevelDepth) + (int)_outlineWidth;
|
||
availableWidth -= extraSpace * 2;
|
||
|
||
Rectangle bounds = new Rectangle(extraSpace, extraSpace,
|
||
Math.Max(1, availableWidth), Height - extraSpace * 2);
|
||
|
||
return bounds;
|
||
}
|
||
|
||
// Boyut güncelleme
|
||
private void UpdateSize()
|
||
{
|
||
if (!_autoSize || string.IsNullOrEmpty(_text) || IsDisposed)
|
||
return;
|
||
|
||
try
|
||
{
|
||
using (Graphics g = CreateGraphics())
|
||
{
|
||
StringFormat sf = GetStringFormat();
|
||
SizeF textSize = g.MeasureString(_text, _font, _maxWidth, sf);
|
||
sf.Dispose();
|
||
|
||
int extraSpace = Math.Max(_shadowOffset, _bevelDepth) + (int)_outlineWidth;
|
||
|
||
Size newSize = new Size(
|
||
(int)Math.Ceiling(textSize.Width) + extraSpace * 2,
|
||
(int)Math.Ceiling(textSize.Height) + extraSpace * 2
|
||
);
|
||
|
||
if (Size != newSize)
|
||
{
|
||
Size = newSize;
|
||
}
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// CreateGraphics bazen başarısız olabilir
|
||
}
|
||
}
|
||
|
||
protected override void OnResize(EventArgs e)
|
||
{
|
||
base.OnResize(e);
|
||
Invalidate();
|
||
}
|
||
|
||
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
|
||
{
|
||
if (_autoSize && (specified & BoundsSpecified.Size) != BoundsSpecified.None)
|
||
{
|
||
// AutoSize açıkken sadece konum değişikliklerine izin ver
|
||
base.SetBoundsCore(x, y, Width, Height, BoundsSpecified.Location);
|
||
}
|
||
else
|
||
{
|
||
base.SetBoundsCore(x, y, width, height, specified);
|
||
}
|
||
}
|
||
|
||
protected override void Dispose(bool disposing)
|
||
{
|
||
if (disposing)
|
||
{
|
||
_font?.Dispose();
|
||
}
|
||
base.Dispose(disposing);
|
||
}
|
||
}
|
||
} |