mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-04-21 10:53:59 +00:00
更新GUI登录UI,更新UILib
This commit is contained in:
@@ -1 +1 @@
|
||||
2026-03-22 19:16:27
|
||||
2026-03-23 21:30:51
|
||||
@@ -1 +1 @@
|
||||
e43417c
|
||||
9162e2d
|
||||
@@ -20,6 +20,7 @@ using CMLeonOS.Gui.UILib;
|
||||
using CMLeonOS.Logger;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CMLeonOS.Gui.ShellComponents
|
||||
@@ -33,6 +34,7 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
Table userTable;
|
||||
|
||||
TextBox passwordBox;
|
||||
Button logOnButton;
|
||||
|
||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||
|
||||
@@ -43,21 +45,122 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Lock.Key.bmp")]
|
||||
private static byte[] _iconBytes_Key;
|
||||
internal static Bitmap Icon_Key = new Bitmap(_iconBytes_Key);
|
||||
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Lock.User.bmp")]
|
||||
private static byte[] _iconBytes_User;
|
||||
internal static Bitmap Icon_User = new Bitmap(_iconBytes_User);
|
||||
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Lock.UserArrow.bmp")]
|
||||
private static byte[] _iconBytes_UserArrow;
|
||||
internal static Bitmap Icon_UserArrow = new Bitmap(_iconBytes_UserArrow);
|
||||
}
|
||||
|
||||
private const int width = 352;
|
||||
private const int height = 200;
|
||||
private const int padding = 12;
|
||||
private const int width = 700;
|
||||
private const int height = 420;
|
||||
private const int leftPanelWidth = 240;
|
||||
private const int rightContentPadding = 28;
|
||||
private const int rightContentBottomPadding = 30;
|
||||
private const int accountsLabelY = 102;
|
||||
private const int tableY = 124;
|
||||
private const int tableHeight = 140;
|
||||
private const int passwordLabelY = tableY + tableHeight + 18;
|
||||
private const int passwordY = passwordLabelY + 22;
|
||||
private const int passwordHeight = 30;
|
||||
private const int logOnButtonY = passwordY + 44;
|
||||
private const int logOnButtonHeight = 38;
|
||||
|
||||
private readonly Color windowBackground = Color.FromArgb(232, 238, 246);
|
||||
private readonly Color outerBorder = Color.FromArgb(169, 181, 198);
|
||||
private readonly Color leftPanel = Color.FromArgb(34, 53, 84);
|
||||
private readonly Color leftPanelAccent = Color.FromArgb(74, 124, 201);
|
||||
private readonly Color leftPanelSoft = Color.FromArgb(53, 77, 116);
|
||||
private readonly Color rightPanel = Color.FromArgb(247, 250, 253);
|
||||
private readonly Color titleColor = Color.FromArgb(28, 39, 56);
|
||||
private readonly Color bodyColor = Color.FromArgb(92, 103, 119);
|
||||
private readonly Color hintColor = Color.FromArgb(132, 142, 156);
|
||||
private readonly Color inputBackground = Color.White;
|
||||
private readonly Color inputForeground = Color.FromArgb(31, 42, 55);
|
||||
private readonly Color selectionBackground = Color.FromArgb(223, 236, 255);
|
||||
private readonly Color selectionBorder = Color.FromArgb(91, 140, 223);
|
||||
private readonly Color primaryButton = Color.FromArgb(53, 111, 214);
|
||||
private readonly Color primaryButtonBorder = Color.FromArgb(33, 83, 171);
|
||||
private readonly Color primaryButtonText = Color.White;
|
||||
|
||||
private double shakiness = 0;
|
||||
|
||||
private List<User> users = new List<User>();
|
||||
|
||||
private void RenderBackground()
|
||||
{
|
||||
window.Clear(Color.LightGray);
|
||||
window.Clear(windowBackground);
|
||||
window.DrawRectangle(0, 0, width, height, outerBorder);
|
||||
|
||||
window.DrawImageAlpha(Images.Icon_Key, padding, padding);
|
||||
int leftWidth = leftPanelWidth;
|
||||
int rightX = leftWidth + 1;
|
||||
int rightWidth = width - rightX;
|
||||
|
||||
window.DrawString("Select a user and enter password,\nthen press Enter to log on", Color.Black, (int)(padding + Images.Icon_Key.Width + padding), padding);
|
||||
window.DrawFilledRectangle(0, 0, leftWidth, height, leftPanel);
|
||||
window.DrawFilledRectangle(leftWidth - 6, 0, 6, height, leftPanelAccent);
|
||||
window.DrawFilledRectangle(rightX, 0, rightWidth, height, rightPanel);
|
||||
|
||||
window.DrawFilledRectangle(20, 22, 56, 56, leftPanelSoft);
|
||||
window.DrawRectangle(20, 22, 56, 56, Color.FromArgb(109, 149, 214));
|
||||
window.DrawImageAlpha(Images.Icon_Key, 32, 34);
|
||||
|
||||
window.DrawString("Welcome Back", Color.White, 20, 96);
|
||||
window.DrawString("CMLeonOS Desktop", Color.FromArgb(190, 208, 233), 20, 120);
|
||||
|
||||
string selectedUserName = GetSelectedUser()?.Username ?? "Guest";
|
||||
window.DrawString("Selected account", Color.FromArgb(171, 190, 217), 20, 168);
|
||||
window.DrawString(selectedUserName, Color.White, 20, 190);
|
||||
window.DrawString(GetSelectedUserSubtitle(), Color.FromArgb(176, 197, 224), 20, 214);
|
||||
|
||||
window.DrawFilledRectangle(20, height - 72, leftWidth - 40, 44, leftPanelSoft);
|
||||
window.DrawRectangle(20, height - 72, leftWidth - 40, 44, Color.FromArgb(88, 118, 171));
|
||||
window.DrawString("Tip: type password.", Color.White, 32, height - 62);
|
||||
window.DrawString("Press Enter to sign in.", Color.FromArgb(190, 208, 233), 32, height - 44);
|
||||
|
||||
int rightContentX = leftWidth + rightContentPadding;
|
||||
window.DrawString("Sign in", titleColor, rightContentX, 28);
|
||||
window.DrawString("Choose an account, then enter your password.", bodyColor, rightContentX, 54);
|
||||
window.DrawString("Continue to the desktop when ready.", bodyColor, rightContentX, 72);
|
||||
|
||||
window.DrawString("Accounts", hintColor, rightContentX, accountsLabelY);
|
||||
window.DrawString("Password", hintColor, rightContentX, passwordLabelY);
|
||||
window.DrawString("Secure local session", Color.FromArgb(118, 128, 141), rightContentX, height - rightContentBottomPadding);
|
||||
|
||||
}
|
||||
|
||||
private User GetSelectedUser()
|
||||
{
|
||||
if (userTable == null || users == null || users.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (userTable.SelectedCellIndex < 0 || userTable.SelectedCellIndex >= users.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return users[userTable.SelectedCellIndex];
|
||||
}
|
||||
|
||||
private string GetSelectedUserSubtitle()
|
||||
{
|
||||
User selectedUser = GetSelectedUser();
|
||||
if (selectedUser == null)
|
||||
{
|
||||
return "No local users available";
|
||||
}
|
||||
|
||||
return selectedUser.Admin ? "Administrator account" : "Standard local account";
|
||||
}
|
||||
|
||||
private void RefreshLayout()
|
||||
{
|
||||
RenderBackground();
|
||||
wm.Update(window);
|
||||
}
|
||||
|
||||
private void ShowError(string text)
|
||||
@@ -78,12 +181,11 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
return;
|
||||
}
|
||||
|
||||
if (userTable.SelectedCellIndex >= UserSystem.GetUsers().Count)
|
||||
if (userTable.SelectedCellIndex >= users.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var users = UserSystem.GetUsers();
|
||||
User selectedUser = users[userTable.SelectedCellIndex];
|
||||
string password = passwordBox.Text.Trim();
|
||||
|
||||
@@ -145,7 +247,7 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
{
|
||||
base.Start();
|
||||
|
||||
var users = UserSystem.GetUsers();
|
||||
users = UserSystem.GetUsers() ?? new List<User>();
|
||||
Logger.Logger.Instance.Info("Lock", $"Lock started. Total users: {users?.Count ?? 0}");
|
||||
if (users != null)
|
||||
{
|
||||
@@ -164,21 +266,21 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
|
||||
RenderBackground();
|
||||
|
||||
int contentHeight = 110;
|
||||
int contentWidth = 160;
|
||||
int startX = (width - contentWidth) / 2;
|
||||
int startY = (height - contentHeight) / 2;
|
||||
int contentX = leftPanelWidth + rightContentPadding;
|
||||
int contentWidth = width - contentX - rightContentPadding;
|
||||
|
||||
userTable = new Table(window, startX, startY, contentWidth, 80);
|
||||
userTable.CellHeight = 25;
|
||||
userTable.Background = Color.White;
|
||||
userTable.Foreground = Color.Black;
|
||||
userTable.Border = Color.Gray;
|
||||
userTable.SelectedBackground = Color.FromArgb(221, 246, 255);
|
||||
userTable.SelectedForeground = Color.Black;
|
||||
userTable.SelectedBorder = Color.FromArgb(126, 205, 234);
|
||||
userTable = new Table(window, contentX, tableY, contentWidth, tableHeight);
|
||||
userTable.CellHeight = 40;
|
||||
userTable.Background = inputBackground;
|
||||
userTable.Foreground = inputForeground;
|
||||
userTable.Border = Color.FromArgb(203, 212, 224);
|
||||
userTable.SelectedBackground = selectionBackground;
|
||||
userTable.SelectedForeground = inputForeground;
|
||||
userTable.SelectedBorder = selectionBorder;
|
||||
userTable.AllowSelection = true;
|
||||
userTable.AllowDeselection = false;
|
||||
userTable.ScrollbarThickness = 18;
|
||||
userTable.TableCellSelected = _ => RefreshLayout();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
@@ -193,13 +295,27 @@ namespace CMLeonOS.Gui.ShellComponents
|
||||
|
||||
wm.AddWindow(userTable);
|
||||
|
||||
passwordBox = new TextBox(window, startX, startY + 90, contentWidth, 20);
|
||||
passwordBox = new TextBox(window, contentX, passwordY, contentWidth, passwordHeight);
|
||||
passwordBox.Shield = true;
|
||||
passwordBox.PlaceholderText = "Password";
|
||||
passwordBox.PlaceholderText = "Enter password";
|
||||
passwordBox.Background = inputBackground;
|
||||
passwordBox.Foreground = inputForeground;
|
||||
passwordBox.PlaceholderForeground = hintColor;
|
||||
passwordBox.Changed = RefreshLayout;
|
||||
passwordBox.Submitted = LogOn;
|
||||
wm.AddWindow(passwordBox);
|
||||
|
||||
wm.Update(window);
|
||||
logOnButton = new Button(window, contentX, logOnButtonY, contentWidth, logOnButtonHeight);
|
||||
logOnButton.Text = "Log On";
|
||||
logOnButton.Background = primaryButton;
|
||||
logOnButton.Border = primaryButtonBorder;
|
||||
logOnButton.Foreground = primaryButtonText;
|
||||
logOnButton.Image = Images.Icon_UserArrow;
|
||||
logOnButton.ImageLocation = Button.ButtonImageLocation.Left;
|
||||
logOnButton.OnClick = LogOnClick;
|
||||
wm.AddWindow(logOnButton);
|
||||
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
|
||||
@@ -236,14 +236,36 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
private void RenderDecoration()
|
||||
{
|
||||
decorationWindow.Clear(Color.FromArgb(56, 56, 71));
|
||||
decorationWindow.Clear(UITheme.WindowTitleBackground);
|
||||
decorationWindow.DrawHorizontalLine(Width, 0, 0, UITheme.WindowTitleTopHighlight);
|
||||
decorationWindow.DrawHorizontalLine(Width, 0, titlebarHeight - 1, UITheme.WindowTitleBottomBorder);
|
||||
|
||||
int buttonSpace = 0;
|
||||
if (_canClose)
|
||||
{
|
||||
buttonSpace += titlebarHeight;
|
||||
}
|
||||
if (_canResize)
|
||||
{
|
||||
buttonSpace += titlebarHeight;
|
||||
}
|
||||
if (buttonSpace > 0)
|
||||
{
|
||||
decorationWindow.DrawFilledRectangle(Width - buttonSpace, 1, buttonSpace, titlebarHeight - 2, UITheme.WindowButtonBackground);
|
||||
}
|
||||
|
||||
if (_smallIcon != null)
|
||||
{
|
||||
decorationWindow.DrawImageAlpha(_smallIcon, 2, 2);
|
||||
decorationWindow.DrawImageAlpha(_smallIcon, 3, 2);
|
||||
}
|
||||
|
||||
decorationWindow.DrawString(Title, Color.White, (Width / 2) - ((FontData.Width * Title.Length) / 2), 4);
|
||||
int maxTitleChars = Math.Max(4, (Width - buttonSpace - 42) / FontData.Width);
|
||||
string displayTitle = Title;
|
||||
if (displayTitle.Length > maxTitleChars)
|
||||
{
|
||||
displayTitle = displayTitle.Substring(0, Math.Max(1, maxTitleChars - 1)) + "~";
|
||||
}
|
||||
decorationWindow.DrawString(displayTitle, UITheme.WindowTitleText, 28, 4);
|
||||
|
||||
if (_canClose)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Cosmos.System.Graphics;
|
||||
using Cosmos.System;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
@@ -24,6 +25,11 @@ namespace CMLeonOS.Gui.UILib
|
||||
{
|
||||
public Button(Window parent, int x, int y, int width, int height) : base(parent, x, y, width, height)
|
||||
{
|
||||
OnDown = (_, _) =>
|
||||
{
|
||||
held = true;
|
||||
Render();
|
||||
};
|
||||
}
|
||||
|
||||
internal enum ButtonImageLocation
|
||||
@@ -60,7 +66,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _background = Color.FromArgb(48, 48, 48);
|
||||
private Color _background = UITheme.Accent;
|
||||
internal Color Background
|
||||
{
|
||||
get
|
||||
@@ -88,7 +94,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _border = Color.Black;
|
||||
private Color _border = UITheme.AccentDark;
|
||||
internal Color Border
|
||||
{
|
||||
get
|
||||
@@ -116,29 +122,58 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private bool held = false;
|
||||
|
||||
internal override void Render()
|
||||
{
|
||||
Clear(Background);
|
||||
if (held && MouseManager.MouseState != MouseState.Left)
|
||||
{
|
||||
held = false;
|
||||
}
|
||||
|
||||
Color buttonBackground = held
|
||||
? Color.FromArgb(Math.Max(0, Background.R - 24), Math.Max(0, Background.G - 24), Math.Max(0, Background.B - 24))
|
||||
: Background;
|
||||
|
||||
Clear(UITheme.Surface);
|
||||
DrawFilledRectangle(0, 0, Width, Height, buttonBackground);
|
||||
DrawHorizontalLine(Width - 2, 1, 1, Color.FromArgb(
|
||||
Math.Min(255, buttonBackground.R + 20),
|
||||
Math.Min(255, buttonBackground.G + 20),
|
||||
Math.Min(255, buttonBackground.B + 20)));
|
||||
|
||||
if (_image != null)
|
||||
{
|
||||
switch (_imageLocation)
|
||||
{
|
||||
case ButtonImageLocation.Left:
|
||||
DrawImageAlpha(_image, (int)((Width / 2) - ((8 / 2) * Text.Length) - 8 - _image.Width), (int)((Height / 2) - (_image.Height / 2)));
|
||||
DrawString(Text, Foreground, (Width / 2) - ((8 / 2) * Text.Length), (Height / 2) - (16 / 2));
|
||||
{
|
||||
int imageWidth = (int)_image.Width;
|
||||
int imageHeight = (int)_image.Height;
|
||||
int textWidth = 8 * Text.Length;
|
||||
int contentWidth = imageWidth + 6 + textWidth;
|
||||
int imageX = Math.Max(4, (Width / 2) - (contentWidth / 2));
|
||||
int imageY = (Height / 2) - (imageHeight / 2);
|
||||
int textXLeft = imageX + imageWidth + 6;
|
||||
int textYLeft = (Height / 2) - (16 / 2);
|
||||
|
||||
DrawImageAlpha(_image, imageX, imageY);
|
||||
DrawString(Text, Foreground, textXLeft, textYLeft);
|
||||
break;
|
||||
}
|
||||
case ButtonImageLocation.AboveText:
|
||||
DrawImageAlpha(_image, (int)((Width / 2) - (_image.Width / 2)), (int)((Height / 2) - (_image.Height / 2)));
|
||||
DrawString(Text, Foreground, (Width / 2) - (4 * Text.Length), Height - 16);
|
||||
{
|
||||
DrawImageAlpha(_image, (int)((Width / 2) - (_image.Width / 2)), Math.Max(1, (int)((Height / 2) - (_image.Height / 2) - 4)));
|
||||
DrawString(Text, Foreground, (Width / 2) - (4 * Text.Length), Height - 17);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Exception("Unrecognised image location in button.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawString(Text, Foreground, (Width / 2) - (4 * Text.Length), (Height / 2) - 8);
|
||||
DrawString(Text, Foreground, (Width / 2) - (4 * Text.Length), (Height / 2) - 8 + (held ? 1 : 0));
|
||||
}
|
||||
|
||||
DrawRectangle(0, 0, Width, Height, Border);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _background = Color.White;
|
||||
private Color _background = UITheme.Surface;
|
||||
internal Color Background
|
||||
{
|
||||
get
|
||||
@@ -88,7 +88,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _foreground = Color.Black;
|
||||
private Color _foreground = UITheme.TextPrimary;
|
||||
internal Color Foreground
|
||||
{
|
||||
get
|
||||
@@ -117,7 +117,8 @@ namespace CMLeonOS.Gui.UILib
|
||||
int textX = iconSize + 8;
|
||||
int textY = (Height / 2) - (16 / 2);
|
||||
|
||||
DrawFilledRectangle(iconX, iconY, iconSize, iconSize, Color.LightGray);
|
||||
DrawFilledRectangle(iconX, iconY, iconSize, iconSize, _checked ? UITheme.AccentLight : UITheme.SurfaceMuted);
|
||||
DrawRectangle(iconX, iconY, iconSize, iconSize, _checked ? UITheme.Accent : UITheme.SurfaceBorder);
|
||||
if (_checked)
|
||||
{
|
||||
DrawImageAlpha(checkBitmap, iconX, iconY);
|
||||
@@ -128,4 +129,4 @@ namespace CMLeonOS.Gui.UILib
|
||||
WM.Update(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,16 +44,19 @@ namespace CMLeonOS.Gui.UILib
|
||||
int width = Math.Max(192, (Padding * 2) + (8 * longestLineLength));
|
||||
int height = 128 + ((Message.Split('\n').Length - 1) * 16);
|
||||
|
||||
AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (height / 2)), (int)((wm.ScreenWidth / 2) - (width / 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;
|
||||
wm.AddWindow(window);
|
||||
|
||||
window.Clear(Color.LightGray);
|
||||
window.DrawFilledRectangle(0, window.Height - (Padding * 2) - 20, window.Width, (Padding * 2) + 20, Color.Gray);
|
||||
window.DrawString(Message, Color.Black, Padding, Padding);
|
||||
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);
|
||||
|
||||
Button ok = new Button(window, window.Width - 80 - Padding, window.Height - 20 - Padding, 80, 20);
|
||||
ok.Text = "OK";
|
||||
ok.Background = UITheme.Accent;
|
||||
ok.Border = UITheme.AccentDark;
|
||||
ok.OnClick = (int x, int y) =>
|
||||
{
|
||||
wm.RemoveWindow(window);
|
||||
|
||||
@@ -42,13 +42,14 @@ namespace CMLeonOS.Gui.UILib
|
||||
int width = Math.Max(256, (Padding * 2) + (8 * longestLineLength));
|
||||
int height = 128 + ((Message.Split('\n').Length - 1) * 16);
|
||||
|
||||
AppWindow window = new AppWindow(Process, (int)((wm.ScreenWidth / 2) - (height / 2)), (int)((wm.ScreenWidth / 2) - (width / 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;
|
||||
wm.AddWindow(window);
|
||||
|
||||
window.Clear(Color.LightGray);
|
||||
window.DrawFilledRectangle(0, window.Height - (Padding * 2) - 20, window.Width, (Padding * 2) + 20, Color.Gray);
|
||||
window.DrawString(Message, Color.Black, Padding, Padding);
|
||||
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);
|
||||
textBox.PlaceholderText = Placeholder;
|
||||
@@ -56,6 +57,8 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
Button ok = new Button(window, window.Width - 80 - Padding, window.Height - 20 - Padding, 80, 20);
|
||||
ok.Text = "OK";
|
||||
ok.Background = UITheme.Accent;
|
||||
ok.Border = UITheme.AccentDark;
|
||||
ok.OnClick = (int x, int y) =>
|
||||
{
|
||||
wm.RemoveWindow(window);
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
Render();
|
||||
}
|
||||
|
||||
private Color _background = Color.White;
|
||||
private Color _background = UITheme.Surface;
|
||||
internal Color Background
|
||||
{
|
||||
get
|
||||
@@ -55,7 +55,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _foreground = Color.Gray;
|
||||
private Color _foreground = UITheme.TextSecondary;
|
||||
internal Color Foreground
|
||||
{
|
||||
get
|
||||
@@ -143,9 +143,9 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
private bool held = false;
|
||||
|
||||
private static int slotHeight = 3;
|
||||
private static int sliderHeight = 15;
|
||||
private static int sliderWidth = 5;
|
||||
private static int slotHeight = 4;
|
||||
private static int sliderHeight = 16;
|
||||
private static int sliderWidth = 8;
|
||||
|
||||
private void RangeSliderDown(int x, int y)
|
||||
{
|
||||
@@ -187,7 +187,9 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
|
||||
// Slot
|
||||
DrawFilledRectangle(0, slotY, Width, slotHeight, Color.FromArgb(168, 168, 168));
|
||||
DrawFilledRectangle(0, slotY, Width, slotHeight, UITheme.SurfaceBorder);
|
||||
int fillWidth = (int)(_value.Map((float)_minimum, (float)_maximum, 0, Width - sliderWidth)) + (sliderWidth / 2);
|
||||
DrawFilledRectangle(0, slotY, Math.Max(0, fillWidth), slotHeight, UITheme.AccentLight);
|
||||
|
||||
// Slider
|
||||
DrawFilledRectangle(
|
||||
@@ -195,7 +197,14 @@ namespace CMLeonOS.Gui.UILib
|
||||
sliderY,
|
||||
sliderWidth,
|
||||
sliderHeight,
|
||||
held ? Color.FromArgb(0, 71, 112) : Color.FromArgb(0, 115, 186)
|
||||
held ? UITheme.AccentDark : UITheme.Accent
|
||||
);
|
||||
DrawRectangle(
|
||||
(int)(_value.Map((float)_minimum, (float)_maximum, 0, Width - sliderWidth)),
|
||||
sliderY,
|
||||
sliderWidth,
|
||||
sliderHeight,
|
||||
UITheme.AccentDark
|
||||
);
|
||||
|
||||
if (_rangeLabels)
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Cosmos.System;
|
||||
using Cosmos.System.Graphics;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CMLeonOS.Gui.UILib
|
||||
{
|
||||
@@ -28,19 +28,10 @@ namespace CMLeonOS.Gui.UILib
|
||||
OnClick = null;
|
||||
}
|
||||
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.SwitchOff.bmp")]
|
||||
private static byte[] offBytes;
|
||||
private static Bitmap offBitmap = new Bitmap(offBytes);
|
||||
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.SwitchOn.bmp")]
|
||||
private static byte[] onBytes;
|
||||
private static Bitmap onBitmap = new Bitmap(onBytes);
|
||||
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.SwitchKnob.bmp")]
|
||||
private static byte[] knobBytes;
|
||||
private static Bitmap knobBitmap = new Bitmap(knobBytes);
|
||||
|
||||
private const int maximumToggleDrag = 4;
|
||||
private const int switchWidth = 34;
|
||||
private const int switchHeight = 18;
|
||||
private const int knobSize = 14;
|
||||
|
||||
private int lastMouseX = 0;
|
||||
private int totalDragged = 0;
|
||||
@@ -67,7 +58,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
// Interpret as a drag rather than a toggle,
|
||||
// setting the Checked state based on where
|
||||
// the switch knob is.
|
||||
Checked = knobX >= (offBitmap.Width / 2) - (knobBitmap.Width / 2);
|
||||
Checked = knobX >= (switchWidth - knobSize) / 2d;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +67,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
internal override void Render()
|
||||
{
|
||||
knobGoal = (int)(Checked ? offBitmap.Width - knobBitmap.Width : 0);
|
||||
knobGoal = Checked ? switchWidth - knobSize : 0;
|
||||
|
||||
if (held && MouseManager.MouseState != MouseState.Left)
|
||||
{
|
||||
@@ -88,7 +79,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
int diff = (int)(MouseManager.X - lastMouseX);
|
||||
lastMouseX = (int)MouseManager.X;
|
||||
totalDragged += Math.Abs(diff);
|
||||
knobX = Math.Clamp(knobX + diff, 0, offBitmap.Width - knobBitmap.Width);
|
||||
knobX = Math.Clamp(knobX + diff, 0, switchWidth - knobSize);
|
||||
|
||||
WM.UpdateQueue.Enqueue(this);
|
||||
}
|
||||
@@ -118,13 +109,17 @@ namespace CMLeonOS.Gui.UILib
|
||||
Clear(Background);
|
||||
|
||||
int switchX = 0;
|
||||
int switchY = (Height / 2) - ((int)offBitmap.Height / 2);
|
||||
int switchY = (Height / 2) - (switchHeight / 2);
|
||||
|
||||
int textX = (int)(offBitmap.Width + 8);
|
||||
int textX = switchWidth + 8;
|
||||
int textY = (Height / 2) - (16 / 2);
|
||||
|
||||
DrawImageAlpha(Checked ? onBitmap : offBitmap, switchX, switchY);
|
||||
DrawImageAlpha(knobBitmap, (int)knobX, switchY);
|
||||
DrawFilledRectangle(switchX, switchY, switchWidth, switchHeight, Checked ? UITheme.Accent : UITheme.SurfaceMuted);
|
||||
DrawRectangle(switchX, switchY, switchWidth, switchHeight, Checked ? UITheme.AccentDark : UITheme.SurfaceBorder);
|
||||
|
||||
int knobY = switchY + ((switchHeight - knobSize) / 2);
|
||||
DrawFilledRectangle((int)knobX + 1, knobY, knobSize, knobSize, Color.White);
|
||||
DrawRectangle((int)knobX + 1, knobY, knobSize, knobSize, UITheme.SurfaceBorder);
|
||||
|
||||
DrawString(Text, Foreground, textX, textY);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _background = Color.LightGray;
|
||||
private Color _background = UITheme.Surface;
|
||||
internal Color Background
|
||||
{
|
||||
get
|
||||
@@ -96,7 +96,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _foreground = Color.Black;
|
||||
private Color _foreground = UITheme.TextPrimary;
|
||||
internal Color Foreground
|
||||
{
|
||||
get
|
||||
@@ -110,7 +110,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _border = Color.Gray;
|
||||
private Color _border = UITheme.SurfaceBorder;
|
||||
internal Color Border
|
||||
{
|
||||
get
|
||||
@@ -124,7 +124,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _selectedBackground = Color.FromArgb(221, 246, 255);
|
||||
private Color _selectedBackground = UITheme.AccentLight;
|
||||
internal Color SelectedBackground
|
||||
{
|
||||
get
|
||||
@@ -138,7 +138,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _selectedForeground = Color.Black;
|
||||
private Color _selectedForeground = UITheme.TextPrimary;
|
||||
internal Color SelectedForeground
|
||||
{
|
||||
get
|
||||
@@ -152,7 +152,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _selectedBorder = Color.FromArgb(126, 205, 234);
|
||||
private Color _selectedBorder = UITheme.Accent;
|
||||
internal Color SelectedBorder
|
||||
{
|
||||
get
|
||||
@@ -258,7 +258,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
if (CanScrollUp || CanScrollDown)
|
||||
{
|
||||
/* Background */
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, Height, _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, Height, UITheme.SurfaceMuted);
|
||||
|
||||
/* Track */
|
||||
int trackAvailableHeight = Height - (ScrollbarThickness * 2);
|
||||
@@ -266,22 +266,22 @@ namespace CMLeonOS.Gui.UILib
|
||||
double trackProgress = (double)scrollY / (double)((Cells.Count * CellHeight) - Height);
|
||||
int trackY = (int)(_scrollbarThickness + (((double)trackAvailableHeight - ((double)trackAvailableHeight * trackSize)) * trackProgress));
|
||||
// Border
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, Height, _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, Height, UITheme.SurfaceBorder);
|
||||
// Background
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, trackY + 1, _scrollbarThickness - 2, (int)(trackSize * trackAvailableHeight) - 2, _background);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, trackY + 1, _scrollbarThickness - 2, (int)(trackSize * trackAvailableHeight) - 2, UITheme.AccentLight);
|
||||
|
||||
/* Up arrow */
|
||||
// Border
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, _scrollbarThickness, _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, 0, _scrollbarThickness, _scrollbarThickness, UITheme.SurfaceBorder);
|
||||
// Background
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, 1, _scrollbarThickness - 2, _scrollbarThickness - 2, CanScrollUp ? _background : _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, 1, _scrollbarThickness - 2, _scrollbarThickness - 2, CanScrollUp ? UITheme.Surface : UITheme.SurfaceMuted);
|
||||
DrawImageAlpha(scrollbarUpBitmap, (int)((Width - _scrollbarThickness) + ((_scrollbarThickness / 2) - (scrollbarUpBitmap.Width / 2))), (int)((_scrollbarThickness / 2) - (scrollbarUpBitmap.Height / 2)));
|
||||
|
||||
/* Down arrow */
|
||||
// Border
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, Height - _scrollbarThickness, _scrollbarThickness, _scrollbarThickness, _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness, Height - _scrollbarThickness, _scrollbarThickness, _scrollbarThickness, UITheme.SurfaceBorder);
|
||||
// Background
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, Height - _scrollbarThickness + 1, _scrollbarThickness - 2, _scrollbarThickness - 2, CanScrollDown ? _background : _border);
|
||||
DrawFilledRectangle(Width - _scrollbarThickness + 1, Height - _scrollbarThickness + 1, _scrollbarThickness - 2, _scrollbarThickness - 2, CanScrollDown ? UITheme.Surface : UITheme.SurfaceMuted);
|
||||
DrawImageAlpha(scrollbarDownBitmap, (int)((Width - _scrollbarThickness) + ((_scrollbarThickness / 2) - (scrollbarUpBitmap.Width / 2))), (int)((Height - _scrollbarThickness) + ((_scrollbarThickness / 2) - (scrollbarUpBitmap.Height / 2))));
|
||||
}
|
||||
}
|
||||
@@ -344,7 +344,8 @@ namespace CMLeonOS.Gui.UILib
|
||||
{
|
||||
TableCell cell = Cells[i];
|
||||
bool selected = _selectedCellIndex == i;
|
||||
Rectangle cellRect = new Rectangle(0, (int)((i * _cellHeight) - scrollY), Width, _cellHeight);
|
||||
int contentWidth = Width - ((CanScrollUp || CanScrollDown) ? _scrollbarThickness : 0);
|
||||
Rectangle cellRect = new Rectangle(0, (int)((i * _cellHeight) - scrollY), contentWidth, _cellHeight);
|
||||
|
||||
if (cellRect.Y < -cellRect.Height || cellRect.Y > Height)
|
||||
{
|
||||
@@ -368,7 +369,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
switch (_textAlignment)
|
||||
{
|
||||
case Alignment.Start:
|
||||
textX = cellRect.X + (cell.Image != null ? (CellHeight - FontData.Height) / 2 : 0);
|
||||
textX = cellRect.X + 6 + (cell.Image != null ? (CellHeight - FontData.Height) / 2 : 0);
|
||||
break;
|
||||
case Alignment.Middle:
|
||||
textX = cellRect.X + (cellRect.Width / 2) - (cell.Text.Length * FontData.Width / 2);
|
||||
@@ -385,8 +386,8 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
if (cell.Image != null)
|
||||
{
|
||||
textX += (int)cell.Image.Width;
|
||||
DrawImageAlpha(cell.Image, cellRect.X, (int)(cellRect.Y + (cellRect.Height / 2) - (cell.Image.Height / 2)));
|
||||
textX += (int)cell.Image.Width + 6;
|
||||
DrawImageAlpha(cell.Image, cellRect.X + 4, (int)(cellRect.Y + (cellRect.Height / 2) - (cell.Image.Height / 2)));
|
||||
}
|
||||
|
||||
if (cell.ForegroundColourOverride != null)
|
||||
@@ -397,6 +398,8 @@ namespace CMLeonOS.Gui.UILib
|
||||
{
|
||||
DrawString(cell.Text, selected ? SelectedForeground : Foreground, textX, textY);
|
||||
}
|
||||
|
||||
DrawHorizontalLine(cellRect.Width - 2, 1, cellRect.Y + cellRect.Height - 1, UITheme.SurfaceBorder);
|
||||
}
|
||||
|
||||
//DrawString($"{scrollY.ToString()} {dragging.ToString()} {scrollMax.ToString()}", Color.Red, 0, 0);
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
internal bool Shield { get; set; } = false;
|
||||
|
||||
private Color _background = Color.White;
|
||||
private Color _background = UITheme.Surface;
|
||||
internal Color Background
|
||||
{
|
||||
get
|
||||
@@ -103,7 +103,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _foreground = Color.Black;
|
||||
private Color _foreground = UITheme.TextPrimary;
|
||||
internal Color Foreground
|
||||
{
|
||||
get
|
||||
@@ -118,7 +118,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
}
|
||||
}
|
||||
|
||||
private Color _placeholderForeground = Color.Gray;
|
||||
private Color _placeholderForeground = UITheme.TextSecondary;
|
||||
internal Color PlaceholderForeground
|
||||
{
|
||||
get
|
||||
@@ -339,6 +339,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
private const int fontWidth = 8;
|
||||
private const int fontHeight = 16;
|
||||
private const int horizontalPadding = 4;
|
||||
|
||||
private int caretLine = -1;
|
||||
private int caretCol = 0;
|
||||
@@ -364,12 +365,12 @@ namespace CMLeonOS.Gui.UILib
|
||||
|
||||
if (Text == string.Empty)
|
||||
{
|
||||
DrawRectangle(0, 0, Width, Height, Color.Gray);
|
||||
DrawString(PlaceholderText, PlaceholderForeground, 0, 0);
|
||||
DrawRectangle(0, 0, Width, Height, caretLine == -1 ? UITheme.SurfaceBorder : UITheme.AccentDark);
|
||||
DrawString(PlaceholderText, PlaceholderForeground, horizontalPadding, 2);
|
||||
|
||||
if (caretLine == 0 && cursorVisible)
|
||||
{
|
||||
DrawVerticalLine(fontHeight, 1, 0, Foreground);
|
||||
DrawVerticalLine(fontHeight, horizontalPadding, 2, Foreground);
|
||||
}
|
||||
|
||||
WM.Update(this);
|
||||
@@ -392,11 +393,11 @@ namespace CMLeonOS.Gui.UILib
|
||||
if (i < lines.Count)
|
||||
{
|
||||
string lineText = Shield ? new string('*', lines[i].Length) : lines[i];
|
||||
RenderLine(i, lineText, lineY, -scrollX);
|
||||
RenderLine(i, lineText, lineY + 2, horizontalPadding - scrollX);
|
||||
|
||||
if (caretLine == i && cursorVisible)
|
||||
{
|
||||
DrawVerticalLine(fontHeight, ((caretCol * fontWidth) - scrollX) + 1, (caretLine * fontHeight) - scrollY, Foreground);
|
||||
DrawVerticalLine(fontHeight, ((caretCol * fontWidth) - scrollX) + horizontalPadding, ((caretLine * fontHeight) - scrollY) + 2, Foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,7 +405,7 @@ namespace CMLeonOS.Gui.UILib
|
||||
markedLinesBegin = -1;
|
||||
markedLinesEnd = -1;
|
||||
|
||||
DrawRectangle(0, 0, Width, Height, Color.Gray);
|
||||
DrawRectangle(0, 0, Width, Height, caretLine == -1 ? UITheme.SurfaceBorder : UITheme.AccentDark);
|
||||
|
||||
WM.Update(this);
|
||||
}
|
||||
|
||||
42
Gui/UILib/UITheme.cs
Normal file
42
Gui/UILib/UITheme.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
// The CMLeonOS Project (https://github.com/Leonmmcoset/CMLeonOS)
|
||||
// Copyright (C) 2025-present LeonOS 2 Developer Team
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace CMLeonOS.Gui.UILib
|
||||
{
|
||||
internal static class UITheme
|
||||
{
|
||||
internal static readonly Color WindowTitleBackground = Color.FromArgb(26, 34, 46);
|
||||
internal static readonly Color WindowTitleTopHighlight = Color.FromArgb(52, 67, 90);
|
||||
internal static readonly Color WindowTitleBottomBorder = Color.FromArgb(14, 18, 26);
|
||||
internal static readonly Color WindowTitleText = Color.FromArgb(239, 244, 252);
|
||||
internal static readonly Color WindowButtonBackground = Color.FromArgb(38, 49, 66);
|
||||
|
||||
internal static readonly Color Surface = Color.FromArgb(245, 248, 252);
|
||||
internal static readonly Color SurfaceMuted = Color.FromArgb(228, 235, 245);
|
||||
internal static readonly Color SurfaceBorder = Color.FromArgb(149, 164, 183);
|
||||
internal static readonly Color TextPrimary = Color.FromArgb(33, 43, 56);
|
||||
internal static readonly Color TextSecondary = Color.FromArgb(96, 109, 128);
|
||||
|
||||
internal static readonly Color Accent = Color.FromArgb(45, 117, 222);
|
||||
internal static readonly Color AccentDark = Color.FromArgb(28, 89, 184);
|
||||
internal static readonly Color AccentLight = Color.FromArgb(204, 225, 255);
|
||||
|
||||
internal static readonly Color Success = Color.FromArgb(45, 152, 99);
|
||||
internal static readonly Color Warning = Color.FromArgb(210, 139, 54);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user