From 36aca2c04d2fb2018b39049bb0b92a3bb8bf873f Mon Sep 17 00:00:00 2001 From: duffyduck Date: Fri, 3 Apr 2026 18:17:26 +0200 Subject: [PATCH] Add custom app icon: contact silhouette with sync arrows Generated programmatically, no external ICO file needed. Blue rounded square with white person silhouette and green/yellow sync arrows. Used for main window title bar and system tray. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/StarfaceOutlookSync/UI/AppIcon.cs | 108 +++++++++++++++++++++++++ src/StarfaceOutlookSync/UI/MainForm.cs | 3 +- 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/StarfaceOutlookSync/UI/AppIcon.cs diff --git a/src/StarfaceOutlookSync/UI/AppIcon.cs b/src/StarfaceOutlookSync/UI/AppIcon.cs new file mode 100644 index 00000000..61e0dd1d --- /dev/null +++ b/src/StarfaceOutlookSync/UI/AppIcon.cs @@ -0,0 +1,108 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace StarfaceOutlookSync.UI +{ + /// + /// Generiert das App-Icon programmatisch (Kontakt-Symbol mit Sync-Pfeilen). + /// Kein externes ICO-File noetig. + /// + public static class AppIcon + { + private static Icon _icon; + + public static Icon GetIcon() + { + if (_icon != null) return _icon; + _icon = CreateIcon(32); + return _icon; + } + + public static Icon GetSmallIcon() + { + return CreateIcon(16); + } + + private static Icon CreateIcon(int size) + { + using (var bmp = new Bitmap(size, size)) + using (var g = Graphics.FromImage(bmp)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + g.Clear(Color.Transparent); + + if (size >= 32) + DrawIcon32(g); + else + DrawIcon16(g); + + return Icon.FromHandle(bmp.GetHicon()); + } + } + + private static void DrawIcon32(Graphics g) + { + // Hintergrund: abgerundetes Quadrat + using (var bgBrush = new SolidBrush(Color.FromArgb(0, 120, 212))) + { + FillRoundedRect(g, bgBrush, 0, 0, 31, 31, 6); + } + + // Person (Kopf) + using (var whiteBrush = new SolidBrush(Color.White)) + { + g.FillEllipse(whiteBrush, 11, 4, 10, 10); + // Person (Koerper) + g.FillPie(whiteBrush, 6, 14, 20, 18, 180, 180); + } + + // Sync-Pfeile unten rechts + using (var arrowPen = new Pen(Color.FromArgb(120, 255, 120), 2f)) + { + arrowPen.StartCap = LineCap.Round; + arrowPen.EndCap = LineCap.ArrowAnchor; + // Pfeil rechts + g.DrawArc(arrowPen, 20, 22, 10, 8, 200, 140); + arrowPen.Color = Color.FromArgb(255, 200, 80); + // Pfeil links + g.DrawArc(arrowPen, 20, 22, 10, 8, 20, 140); + } + } + + private static void DrawIcon16(Graphics g) + { + // Hintergrund + using (var bgBrush = new SolidBrush(Color.FromArgb(0, 120, 212))) + { + FillRoundedRect(g, bgBrush, 0, 0, 15, 15, 3); + } + + // Person (vereinfacht) + using (var whiteBrush = new SolidBrush(Color.White)) + { + g.FillEllipse(whiteBrush, 4, 1, 7, 7); + g.FillPie(whiteBrush, 2, 8, 12, 10, 180, 180); + } + + // Kleiner Sync-Indikator + using (var dotBrush = new SolidBrush(Color.FromArgb(120, 255, 120))) + { + g.FillEllipse(dotBrush, 11, 11, 4, 4); + } + } + + private static void FillRoundedRect(Graphics g, Brush brush, int x, int y, int w, int h, int r) + { + using (var path = new GraphicsPath()) + { + path.AddArc(x, y, r * 2, r * 2, 180, 90); + path.AddArc(x + w - r * 2, y, r * 2, r * 2, 270, 90); + path.AddArc(x + w - r * 2, y + h - r * 2, r * 2, r * 2, 0, 90); + path.AddArc(x, y + h - r * 2, r * 2, r * 2, 90, 90); + path.CloseFigure(); + g.FillPath(brush, path); + } + } + } +} diff --git a/src/StarfaceOutlookSync/UI/MainForm.cs b/src/StarfaceOutlookSync/UI/MainForm.cs index 86e36c55..902aa8c3 100644 --- a/src/StarfaceOutlookSync/UI/MainForm.cs +++ b/src/StarfaceOutlookSync/UI/MainForm.cs @@ -62,6 +62,7 @@ namespace StarfaceOutlookSync.UI MinimumSize = new Size(500, 350); StartPosition = FormStartPosition.CenterScreen; Font = new Font("Segoe UI", 9); + Icon = AppIcon.GetIcon(); // Profil-Liste _profileList = new ListView @@ -128,7 +129,7 @@ namespace StarfaceOutlookSync.UI _trayIcon = new NotifyIcon { Text = "Starface Kontakt-Sync", - Icon = SystemIcons.Application, + Icon = AppIcon.GetSmallIcon(), ContextMenuStrip = _trayMenu, Visible = true };