diff --git a/MainForm.cs b/MainForm.cs index dbbddac..9b627cb 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -3,6 +3,7 @@ using Krassheiten.SystemGameManager.Controller; using Krassheiten.SystemGameManager.Service; using Krassheiten.SystemGameManager.View; +using Krassheiten.SystemGameManager.View.Components; using System.Text.Json; namespace Krassheiten.SystemGameManager; @@ -11,6 +12,7 @@ public class MainForm : Form { private readonly Button btnLoadInfo; private readonly Label statusLabel; + private readonly TabControl tabs; private readonly GameViewService gameViewService; private readonly PcInfoView pcInfoView; private readonly GameInfoView gameInfoView; @@ -21,42 +23,109 @@ public MainForm() { Text = $"System & Game Manager (v{GetVersionFromReleases()})"; StartPosition = FormStartPosition.CenterScreen; - MinimumSize = new Size(980, 640); - Width = 1180; - Height = 760; - BackColor = Color.FromArgb(245, 247, 250); + MinimumSize = new Size(1280, 820); + Width = 1360; + Height = 860; + BackColor = UIHelpers.WindowBackground; DoubleBuffered = true; + Font = new Font("Segoe UI", 9F); gameViewService = new GameViewService(); pcInfoView = new PcInfoView(); gameInfoView = new GameInfoView(gameViewService.Artwork, OpenGameDirectory); gameAudioView = new GameAudioView(); + var root = new TableLayoutPanel() + { + Dock = DockStyle.Fill, + BackColor = UIHelpers.WindowBackground, + ColumnCount = 2, + RowCount = 1 + }; + root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72)); + root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); + + var sidebar = new Panel() + { + Dock = DockStyle.Fill, + BackColor = UIHelpers.SidebarBackground, + Padding = new Padding(10, 76, 10, 14) + }; + + var sidebarActions = new FlowLayoutPanel() + { + Dock = DockStyle.Top, + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + BackColor = Color.Transparent, + AutoSize = true + }; + + var menuButton = CreateSidebarButton("☰"); + var homeButton = CreateSidebarButton("⌗", true); + var settingsButton = CreateSidebarButton("⚙"); + var infoButton = CreateSidebarButton("i"); + + menuButton.Margin = new Padding(0, 0, 0, 16); + homeButton.Margin = new Padding(0, 0, 0, 16); + settingsButton.Margin = new Padding(0, 0, 0, 16); + infoButton.Anchor = AnchorStyles.Left | AnchorStyles.Bottom; + + sidebarActions.Controls.Add(menuButton); + sidebarActions.Controls.Add(homeButton); + sidebarActions.Controls.Add(settingsButton); + sidebar.Controls.Add(sidebarActions); + + var infoHost = new Panel() + { + Dock = DockStyle.Bottom, + Height = 44 + }; + infoHost.Controls.Add(infoButton); + sidebar.Controls.Add(infoHost); + + var shell = new TableLayoutPanel() + { + Dock = DockStyle.Fill, + BackColor = UIHelpers.WindowBackground, + ColumnCount = 1, + RowCount = 2 + }; + shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 86)); + shell.RowStyles.Add(new RowStyle(SizeType.Percent, 100)); + var toolbar = new Panel() { Dock = DockStyle.Top, - Height = 60, - Padding = new Padding(12), - BackColor = Color.White + Height = 86, + Padding = new Padding(16, 18, 16, 10), + BackColor = UIHelpers.SurfaceBackground }; - btnLoadInfo = CreatePrimaryButton("Infos laden", 125); + btnLoadInfo = UIHelpers.CreatePrimaryButton("Infos laden", 132); btnLoadInfo.Dock = DockStyle.Left; + btnLoadInfo.Text = "ⓘ Infos laden"; statusLabel = new Label() { Text = "Bereit", Dock = DockStyle.Fill, - Padding = new Padding(14, 7, 0, 0), + Padding = new Padding(16, 7, 0, 0), TextAlign = ContentAlignment.MiddleLeft, - ForeColor = Color.FromArgb(55, 65, 81) + ForeColor = UIHelpers.TextSecondaryColor }; - var tabs = new TabControl() + tabs = new TabControl() { Dock = DockStyle.Fill, - Padding = new Point(18, 8) + BackColor = UIHelpers.WindowBackground, + Padding = new Point(22, 12), + DrawMode = TabDrawMode.OwnerDrawFixed, + ItemSize = new Size(210, 42), + SizeMode = TabSizeMode.Fixed }; + tabs.DrawItem += (_, e) => DrawTab(tabs, e); + tabs.SelectedIndexChanged += (_, _) => tabs.Invalidate(); tabs.TabPages.Add(pcInfoView.CreateTab()); tabs.TabPages.Add(gameInfoView.CreateTab()); @@ -68,8 +137,13 @@ public MainForm() toolbar.Controls.Add(statusLabel); toolbar.Controls.Add(btnLoadInfo); - Controls.Add(tabs); - Controls.Add(toolbar); + shell.Controls.Add(toolbar, 0, 0); + shell.Controls.Add(tabs, 0, 1); + + root.Controls.Add(sidebar, 0, 0); + root.Controls.Add(shell, 1, 0); + + Controls.Add(root); pcInfoView.ShowLoadingState(); gameInfoView.ShowLoadingState(); @@ -140,22 +214,54 @@ private MainViewData BuildViewData() gameViewService.BuildViewData()); } - private static Button CreatePrimaryButton(string text, int width) + private static void DrawTab(TabControl tabControl, DrawItemEventArgs e) + { + var page = tabControl.TabPages[e.Index]; + var bounds = e.Bounds; + bool isSelected = e.Index == tabControl.SelectedIndex; + + using var backgroundBrush = new SolidBrush(UIHelpers.SurfaceBackground); + e.Graphics.FillRectangle(backgroundBrush, bounds); + + var textBounds = Rectangle.Inflate(bounds, -10, -2); + using var textFont = new Font("Segoe UI", 10F, isSelected ? FontStyle.Bold : FontStyle.Regular); + TextRenderer.DrawText( + e.Graphics, + page.Text, + textFont, + textBounds, + isSelected ? UIHelpers.TextPrimaryColor : UIHelpers.TextSecondaryColor, + TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis); + + using var borderPen = new Pen(UIHelpers.BorderColor); + e.Graphics.DrawLine(borderPen, bounds.Left, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1); + + if (!isSelected) + { + return; + } + + using var accentBrush = new SolidBrush(UIHelpers.AccentColor); + e.Graphics.FillRectangle(accentBrush, bounds.Left + 12, bounds.Bottom - 3, bounds.Width - 24, 3); + } + + private static Button CreateSidebarButton(string text, bool isActive = false) { var button = new Button() { Text = text, - Width = width, - Height = 34, + Width = 50, + Height = 50, FlatStyle = FlatStyle.Flat, - BackColor = Color.FromArgb(79, 70, 229), - ForeColor = Color.White, + BackColor = isActive ? UIHelpers.SidebarActiveBackground : Color.Transparent, + ForeColor = isActive ? UIHelpers.TextPrimaryColor : Color.FromArgb(223, 231, 210), + Font = new Font("Segoe UI Symbol", 15F, FontStyle.Regular), Cursor = Cursors.Hand }; button.FlatAppearance.BorderSize = 0; - button.FlatAppearance.MouseDownBackColor = Color.FromArgb(67, 56, 202); - button.FlatAppearance.MouseOverBackColor = Color.FromArgb(99, 102, 241); + button.FlatAppearance.MouseDownBackColor = UIHelpers.SidebarActiveBackground; + button.FlatAppearance.MouseOverBackColor = UIHelpers.SidebarActiveBackground; return button; } @@ -182,4 +288,4 @@ private static string GetVersionFromReleases() } private sealed record MainViewData(string SystemText, GameViewService.GameManagerViewData GameManager); -} \ No newline at end of file +} diff --git a/view/Components/GameAudioCardControl.cs b/view/Components/GameAudioCardControl.cs index 740b76a..e1d0d74 100644 --- a/view/Components/GameAudioCardControl.cs +++ b/view/Components/GameAudioCardControl.cs @@ -14,9 +14,10 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out Dock = DockStyle.Top, AutoSize = true, Padding = new Padding(14), - BackColor = Color.White, + BackColor = UIHelpers.CardBackground, Margin = new Padding(0, 0, 0, 12) }; + UIHelpers.SetRoundedRegion(card, 18); var layout = new TableLayoutPanel() { @@ -48,7 +49,7 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out Text = game.Name, AutoSize = true, Font = new Font("Segoe UI", 10F, FontStyle.Bold), - ForeColor = Color.FromArgb(17, 24, 39), + ForeColor = UIHelpers.TextPrimaryColor, Margin = new Padding(0, 0, 0, 4) }; @@ -56,7 +57,7 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out { Text = string.IsNullOrWhiteSpace(game.InstallFolderPath) ? "Pfad nicht verfügbar" : game.InstallFolderPath, AutoSize = true, - ForeColor = Color.FromArgb(107, 114, 128), + ForeColor = UIHelpers.TextSecondaryColor, Margin = new Padding(0, 0, 0, 4) }; @@ -65,7 +66,7 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out Text = $"Game: {game.GameVolumePercent ?? Game.GAME_VOLUME_PERCENT}% | Music: {game.MusicVolumePercent ?? Game.MUSIC_VOLUME_PERCENT}%", AutoSize = true, Font = new Font("Segoe UI", 9F, FontStyle.Bold), - ForeColor = Color.FromArgb(67, 56, 202), + ForeColor = UIHelpers.AccentColor, Margin = new Padding(0, 0, 0, 0) }; @@ -84,7 +85,7 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out Text = "Audioausgabe:", AutoSize = true, Anchor = AnchorStyles.Left, - ForeColor = Color.FromArgb(55, 65, 81), + ForeColor = UIHelpers.TextMutedColor, Margin = new Padding(0, 4, 8, 0) }; @@ -93,7 +94,7 @@ public static Panel Create(Game.Record game, out CheckBox selectionCheckBox, out Text = game.AudioOutputDevice ?? "(Standard-Gerät)", AutoSize = true, Anchor = AnchorStyles.Left, - ForeColor = Color.FromArgb(55, 65, 81), + ForeColor = UIHelpers.TextSecondaryColor, Margin = new Padding(0, 4, 0, 0) }; diff --git a/view/Components/GameCardControl.cs b/view/Components/GameCardControl.cs index 5342deb..c3da786 100644 --- a/view/Components/GameCardControl.cs +++ b/view/Components/GameCardControl.cs @@ -12,16 +12,16 @@ public static Control Create(GameViewService.GameCardItem game, Image? artwork, var shell = new HoverShadowPanel() { - Width = 290, - Height = 390, + Width = 348, + Height = 306, Margin = new Padding(0, 0, 18, 18) }; var body = new Panel() { Dock = DockStyle.Fill, - BackColor = Color.White, - Padding = new Padding(14) + BackColor = UIHelpers.CardBackground, + Padding = new Padding(10) }; UIHelpers.SetRoundedRegion(body, 18); @@ -29,26 +29,22 @@ public static Control Create(GameViewService.GameCardItem game, Image? artwork, { Dock = DockStyle.Fill, ColumnCount = 1, - RowCount = 6, + RowCount = 2, BackColor = Color.Transparent, Margin = new Padding(0), Padding = new Padding(0) }; - layout.RowStyles.Add(new RowStyle(SizeType.Absolute, 150)); - layout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); - layout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); - layout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); layout.RowStyles.Add(new RowStyle(SizeType.Percent, 100)); - layout.RowStyles.Add(new RowStyle(SizeType.Absolute, 40)); + layout.RowStyles.Add(new RowStyle(SizeType.Absolute, 46)); var imageHost = new Panel() { Dock = DockStyle.Fill, - BackColor = Color.FromArgb(236, 240, 248), - Margin = new Padding(0, 0, 0, 10) + BackColor = UIHelpers.SurfaceBackground, + Margin = new Padding(0, 0, 0, 8) }; - UIHelpers.SetRoundedRegion(imageHost, 14); + UIHelpers.SetRoundedRegion(imageHost, 12); var picture = new PictureBox() { @@ -65,59 +61,54 @@ public static Control Create(GameViewService.GameCardItem game, Image? artwork, imageHost.Controls.Add(picture); - var badge = new Label() - { - Text = "INSTALLIERT", - AutoSize = true, - BackColor = Color.FromArgb(224, 231, 255), - ForeColor = Color.FromArgb(67, 56, 202), - Padding = new Padding(8, 4, 8, 4), - Font = new Font("Segoe UI", 8F, FontStyle.Bold), - Margin = new Padding(0, 2, 0, 10) - }; - - var title = new Label() + var footer = new TableLayoutPanel() { - Text = game.Title, Dock = DockStyle.Fill, - AutoSize = false, - Height = 48, - Font = new Font("Segoe UI", 12F, FontStyle.Bold), - ForeColor = Color.FromArgb(17, 24, 39), - Margin = new Padding(0, 0, 0, 8) + ColumnCount = 2, + RowCount = 1, + Margin = new Padding(0), + Padding = new Padding(0), + BackColor = Color.Transparent }; + footer.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); + footer.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); - var pathTitle = new Label() + var badge = new Label() { - Text = "Installationspfad", + Text = "✓ INSTALLIERT", AutoSize = true, - Font = new Font("Segoe UI", 8.5F, FontStyle.Bold), - ForeColor = Color.FromArgb(107, 114, 128), - Margin = new Padding(0, 0, 0, 4) + Anchor = AnchorStyles.Left | AnchorStyles.Top, + BackColor = UIHelpers.AccentBadgeBackground, + ForeColor = UIHelpers.AccentColor, + Padding = new Padding(12, 5, 12, 5), + Font = new Font("Segoe UI", 9F, FontStyle.Bold), + Margin = new Padding(0, 4, 0, 0) }; + UIHelpers.SetRoundedRegion(badge, 10); - var pathLabel = new Label() + var optionsButton = new Button() { - Text = game.InstallPath, - Dock = DockStyle.Fill, - AutoSize = false, - Height = 44, - AutoEllipsis = true, - ForeColor = Color.FromArgb(75, 85, 99), - Margin = new Padding(0, 0, 0, 8) + Text = "⋮", + Width = 32, + Height = 30, + FlatStyle = FlatStyle.Flat, + BackColor = Color.Transparent, + ForeColor = UIHelpers.TextSecondaryColor, + Font = new Font("Segoe UI", 12F, FontStyle.Bold), + Cursor = Cursors.Hand, + Margin = new Padding(0) }; - - var openButton = UIHelpers.CreatePrimaryButton("Ordner öffnen", 120); - openButton.Anchor = AnchorStyles.Left | AnchorStyles.Bottom; - openButton.Margin = new Padding(0); - openButton.Click += (_, _) => openGameDirectory(game.InstallPath); + optionsButton.FlatAppearance.BorderSize = 0; + optionsButton.FlatAppearance.MouseOverBackColor = UIHelpers.CardHoverBackground; + optionsButton.FlatAppearance.MouseDownBackColor = UIHelpers.CardHoverBackground; + optionsButton.Click += (_, _) => openGameDirectory(game.InstallPath); + optionsButton.Anchor = AnchorStyles.Right | AnchorStyles.Top; + optionsButton.AccessibleDescription = game.Title; layout.Controls.Add(imageHost, 0, 0); - layout.Controls.Add(badge, 0, 1); - layout.Controls.Add(title, 0, 2); - layout.Controls.Add(pathTitle, 0, 3); - layout.Controls.Add(pathLabel, 0, 4); - layout.Controls.Add(openButton, 0, 5); + footer.Controls.Add(badge, 0, 0); + footer.Controls.Add(optionsButton, 1, 0); + layout.Controls.Add(footer, 0, 1); body.Controls.Add(layout); shell.Controls.Add(body); diff --git a/view/Components/HoverShadowPanel.cs b/view/Components/HoverShadowPanel.cs index 1905008..fcfbda2 100644 --- a/view/Components/HoverShadowPanel.cs +++ b/view/Components/HoverShadowPanel.cs @@ -44,7 +44,7 @@ protected override void OnPaint(PaintEventArgs e) var cardBounds = new Rectangle(6, 6, Width - 22, Height - 22); var layers = IsHovered ? 6 : 3; - var baseAlpha = IsHovered ? 18 : 8; + var baseAlpha = IsHovered ? 16 : 7; for (var layer = layers; layer >= 1; layer--) { @@ -55,7 +55,7 @@ protected override void OnPaint(PaintEventArgs e) Math.Max(1, cardBounds.Height)); using var path = UIHelpers.CreateRoundedRectanglePath(shadowBounds, 18); - using var brush = new SolidBrush(Color.FromArgb(baseAlpha + (layer * 5), 15, 23, 42)); + using var brush = new SolidBrush(Color.FromArgb(baseAlpha + (layer * 4), 0, 0, 0)); e.Graphics.FillPath(brush, path); } } @@ -65,7 +65,7 @@ public static void AddHoverEffect(HoverShadowPanel shell, Panel body) void SetState(bool hovered) { shell.IsHovered = hovered; - body.BackColor = hovered ? Color.FromArgb(245, 247, 255) : Color.White; + body.BackColor = hovered ? UIHelpers.CardHoverBackground : UIHelpers.CardBackground; } void EnterHandler(object? sender, EventArgs e) => SetState(true); diff --git a/view/Components/LauncherBadgeControl.cs b/view/Components/LauncherBadgeControl.cs index 74cbbd7..ed0a722 100644 --- a/view/Components/LauncherBadgeControl.cs +++ b/view/Components/LauncherBadgeControl.cs @@ -7,41 +7,91 @@ internal static class LauncherBadgeControl { public static Control Create(string title, string subtitle) { - var shell = new Panel() + var shell = new HoverShadowPanel() { - AutoSize = true, - Margin = new Padding(0, 0, 10, 10), - Padding = new Padding(1), - BackColor = Color.FromArgb(221, 227, 237) + Width = 266, + Height = 104, + Margin = new Padding(0, 0, 14, 14) }; - var body = new FlowLayoutPanel() + var body = new TableLayoutPanel() { - AutoSize = true, - FlowDirection = FlowDirection.TopDown, - WrapContents = false, - BackColor = Color.White, - Padding = new Padding(12), - Margin = new Padding(0) + Dock = DockStyle.Fill, + BackColor = UIHelpers.CardBackground, + Padding = new Padding(14, 12, 14, 12), + Margin = new Padding(0), + ColumnCount = 3, + RowCount = 2 + }; + body.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 56)); + body.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); + body.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); + UIHelpers.SetRoundedRegion(body, 18); + + var avatar = new Panel() + { + Width = 42, + Height = 42, + BackColor = Color.FromArgb(58, 63, 45), + Margin = new Padding(0, 4, 12, 0) }; + UIHelpers.SetRoundedRegion(avatar, 12); + + avatar.Controls.Add(new Label + { + Text = GetLauncherMonogram(title), + Dock = DockStyle.Fill, + TextAlign = ContentAlignment.MiddleCenter, + ForeColor = UIHelpers.AccentColor, + Font = new Font("Segoe UI", 10F, FontStyle.Bold) + }); + + body.Controls.Add(avatar, 0, 0); + body.SetRowSpan(avatar, 2); body.Controls.Add(new Label { Text = title, AutoSize = true, - Font = new Font("Segoe UI", 9F, FontStyle.Bold), - ForeColor = Color.FromArgb(31, 41, 55) - }); + Font = new Font("Segoe UI", 10.5F, FontStyle.Bold), + ForeColor = UIHelpers.TextPrimaryColor, + Margin = new Padding(0, 4, 0, 6) + }, 1, 0); body.Controls.Add(new Label { Text = subtitle, AutoSize = true, - MaximumSize = new Size(280, 0), - ForeColor = Color.FromArgb(107, 114, 128) - }); + MaximumSize = new Size(170, 0), + ForeColor = UIHelpers.TextSecondaryColor, + Margin = new Padding(0) + }, 1, 1); + + var chevronLabel = new Label + { + Text = "›", + AutoSize = true, + Font = new Font("Segoe UI", 18F, FontStyle.Regular), + ForeColor = UIHelpers.AccentColor, + Anchor = AnchorStyles.Right | AnchorStyles.Top, + Margin = new Padding(8, 6, 0, 0) + }; + body.Controls.Add(chevronLabel, 2, 0); + body.SetRowSpan(chevronLabel, 2); shell.Controls.Add(body); + HoverShadowPanel.AddHoverEffect(shell, body); return shell; } + + private static string GetLauncherMonogram(string title) + { + var words = title + .Split([' ', '-', '_'], StringSplitOptions.RemoveEmptyEntries) + .Take(2) + .Select(part => char.ToUpperInvariant(part[0])) + .ToArray(); + + return words.Length == 0 ? "L" : new string(words); + } } diff --git a/view/Components/MessageCardControl.cs b/view/Components/MessageCardControl.cs index 50a92e0..815ef72 100644 --- a/view/Components/MessageCardControl.cs +++ b/view/Components/MessageCardControl.cs @@ -12,8 +12,9 @@ public static Control Create(string title, string message) Dock = DockStyle.Top, AutoSize = true, Padding = new Padding(14), - BackColor = Color.White + BackColor = UIHelpers.CardBackground }; + UIHelpers.SetRoundedRegion(card, 18); var layout = new FlowLayoutPanel() { @@ -31,7 +32,7 @@ public static Control Create(string title, string message) Text = title, AutoSize = true, Font = new Font("Segoe UI", 10F, FontStyle.Bold), - ForeColor = Color.FromArgb(17, 24, 39), + ForeColor = UIHelpers.TextPrimaryColor, Margin = new Padding(0, 0, 0, 8) }); @@ -40,7 +41,7 @@ public static Control Create(string title, string message) Text = message, AutoSize = true, MaximumSize = new Size(900, 0), - ForeColor = Color.FromArgb(107, 114, 128) + ForeColor = UIHelpers.TextSecondaryColor }); card.Controls.Add(layout); diff --git a/view/Components/StateCardControl.cs b/view/Components/StateCardControl.cs index 1045c52..cde781b 100644 --- a/view/Components/StateCardControl.cs +++ b/view/Components/StateCardControl.cs @@ -17,7 +17,7 @@ public static Control Create(string title, string message) var body = new Panel() { Dock = DockStyle.Fill, - BackColor = Color.White, + BackColor = UIHelpers.CardBackground, Padding = new Padding(18) }; UIHelpers.SetRoundedRegion(body, 18); @@ -37,7 +37,7 @@ public static Control Create(string title, string message) Text = title, AutoSize = true, Font = new Font("Segoe UI", 12F, FontStyle.Bold), - ForeColor = Color.FromArgb(17, 24, 39), + ForeColor = UIHelpers.TextPrimaryColor, Margin = new Padding(0, 0, 0, 8) }); @@ -46,7 +46,7 @@ public static Control Create(string title, string message) Text = message, AutoSize = true, MaximumSize = new Size(360, 0), - ForeColor = Color.FromArgb(107, 114, 128) + ForeColor = UIHelpers.TextSecondaryColor }); body.Controls.Add(textLayout); diff --git a/view/Components/UIHelpers.cs b/view/Components/UIHelpers.cs index 92bd289..b82ca3d 100644 --- a/view/Components/UIHelpers.cs +++ b/view/Components/UIHelpers.cs @@ -6,6 +6,22 @@ namespace Krassheiten.SystemGameManager.View.Components; internal static class UIHelpers { + public static Color WindowBackground => Color.FromArgb(22, 24, 23); + public static Color WindowGradientEnd => Color.FromArgb(18, 21, 24); + public static Color SurfaceBackground => Color.FromArgb(30, 33, 31); + public static Color CardBackground => Color.FromArgb(36, 39, 37); + public static Color CardHoverBackground => Color.FromArgb(46, 51, 47); + public static Color BorderColor => Color.FromArgb(64, 69, 64); + public static Color SidebarBackground => Color.FromArgb(47, 63, 43); + public static Color SidebarActiveBackground => Color.FromArgb(99, 119, 80); + public static Color AccentColor => Color.FromArgb(163, 176, 94); + public static Color AccentPressedColor => Color.FromArgb(128, 140, 69); + public static Color AccentHoverColor => Color.FromArgb(182, 195, 108); + public static Color AccentBadgeBackground => Color.FromArgb(68, 74, 49); + public static Color TextPrimaryColor => Color.FromArgb(242, 243, 237); + public static Color TextSecondaryColor => Color.FromArgb(184, 189, 176); + public static Color TextMutedColor => Color.FromArgb(136, 142, 131); + public static Button CreatePrimaryButton(string text, int width) { var button = new Button() @@ -14,17 +30,48 @@ public static Button CreatePrimaryButton(string text, int width) Width = width, Height = 34, FlatStyle = FlatStyle.Flat, - BackColor = Color.FromArgb(79, 70, 229), - ForeColor = Color.White, Cursor = Cursors.Hand }; - button.FlatAppearance.BorderSize = 0; - button.FlatAppearance.MouseDownBackColor = Color.FromArgb(67, 56, 202); - button.FlatAppearance.MouseOverBackColor = Color.FromArgb(99, 102, 241); + ApplyPrimaryButtonStyle(button); + return button; + } + + public static Button CreateSecondaryButton(string text, int width) + { + var button = new Button() + { + Text = text, + Width = width, + Height = 34, + FlatStyle = FlatStyle.Flat, + Cursor = Cursors.Hand + }; + + ApplySecondaryButtonStyle(button); return button; } + public static void ApplyPrimaryButtonStyle(Button button) + { + button.BackColor = AccentColor; + button.ForeColor = Color.FromArgb(35, 40, 24); + button.FlatAppearance.BorderColor = AccentColor; + button.FlatAppearance.BorderSize = 0; + button.FlatAppearance.MouseDownBackColor = AccentPressedColor; + button.FlatAppearance.MouseOverBackColor = AccentHoverColor; + } + + public static void ApplySecondaryButtonStyle(Button button) + { + button.BackColor = SurfaceBackground; + button.ForeColor = TextPrimaryColor; + button.FlatAppearance.BorderColor = BorderColor; + button.FlatAppearance.BorderSize = 1; + button.FlatAppearance.MouseDownBackColor = CardBackground; + button.FlatAppearance.MouseOverBackColor = CardHoverBackground; + } + public static void SetRoundedRegion(Control control, int radius) { void ApplyRegion() diff --git a/view/GameAudioView.cs b/view/GameAudioView.cs index 3cabb53..8e531d7 100644 --- a/view/GameAudioView.cs +++ b/view/GameAudioView.cs @@ -31,7 +31,7 @@ internal sealed class GameAudioView { Dock = DockStyle.Fill, AutoScroll = true, - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; private bool isUpdatingSliders; @@ -54,16 +54,16 @@ public TabPage CreateTab() { var tab = new TabPage("Game-Audio-Manager") { - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; var layout = new TableLayoutPanel() { Dock = DockStyle.Fill, - Padding = new Padding(12), + Padding = new Padding(18, 16, 18, 18), ColumnCount = 1, RowCount = 5, - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; layout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); @@ -89,8 +89,8 @@ public TabPage CreateTab() { Text = "Audio-Steuerung für Spiele und Musik", AutoSize = true, - Font = new Font("Segoe UI", 11F, FontStyle.Bold), - ForeColor = Color.FromArgb(31, 41, 55), + Font = new Font("Segoe UI", 12.5F, FontStyle.Bold), + ForeColor = UIHelpers.TextPrimaryColor, Anchor = AnchorStyles.Left, Margin = new Padding(0, 6, 0, 0) }; @@ -118,7 +118,7 @@ public TabPage CreateTab() Text = "Lautstärke für ausgewählte Spiele", AutoSize = true, Font = new Font("Segoe UI", 10F, FontStyle.Bold), - ForeColor = Color.FromArgb(17, 24, 39), + ForeColor = UIHelpers.TextPrimaryColor, Margin = new Padding(0, 0, 0, 8) }; @@ -132,7 +132,7 @@ public TabPage CreateTab() { Dock = DockStyle.Top, Height = 1, - BackColor = Color.FromArgb(221, 227, 237), + BackColor = UIHelpers.BorderColor, Margin = new Padding(0, 6, 0, 10) }; @@ -156,7 +156,7 @@ public TabPage CreateTab() Text = "Spiele auswählen", AutoSize = true, Font = new Font("Segoe UI", 10F, FontStyle.Bold), - ForeColor = Color.FromArgb(31, 41, 55), + ForeColor = UIHelpers.TextPrimaryColor, Anchor = AnchorStyles.Left | AnchorStyles.Top, Margin = new Padding(0, 6, 0, 0) }; @@ -373,7 +373,7 @@ private static void AddSliderRow(TableLayoutPanel layout, int rowIndex, string t Text = title, AutoSize = true, Anchor = AnchorStyles.Left, - ForeColor = Color.FromArgb(55, 65, 81), + ForeColor = UIHelpers.TextSecondaryColor, Margin = new Padding(0, 6, 0, 0) }, 0, rowIndex); @@ -383,13 +383,15 @@ private static void AddSliderRow(TableLayoutPanel layout, int rowIndex, string t private static Panel CreateSectionPanel() { - return new Panel() + var panel = new Panel() { Dock = DockStyle.Top, AutoSize = true, Padding = new Padding(14), - BackColor = Color.White + BackColor = UIHelpers.CardBackground }; + UIHelpers.SetRoundedRegion(panel, 18); + return panel; } private void SetControlsEnabled(bool enabled) @@ -433,54 +435,28 @@ private static Label CreateValueLabel(int value) AutoSize = true, Anchor = AnchorStyles.Left, Font = new Font("Segoe UI", 9F, FontStyle.Bold), - ForeColor = Color.FromArgb(67, 56, 202), + ForeColor = UIHelpers.AccentColor, Margin = new Padding(8, 6, 0, 0) }; } private static Button CreateSaveButton() { - var button = new Button() - { - Text = "Save", - Width = 100, - Height = 34, - Anchor = AnchorStyles.Right, - FlatStyle = FlatStyle.Flat, - BackColor = Color.FromArgb(37, 99, 235), - ForeColor = Color.White, - Cursor = Cursors.Hand, - Enabled = false, - Margin = new Padding(12, 0, 0, 0) - }; - - button.FlatAppearance.BorderSize = 0; - button.FlatAppearance.MouseDownBackColor = Color.FromArgb(29, 78, 216); - button.FlatAppearance.MouseOverBackColor = Color.FromArgb(59, 130, 246); + var button = UIHelpers.CreatePrimaryButton("Save", 100); + button.Anchor = AnchorStyles.Right; + button.Enabled = false; + button.Margin = new Padding(12, 0, 0, 0); return button; } private static Button CreateActionButton(string text) { - var button = new Button() - { - Text = text, - AutoSize = true, - Height = 30, - Anchor = AnchorStyles.Right, - FlatStyle = FlatStyle.Flat, - BackColor = Color.FromArgb(243, 244, 246), - ForeColor = Color.FromArgb(31, 41, 55), - Cursor = Cursors.Hand, - Enabled = false, - Margin = new Padding(6, 0, 0, 0), - Padding = new Padding(10, 0, 10, 0) - }; - - button.FlatAppearance.BorderColor = Color.FromArgb(209, 213, 219); - button.FlatAppearance.BorderSize = 1; - button.FlatAppearance.MouseDownBackColor = Color.FromArgb(229, 231, 235); - button.FlatAppearance.MouseOverBackColor = Color.FromArgb(249, 250, 251); + var button = UIHelpers.CreateSecondaryButton(text, 148); + button.Height = 30; + button.Anchor = AnchorStyles.Right; + button.Enabled = false; + button.Margin = new Padding(6, 0, 0, 0); + button.Padding = new Padding(10, 0, 10, 0); return button; } @@ -492,7 +468,9 @@ private static ComboBox CreateGlobalOutputDeviceComboBox() Width = 220, FlatStyle = FlatStyle.Flat, Enabled = false, - Margin = new Padding(6, 0, 0, 0) + Margin = new Padding(6, 0, 0, 0), + BackColor = UIHelpers.SurfaceBackground, + ForeColor = UIHelpers.TextPrimaryColor }; combo.Items.Add("(Standard-Gerät)"); @@ -518,4 +496,4 @@ private static int GetAverageValue(IEnumerable values, int fallback) } private sealed record GameCheckBinding(Game.Record Game, CheckBox CheckBox, Label VolumeLabel, Label OutputDeviceLabel); -} \ No newline at end of file +} diff --git a/view/GameInfoView.cs b/view/GameInfoView.cs index 117399e..eef9d18 100644 --- a/view/GameInfoView.cs +++ b/view/GameInfoView.cs @@ -25,16 +25,16 @@ internal sealed class GameInfoView AutoScroll = true, WrapContents = true, Margin = new Padding(0), - Padding = new Padding(0, 8, 12, 12), - BackColor = Color.FromArgb(245, 247, 250) + Padding = new Padding(0, 8, 6, 12), + BackColor = Color.Transparent }; private readonly Label gameManagerSummaryLabel = new() { Text = "Noch keine Daten geladen.", AutoSize = true, - ForeColor = Color.FromArgb(224, 231, 255), - Font = new Font("Segoe UI", 10F, FontStyle.Bold), + ForeColor = UIHelpers.AccentColor, + Font = new Font("Segoe UI", 10.5F, FontStyle.Bold), Margin = new Padding(0, 4, 0, 0) }; @@ -48,16 +48,16 @@ public TabPage CreateTab() { var tab = new TabPage("Game-Manager") { - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; var layout = new TableLayoutPanel() { Dock = DockStyle.Fill, - Padding = new Padding(12), + Padding = new Padding(18, 16, 18, 18), ColumnCount = 1, RowCount = 5, - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; layout.RowStyles.Add(new RowStyle(SizeType.Absolute, 118)); @@ -69,17 +69,47 @@ public TabPage CreateTab() var heroPanel = new Panel() { Dock = DockStyle.Fill, - BackColor = Color.FromArgb(30, 41, 59), - Padding = new Padding(18), - Margin = new Padding(0, 0, 0, 12) + BackColor = UIHelpers.SurfaceBackground, + Padding = new Padding(22), + Margin = new Padding(0, 0, 0, 18) + }; + UIHelpers.SetRoundedRegion(heroPanel, 22); + + var heroLayout = new TableLayoutPanel() + { + Dock = DockStyle.Fill, + BackColor = Color.Transparent, + Margin = new Padding(0), + Padding = new Padding(0), + ColumnCount = 2, + RowCount = 1 + }; + heroLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 82)); + heroLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); + + var heroIconHost = new Panel() + { + Width = 64, + Height = 64, + BackColor = Color.FromArgb(61, 70, 47), + Margin = new Padding(0, 2, 14, 0) }; + UIHelpers.SetRoundedRegion(heroIconHost, 18); + heroIconHost.Controls.Add(new Label + { + Text = "🎮", + Dock = DockStyle.Fill, + TextAlign = ContentAlignment.MiddleCenter, + Font = new Font("Segoe UI Emoji", 24F, FontStyle.Regular), + ForeColor = UIHelpers.AccentColor + }); var heroTitle = new Label() { Text = "Game Library", AutoSize = true, - Font = new Font("Segoe UI", 16F, FontStyle.Bold), - ForeColor = Color.White, + Font = new Font("Segoe UI", 18F, FontStyle.Bold), + ForeColor = UIHelpers.TextPrimaryColor, Margin = new Padding(0) }; @@ -87,8 +117,8 @@ public TabPage CreateTab() { Text = "Launcher, Spiele und schnelle Aktionen auf einen Blick.", AutoSize = true, - ForeColor = Color.FromArgb(209, 213, 219), - Margin = new Padding(0, 6, 0, 0) + ForeColor = UIHelpers.TextSecondaryColor, + Margin = new Padding(0, 8, 0, 0) }; var heroTextLayout = new FlowLayoutPanel() @@ -104,24 +134,26 @@ public TabPage CreateTab() heroTextLayout.Controls.Add(heroTitle); heroTextLayout.Controls.Add(gameManagerSummaryLabel); heroTextLayout.Controls.Add(heroSubtitle); - heroPanel.Controls.Add(heroTextLayout); + heroLayout.Controls.Add(heroIconHost, 0, 0); + heroLayout.Controls.Add(heroTextLayout, 1, 0); + heroPanel.Controls.Add(heroLayout); var launcherTitle = new Label() { Text = "Launcher", AutoSize = true, - Font = new Font("Segoe UI", 11F, FontStyle.Bold), - ForeColor = Color.FromArgb(31, 41, 55), - Margin = new Padding(0, 0, 0, 8) + Font = new Font("Segoe UI", 12.5F, FontStyle.Bold), + ForeColor = UIHelpers.TextPrimaryColor, + Margin = new Padding(0, 0, 0, 10) }; var gamesTitle = new Label() { Text = "Installierte Spiele", AutoSize = true, - Font = new Font("Segoe UI", 11F, FontStyle.Bold), - ForeColor = Color.FromArgb(31, 41, 55), - Margin = new Padding(0, 6, 0, 6) + Font = new Font("Segoe UI", 12.5F, FontStyle.Bold), + ForeColor = UIHelpers.TextPrimaryColor, + Margin = new Padding(0, 10, 0, 8) }; layout.Controls.Add(heroPanel, 0, 0); @@ -192,4 +224,4 @@ public void Populate(GameViewService.GameManagerViewData viewData) gameCardsPanel.ResumeLayout(); } } -} \ No newline at end of file +} diff --git a/view/PcInfoView.cs b/view/PcInfoView.cs index c7a7c8f..f4e179b 100644 --- a/view/PcInfoView.cs +++ b/view/PcInfoView.cs @@ -2,6 +2,7 @@ using System.Text; using System.Windows.Forms; using Krassheiten.SystemGameManager.Controller; +using Krassheiten.SystemGameManager.View.Components; namespace Krassheiten.SystemGameManager.View; @@ -13,16 +14,27 @@ public TabPage CreateTab() { var tab = new TabPage("SystemManager") { - BackColor = Color.FromArgb(245, 247, 250) + BackColor = UIHelpers.WindowBackground }; var wrapper = new Panel() { Dock = DockStyle.Fill, - Padding = new Padding(10) + Padding = new Padding(18, 16, 18, 18), + BackColor = UIHelpers.WindowBackground }; - wrapper.Controls.Add(systemOutput); + var card = new Panel() + { + Dock = DockStyle.Fill, + Padding = new Padding(1), + BackColor = UIHelpers.BorderColor + }; + UIHelpers.SetRoundedRegion(card, 20); + + systemOutput.BorderStyle = BorderStyle.None; + card.Controls.Add(systemOutput); + wrapper.Controls.Add(card); tab.Controls.Add(wrapper); return tab; } @@ -84,10 +96,10 @@ private static RichTextBox CreateReadOnlyOutputBox() ReadOnly = true, Dock = DockStyle.Fill, Font = new Font("Consolas", 10F), - BackColor = Color.White, - ForeColor = Color.FromArgb(31, 41, 55), + BackColor = UIHelpers.SurfaceBackground, + ForeColor = UIHelpers.TextPrimaryColor, WordWrap = false, - BorderStyle = BorderStyle.FixedSingle + BorderStyle = BorderStyle.None }; } @@ -95,4 +107,4 @@ private static void AppendField(StringBuilder builder, string label, string? val { builder.AppendLine($"{label + ":",-14} {value ?? "nicht verfügbar"}"); } -} \ No newline at end of file +}