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);
}