mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-04-21 10:53:59 +00:00
Paint增加保存,重写StartMenu的UI,修复部分渲染bug
This commit is contained in:
@@ -1 +1 @@
|
|||||||
2026-03-24 17:41:18
|
2026-03-24 18:39:25
|
||||||
@@ -1 +1 @@
|
|||||||
6c75c51
|
fc61afb
|
||||||
@@ -15,9 +15,13 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using Cosmos.System;
|
using Cosmos.System;
|
||||||
|
using Cosmos.System.Graphics;
|
||||||
using CMLeonOS;
|
using CMLeonOS;
|
||||||
using CMLeonOS.Gui.UILib;
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace CMLeonOS.Gui.Apps.Paint
|
namespace CMLeonOS.Gui.Apps.Paint
|
||||||
{
|
{
|
||||||
@@ -30,14 +34,24 @@ namespace CMLeonOS.Gui.Apps.Paint
|
|||||||
AppWindow window;
|
AppWindow window;
|
||||||
|
|
||||||
Window canvas;
|
Window canvas;
|
||||||
|
Button openButton;
|
||||||
|
Button saveButton;
|
||||||
|
Button saveAsButton;
|
||||||
|
|
||||||
ToolBox toolBox;
|
ToolBox toolBox;
|
||||||
|
|
||||||
ColourPicker colourPicker;
|
ColourPicker colourPicker;
|
||||||
|
FileBrowser fileBrowser;
|
||||||
|
|
||||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
private bool down = false;
|
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;
|
internal Color SelectedColor { get; set; } = Color.Black;
|
||||||
|
|
||||||
@@ -54,6 +68,190 @@ namespace CMLeonOS.Gui.Apps.Paint
|
|||||||
down = true;
|
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()
|
public override void Start()
|
||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
@@ -61,22 +259,39 @@ namespace CMLeonOS.Gui.Apps.Paint
|
|||||||
window.Title = "Paint";
|
window.Title = "Paint";
|
||||||
window.Icon = AppManager.GetAppMetadata("Paint").Icon;
|
window.Icon = AppManager.GetAppMetadata("Paint").Icon;
|
||||||
window.Closing = TryStop;
|
window.Closing = TryStop;
|
||||||
|
window.UserResized = Relayout;
|
||||||
window.Clear(Color.FromArgb(73, 73, 73));
|
window.Clear(Color.FromArgb(73, 73, 73));
|
||||||
wm.AddWindow(window);
|
wm.AddWindow(window);
|
||||||
|
|
||||||
int canvasWidth = 384;
|
canvas = new Window(this, 0, 0, 1, 1);
|
||||||
int canvasHeight = 256;
|
|
||||||
canvas = new Window(this, (window.Width / 2) - (canvasWidth / 2), (window.Height / 2) - (canvasHeight / 2), canvasWidth, canvasHeight);
|
|
||||||
canvas.RelativeTo = window;
|
canvas.RelativeTo = window;
|
||||||
canvas.OnDown = CanvasDown;
|
canvas.OnDown = CanvasDown;
|
||||||
canvas.Clear(Color.White);
|
canvas.Clear(Color.White);
|
||||||
wm.AddWindow(canvas);
|
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;
|
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;
|
colourPicker.RelativeTo = window;
|
||||||
|
|
||||||
|
UpdateWindowTitle();
|
||||||
|
Relayout();
|
||||||
|
|
||||||
wm.Update(window);
|
wm.Update(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,14 +195,14 @@ namespace CMLeonOS.Gui.Apps
|
|||||||
|
|
||||||
appearance.DrawString("Wallpaper", Color.Gray, 12, 132);
|
appearance.DrawString("Wallpaper", Color.Gray, 12, 132);
|
||||||
appearance.DrawString(GetWallpaperLabel(), Color.Black, 12, 152);
|
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.Text = "Choose BMP";
|
||||||
chooseWallpaper.OnClick = (_, _) => OpenWallpaperBrowser();
|
chooseWallpaper.OnClick = (_, _) => OpenWallpaperBrowser();
|
||||||
wm.AddWindow(chooseWallpaper);
|
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.Text = "Use Default";
|
||||||
defaultWallpaper.OnClick = (_, _) => ApplyWallpaper(string.Empty);
|
defaultWallpaper.OnClick = (_, _) => ApplyWallpaper(string.Empty);
|
||||||
wm.AddWindow(defaultWallpaper);
|
wm.AddWindow(defaultWallpaper);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Cosmos.System.Graphics;
|
|||||||
using CMLeonOS;
|
using CMLeonOS;
|
||||||
using CMLeonOS.Gui.UILib;
|
using CMLeonOS.Gui.UILib;
|
||||||
using CMLeonOS.UILib.Animations;
|
using CMLeonOS.UILib.Animations;
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace CMLeonOS.Gui.ShellComponents
|
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
|
internal static StartMenu CurrentStartMenu
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -57,94 +79,97 @@ namespace CMLeonOS.Gui.ShellComponents
|
|||||||
|
|
||||||
private Button shutdownButton;
|
private Button shutdownButton;
|
||||||
private Button rebootButton;
|
private Button rebootButton;
|
||||||
|
private Button logOutButton;
|
||||||
private Button allAppsButton;
|
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 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)
|
internal void ShowStartMenu(bool focusSearch = false)
|
||||||
{
|
{
|
||||||
isOpen = true;
|
isOpen = true;
|
||||||
|
|
||||||
bool leftHandStartButton = settingsService.LeftHandStartButton;
|
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));
|
int searchY = outerPadding + 40;
|
||||||
window.DrawImageAlpha(Icons.Icon_User, userRect.X, (int)(userRect.Y + (userRect.Height / 2) - (Icons.Icon_User.Height / 2)));
|
int searchWidth = window.Width - (outerPadding * 2);
|
||||||
window.DrawString(UserSystem.CurrentLoggedInUser.Username, Color.White, (int)(userRect.X + Icons.Icon_User.Width + userPadding), (int)(userRect.Y + (userRect.Height / 2) - (16 / 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);
|
wm.AddWindow(window);
|
||||||
|
|
||||||
int x = 12;
|
int topActionY = footerY + 10;
|
||||||
int y = 44;
|
int bottomActionY = footerY + footerHeight - actionButtonHeight - 10;
|
||||||
for (int i = 0; i < 4; i++)
|
shutdownButton = new Button(window, window.Width - outerPadding - actionButtonWidth, bottomActionY, actionButtonWidth, actionButtonHeight);
|
||||||
{
|
StyleActionButton(shutdownButton, "Shut down");
|
||||||
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";
|
|
||||||
shutdownButton.OnClick = ShutdownClicked;
|
shutdownButton.OnClick = ShutdownClicked;
|
||||||
wm.AddWindow(shutdownButton);
|
wm.AddWindow(shutdownButton);
|
||||||
|
|
||||||
rebootButton = new Button(window, window.Width - (buttonsPadding * 2 + buttonsWidth * 2), window.Height - buttonsHeight - ((userHeight / 2) - (buttonsHeight / 2)), buttonsWidth, buttonsHeight);
|
rebootButton = new Button(window, window.Width - outerPadding - actionButtonWidth * 2 - 8, bottomActionY, actionButtonWidth, actionButtonHeight);
|
||||||
rebootButton.Text = "Restart";
|
StyleActionButton(rebootButton, "Restart");
|
||||||
rebootButton.OnClick = RebootClicked;
|
rebootButton.OnClick = RebootClicked;
|
||||||
wm.AddWindow(rebootButton);
|
wm.AddWindow(rebootButton);
|
||||||
|
|
||||||
allAppsButton = new Button(window, window.Width - buttonsWidth - buttonsPadding, window.Height - buttonsHeight - userHeight, buttonsWidth, buttonsHeight);
|
logOutButton = new Button(window, window.Width - outerPadding - actionButtonWidth * 2 - 8, topActionY, actionButtonWidth, actionButtonHeight);
|
||||||
allAppsButton.Text = "All apps >";
|
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;
|
allAppsButton.OnClick = AllAppsClicked;
|
||||||
wm.AddWindow(allAppsButton);
|
wm.AddWindow(allAppsButton);
|
||||||
|
|
||||||
Table searchResults = null;
|
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)
|
if (focusSearch)
|
||||||
{
|
{
|
||||||
wm.Focus = searchBox;
|
wm.Focus = searchBox;
|
||||||
}
|
}
|
||||||
searchBox.PlaceholderText = "Search";
|
searchBox.PlaceholderText = "Search";
|
||||||
|
searchBox.Background = SearchBackground;
|
||||||
|
searchBox.Foreground = SearchForeground;
|
||||||
|
searchBox.PlaceholderForeground = SearchPlaceholder;
|
||||||
searchBox.Changed = () =>
|
searchBox.Changed = () =>
|
||||||
{
|
{
|
||||||
if (searchResults == null)
|
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.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) =>
|
searchResults.TableCellSelected = (int index) =>
|
||||||
{
|
{
|
||||||
@@ -162,12 +187,12 @@ namespace CMLeonOS.Gui.ShellComponents
|
|||||||
{
|
{
|
||||||
foreach (AppMetadata app in AppManager.AppMetadatas)
|
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;
|
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));
|
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);
|
Power.Shutdown(reboot: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LogOutClicked(int x, int y)
|
||||||
|
{
|
||||||
|
HideStartMenu();
|
||||||
|
ProcessManager.GetProcess<WindowManager>()?.ClearAllWindows();
|
||||||
|
ProcessManager.AddProcess(wm, new Lock()).Start();
|
||||||
|
}
|
||||||
|
|
||||||
private void AllAppsClicked(int x, int y)
|
private void AllAppsClicked(int x, int y)
|
||||||
{
|
{
|
||||||
Table allAppsTable = new Table(window, 0, 0, window.Width, window.Height);
|
Table allAppsTable = new Table(window, 0, 0, window.Width, window.Height);
|
||||||
|
|
||||||
allAppsTable.CellHeight = 32;
|
allAppsTable.CellHeight = 32;
|
||||||
|
|
||||||
allAppsTable.Background = Color.FromArgb(56, 56, 71);
|
allAppsTable.Background = MenuBackground;
|
||||||
allAppsTable.Foreground = Color.White;
|
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)
|
foreach (AppMetadata app in AppManager.AppMetadatas)
|
||||||
{
|
{
|
||||||
TableCell cell = new TableCell(app.Icon.Resize(20, 20), app.Name);
|
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.Cells.Add(cell);
|
||||||
}
|
}
|
||||||
allAppsTable.Render();
|
allAppsTable.Render();
|
||||||
|
|||||||
@@ -155,6 +155,27 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
private int originalWidth;
|
private int originalWidth;
|
||||||
private int originalHeight;
|
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()
|
private void StartOpenAnimation()
|
||||||
{
|
{
|
||||||
int targetY = Y;
|
int targetY = Y;
|
||||||
@@ -170,6 +191,7 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
EasingType = EasingType.Sine,
|
EasingType = EasingType.Sine,
|
||||||
EasingDirection = EasingDirection.Out
|
EasingDirection = EasingDirection.Out
|
||||||
};
|
};
|
||||||
|
animation.Completed = RefreshWindowTree;
|
||||||
animation.Start();
|
animation.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,14 +35,16 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
{
|
{
|
||||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
string[] lines = Message.Split('\n');
|
||||||
int longestLineLength = 0;
|
int longestLineLength = 0;
|
||||||
foreach (string line in Message.Split('\n'))
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
longestLineLength = Math.Max(longestLineLength, line.Length);
|
longestLineLength = Math.Max(longestLineLength, line.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = Math.Max(192, (Padding * 2) + (8 * longestLineLength));
|
int width = Math.Max(208, (Padding * 2) + (8 * longestLineLength));
|
||||||
int height = 128 + ((Message.Split('\n').Length - 1) * 16);
|
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);
|
AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (width / 2)), (int)((wm.ScreenHeight / 2) - (height / 2)), width, height);
|
||||||
window.Title = Title;
|
window.Title = Title;
|
||||||
@@ -51,7 +53,13 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
window.Clear(UITheme.Surface);
|
window.Clear(UITheme.Surface);
|
||||||
window.DrawRectangle(0, 0, window.Width, window.Height, UITheme.SurfaceBorder);
|
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.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);
|
Button ok = new Button(window, window.Width - 80 - Padding, window.Height - 20 - Padding, 80, 20);
|
||||||
ok.Text = "OK";
|
ok.Text = "OK";
|
||||||
@@ -64,6 +72,7 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
wm.AddWindow(ok);
|
wm.AddWindow(ok);
|
||||||
|
|
||||||
wm.Update(window);
|
wm.Update(window);
|
||||||
|
ok.Render();
|
||||||
|
|
||||||
ProcessManager.GetProcess<Sound.SoundService>().PlaySystemSound(Sound.SystemSound.Alert);
|
ProcessManager.GetProcess<Sound.SoundService>().PlaySystemSound(Sound.SystemSound.Alert);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,14 +33,16 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
{
|
{
|
||||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
string[] lines = Message.Split('\n');
|
||||||
int longestLineLength = 0;
|
int longestLineLength = 0;
|
||||||
foreach (string line in Message.Split('\n'))
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
longestLineLength = Math.Max(longestLineLength, line.Length);
|
longestLineLength = Math.Max(longestLineLength, line.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = Math.Max(256, (Padding * 2) + (8 * longestLineLength));
|
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);
|
AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (width / 2)), (int)((wm.ScreenHeight / 2) - (height / 2)), width, height);
|
||||||
window.Title = Title;
|
window.Title = Title;
|
||||||
@@ -49,9 +51,15 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
window.Clear(UITheme.Surface);
|
window.Clear(UITheme.Surface);
|
||||||
window.DrawRectangle(0, 0, window.Width, window.Height, UITheme.SurfaceBorder);
|
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.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;
|
textBox.PlaceholderText = Placeholder;
|
||||||
wm.AddWindow(textBox);
|
wm.AddWindow(textBox);
|
||||||
|
|
||||||
@@ -68,6 +76,7 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
wm.AddWindow(ok);
|
wm.AddWindow(ok);
|
||||||
|
|
||||||
wm.Update(window);
|
wm.Update(window);
|
||||||
|
ok.Render();
|
||||||
|
|
||||||
ProcessManager.GetProcess<Sound.SoundService>().PlaySystemSound(Sound.SystemSound.Alert);
|
ProcessManager.GetProcess<Sound.SoundService>().PlaySystemSound(Sound.SystemSound.Alert);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user