From cbe009fc788ebe8d7f88ed6130f9d58256455d7a Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 13:20:04 -0400 Subject: [PATCH 1/8] Rename WebService to ReferenceOpenerService and add OpenFileSystemPath --- Prowl.Editor/Panels/ProjectPanel.cs | 16 ++---- Prowl.Editor/Project/ProjectLauncher.cs | 4 +- Prowl.Editor/ReferenceOpenerService.cs | 67 +++++++++++++++++++++++++ Prowl.Editor/WebService.cs | 34 ------------- 4 files changed, 72 insertions(+), 49 deletions(-) create mode 100644 Prowl.Editor/ReferenceOpenerService.cs delete mode 100644 Prowl.Editor/WebService.cs diff --git a/Prowl.Editor/Panels/ProjectPanel.cs b/Prowl.Editor/Panels/ProjectPanel.cs index 2907c21cd..87fc67edc 100644 --- a/Prowl.Editor/Panels/ProjectPanel.cs +++ b/Prowl.Editor/Panels/ProjectPanel.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using Prowl.Editor.Docking; using Prowl.Editor.Widgets; @@ -698,19 +700,7 @@ private static void OpenWithSystem(ContentItem item) private static void ShowInExplorer(ContentItem item) { string absPath = Path.Combine(Project.Current!.AssetsPath, item.RelativePath); - ShowInExplorerPath(absPath); - } - - private static void ShowInExplorerPath(string absPath) - { - try - { - if (Directory.Exists(absPath)) - System.Diagnostics.Process.Start("explorer.exe", absPath); - else if (File.Exists(absPath)) - System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{absPath}\""); - } - catch { } + ReferenceOpenerService.OpenFileSystemPath(absPath); } // ================================================================ diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index 54b900bf4..2e32d586a 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -147,12 +147,12 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) { EditorGUI.Button(paper, "yt_link", "YouTube").OnValueChanged((_) => { - WebService.OpenUrl("https://youtube.com/@prowlengine"); + ReferenceOpenerService.OpenUrl("https://youtube.com/@prowlengine"); }); EditorGUI.Button(paper, "gh_link", "GitHub").OnValueChanged((_) => { - WebService.OpenUrl("https://github.com/ProwlEngine/Prowl"); + ReferenceOpenerService.OpenUrl("https://github.com/ProwlEngine/Prowl"); }); } } diff --git a/Prowl.Editor/ReferenceOpenerService.cs b/Prowl.Editor/ReferenceOpenerService.cs new file mode 100644 index 000000000..d3c679a5f --- /dev/null +++ b/Prowl.Editor/ReferenceOpenerService.cs @@ -0,0 +1,67 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +namespace Prowl.Editor; + +public static class ReferenceOpenerService +{ + public static void OpenUrl(string url) + { + try + { + // For Windows: Launching via shell + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); + } + // For macOS: Use the 'open' command + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", url); + } + // For Linux: Use 'xdg-open' + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("xdg-open", url); + } + } + catch (Exception ex) + { + Console.WriteLine($"Unable to open link: {ex.Message}"); + } + } + + public static void OpenFileSystemPath(string absPath) + { + try + { + // For Windows: Launching via shell + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (Directory.Exists(absPath)) + { + Process.Start("explorer.exe", absPath); + } + else if (File.Exists(absPath)) + { + Process.Start("explorer.exe", $"/select,\"{absPath}\""); + } + } + // For macOS: Use the 'open' command + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // The -R flag tells Finder to "reveal" the item (select it) + Process.Start("open", $"-R \"{absPath}\""); + } + // For Linux: Use 'xdg-open' + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + // Linux varies by distro; 'dbus-send' or 'xdg-open' are common alternatives + Process.Start("xdg-open", $"\"{System.IO.Path.GetDirectoryName(absPath)}\""); + } + } + catch { } + } +} \ No newline at end of file diff --git a/Prowl.Editor/WebService.cs b/Prowl.Editor/WebService.cs deleted file mode 100644 index 142fe17cc..000000000 --- a/Prowl.Editor/WebService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace Prowl.Editor; - -public static class WebService -{ - public static void OpenUrl(string url) - { - try - { - // For Windows: Launching via shell - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); - } - // For macOS: Use the 'open' command - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - Process.Start("open", url); - } - // For Linux: Use 'xdg-open' - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Process.Start("xdg-open", url); - } - } - catch (Exception ex) - { - Console.WriteLine($"Unable to open link: {ex.Message}"); - } - } -} \ No newline at end of file From ded194b18a8aa266bcd72df1209b087b7b40be51 Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 13:25:28 -0400 Subject: [PATCH 2/8] Add website and discord links --- Prowl.Editor/Project/ProjectLauncher.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index 2e32d586a..08cc67fcd 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -145,6 +145,16 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) .Margin(16, 12) .Enter()) { + EditorGUI.Button(paper, "yt_link", "Website").OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://prowlengine.com"); + }); + + EditorGUI.Button(paper, "yt_link", "Discord").OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://discord.gg/HgBsBqfSpa"); + }); + EditorGUI.Button(paper, "yt_link", "YouTube").OnValueChanged((_) => { ReferenceOpenerService.OpenUrl("https://youtube.com/@prowlengine"); From 92a5e7059816f96bedef023062176568b133686a Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:52:12 -0400 Subject: [PATCH 3/8] Overhauled revert back to old launcher style + new button types --- Prowl.Editor/Project/ProjectLauncher.cs | 188 +++++++++++------------- Prowl.Editor/Widgets/EditorGUI.cs | 55 ++++++- 2 files changed, 139 insertions(+), 104 deletions(-) diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index 08cc67fcd..4d8b5bffa 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -52,79 +52,101 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) int h = Window.InternalWindow.Size.Y; // Full background - // paper.Box("pl_bg") - // .PositionType(PositionType.SelfDirected) - // .Position(0, 0) - // .Size(w, h) - // .BackgroundColor(EditorTheme.Neutral100) - // .OnPostLayout((handle, rect) => paper.Draw(ref handle, (canvas, r) => - // { - // float cx = w / 2f; - // float cy = h / 2f; - // float radius = Math.Max(cx, cy) * 1.2f; - // float t = _animTime * 0.05f; - // var transparent = Prowl.Vector.Color32.FromArgb(0, 0, 0, 0); - - // // Subtle background gradients (same as editor but dimmer) - // float px = cx + (float)Math.Sin(t) * cx * 0.6f; - // float py = cy + (float)Math.Sin(t * 2) * cy * 0.3f; - // var purple = Prowl.Vector.Color32.FromArgb(25, 140, 60, 200); - // canvas.SetRadialBrush(px, py, 0, radius, purple, transparent); - // canvas.BeginPath(); - // canvas.Rect(0, 0, w, h); - // canvas.Fill(); - - // float bx = cx - (float)Math.Sin(t) * cx * 0.6f; - // float by = cy - (float)Math.Sin(t * 2) * cy * 0.3f; - // var blue = Prowl.Vector.Color32.FromArgb(25, 60, 140, 220); - // canvas.SetRadialBrush(bx, by, 0, radius, blue, transparent); - // canvas.BeginPath(); - // canvas.Rect(0, 0, w, h); - // canvas.Fill(); - // })); + paper.Box("pl_bg") + .PositionType(PositionType.SelfDirected) + .Position(0, 0) + .Size(w, h) + .BackgroundColor(EditorTheme.Neutral100) + .OnPostLayout((handle, rect) => paper.Draw(ref handle, (canvas, r) => + { + float cx = w / 2f; + float cy = h / 2f; + float radius = Math.Max(cx, cy) * 1.2f; + float t = _animTime * 0.05f; + var transparent = Prowl.Vector.Color32.FromArgb(0, 0, 0, 0); + + // Subtle background gradients (same as editor but dimmer) + float px = cx + (float)Math.Sin(t) * cx * 0.6f; + float py = cy + (float)Math.Sin(t * 2) * cy * 0.3f; + var purple = Prowl.Vector.Color32.FromArgb(25, 140, 60, 200); + canvas.SetRadialBrush(px, py, 0, radius, purple, transparent); + canvas.BeginPath(); + canvas.Rect(0, 0, w, h); + canvas.Fill(); + + float bx = cx - (float)Math.Sin(t) * cx * 0.6f; + float by = cy - (float)Math.Sin(t * 2) * cy * 0.3f; + var blue = Prowl.Vector.Color32.FromArgb(25, 60, 140, 220); + canvas.SetRadialBrush(bx, by, 0, radius, blue, transparent); + canvas.BeginPath(); + canvas.Rect(0, 0, w, h); + canvas.Fill(); + })); // Center card - // float cardW = 600f; - // float cardH = 500f; + float cardW = 600f; + float cardH = 500f; - float sidebarW = 200f; + // float sidebarW = 200f; - using (paper.Row("root") - .PositionType(PositionType.SelfDirected) - .Position(0, 0) - .Size(w, h) + using (paper.Column("root") + .Margin(UnitValue.StretchOne) + .Size(cardW, cardH) .BorderColor(EditorTheme.Ink100) .BorderWidth(1) + .Rounded(EditorTheme.Roundness) .BackgroundColor(EditorTheme.Neutral300) .Enter()) { - using (paper.Column("sidebar") - .BackgroundColor(EditorTheme.Neutral400) - .Size(sidebarW, h) + // Header + using (paper.Row("header") + .Height(60) + .RowBetween(0) + .RoundedTop(EditorTheme.Roundness) + .BackgroundColor(EditorTheme.Neutral300) .BorderColor(EditorTheme.Ink100) .BorderWidth(1) .Enter()) { - - // Prowl Emblem - using (paper.Row("pl_header") - .Height(60) - .RowBetween(12) - .BackgroundColor(EditorTheme.Neutral300) - .BorderColor(EditorTheme.Ink100) - .BorderWidth(1) - .Enter()) - { paper.Box("pl_title") .Height(60) - .Margin(16, 16, 0, 8) + .Width(110) + .Margin(16, 0, 8, 0) .Text("PROWL", boldFont) .TextColor(EditorTheme.Ink500) .FontSize(28f) .Alignment(TextAlignment.MiddleLeft); - // Spacer - paper.Box("pl_spacer"); + // Links + using (paper.Row("pl_header") + .Height(UnitValue.Auto) + .RowBetween(12) + .Margin(0, 0, 28, 0) + .Enter()) + { + EditorGUI.ButtonSquareGhost(paper, "www_link", EditorIcons.Globe).OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://prowlengine.com"); + }); + + EditorGUI.ButtonSquareGhost(paper, "ds_link", EditorIcons.Message).OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://discord.gg/HgBsBqfSpa"); + }); + + EditorGUI.ButtonSquareGhost(paper, "yt_link", EditorIcons.Video).OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://youtube.com/@prowlengine"); + }); + + EditorGUI.ButtonSquareGhost(paper, "gh_link", EditorIcons.Code).OnValueChanged((_) => + { + ReferenceOpenerService.OpenUrl("https://github.com/ProwlEngine/Prowl"); + }); + } + + paper.Box("spacer"); + paper.Box("pl_version") .Height(60) @@ -134,63 +156,22 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) .TextColor(EditorTheme.Ink400) .FontSize(12f) .Alignment(TextAlignment.MiddleRight); - } - - paper.Box("spacer").Height(UnitValue.Stretch()); - - // Links - using (paper.Column("pl_header") - .Height(60) - .ColBetween(12) - .Margin(16, 12) - .Enter()) - { - EditorGUI.Button(paper, "yt_link", "Website").OnValueChanged((_) => - { - ReferenceOpenerService.OpenUrl("https://prowlengine.com"); - }); - - EditorGUI.Button(paper, "yt_link", "Discord").OnValueChanged((_) => - { - ReferenceOpenerService.OpenUrl("https://discord.gg/HgBsBqfSpa"); - }); - - EditorGUI.Button(paper, "yt_link", "YouTube").OnValueChanged((_) => - { - ReferenceOpenerService.OpenUrl("https://youtube.com/@prowlengine"); - }); - - EditorGUI.Button(paper, "gh_link", "GitHub").OnValueChanged((_) => - { - ReferenceOpenerService.OpenUrl("https://github.com/ProwlEngine/Prowl"); - }); - } } + using (paper.Column("content") - .Size(w - sidebarW, h) + .Size(cardW, cardH - 90) .Enter()) { // New / Open buttons using (paper.Row("toolbar") - .Height(40) - .Margin(10, 10, 32, 0) + .Height(30) + .Margin(10, 10, 16, 0) .RowBetween(8) .Enter()) { - paper.Box("tl_label") - .Width(UnitValue.Auto) - .Height(EditorTheme.RowHeight) - .Text("Projects", boldFont) - .TextColor(EditorTheme.Ink500) - .FontSize(EditorTheme.FontSize + 8) - .Alignment(TextAlignment.MiddleLeft); - - // Spacer - paper.Box("tl_tb_spacer"); - // Spacer - EditorGUI.SearchBar(paper, "search", "", "Search"); + EditorGUI.SearchBar(paper, "search", "", "Search Projects"); EditorGUI.Button(paper, "tl_btn_open", $"{EditorIcons.FolderOpen} Open Project", 130) .OnValueChanged(_ => @@ -211,7 +192,8 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) .BorderColor(EditorTheme.Blue400) .BorderWidth(1) .OnClick((_) => _showNewProject = !_showNewProject) - .Enter()) { + .Enter()) + { paper.Box($"label") .Height(EditorTheme.RowHeight) .Margin(EditorTheme.RowHeight / 4, 0) @@ -229,7 +211,7 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) } // Recent projects list - DrawRecentProjects(paper, font, w - sidebarW, h - 60 - 40 - (_showNewProject ? 80 : 0)); + DrawRecentProjects(paper, font, cardW, cardH - 60 - 46 - (_showNewProject ? 80 : 0)); } } } @@ -301,7 +283,7 @@ private static void DrawRecentProjects(Paper paper, Prowl.Scribe.FontFile font, { var entries = RecentProjects.Entries; - using (ScrollView.Begin(paper, "pl_scroll", width, height, colSpacing: 8, paddingLeft: 8)) + using (ScrollView.Begin(paper, "pl_scroll", width, height, colSpacing: 8, paddingLeft: 8, paddingRight: 8)) { if (entries.Count == 0) { @@ -389,6 +371,8 @@ private static void DrawRecentProjects(Paper paper, Prowl.Scribe.FontFile font, } } } + + paper.Box("spacer").Height(6); } } diff --git a/Prowl.Editor/Widgets/EditorGUI.cs b/Prowl.Editor/Widgets/EditorGUI.cs index c3d9ff43e..1f310704c 100644 --- a/Prowl.Editor/Widgets/EditorGUI.cs +++ b/Prowl.Editor/Widgets/EditorGUI.cs @@ -106,7 +106,36 @@ public static WidgetResult Button(Paper paper, string id, string label, fl .BackgroundColor(EditorTheme.Ink100) .Hovered.BackgroundColor(EditorTheme.Ink200).End() .Rounded(3) - .BorderColor(EditorTheme.Ink200) + .BorderColor(EditorTheme.Ink100) + .BorderWidth(1) + .OnClick(e => userCallback?.Invoke(true)); + + if (width > 0) el.Width(width); + using (el.Enter()) + { + if (Font != null) + paper.Box($"{id}_label") + .Height(EditorTheme.RowHeight) + .Margin(EditorTheme.RowHeight/4, 0) + .Alignment(PaperUI.TextAlignment.MiddleLeft) + .Text(label, Font) + .TextColor(EditorTheme.Ink500) + .FontSize(FontSz); + } + + return new WidgetResult(cb => userCallback = cb); + } + + public static WidgetResult ButtonGhost(Paper paper, string id, string label, float width = 0) + { + Action? userCallback = null; + + var el = paper.Box(id) + .Height(EditorTheme.RowHeight) + // .BackgroundColor(EditorTheme.Ink100) + .Hovered.BackgroundColor(EditorTheme.Ink100).End() + .Rounded(3) + .BorderColor(EditorTheme.Ink100) .BorderWidth(1) .OnClick(e => userCallback?.Invoke(true)); @@ -140,7 +169,29 @@ public static WidgetResult ButtonSquare(Paper paper, string id, string ico .BackgroundColor(EditorTheme.Ink100) .Hovered.BackgroundColor(EditorTheme.Ink200).End() .Rounded(3) - .BorderColor(EditorTheme.Ink200).BorderWidth(1) + .BorderColor(EditorTheme.Ink100) + .BorderWidth(1) + .OnClick(e => userCallback?.Invoke(true)); + + return new WidgetResult(cb => userCallback = cb); + } + + public static WidgetResult ButtonSquareGhost(Paper paper, string id, string icon) + { + Action? userCallback = null; + + paper.Box(id) + .Alignment(PaperUI.TextAlignment.MiddleCenter) + .Text(icon, Font) + .TextColor(EditorTheme.Ink500) + .FontSize(FontSz) + .Height(EditorTheme.RowHeight) + .Width(EditorTheme.RowHeight) + // .BackgroundColor(EditorTheme.Ink100) + .Hovered.BackgroundColor(EditorTheme.Ink100).End() + .Rounded(3) + .BorderColor(EditorTheme.Ink100) + .BorderWidth(1) .OnClick(e => userCallback?.Invoke(true)); return new WidgetResult(cb => userCallback = cb); From d22bdc5825ae6ae256cd6a3f4575a05bd8484674 Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:56:03 -0400 Subject: [PATCH 4/8] Update FileDialog.cs --- Prowl.Editor/Widgets/FileDialog.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Prowl.Editor/Widgets/FileDialog.cs b/Prowl.Editor/Widgets/FileDialog.cs index 2f82f69a7..266aaaa14 100644 --- a/Prowl.Editor/Widgets/FileDialog.cs +++ b/Prowl.Editor/Widgets/FileDialog.cs @@ -244,7 +244,8 @@ public static void Draw(Paper paper) // Fullscreen blocker paper.Box("fd_overlay") - .PositionType(PositionType.SelfDirected).Position(0, 0) + .PositionType(PositionType.SelfDirected) + .Position(0, 0) .Size(UnitValue.Stretch(), UnitValue.Stretch()) .BackgroundColor(Color.FromArgb(120, 0, 0, 0)) .Layer(Layer.Overlay) From 4b7b82fd989bc01bcfed8f7077676a26e444c8ee Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:03:09 -0400 Subject: [PATCH 5/8] Update ProjectLauncher.cs --- Prowl.Editor/Project/ProjectLauncher.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index 4d8b5bffa..adec1074e 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -89,7 +89,9 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) // float sidebarW = 200f; - using (paper.Column("root") + using (paper.Box("container").Size(w, h).Position(0, 0).PositionType(PositionType.SelfDirected).Enter()) + { + using (paper.Column("pl_window") .Margin(UnitValue.StretchOne) .Size(cardW, cardH) .BorderColor(EditorTheme.Ink100) @@ -214,6 +216,7 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) DrawRecentProjects(paper, font, cardW, cardH - 60 - 46 - (_showNewProject ? 80 : 0)); } } + } } private static void DrawNewProjectPanel(Paper paper, Prowl.Scribe.FontFile font) From f3ab636d69877f5cd99e5907da45373026317aed Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:04:43 -0400 Subject: [PATCH 6/8] Update ProjectLauncher.cs --- Prowl.Editor/Project/ProjectLauncher.cs | 120 ++++++++++++------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index adec1074e..4a2e191b7 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -91,25 +91,25 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) using (paper.Box("container").Size(w, h).Position(0, 0).PositionType(PositionType.SelfDirected).Enter()) { - using (paper.Column("pl_window") - .Margin(UnitValue.StretchOne) - .Size(cardW, cardH) - .BorderColor(EditorTheme.Ink100) - .BorderWidth(1) - .Rounded(EditorTheme.Roundness) - .BackgroundColor(EditorTheme.Neutral300) - .Enter()) - { - // Header - using (paper.Row("header") - .Height(60) - .RowBetween(0) - .RoundedTop(EditorTheme.Roundness) - .BackgroundColor(EditorTheme.Neutral300) + using (paper.Column("pl_window") + .Margin(UnitValue.StretchOne) + .Size(cardW, cardH) .BorderColor(EditorTheme.Ink100) .BorderWidth(1) + .Rounded(EditorTheme.Roundness) + .BackgroundColor(EditorTheme.Neutral300) .Enter()) { + // Header + using (paper.Row("header") + .Height(60) + .RowBetween(0) + .RoundedTop(EditorTheme.Roundness) + .BackgroundColor(EditorTheme.Neutral300) + .BorderColor(EditorTheme.Ink100) + .BorderWidth(1) + .Enter()) + { paper.Box("pl_title") .Height(60) .Width(110) @@ -158,65 +158,65 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) .TextColor(EditorTheme.Ink400) .FontSize(12f) .Alignment(TextAlignment.MiddleRight); - } + } - using (paper.Column("content") - .Size(cardW, cardH - 90) - .Enter()) - { - // New / Open buttons - using (paper.Row("toolbar") - .Height(30) - .Margin(10, 10, 16, 0) - .RowBetween(8) + using (paper.Column("content") + .Size(cardW, cardH - 90) .Enter()) { - // Spacer - EditorGUI.SearchBar(paper, "search", "", "Search Projects"); + // New / Open buttons + using (paper.Row("toolbar") + .Height(30) + .Margin(10, 10, 16, 0) + .RowBetween(8) + .Enter()) + { + // Spacer + EditorGUI.SearchBar(paper, "search", "", "Search Projects"); - EditorGUI.Button(paper, "tl_btn_open", $"{EditorIcons.FolderOpen} Open Project", 130) - .OnValueChanged(_ => - { - FileDialog.Open(FileDialogMode.SelectFolder, path => + EditorGUI.Button(paper, "tl_btn_open", $"{EditorIcons.FolderOpen} Open Project", 130) + .OnValueChanged(_ => { - if (path == null) return; - TryOpenProject(path); + FileDialog.Open(FileDialogMode.SelectFolder, path => + { + if (path == null) return; + TryOpenProject(path); + }); }); - }); - using (paper.Box("tl_btn_new") - .Height(EditorTheme.RowHeight) - .Width(120) - .BackgroundColor(EditorTheme.Blue300) - .Hovered.BackgroundColor(EditorTheme.Blue400).End() - .Rounded(3) - .BorderColor(EditorTheme.Blue400) - .BorderWidth(1) - .OnClick((_) => _showNewProject = !_showNewProject) - .Enter()) - { - paper.Box($"label") + using (paper.Box("tl_btn_new") .Height(EditorTheme.RowHeight) - .Margin(EditorTheme.RowHeight / 4, 0) - .Alignment(PaperUI.TextAlignment.MiddleLeft) - .Text($" {EditorIcons.Plus} New Project", EditorTheme.DefaultFont) - .TextColor(EditorTheme.Ink500) - .FontSize(EditorTheme.FontSize); + .Width(120) + .BackgroundColor(EditorTheme.Blue300) + .Hovered.BackgroundColor(EditorTheme.Blue400).End() + .Rounded(3) + .BorderColor(EditorTheme.Blue400) + .BorderWidth(1) + .OnClick((_) => _showNewProject = !_showNewProject) + .Enter()) + { + paper.Box($"label") + .Height(EditorTheme.RowHeight) + .Margin(EditorTheme.RowHeight / 4, 0) + .Alignment(PaperUI.TextAlignment.MiddleLeft) + .Text($" {EditorIcons.Plus} New Project", EditorTheme.DefaultFont) + .TextColor(EditorTheme.Ink500) + .FontSize(EditorTheme.FontSize); + } } - } - // New project panel (collapsible) - if (_showNewProject) - { - DrawNewProjectPanel(paper, font); - } + // New project panel (collapsible) + if (_showNewProject) + { + DrawNewProjectPanel(paper, font); + } - // Recent projects list - DrawRecentProjects(paper, font, cardW, cardH - 60 - 46 - (_showNewProject ? 80 : 0)); + // Recent projects list + DrawRecentProjects(paper, font, cardW, cardH - 60 - 46 - (_showNewProject ? 80 : 0)); + } } } - } } private static void DrawNewProjectPanel(Paper paper, Prowl.Scribe.FontFile font) From 8b0e4ff0b26fb63dbe9d4bdefe70b57d5d190f7a Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:24:57 -0400 Subject: [PATCH 7/8] Update ProjectLauncher.cs --- Prowl.Editor/Project/ProjectLauncher.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Prowl.Editor/Project/ProjectLauncher.cs b/Prowl.Editor/Project/ProjectLauncher.cs index 4a2e191b7..db9db3333 100644 --- a/Prowl.Editor/Project/ProjectLauncher.cs +++ b/Prowl.Editor/Project/ProjectLauncher.cs @@ -87,8 +87,6 @@ public static void Draw(Paper paper, float dt, bool forceDraw = false) float cardW = 600f; float cardH = 500f; - // float sidebarW = 200f; - using (paper.Box("container").Size(w, h).Position(0, 0).PositionType(PositionType.SelfDirected).Enter()) { using (paper.Column("pl_window") From 5ddb6e6c4a8edfb6b618c7a12f46eb7f472937da Mon Sep 17 00:00:00 2001 From: Abdiel Lopez <48071553+PaperPrototype@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:32:15 -0400 Subject: [PATCH 8/8] Missing .DS_Store in default gitignore for MacOS --- Prowl.Editor/Project/Project.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prowl.Editor/Project/Project.cs b/Prowl.Editor/Project/Project.cs index b248c2c32..4daccf907 100644 --- a/Prowl.Editor/Project/Project.cs +++ b/Prowl.Editor/Project/Project.cs @@ -61,7 +61,7 @@ public static Project Create(string parentFolder, string projectName) if (!File.Exists(gitignore)) { File.WriteAllText(gitignore, - "Library/\nTemp/\nLogs/\n*.csproj\n*.sln\n.vs/\nbin/\nobj/\n"); + "Library/\nTemp/\nLogs/\n*.csproj\n*.sln\n.vs/\nbin/\nobj/\n# MacOS/\n.DS_Store/\n"); } return project;