From d044e97cea0feb4687376f0b5b38c91d2d4bf791 Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Tue, 24 Mar 2026 18:42:49 +0800 Subject: [PATCH] =?UTF-8?q?Paint=E5=A2=9E=E5=8A=A0=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E9=87=8D=E5=86=99StartMenu=E7=9A=84UI=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E6=B8=B2=E6=9F=93bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BuildTime.txt | 2 +- GitCommit.txt | 2 +- Gui/Apps/Paint/Paint.cs | 225 ++++++++++++++++++++++++++++++- Gui/Apps/Settings.cs | 6 +- Gui/ShellComponents/StartMenu.cs | 148 ++++++++++++-------- Gui/UILib/AppWindow.cs | 22 +++ Gui/UILib/MessageBox.cs | 17 ++- Gui/UILib/PromptBox.cs | 17 ++- 8 files changed, 363 insertions(+), 76 deletions(-) diff --git a/BuildTime.txt b/BuildTime.txt index 67fd6f9..6ce4325 100644 --- a/BuildTime.txt +++ b/BuildTime.txt @@ -1 +1 @@ -2026-03-24 17:41:18 \ No newline at end of file +2026-03-24 18:39:25 \ No newline at end of file diff --git a/GitCommit.txt b/GitCommit.txt index 9ea4b91..6ca38a4 100644 --- a/GitCommit.txt +++ b/GitCommit.txt @@ -1 +1 @@ -6c75c51 \ No newline at end of file +fc61afb \ No newline at end of file diff --git a/Gui/Apps/Paint/Paint.cs b/Gui/Apps/Paint/Paint.cs index 64a2a0f..4cf2efb 100644 --- a/Gui/Apps/Paint/Paint.cs +++ b/Gui/Apps/Paint/Paint.cs @@ -15,9 +15,13 @@ // along with this program. If not, see . using Cosmos.System; +using Cosmos.System.Graphics; using CMLeonOS; using CMLeonOS.Gui.UILib; +using CMLeonOS.Utils; +using System; using System.Drawing; +using System.IO; namespace CMLeonOS.Gui.Apps.Paint { @@ -30,14 +34,24 @@ namespace CMLeonOS.Gui.Apps.Paint AppWindow window; Window canvas; + Button openButton; + Button saveButton; + Button saveAsButton; ToolBox toolBox; ColourPicker colourPicker; + FileBrowser fileBrowser; WindowManager wm = ProcessManager.GetProcess(); private bool down = false; + private const int sidePanelWidth = 128; + private const int topBarHeight = 40; + private const int topButtonWidth = 84; + private const int topButtonHeight = 24; + private const int topButtonGap = 8; + private string currentFilePath = string.Empty; internal Color SelectedColor { get; set; } = Color.Black; @@ -54,6 +68,190 @@ namespace CMLeonOS.Gui.Apps.Paint down = true; } + private void ShowMessage(string title, string text) + { + MessageBox messageBox = new MessageBox(this, title, text); + messageBox.Show(); + } + + private void Relayout() + { + toolBox.MoveAndResize(0, 0, sidePanelWidth, window.Height); + colourPicker.MoveAndResize(window.Width - sidePanelWidth, 0, sidePanelWidth, window.Height); + + int buttonsX = sidePanelWidth + 12; + openButton.MoveAndResize(buttonsX, 8, topButtonWidth, topButtonHeight); + saveButton.MoveAndResize(buttonsX + topButtonWidth + topButtonGap, 8, topButtonWidth, topButtonHeight); + saveAsButton.MoveAndResize(buttonsX + (topButtonWidth + topButtonGap) * 2, 8, topButtonWidth, topButtonHeight); + openButton.Render(); + saveButton.Render(); + saveAsButton.Render(); + + int canvasX = sidePanelWidth + 12; + int canvasY = topBarHeight + 8; + int canvasWidth = window.Width - sidePanelWidth * 2 - 24; + int canvasHeight = window.Height - canvasY - 12; + canvas.MoveAndResize(canvasX, canvasY, canvasWidth, canvasHeight); + + if (canvasWidth > 0 && canvasHeight > 0) + { + canvas.DrawRectangle(0, 0, canvas.Width, canvas.Height, Color.Black); + wm.Update(canvas); + } + } + + private void UpdateWindowTitle() + { + if (string.IsNullOrWhiteSpace(currentFilePath)) + { + window.Title = "Paint"; + return; + } + + window.Title = $"Paint - {Path.GetFileName(currentFilePath)}"; + } + + private byte[] BuildBmpBytes() + { + int width = canvas.Width; + int height = canvas.Height; + int bytesPerPixel = 4; + int pixelDataSize = width * height * bytesPerPixel; + int fileSize = 54 + pixelDataSize; + byte[] bytes = new byte[fileSize]; + + bytes[0] = (byte)'B'; + bytes[1] = (byte)'M'; + BitConverter.GetBytes(fileSize).CopyTo(bytes, 2); + BitConverter.GetBytes(54).CopyTo(bytes, 10); + BitConverter.GetBytes(40).CopyTo(bytes, 14); + BitConverter.GetBytes(width).CopyTo(bytes, 18); + BitConverter.GetBytes(height).CopyTo(bytes, 22); + BitConverter.GetBytes((short)1).CopyTo(bytes, 26); + BitConverter.GetBytes((short)32).CopyTo(bytes, 28); + BitConverter.GetBytes(pixelDataSize).CopyTo(bytes, 34); + + int offset = 54; + for (int y = height - 1; y >= 0; y--) + { + for (int x = 0; x < width; x++) + { + Color color = canvas.GetPixel(x, y); + bytes[offset++] = color.B; + bytes[offset++] = color.G; + bytes[offset++] = color.R; + bytes[offset++] = color.A; + } + } + + return bytes; + } + + private void SaveCanvas(string path) + { + try + { + string sanitizedPath = PathUtil.Sanitize(path.Trim()); + if (!sanitizedPath.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)) + { + sanitizedPath += ".bmp"; + } + + string directory = Path.GetDirectoryName(sanitizedPath); + if (!string.IsNullOrWhiteSpace(directory)) + { + Directory.CreateDirectory(directory); + } + + File.WriteAllBytes(sanitizedPath, BuildBmpBytes()); + currentFilePath = sanitizedPath; + UpdateWindowTitle(); + ShowMessage("Paint", "Saved BMP successfully."); + } + catch (Exception ex) + { + ShowMessage("Paint", $"Save failed: {ex.Message}"); + } + } + + private void OpenImage(string path) + { + try + { + string sanitizedPath = PathUtil.Sanitize(path.Trim()); + if (!File.Exists(sanitizedPath)) + { + ShowMessage("Paint", "File not found."); + return; + } + + if (!sanitizedPath.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)) + { + ShowMessage("Paint", "Only BMP files are supported."); + return; + } + + Bitmap bitmap = new Bitmap(File.ReadAllBytes(sanitizedPath)); + canvas.Clear(Color.White); + + int drawWidth = Math.Min(canvas.Width, (int)bitmap.Width); + int drawHeight = Math.Min(canvas.Height, (int)bitmap.Height); + for (int y = 0; y < drawHeight; y++) + { + int rowOffset = y * (int)bitmap.Width; + for (int x = 0; x < drawWidth; x++) + { + canvas.DrawPoint(x, y, Color.FromArgb(bitmap.RawData[rowOffset + x])); + } + } + + canvas.DrawRectangle(0, 0, canvas.Width, canvas.Height, Color.Black); + wm.Update(canvas); + + currentFilePath = sanitizedPath; + UpdateWindowTitle(); + } + catch (Exception ex) + { + ShowMessage("Paint", $"Open failed: {ex.Message}"); + } + } + + private void OpenClicked(int x, int y) + { + fileBrowser = new FileBrowser(this, wm, (string selectedPath) => + { + if (!string.IsNullOrWhiteSpace(selectedPath)) + { + OpenImage(selectedPath); + } + }, selectDirectoryOnly: false); + fileBrowser.Show(); + } + + private void SaveAsClicked(int x, int y) + { + fileBrowser = new FileBrowser(this, wm, (string selectedPath) => + { + if (!string.IsNullOrWhiteSpace(selectedPath)) + { + SaveCanvas(selectedPath); + } + }, selectDirectoryOnly: true); + fileBrowser.Show(); + } + + private void SaveClicked(int x, int y) + { + if (string.IsNullOrWhiteSpace(currentFilePath)) + { + SaveAsClicked(x, y); + return; + } + + SaveCanvas(currentFilePath); + } + public override void Start() { base.Start(); @@ -61,22 +259,39 @@ namespace CMLeonOS.Gui.Apps.Paint window.Title = "Paint"; window.Icon = AppManager.GetAppMetadata("Paint").Icon; window.Closing = TryStop; + window.UserResized = Relayout; window.Clear(Color.FromArgb(73, 73, 73)); wm.AddWindow(window); - int canvasWidth = 384; - int canvasHeight = 256; - canvas = new Window(this, (window.Width / 2) - (canvasWidth / 2), (window.Height / 2) - (canvasHeight / 2), canvasWidth, canvasHeight); + canvas = new Window(this, 0, 0, 1, 1); canvas.RelativeTo = window; canvas.OnDown = CanvasDown; canvas.Clear(Color.White); wm.AddWindow(canvas); - toolBox = new ToolBox(this, 0, 0, 128, window.Height); + openButton = new Button(window, 0, 0, 1, 1); + openButton.Text = "Open"; + openButton.OnClick = OpenClicked; + wm.AddWindow(openButton); + + saveButton = new Button(window, 0, 0, 1, 1); + saveButton.Text = "Save"; + saveButton.OnClick = SaveClicked; + wm.AddWindow(saveButton); + + saveAsButton = new Button(window, 0, 0, 1, 1); + saveAsButton.Text = "Save As"; + saveAsButton.OnClick = SaveAsClicked; + wm.AddWindow(saveAsButton); + + toolBox = new ToolBox(this, 0, 0, sidePanelWidth, window.Height); toolBox.RelativeTo = window; - colourPicker = new ColourPicker(this, window.Width - 128, 0, 128, window.Height); + colourPicker = new ColourPicker(this, window.Width - sidePanelWidth, 0, sidePanelWidth, window.Height); colourPicker.RelativeTo = window; + UpdateWindowTitle(); + Relayout(); + wm.Update(window); } diff --git a/Gui/Apps/Settings.cs b/Gui/Apps/Settings.cs index 101aaf8..94d9912 100644 --- a/Gui/Apps/Settings.cs +++ b/Gui/Apps/Settings.cs @@ -195,14 +195,14 @@ namespace CMLeonOS.Gui.Apps appearance.DrawString("Wallpaper", Color.Gray, 12, 132); appearance.DrawString(GetWallpaperLabel(), Color.Black, 12, 152); - appearance.DrawString("Choose a BMP file or restore the embedded default wallpaper.", Color.Gray, 12, 172); + appearance.DrawString("Use a BMP file or restore the default wallpaper.", Color.Gray, 12, 170); - Button chooseWallpaper = new Button(appearance, 12, 198, 132, 24); + Button chooseWallpaper = new Button(appearance, 12, 192, 132, 24); chooseWallpaper.Text = "Choose BMP"; chooseWallpaper.OnClick = (_, _) => OpenWallpaperBrowser(); wm.AddWindow(chooseWallpaper); - Button defaultWallpaper = new Button(appearance, 154, 198, 132, 24); + Button defaultWallpaper = new Button(appearance, 154, 192, 132, 24); defaultWallpaper.Text = "Use Default"; defaultWallpaper.OnClick = (_, _) => ApplyWallpaper(string.Empty); wm.AddWindow(defaultWallpaper); diff --git a/Gui/ShellComponents/StartMenu.cs b/Gui/ShellComponents/StartMenu.cs index a5b8c2a..b945056 100644 --- a/Gui/ShellComponents/StartMenu.cs +++ b/Gui/ShellComponents/StartMenu.cs @@ -18,6 +18,7 @@ using Cosmos.System.Graphics; using CMLeonOS; using CMLeonOS.Gui.UILib; using CMLeonOS.UILib.Animations; +using System; using System.Drawing; namespace CMLeonOS.Gui.ShellComponents @@ -28,6 +29,27 @@ namespace CMLeonOS.Gui.ShellComponents { } + private const int menuWidth = 456; + private const int menuHeight = 320; + private const int outerPadding = 16; + private const int searchHeight = 28; + private const int footerHeight = 72; + private const int actionButtonWidth = 104; + private const int actionButtonHeight = 24; + + private static readonly Color MenuBackground = Color.FromArgb(24, 31, 43); + private static readonly Color PanelBackground = Color.FromArgb(35, 44, 58); + private static readonly Color PanelBorder = Color.FromArgb(58, 70, 89); + private static readonly Color HeaderText = Color.White; + private static readonly Color SubText = Color.FromArgb(178, 190, 210); + private static readonly Color SearchBackground = Color.FromArgb(245, 247, 250); + private static readonly Color SearchForeground = Color.FromArgb(28, 34, 45); + private static readonly Color SearchPlaceholder = Color.FromArgb(126, 136, 149); + private static readonly Color NeutralButton = Color.FromArgb(70, 83, 104); + private static readonly Color NeutralButtonBorder = Color.FromArgb(90, 105, 127); + private static readonly Color SearchResultsBackground = Color.FromArgb(31, 39, 52); + private static readonly Color SearchResultsBorder = Color.FromArgb(54, 66, 84); + internal static StartMenu CurrentStartMenu { get @@ -57,94 +79,97 @@ namespace CMLeonOS.Gui.ShellComponents private Button shutdownButton; private Button rebootButton; + private Button logOutButton; private Button allAppsButton; - private const int buttonsPadding = 12; - private const int buttonsWidth = 96; - private const int buttonsHeight = 20; - private const int userHeight = 56; - private const int userPadding = 12; - private const int searchWidth = 128; - private bool isOpen = false; + private void StyleActionButton(Button button, string text) + { + button.Text = text; + button.Background = NeutralButton; + button.Border = NeutralButtonBorder; + button.Foreground = Color.White; + } + internal void ShowStartMenu(bool focusSearch = false) { isOpen = true; bool leftHandStartButton = settingsService.LeftHandStartButton; - window = new Window(this, leftHandStartButton ? 0 : (int)(wm.ScreenWidth / 2 - 408 / 2), 24, 408, 222); + int menuX = leftHandStartButton ? 0 : (int)(wm.ScreenWidth / 2 - menuWidth / 2); + window = new Window(this, menuX, 24, menuWidth, menuHeight); - window.Clear(Color.FromArgb(56, 56, 71)); + window.Clear(MenuBackground); + window.DrawRectangle(0, 0, window.Width, window.Height, PanelBorder); - window.DrawString($"Start", Color.White, 12, 12); + window.DrawString("Start", HeaderText, outerPadding, outerPadding - 2); + window.DrawString("Apps, search, and quick actions", SubText, outerPadding, outerPadding + 18); - Rectangle userRect = new Rectangle(userPadding, window.Height - userHeight + userPadding, window.Width - (userPadding * 2), userHeight - (userPadding * 2)); - window.DrawImageAlpha(Icons.Icon_User, userRect.X, (int)(userRect.Y + (userRect.Height / 2) - (Icons.Icon_User.Height / 2))); - window.DrawString(UserSystem.CurrentLoggedInUser.Username, Color.White, (int)(userRect.X + Icons.Icon_User.Width + userPadding), (int)(userRect.Y + (userRect.Height / 2) - (16 / 2))); + int searchY = outerPadding + 40; + int searchWidth = window.Width - (outerPadding * 2); + window.DrawFilledRectangle(outerPadding, searchY, searchWidth, searchHeight, SearchBackground); + window.DrawRectangle(outerPadding, searchY, searchWidth, searchHeight, Color.FromArgb(207, 214, 224)); + + int footerY = window.Height - footerHeight - outerPadding; + window.DrawFilledRectangle(outerPadding, footerY, window.Width - (outerPadding * 2), footerHeight, PanelBackground); + window.DrawRectangle(outerPadding, footerY, window.Width - (outerPadding * 2), footerHeight, PanelBorder); + + Rectangle userRect = new Rectangle(outerPadding + 10, footerY + 10, 180, footerHeight - 20); + window.DrawFilledRectangle(userRect.X, userRect.Y, userRect.Width, userRect.Height, Color.FromArgb(44, 55, 73)); + window.DrawRectangle(userRect.X, userRect.Y, userRect.Width, userRect.Height, Color.FromArgb(71, 86, 109)); + window.DrawImageAlpha(Icons.Icon_User, userRect.X + 10, (int)(userRect.Y + (userRect.Height / 2) - (Icons.Icon_User.Height / 2))); + window.DrawString(UserSystem.CurrentLoggedInUser.Username, Color.White, userRect.X + 38, userRect.Y + 10); + window.DrawString("Local session", SubText, userRect.X + 38, userRect.Y + 28); wm.AddWindow(window); - int x = 12; - int y = 44; - for (int i = 0; i < 4; i++) - { - AppMetadata app = AppManager.AppMetadatas[i]; - - Button appButton = new Button(window, x, y, 90, 90); - - appButton.Background = app.ThemeColor; - appButton.Foreground = app.ThemeColor.GetForegroundColour(); - - appButton.Text = app.Name; - appButton.Image = app.Icon; - - appButton.OnClick = (x, y) => - { - app.Start(this); - HideStartMenu(); - }; - - wm.AddWindow(appButton); - - x += appButton.Width + 8; - if (x > window.Width - 90) - { - x = 12; - y += 90 + 8; - } - } - - shutdownButton = new Button(window, window.Width - buttonsWidth - buttonsPadding, window.Height - buttonsHeight - ((userHeight / 2) - (buttonsHeight / 2)), buttonsWidth, buttonsHeight); - shutdownButton.Text = "Shut down"; + int topActionY = footerY + 10; + int bottomActionY = footerY + footerHeight - actionButtonHeight - 10; + shutdownButton = new Button(window, window.Width - outerPadding - actionButtonWidth, bottomActionY, actionButtonWidth, actionButtonHeight); + StyleActionButton(shutdownButton, "Shut down"); shutdownButton.OnClick = ShutdownClicked; wm.AddWindow(shutdownButton); - rebootButton = new Button(window, window.Width - (buttonsPadding * 2 + buttonsWidth * 2), window.Height - buttonsHeight - ((userHeight / 2) - (buttonsHeight / 2)), buttonsWidth, buttonsHeight); - rebootButton.Text = "Restart"; + rebootButton = new Button(window, window.Width - outerPadding - actionButtonWidth * 2 - 8, bottomActionY, actionButtonWidth, actionButtonHeight); + StyleActionButton(rebootButton, "Restart"); rebootButton.OnClick = RebootClicked; wm.AddWindow(rebootButton); - allAppsButton = new Button(window, window.Width - buttonsWidth - buttonsPadding, window.Height - buttonsHeight - userHeight, buttonsWidth, buttonsHeight); - allAppsButton.Text = "All apps >"; + logOutButton = new Button(window, window.Width - outerPadding - actionButtonWidth * 2 - 8, topActionY, actionButtonWidth, actionButtonHeight); + StyleActionButton(logOutButton, "Log out"); + logOutButton.OnClick = LogOutClicked; + wm.AddWindow(logOutButton); + + allAppsButton = new Button(window, window.Width - outerPadding - actionButtonWidth, topActionY, actionButtonWidth, actionButtonHeight); + StyleActionButton(allAppsButton, "All apps"); allAppsButton.OnClick = AllAppsClicked; wm.AddWindow(allAppsButton); Table searchResults = null; - TextBox searchBox = new TextBox(window, (window.Width / 2) - (searchWidth / 2), 12, searchWidth, 20); + TextBox searchBox = new TextBox(window, outerPadding + 6, searchY + 4, searchWidth - 12, searchHeight - 8); if (focusSearch) { wm.Focus = searchBox; } searchBox.PlaceholderText = "Search"; + searchBox.Background = SearchBackground; + searchBox.Foreground = SearchForeground; + searchBox.PlaceholderForeground = SearchPlaceholder; searchBox.Changed = () => { if (searchResults == null) { - searchResults = new Table(searchBox, 0, searchBox.Height, searchBox.Width, 0); + searchResults = new Table(searchBox, 0, searchBox.Height + 4, searchBox.Width, 0); searchResults.CellHeight = 24; + searchResults.Background = SearchResultsBackground; + searchResults.Foreground = Color.White; + searchResults.Border = SearchResultsBorder; + searchResults.SelectedBackground = Color.FromArgb(62, 84, 120); + searchResults.SelectedBorder = Color.FromArgb(88, 117, 164); + searchResults.SelectedForeground = Color.White; searchResults.TableCellSelected = (int index) => { @@ -162,12 +187,12 @@ namespace CMLeonOS.Gui.ShellComponents { foreach (AppMetadata app in AppManager.AppMetadatas) { - if (app.Name.ToLower().StartsWith(searchBox.Text.ToLower())) + if (app.Name.ToLower().Contains(searchBox.Text.ToLower())) { string name = app.Name; - if (name.Length > 8) + if (name.Length > 22) { - name = name.Substring(0, 8).Trim() + "..."; + name = name.Substring(0, 22).Trim() + "..."; } searchResults.Cells.Add(new TableCell(app.Icon.Resize(20, 20), name, tag: app)); } @@ -225,21 +250,28 @@ namespace CMLeonOS.Gui.ShellComponents Power.Shutdown(reboot: true); } + private void LogOutClicked(int x, int y) + { + HideStartMenu(); + ProcessManager.GetProcess()?.ClearAllWindows(); + ProcessManager.AddProcess(wm, new Lock()).Start(); + } + private void AllAppsClicked(int x, int y) { Table allAppsTable = new Table(window, 0, 0, window.Width, window.Height); allAppsTable.CellHeight = 32; - allAppsTable.Background = Color.FromArgb(56, 56, 71); + allAppsTable.Background = MenuBackground; allAppsTable.Foreground = Color.White; - allAppsTable.Border = Color.FromArgb(36, 36, 51); + allAppsTable.Border = PanelBorder; + allAppsTable.SelectedBackground = Color.FromArgb(57, 76, 108); + allAppsTable.SelectedBorder = Color.FromArgb(86, 109, 146); foreach (AppMetadata app in AppManager.AppMetadatas) { TableCell cell = new TableCell(app.Icon.Resize(20, 20), app.Name); - /*cell.BackgroundColourOverride = app.ThemeColor; - cell.ForegroundColourOverride = app.ThemeColor.GetForegroundColour();*/ allAppsTable.Cells.Add(cell); } allAppsTable.Render(); diff --git a/Gui/UILib/AppWindow.cs b/Gui/UILib/AppWindow.cs index 37d141a..ce2dd81 100644 --- a/Gui/UILib/AppWindow.cs +++ b/Gui/UILib/AppWindow.cs @@ -155,6 +155,27 @@ namespace CMLeonOS.Gui.UILib private int originalWidth; private int originalHeight; + private void RefreshWindowTree() + { + wm.Update(this); + RenderDecoration(); + + foreach (Window child in wm.Windows) + { + if (child.RelativeTo == this) + { + if (child is Control control) + { + control.Render(); + } + else + { + wm.Update(child); + } + } + } + } + private void StartOpenAnimation() { int targetY = Y; @@ -170,6 +191,7 @@ namespace CMLeonOS.Gui.UILib EasingType = EasingType.Sine, EasingDirection = EasingDirection.Out }; + animation.Completed = RefreshWindowTree; animation.Start(); } diff --git a/Gui/UILib/MessageBox.cs b/Gui/UILib/MessageBox.cs index 7d0ff51..94bc68c 100644 --- a/Gui/UILib/MessageBox.cs +++ b/Gui/UILib/MessageBox.cs @@ -35,14 +35,16 @@ namespace CMLeonOS.Gui.UILib { WindowManager wm = ProcessManager.GetProcess(); + string[] lines = Message.Split('\n'); int longestLineLength = 0; - foreach (string line in Message.Split('\n')) + foreach (string line in lines) { longestLineLength = Math.Max(longestLineLength, line.Length); } - int width = Math.Max(192, (Padding * 2) + (8 * longestLineLength)); - int height = 128 + ((Message.Split('\n').Length - 1) * 16); + int width = Math.Max(208, (Padding * 2) + (8 * longestLineLength)); + int textHeight = lines.Length * 16; + int height = Math.Max(112, Padding + textHeight + 16 + 20 + Padding * 2); AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (width / 2)), (int)((wm.ScreenHeight / 2) - (height / 2)), width, height); window.Title = Title; @@ -51,7 +53,13 @@ namespace CMLeonOS.Gui.UILib window.Clear(UITheme.Surface); window.DrawRectangle(0, 0, window.Width, window.Height, UITheme.SurfaceBorder); window.DrawFilledRectangle(0, window.Height - (Padding * 2) - 20, window.Width, (Padding * 2) + 20, UITheme.SurfaceMuted); - window.DrawString(Message, UITheme.TextPrimary, Padding, Padding); + + int textY = Padding; + foreach (string line in lines) + { + window.DrawString(line, UITheme.TextPrimary, Padding, textY); + textY += 16; + } Button ok = new Button(window, window.Width - 80 - Padding, window.Height - 20 - Padding, 80, 20); ok.Text = "OK"; @@ -64,6 +72,7 @@ namespace CMLeonOS.Gui.UILib wm.AddWindow(ok); wm.Update(window); + ok.Render(); ProcessManager.GetProcess().PlaySystemSound(Sound.SystemSound.Alert); } diff --git a/Gui/UILib/PromptBox.cs b/Gui/UILib/PromptBox.cs index b71ed68..638b739 100644 --- a/Gui/UILib/PromptBox.cs +++ b/Gui/UILib/PromptBox.cs @@ -33,14 +33,16 @@ namespace CMLeonOS.Gui.UILib { WindowManager wm = ProcessManager.GetProcess(); + string[] lines = Message.Split('\n'); int longestLineLength = 0; - foreach (string line in Message.Split('\n')) + foreach (string line in lines) { longestLineLength = Math.Max(longestLineLength, line.Length); } int width = Math.Max(256, (Padding * 2) + (8 * longestLineLength)); - int height = 128 + ((Message.Split('\n').Length - 1) * 16); + int textHeight = lines.Length * 16; + int height = Math.Max(128, Padding + textHeight + 28 + 20 + Padding * 2); AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (width / 2)), (int)((wm.ScreenHeight / 2) - (height / 2)), width, height); window.Title = Title; @@ -49,9 +51,15 @@ namespace CMLeonOS.Gui.UILib window.Clear(UITheme.Surface); window.DrawRectangle(0, 0, window.Width, window.Height, UITheme.SurfaceBorder); window.DrawFilledRectangle(0, window.Height - (Padding * 2) - 20, window.Width, (Padding * 2) + 20, UITheme.SurfaceMuted); - window.DrawString(Message, UITheme.TextPrimary, Padding, Padding); - TextBox textBox = new TextBox(window, Padding, Padding + FontData.Height + 8, 192, 20); + int textY = Padding; + foreach (string line in lines) + { + window.DrawString(line, UITheme.TextPrimary, Padding, textY); + textY += 16; + } + + TextBox textBox = new TextBox(window, Padding, textY + 8, 192, 20); textBox.PlaceholderText = Placeholder; wm.AddWindow(textBox); @@ -68,6 +76,7 @@ namespace CMLeonOS.Gui.UILib wm.AddWindow(ok); wm.Update(window); + ok.Render(); ProcessManager.GetProcess().PlaySystemSound(Sound.SystemSound.Alert); }