GUI桌面环境
14
BootMenu.cs
@@ -9,6 +9,7 @@ namespace CMLeonOS
|
|||||||
public enum BootMenuAction
|
public enum BootMenuAction
|
||||||
{
|
{
|
||||||
NormalBoot,
|
NormalBoot,
|
||||||
|
GuiBoot,
|
||||||
Reboot,
|
Reboot,
|
||||||
Shutdown
|
Shutdown
|
||||||
}
|
}
|
||||||
@@ -44,8 +45,9 @@ namespace CMLeonOS
|
|||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
PrintOption("Normal Boot", selIdx == 0);
|
PrintOption("Normal Boot", selIdx == 0);
|
||||||
PrintOption("Reboot", selIdx == 1);
|
PrintOption("GUI Boot", selIdx == 1);
|
||||||
PrintOption("Shutdown", selIdx == 2);
|
PrintOption("Reboot", selIdx == 2);
|
||||||
|
PrintOption("Shutdown", selIdx == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BootMenuAction Confirm(int selIdx)
|
private static BootMenuAction Confirm(int selIdx)
|
||||||
@@ -64,9 +66,11 @@ namespace CMLeonOS
|
|||||||
case 0:
|
case 0:
|
||||||
return BootMenuAction.NormalBoot;
|
return BootMenuAction.NormalBoot;
|
||||||
case 1:
|
case 1:
|
||||||
|
return BootMenuAction.GuiBoot;
|
||||||
|
case 2:
|
||||||
Sys.Power.Reboot();
|
Sys.Power.Reboot();
|
||||||
return BootMenuAction.Reboot;
|
return BootMenuAction.Reboot;
|
||||||
case 2:
|
case 3:
|
||||||
Sys.Power.Shutdown();
|
Sys.Power.Shutdown();
|
||||||
return BootMenuAction.Shutdown;
|
return BootMenuAction.Shutdown;
|
||||||
default:
|
default:
|
||||||
@@ -129,10 +133,10 @@ namespace CMLeonOS
|
|||||||
|
|
||||||
if (selIdx < 0)
|
if (selIdx < 0)
|
||||||
{
|
{
|
||||||
selIdx = 2;
|
selIdx = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selIdx > 2)
|
if (selIdx > 3)
|
||||||
{
|
{
|
||||||
selIdx = 0;
|
selIdx = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2026-02-28 19:35:58
|
2026-03-01 17:02:21
|
||||||
@@ -70,7 +70,68 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="font.psf" />
|
<EmbeddedResource Include="font.psf" />
|
||||||
<EmbeddedResource Include="Wallpapers\wallpaper.bmp" />
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Calculator.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Calendar.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Clock.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\CodeStudio.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Default.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\DemoLauncher.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Demos\Mandelbrot.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Demos\Starfield.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Files.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Info.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Logs.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\MemoryStatistics.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Notepad.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Paint.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Settings.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Stopwatch.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\AppIcons\Tasks.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\ButtonBackground.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Calculator\Display.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Calculator\GridButton.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Check.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Clock\ClockBackground.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Close.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\CodeStudio\Run.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\CodeStudio\Splash.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Cursor.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Dock\StartMenu.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\Directory.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\Drive.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\File.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\File_Config.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\File_Rs.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\File_Text.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\Home.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Files\Up.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\Background.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\Gradient.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\Key.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\ShutDown.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\User.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Lock\UserArrow.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Logs\Error.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Logs\Info.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Logs\Warning.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Maximise.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Minimise.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Restore.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\ScrollbarDown.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\ScrollbarUp.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Settings\Admin.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Settings\Info.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Settings\User.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Sounds\Alert.wav" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Sounds\Login.wav" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Start.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\StartMenu\User.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\SwitchKnob.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\SwitchOff.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\SwitchOn.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\TitlebarBackground.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\WaitCursor.bmp" />
|
||||||
|
<EmbeddedResource Include="Gui\Resources\Wallpaper_1280_800.bmp" />
|
||||||
<EmbeddedResource Include="GitCommit.txt" />
|
<EmbeddedResource Include="GitCommit.txt" />
|
||||||
<EmbeddedResource Include="BuildTime.txt" />
|
<EmbeddedResource Include="BuildTime.txt" />
|
||||||
<EmbeddedResource Include="LuaApps\*.lua" />
|
<EmbeddedResource Include="LuaApps\*.lua" />
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
c5fc081
|
545f40c
|
||||||
36
Gui/App.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui
|
||||||
|
{
|
||||||
|
internal class AppMetadata
|
||||||
|
{
|
||||||
|
public AppMetadata(string name, Func<Process> createProcess, Bitmap icon, Color themeColor)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
CreateProcess = createProcess;
|
||||||
|
Icon = icon;
|
||||||
|
ThemeColor = themeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Start(Process parent)
|
||||||
|
{
|
||||||
|
ProcessManager.AddProcess(parent, CreateProcess()).Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Start()
|
||||||
|
{
|
||||||
|
ProcessManager.AddProcess(CreateProcess()).Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string Name { get; private set; }
|
||||||
|
|
||||||
|
internal Func<Process> CreateProcess { get; private set; }
|
||||||
|
|
||||||
|
internal Bitmap Icon { get; private set; }
|
||||||
|
|
||||||
|
internal Color ThemeColor { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
129
Gui/AppManager.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS.Gui.Apps;
|
||||||
|
using CMLeonOS.Logger;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui
|
||||||
|
{
|
||||||
|
internal static class AppManager
|
||||||
|
{
|
||||||
|
internal static List<AppMetadata> AppMetadatas { get; private set; } = new List<AppMetadata>();
|
||||||
|
|
||||||
|
private static bool appsLoaded = false;
|
||||||
|
|
||||||
|
internal static Bitmap DefaultAppIcon
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Icons.Icon_Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Default.bmp")]
|
||||||
|
private static byte[] _iconBytes_Default;
|
||||||
|
internal static Bitmap Icon_Default = new Bitmap(_iconBytes_Default);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Info.bmp")]
|
||||||
|
private static byte[] _iconBytes_Info;
|
||||||
|
internal static Bitmap Icon_Info = new Bitmap(_iconBytes_Info);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Settings.bmp")]
|
||||||
|
private static byte[] _iconBytes_Settings;
|
||||||
|
internal static Bitmap Icon_Settings = new Bitmap(_iconBytes_Settings);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Clock.bmp")]
|
||||||
|
private static byte[] _iconBytes_Clock;
|
||||||
|
internal static Bitmap Icon_Clock = new Bitmap(_iconBytes_Clock);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Tasks.bmp")]
|
||||||
|
private static byte[] _iconBytes_Tasks;
|
||||||
|
internal static Bitmap Icon_Tasks = new Bitmap(_iconBytes_Tasks);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Calculator.bmp")]
|
||||||
|
private static byte[] _iconBytes_Calculator;
|
||||||
|
internal static Bitmap Icon_Calculator = new Bitmap(_iconBytes_Calculator);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.CodeStudio.bmp")]
|
||||||
|
private static byte[] _iconBytes_CodeStudio;
|
||||||
|
internal static Bitmap Icon_CodeStudio = new Bitmap(_iconBytes_CodeStudio);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Notepad.bmp")]
|
||||||
|
private static byte[] _iconBytes_Notepad;
|
||||||
|
internal static Bitmap Icon_Notepad = new Bitmap(_iconBytes_Notepad);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Calendar.bmp")]
|
||||||
|
private static byte[] _iconBytes_Calendar;
|
||||||
|
internal static Bitmap Icon_Calendar = new Bitmap(_iconBytes_Calendar);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Files.bmp")]
|
||||||
|
private static byte[] _iconBytes_Files;
|
||||||
|
internal static Bitmap Icon_Files = new Bitmap(_iconBytes_Files);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Logs.bmp")]
|
||||||
|
private static byte[] _iconBytes_Logs;
|
||||||
|
internal static Bitmap Icon_Logs = new Bitmap(_iconBytes_Logs);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.DemoLauncher.bmp")]
|
||||||
|
private static byte[] _iconBytes_DemoLauncher;
|
||||||
|
internal static Bitmap Icon_DemoLauncher = new Bitmap(_iconBytes_DemoLauncher);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Stopwatch.bmp")]
|
||||||
|
private static byte[] _iconBytes_Stopwatch;
|
||||||
|
internal static Bitmap Icon_Stopwatch = new Bitmap(_iconBytes_Stopwatch);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Paint.bmp")]
|
||||||
|
private static byte[] _iconBytes_Paint;
|
||||||
|
internal static Bitmap Icon_Paint = new Bitmap(_iconBytes_Paint);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.MemoryStatistics.bmp")]
|
||||||
|
private static byte[] _iconBytes_MemoryStatistics;
|
||||||
|
internal static Bitmap Icon_MemoryStatistics = new Bitmap(_iconBytes_MemoryStatistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void RegisterApp(AppMetadata app)
|
||||||
|
{
|
||||||
|
AppMetadatas.Add(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static AppMetadata GetAppMetadata(string name)
|
||||||
|
{
|
||||||
|
foreach (AppMetadata app in AppMetadatas)
|
||||||
|
{
|
||||||
|
if (app.Name == name)
|
||||||
|
{
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LoadAllApps()
|
||||||
|
{
|
||||||
|
if (appsLoaded)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterApp(new AppMetadata("Files", () => { return new Files(); }, Icons.Icon_Files, Color.FromArgb(25, 84, 97)));
|
||||||
|
RegisterApp(new AppMetadata("Clock", () => { return new Clock(); }, Icons.Icon_Clock, Color.FromArgb(168, 55, 47)));
|
||||||
|
RegisterApp(new AppMetadata("Notepad", () => { return new Notepad(); }, Icons.Icon_Notepad, Color.FromArgb(14, 59, 76)));
|
||||||
|
RegisterApp(new AppMetadata("Settings", () => { return new Apps.Settings(); }, Icons.Icon_Settings, Color.FromArgb(0, 115, 186)));
|
||||||
|
RegisterApp(new AppMetadata("Tasks", () => { return new Tasks(); }, Icons.Icon_Tasks, Color.FromArgb(204, 241, 255)));
|
||||||
|
RegisterApp(new AppMetadata("Calculator", () => { return new Calculator(); }, Icons.Icon_Calculator, Color.FromArgb(0, 115, 186)));
|
||||||
|
RegisterApp(new AppMetadata("Event Log", () => { return new Logs(); }, Icons.Icon_Logs, Color.FromArgb(14, 59, 76)));
|
||||||
|
RegisterApp(new AppMetadata("Demos", () => { return new DemoLauncher(); }, Icons.Icon_DemoLauncher, Color.FromArgb(25, 25, 25)));
|
||||||
|
RegisterApp(new AppMetadata("Info", () => { return new Info(); }, Icons.Icon_Info, Color.FromArgb(0, 115, 186)));
|
||||||
|
RegisterApp(new AppMetadata("Stopwatch", () => { return new Stopwatch(); }, Icons.Icon_Stopwatch, Color.FromArgb(168, 55, 47)));
|
||||||
|
RegisterApp(new AppMetadata("Paint", () => { return new Apps.Paint.Paint(); }, Icons.Icon_Paint, Color.FromArgb(0, 115, 186)));
|
||||||
|
RegisterApp(new AppMetadata("Memory Statistics", () => { return new Apps.MemoryStatistics(); }, Icons.Icon_MemoryStatistics, Color.FromArgb(25, 25, 25)));
|
||||||
|
|
||||||
|
Logger.Logger.Instance.Info("AppManager", $"{AppMetadatas.Count} apps were registered.");
|
||||||
|
|
||||||
|
appsLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
290
Gui/Apps/Calculator.cs
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Calculator : Process
|
||||||
|
{
|
||||||
|
internal Calculator() : base("Calculator", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private enum Operator
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
Multiply,
|
||||||
|
Divide
|
||||||
|
}
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Calculator.GridButton.bmp")]
|
||||||
|
private static byte[] gridButtonBytes;
|
||||||
|
private static Bitmap gridButtonBitmap = new Bitmap(gridButtonBytes);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Calculator.Display.bmp")]
|
||||||
|
private static byte[] displayBytes;
|
||||||
|
private static Bitmap displayBitmap = new Bitmap(displayBytes);
|
||||||
|
|
||||||
|
private const int padding = 16;
|
||||||
|
private const int gridButtonSize = 40;
|
||||||
|
private const int resultHeight = 40;
|
||||||
|
|
||||||
|
private long num1 = 0;
|
||||||
|
private long num2 = 0;
|
||||||
|
private Operator op = Operator.None;
|
||||||
|
|
||||||
|
private void RenderGridButton(string text, int x, int y)
|
||||||
|
{
|
||||||
|
int buttonX = (x * gridButtonSize);
|
||||||
|
int buttonY = (y * gridButtonSize) + resultHeight;
|
||||||
|
window.DrawImage(gridButtonBitmap, buttonX, buttonY);
|
||||||
|
window.DrawString(text, Color.Black, buttonX + (gridButtonSize / 2) - ((text.Length * 8) / 2), buttonY + (gridButtonSize / 2) - (16 / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowClick(int x, int y)
|
||||||
|
{
|
||||||
|
int gridX = x / gridButtonSize;
|
||||||
|
int gridY = (y - resultHeight) / gridButtonSize;
|
||||||
|
if (gridY < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (gridY)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
switch (gridX)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
InputNum("7");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
InputNum("8");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
InputNum("9");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
InputOp(Operator.Add);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
switch (gridX)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
InputNum("4");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
InputNum("5");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
InputNum("6");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
InputOp(Operator.Subtract);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (gridX)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
InputNum("1");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
InputNum("2");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
InputNum("3");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
InputOp(Operator.Multiply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (gridX)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
InputNum("0");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
InputBksp();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
InputEquals();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
InputOp(Operator.Divide);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderDisplay(bool updateWindow = true)
|
||||||
|
{
|
||||||
|
window.DrawImage(displayBitmap, 0, 0);
|
||||||
|
string text;
|
||||||
|
if (op != Operator.None)
|
||||||
|
{
|
||||||
|
char opChar;
|
||||||
|
opChar = op switch
|
||||||
|
{
|
||||||
|
Operator.Add => '+',
|
||||||
|
Operator.Subtract => '-',
|
||||||
|
Operator.Multiply => '*',
|
||||||
|
Operator.Divide => '/',
|
||||||
|
_ => throw new Exception("Unrecognised operator.")
|
||||||
|
};
|
||||||
|
text = num1.ToString().TrimEnd('.') + opChar + num2.ToString().TrimEnd('.');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text = num1.ToString().TrimEnd('.');
|
||||||
|
}
|
||||||
|
window.DrawString(text, Color.Black, window.Width - 12 - (text.Length * 8), 12);
|
||||||
|
if (updateWindow)
|
||||||
|
{
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputNum(string num)
|
||||||
|
{
|
||||||
|
if (op != Operator.None)
|
||||||
|
{
|
||||||
|
num2 = long.Parse(num2.ToString() + num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num1 = long.Parse(num1.ToString() + num);
|
||||||
|
}
|
||||||
|
RenderDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputOp(Operator @operator)
|
||||||
|
{
|
||||||
|
if (op != Operator.None)
|
||||||
|
{
|
||||||
|
num1 = num2;
|
||||||
|
}
|
||||||
|
op = @operator;
|
||||||
|
num2 = 0;
|
||||||
|
RenderDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputBksp()
|
||||||
|
{
|
||||||
|
long num = op != Operator.None ? num2 : num1;
|
||||||
|
string numStr = num.ToString();
|
||||||
|
if (numStr.Length > 1)
|
||||||
|
{
|
||||||
|
num = long.Parse(numStr.Substring(0, numStr.Length - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
if (op != Operator.None)
|
||||||
|
{
|
||||||
|
num2 = num;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num1 = num;
|
||||||
|
}
|
||||||
|
RenderDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputEquals()
|
||||||
|
{
|
||||||
|
if (op == Operator.None) return;
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case Operator.Add:
|
||||||
|
num1 = num1 + num2;
|
||||||
|
break;
|
||||||
|
case Operator.Subtract:
|
||||||
|
num1 = num1 - num2;
|
||||||
|
break;
|
||||||
|
case Operator.Multiply:
|
||||||
|
num1 = num1 * num2;
|
||||||
|
break;
|
||||||
|
case Operator.Divide:
|
||||||
|
if (num2 == 0)
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(this, "Calculator", "Cannot divide by zero.");
|
||||||
|
messageBox.Show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
num1 = num1 / num2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unrecognised operator.");
|
||||||
|
}
|
||||||
|
num2 = 0;
|
||||||
|
op = Operator.None;
|
||||||
|
RenderDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderGridButtons()
|
||||||
|
{
|
||||||
|
RenderGridButton("7", 0, 0);
|
||||||
|
RenderGridButton("8", 1, 0);
|
||||||
|
RenderGridButton("9", 2, 0);
|
||||||
|
RenderGridButton("+", 3, 0);
|
||||||
|
|
||||||
|
RenderGridButton("4", 0, 1);
|
||||||
|
RenderGridButton("5", 1, 1);
|
||||||
|
RenderGridButton("6", 2, 1);
|
||||||
|
RenderGridButton("-", 3, 1);
|
||||||
|
|
||||||
|
RenderGridButton("1", 0, 2);
|
||||||
|
RenderGridButton("2", 1, 2);
|
||||||
|
RenderGridButton("3", 2, 2);
|
||||||
|
RenderGridButton("*", 3, 2);
|
||||||
|
|
||||||
|
RenderGridButton("0", 0, 3);
|
||||||
|
RenderGridButton("<-", 1, 3);
|
||||||
|
RenderGridButton("=", 2, 3);
|
||||||
|
RenderGridButton("/", 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, gridButtonSize * 4, (gridButtonSize * 4) + resultHeight);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
|
||||||
|
window.Title = "Calculator";
|
||||||
|
window.Clear(Color.Gray);
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Calculator").Icon;
|
||||||
|
window.OnClick = WindowClick;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
/*inputTextBlock = new TextBlock(window, padding / 2, padding / 2, window.Width - padding, resultHeight - padding);
|
||||||
|
inputTextBlock.Background = Color.Gray;
|
||||||
|
inputTextBlock.Foreground = Color.White;
|
||||||
|
wm.AddWindow(inputTextBlock);*/
|
||||||
|
|
||||||
|
RenderDisplay(updateWindow: false);
|
||||||
|
|
||||||
|
RenderGridButtons();
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
Gui/Apps/Calendar.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Calendar : Process
|
||||||
|
{
|
||||||
|
internal Calendar() : base("Calendar", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
UILib.Calendar cal;
|
||||||
|
|
||||||
|
Button nextButton;
|
||||||
|
|
||||||
|
Button prevButton;
|
||||||
|
|
||||||
|
private void PrevClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (cal.Month == 1)
|
||||||
|
{
|
||||||
|
cal.SetCalendar(cal.Year - 1, 12);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cal.SetCalendar(cal.Year, cal.Month - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NextClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (cal.Month == 12)
|
||||||
|
{
|
||||||
|
|
||||||
|
cal.SetCalendar(cal.Year + 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cal.SetCalendar(cal.Year, cal.Month + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowResized()
|
||||||
|
{
|
||||||
|
cal.Resize(window.Width, window.Height);
|
||||||
|
|
||||||
|
cal.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 320, 256, 384, 288);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Calendar";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Calendar").Icon;
|
||||||
|
window.CanResize = true;
|
||||||
|
window.UserResized = WindowResized;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
cal = new UILib.Calendar(window, 0, 0, window.Width, window.Height);
|
||||||
|
wm.AddWindow(cal);
|
||||||
|
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
cal.Year = now.Year;
|
||||||
|
cal.Month = now.Month;
|
||||||
|
|
||||||
|
prevButton = new Button(window, 8, 8, 24, 24);
|
||||||
|
prevButton.Text = "<";
|
||||||
|
prevButton.OnClick = PrevClicked;
|
||||||
|
wm.AddWindow(prevButton);
|
||||||
|
|
||||||
|
nextButton = new Button(window, 40, 8, 24, 24);
|
||||||
|
nextButton.Text = ">";
|
||||||
|
nextButton.OnClick = NextClicked;
|
||||||
|
wm.AddWindow(nextButton);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
122
Gui/Apps/Clock.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Clock : Process
|
||||||
|
{
|
||||||
|
internal Clock() : base("Clock", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private int lastSecond = DateTime.Now.Second;
|
||||||
|
|
||||||
|
private SettingsService settingsService;
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Clock.ClockBackground.bmp")]
|
||||||
|
private static byte[] clockBackgroundBytes;
|
||||||
|
private static Bitmap clockBackgroundBitmap = new Bitmap(clockBackgroundBytes);
|
||||||
|
|
||||||
|
private void RenderHand(int originX, int originY, int handLength, double radians, Color color)
|
||||||
|
{
|
||||||
|
int x = originX + (int)(handLength * Math.Sin(radians));
|
||||||
|
int y = originY - (int)(handLength * Math.Cos(radians));
|
||||||
|
window.DrawLine(originX, originY, x, y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderClock()
|
||||||
|
{
|
||||||
|
if (settingsService == null)
|
||||||
|
{
|
||||||
|
settingsService = ProcessManager.GetProcess<SettingsService>();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
|
string timeText;
|
||||||
|
if (settingsService.TwelveHourClock)
|
||||||
|
{
|
||||||
|
timeText = DateTime.Now.ToString("h:mm:ss tt");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeText = DateTime.Now.ToString("HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
int originX = window.Width / 2;
|
||||||
|
int originY = window.Height / 2;
|
||||||
|
int diameter = (int)(Math.Min(window.Width, window.Height) * 0.75f);
|
||||||
|
int radius = diameter / 2;
|
||||||
|
|
||||||
|
/* Background */
|
||||||
|
if (window.Width == 192 && window.Height == 192)
|
||||||
|
{
|
||||||
|
window.DrawImage(clockBackgroundBitmap, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.Clear(Color.White);
|
||||||
|
window.DrawCircle(originX, originY, radius, Color.Black);
|
||||||
|
|
||||||
|
for (int i = 1; i <= 12; i++)
|
||||||
|
{
|
||||||
|
int numX = (int)(originX + (Math.Sin(i * Math.PI / 6) * radius * 0.8)) - 4;
|
||||||
|
int numY = (int)(originY - Math.Cos(i * Math.PI / 6) * radius * 0.8) - 8;
|
||||||
|
window.DrawString(i.ToString(), Color.Black, numX, numY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.DrawString(timeText, Color.Black, (window.Width / 2) - ((timeText.Length * 8) / 2), 4);
|
||||||
|
|
||||||
|
/* Second hand */
|
||||||
|
double second = now.Second;
|
||||||
|
double secondRad = second * Math.PI / 30;
|
||||||
|
RenderHand(originX, originY, radius, secondRad, Color.Red);
|
||||||
|
|
||||||
|
/* Minute hand*/
|
||||||
|
double minute = now.Minute + (second / 60);
|
||||||
|
double minuteRad = minute * Math.PI / 30;
|
||||||
|
RenderHand(originX, originY, (int)(radius * 0.75f), minuteRad, Color.Black);
|
||||||
|
|
||||||
|
/* Hour hand */
|
||||||
|
double hour = now.Hour + (minute / 60);
|
||||||
|
double hourRad = hour * Math.PI / 6;
|
||||||
|
RenderHand(originX, originY, (int)(radius * 0.5f), hourRad, Color.Black);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Process
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 192, 192);
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Clock").Icon;
|
||||||
|
window.CanResize = true;
|
||||||
|
window.UserResized = RenderClock;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
wm.AddWindow(window);
|
||||||
|
|
||||||
|
window.Title = "Clock";
|
||||||
|
|
||||||
|
RenderClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
if (lastSecond != now.Second)
|
||||||
|
{
|
||||||
|
RenderClock();
|
||||||
|
lastSecond = now.Second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion Process
|
||||||
|
}
|
||||||
|
}
|
||||||
86
Gui/Apps/DemoLauncher.cs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.SmoothMono;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class DemoLauncher : Process
|
||||||
|
{
|
||||||
|
internal DemoLauncher() : base("DemoLauncher", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Demos.Starfield.bmp")]
|
||||||
|
private static byte[] _iconBytes_Starfield;
|
||||||
|
internal static Bitmap Icon_Starfield = new Bitmap(_iconBytes_Starfield);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.Demos.Mandelbrot.bmp")]
|
||||||
|
private static byte[] _iconBytes_Mandelbrot;
|
||||||
|
internal static Bitmap Icon_Mandelbrot = new Bitmap(_iconBytes_Mandelbrot);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AppMetadata> demoApps = new()
|
||||||
|
{
|
||||||
|
new AppMetadata("Starfield", () => { return new Apps.Demos.Starfield(); }, Icons.Icon_Starfield, Color.Black ),
|
||||||
|
new AppMetadata("Mandelbrot", () => { return new Apps.Demos.Mandelbrot(); }, Icons.Icon_Mandelbrot, Color.Black ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private const string message = "Demo Launcher";
|
||||||
|
|
||||||
|
private void PopulateTable()
|
||||||
|
{
|
||||||
|
table.Cells.Clear();
|
||||||
|
foreach (AppMetadata app in demoApps)
|
||||||
|
{
|
||||||
|
table.Cells.Add(new TableCell(app.Icon.Resize(32, 32), app.Name));
|
||||||
|
}
|
||||||
|
table.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 384, 256);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Demos";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Demos").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
window.Clear(Color.FromArgb(56, 56, 71));
|
||||||
|
|
||||||
|
window.DrawString(message, Color.White, (window.Width / 2) - ((FontData.Width * message.Length) / 2), 12);
|
||||||
|
|
||||||
|
table = new Table(window, 12, 40, window.Width - 24, window.Height - 52);
|
||||||
|
table.Background = Color.FromArgb(56, 56, 71);
|
||||||
|
table.Border = Color.FromArgb(56, 56, 71);
|
||||||
|
table.Foreground = Color.White;
|
||||||
|
table.CellHeight = 32;
|
||||||
|
table.OnDoubleClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
if (table.SelectedCellIndex != -1)
|
||||||
|
{
|
||||||
|
AppMetadata app = demoApps[table.SelectedCellIndex];
|
||||||
|
ProcessManager.AddProcess(app.CreateProcess()).Start();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PopulateTable();
|
||||||
|
wm.AddWindow(table);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
91
Gui/Apps/Demos/Mandelbrot.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Demos
|
||||||
|
{
|
||||||
|
internal class Mandelbrot : Process
|
||||||
|
{
|
||||||
|
internal Mandelbrot() : base("Mandelbrot", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private Color GetColor(double v)
|
||||||
|
{
|
||||||
|
int red = Math.Clamp((int)(255 * v), 0, 255);
|
||||||
|
int green = 0;
|
||||||
|
int blue = Math.Clamp((int)(255 * (1 - v)), 0, 255);
|
||||||
|
|
||||||
|
return Color.FromArgb(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderMandelbrot()
|
||||||
|
{
|
||||||
|
window.Clear(Color.Black);
|
||||||
|
wm.Update(window);
|
||||||
|
|
||||||
|
int width = window.Width;
|
||||||
|
int height = window.Height;
|
||||||
|
|
||||||
|
const int max = 20;
|
||||||
|
const double bail = 2.0;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
double zx = 0;
|
||||||
|
double zy = 0;
|
||||||
|
double cx = (x - width / 2.0) / (width / 4.0);
|
||||||
|
double cy = (y - height / 2.0) / (height / 4.0);
|
||||||
|
|
||||||
|
int iteration = 0;
|
||||||
|
|
||||||
|
while (zx * zx + zy * zy < bail && iteration < max)
|
||||||
|
{
|
||||||
|
double zxNew = zx * zx - zy * zy + cx;
|
||||||
|
zy = 2 * zx * zy + cy;
|
||||||
|
zx = zxNew;
|
||||||
|
iteration++;
|
||||||
|
}
|
||||||
|
|
||||||
|
double smooth = iteration + 1 - Math.Log(Math.Log(Math.Sqrt(zx * zx + zy * zy)) / Math.Log(bail)) / Math.Log(2);
|
||||||
|
window.DrawPoint(x, y, GetColor(smooth / max));
|
||||||
|
|
||||||
|
if (x % 32 == 0)
|
||||||
|
{
|
||||||
|
ProcessManager.Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y % 8 == 0)
|
||||||
|
{
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 256, 256);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Mandelbrot";
|
||||||
|
window.CanResize = true;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
window.UserResized = RenderMandelbrot;
|
||||||
|
|
||||||
|
RenderMandelbrot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
105
Gui/Apps/Demos/Starfield.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Demos
|
||||||
|
{
|
||||||
|
internal class Starfield : Process
|
||||||
|
{
|
||||||
|
internal Starfield() : base("Starfield", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private readonly Random random = new Random();
|
||||||
|
|
||||||
|
private readonly List<Star> stars = new List<Star>();
|
||||||
|
|
||||||
|
private int timerId;
|
||||||
|
|
||||||
|
private class Star
|
||||||
|
{
|
||||||
|
internal double X { get; set; }
|
||||||
|
internal double Y { get; set; }
|
||||||
|
internal double Z { get; set; }
|
||||||
|
internal double Velocity { get; set; }
|
||||||
|
|
||||||
|
internal Star(double x, double y, double z, double velocity)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
Velocity = velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal (double, double) TransformCoordinates(double x, double y, double z, double fov)
|
||||||
|
{
|
||||||
|
double screenX = x / (z * Math.Tan(fov / 2)) + 0.5;
|
||||||
|
double screenY = y / (z * Math.Tan(fov / 2)) + 0.5;
|
||||||
|
|
||||||
|
return (screenX, screenY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 256, 256);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Starfield";
|
||||||
|
window.CanResize = true;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
stars.Add(new Star(
|
||||||
|
x: random.NextDouble() * 2 - 1.5,
|
||||||
|
y: random.NextDouble() * 2 - 1.5,
|
||||||
|
z: 3,
|
||||||
|
velocity: random.NextDouble() * 0.05 + 0.05));
|
||||||
|
}
|
||||||
|
|
||||||
|
timerId = Cosmos.HAL.Global.PIT.RegisterTimer(new Cosmos.HAL.PIT.PITTimer(() =>
|
||||||
|
{
|
||||||
|
foreach (var star in stars)
|
||||||
|
{
|
||||||
|
star.Z -= star.Velocity;
|
||||||
|
|
||||||
|
if (star.Z < 0)
|
||||||
|
{
|
||||||
|
star.X = random.NextDouble() * 2 - 1.5;
|
||||||
|
star.Y = random.NextDouble() * 2 - 1.5;
|
||||||
|
star.Z = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, (ulong)((1000 /* ms */ / 30) * 1e+6 /* ms -> ns */ ), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
window.Clear(Color.Black);
|
||||||
|
|
||||||
|
foreach (var star in stars)
|
||||||
|
{
|
||||||
|
(double X, double Y) pos = TransformCoordinates(star.X, star.Y, star.Z, Math.PI / 2);
|
||||||
|
|
||||||
|
int screenX = (int)((pos.X + 1) * (window.Width / 2));
|
||||||
|
int screenY = (int)((pos.Y + 1) * (window.Height / 2));
|
||||||
|
|
||||||
|
window.DrawPoint(screenX, screenY, Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Stop()
|
||||||
|
{
|
||||||
|
base.Stop();
|
||||||
|
|
||||||
|
Cosmos.HAL.Global.PIT.UnregisterTimer(timerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
330
Gui/Apps/Files.cs
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using CMLeonOS.Logger;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Files : Process
|
||||||
|
{
|
||||||
|
internal Files() : base("Files", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Table entryTable;
|
||||||
|
Table shortcutsTable;
|
||||||
|
|
||||||
|
ImageBlock up;
|
||||||
|
|
||||||
|
TextBox pathBox;
|
||||||
|
|
||||||
|
Window header;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Directory.bmp")]
|
||||||
|
private static byte[] _iconBytes_Directory;
|
||||||
|
internal static Bitmap Icon_Directory = new Bitmap(_iconBytes_Directory);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File.bmp")]
|
||||||
|
private static byte[] _iconBytes_File;
|
||||||
|
internal static Bitmap Icon_File = new Bitmap(_iconBytes_File);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File_Config.bmp")]
|
||||||
|
private static byte[] _iconBytes_File_Config;
|
||||||
|
internal static Bitmap Icon_File_Config = new Bitmap(_iconBytes_File_Config);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File_Rs.bmp")]
|
||||||
|
private static byte[] _iconBytes_File_Rs;
|
||||||
|
internal static Bitmap Icon_File_Rs = new Bitmap(_iconBytes_File_Rs);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File_Text.bmp")]
|
||||||
|
private static byte[] _iconBytes_File_Text;
|
||||||
|
internal static Bitmap Icon_File_Text = new Bitmap(_iconBytes_File_Text);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Drive.bmp")]
|
||||||
|
private static byte[] _iconBytes_Drive;
|
||||||
|
internal static Bitmap Icon_Drive = new Bitmap(_iconBytes_Drive);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Home.bmp")]
|
||||||
|
private static byte[] _iconBytes_Home;
|
||||||
|
internal static Bitmap Icon_Home = new Bitmap(_iconBytes_Home);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Up.bmp")]
|
||||||
|
private static byte[] _iconBytes_Up;
|
||||||
|
internal static Bitmap Icon_Up = new Bitmap(_iconBytes_Up);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string currentDir = @"0:\";
|
||||||
|
|
||||||
|
private const int pathBoxMargin = 4;
|
||||||
|
private const int pathBoxHeight = 24;
|
||||||
|
private const int shortcutsWidth = 128;
|
||||||
|
private const int headerHeight = 32;
|
||||||
|
|
||||||
|
private const string dirEmptyMessage = "This folder is empty.";
|
||||||
|
|
||||||
|
private readonly (string Name, string Path)[] shortcuts = new (string, string)[]
|
||||||
|
{
|
||||||
|
("CMLeonOS (0:)", @"0:\"),
|
||||||
|
("My Home", @$"0:\user\{UserSystem.CurrentLoggedInUser.Username}"),
|
||||||
|
("Users", @"0:\user"),
|
||||||
|
("etc", @"0:\etc"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private Bitmap GetFileIcon(string path)
|
||||||
|
{
|
||||||
|
string extension = Path.GetExtension(path).ToLower();
|
||||||
|
|
||||||
|
return extension switch
|
||||||
|
{
|
||||||
|
".txt" or ".md" or ".log" => Icons.Icon_File_Text,
|
||||||
|
".rs" => Icons.Icon_File_Rs,
|
||||||
|
".ini" or ".cfg" => Icons.Icon_File_Config,
|
||||||
|
_ => Icons.Icon_File
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap GetDirectoryIcon(string path)
|
||||||
|
{
|
||||||
|
if (Path.TrimEndingDirectorySeparator(path).StartsWith(@"0:\user\"))
|
||||||
|
{
|
||||||
|
return Icons.Icon_Home;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (path)
|
||||||
|
{
|
||||||
|
case @"0:\":
|
||||||
|
return Icons.Icon_Drive;
|
||||||
|
default:
|
||||||
|
return Icons.Icon_Directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateEntryTable()
|
||||||
|
{
|
||||||
|
entryTable.Cells.Clear();
|
||||||
|
entryTable.SelectedCellIndex = -1;
|
||||||
|
|
||||||
|
bool empty = true;
|
||||||
|
foreach (string path in Directory.GetDirectories(currentDir))
|
||||||
|
{
|
||||||
|
entryTable.Cells.Add(new TableCell(GetDirectoryIcon(path), Path.GetFileName(path), tag: "Directory"));
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
foreach (string path in Directory.GetFiles(currentDir))
|
||||||
|
{
|
||||||
|
entryTable.Cells.Add(new TableCell(GetFileIcon(path), Path.GetFileName(path), tag: "File"));
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty)
|
||||||
|
{
|
||||||
|
entryTable.Clear(entryTable.Background);
|
||||||
|
entryTable.DrawString(dirEmptyMessage, Color.Black, (entryTable.Width / 2) - ((dirEmptyMessage.Length * 8) / 2), 12);
|
||||||
|
wm.Update(entryTable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entryTable.Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateShortcutTable()
|
||||||
|
{
|
||||||
|
shortcutsTable.Cells.Clear();
|
||||||
|
foreach ((string Name, string Path) item in shortcuts)
|
||||||
|
{
|
||||||
|
shortcutsTable.Cells.Add(new TableCell(GetDirectoryIcon(item.Path), item.Name, tag: item.Path));
|
||||||
|
}
|
||||||
|
shortcutsTable.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool NavigateTo(string path)
|
||||||
|
{
|
||||||
|
string sanitised = PathUtil.Sanitize(path);
|
||||||
|
|
||||||
|
if (!Directory.Exists(sanitised))
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(this, "Files", $"CMLeonOS can't find that folder.\nCheck the spelling and try again.");
|
||||||
|
messageBox.Show();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDir = sanitised;
|
||||||
|
pathBox.Text = sanitised;
|
||||||
|
|
||||||
|
PopulateEntryTable();
|
||||||
|
UpdateSelectedShortcut();
|
||||||
|
RenderHeader();
|
||||||
|
|
||||||
|
if (sanitised == @"0:\")
|
||||||
|
{
|
||||||
|
window.Title = "Files";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.Title = Path.GetDirectoryName(sanitised);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelectedShortcut()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < shortcuts.Length; i++)
|
||||||
|
{
|
||||||
|
if (shortcuts[i].Path == currentDir)
|
||||||
|
{
|
||||||
|
shortcutsTable.SelectedCellIndex = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shortcutsTable.SelectedCellIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EntryTableDoubleClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (entryTable.SelectedCellIndex != -1)
|
||||||
|
{
|
||||||
|
TableCell cell = entryTable.Cells[entryTable.SelectedCellIndex];
|
||||||
|
string path = PathUtil.Combine(currentDir, cell.Text);
|
||||||
|
if ((string)cell.Tag == "Directory")
|
||||||
|
{
|
||||||
|
NavigateTo(path);
|
||||||
|
}
|
||||||
|
else if ((string)cell.Tag == "File")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string extension = Path.GetExtension(path).ToLower();
|
||||||
|
if (extension == ".txt" || extension == ".md")
|
||||||
|
{
|
||||||
|
var notepad = new Notepad(path);
|
||||||
|
var metadata = AppManager.GetAppMetadata("Notepad");
|
||||||
|
metadata.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Logger.Instance.Warning("Files", $"Cannot open file: {path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Logger.Instance.Error("Files", $"Error opening file: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShortcutsTableCellSelected(int index)
|
||||||
|
{
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
bool success = NavigateTo(shortcuts[index].Path);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
UpdateSelectedShortcut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PathBoxSubmitted()
|
||||||
|
{
|
||||||
|
bool success = NavigateTo(pathBox.Text);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
pathBox.Text = currentDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpClicked()
|
||||||
|
{
|
||||||
|
DirectoryInfo parent = Directory.GetParent(currentDir);
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
NavigateTo(parent.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderHeader(bool updateWindow = true)
|
||||||
|
{
|
||||||
|
header.Clear(Color.DarkBlue);
|
||||||
|
|
||||||
|
header.DrawImageAlpha(GetDirectoryIcon(currentDir), 8, 8);
|
||||||
|
|
||||||
|
DirectoryInfo info = new DirectoryInfo(currentDir);
|
||||||
|
|
||||||
|
string currentDirFriendlyName = Path.GetFileName(currentDir);
|
||||||
|
if (currentDir == $@"0:\user\{UserSystem.CurrentLoggedInUser.Username}")
|
||||||
|
{
|
||||||
|
currentDirFriendlyName = "My Home";
|
||||||
|
}
|
||||||
|
header.DrawString(info.Parent == null ? currentDir : currentDirFriendlyName, Color.White, 32, 8);
|
||||||
|
|
||||||
|
if (updateWindow)
|
||||||
|
{
|
||||||
|
wm.Update(header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (x < pathBoxHeight && y < pathBoxHeight)
|
||||||
|
{
|
||||||
|
UpClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 288, 240, 512, 304);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Files";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Files").Icon;
|
||||||
|
window.OnClick = WindowClicked;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
window.Clear(Color.DarkGray);
|
||||||
|
|
||||||
|
window.DrawImageAlpha(Icons.Icon_Up, 0, 0);
|
||||||
|
|
||||||
|
pathBox = new TextBox(window, (pathBoxMargin / 2) + pathBoxHeight, pathBoxMargin / 2, window.Width - pathBoxMargin - pathBoxHeight, 24 - pathBoxMargin);
|
||||||
|
pathBox.Text = currentDir;
|
||||||
|
pathBox.Submitted = PathBoxSubmitted;
|
||||||
|
wm.AddWindow(pathBox);
|
||||||
|
|
||||||
|
entryTable = new Table(window, shortcutsWidth, pathBoxHeight + headerHeight, window.Width - shortcutsWidth, window.Height - pathBoxHeight - headerHeight);
|
||||||
|
entryTable.OnDoubleClick = EntryTableDoubleClicked;
|
||||||
|
PopulateEntryTable();
|
||||||
|
wm.AddWindow(entryTable);
|
||||||
|
|
||||||
|
header = new Window(this, window, shortcutsWidth, pathBoxHeight, window.Width - shortcutsWidth, headerHeight);
|
||||||
|
wm.AddWindow(header);
|
||||||
|
RenderHeader(updateWindow: false);
|
||||||
|
|
||||||
|
shortcutsTable = new Table(window, 0, pathBoxHeight, shortcutsWidth, window.Height - pathBoxHeight);
|
||||||
|
shortcutsTable.AllowDeselection = false;
|
||||||
|
shortcutsTable.Background = Color.DarkGray;
|
||||||
|
shortcutsTable.Foreground = Color.White;
|
||||||
|
PopulateShortcutTable();
|
||||||
|
shortcutsTable.SelectedCellIndex = 0;
|
||||||
|
shortcutsTable.TableCellSelected = ShortcutsTableCellSelected;
|
||||||
|
wm.AddWindow(shortcutsTable);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
Gui/Apps/Info.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Info : Process
|
||||||
|
{
|
||||||
|
internal Info() : base("Info", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 320, 256);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Info";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Info").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
window.Clear(Color.LightGray);
|
||||||
|
window.DrawFilledRectangle(0, 0, window.Width, 40, Color.Black);
|
||||||
|
window.DrawString("CMLeonOS", System.Drawing.Color.White, 12, 12);
|
||||||
|
|
||||||
|
window.DrawString($"OS: CMLeonOS {Kernel.Version}", Color.Black, 12, 52);
|
||||||
|
window.DrawString($"Memory: {Cosmos.Core.CPU.GetAmountOfRAM()} MB", Color.Black, 12, 80);
|
||||||
|
|
||||||
|
window.DrawString("Credits", Color.DarkBlue, 12, 108);
|
||||||
|
window.DrawString("Cosmos Team - OS tooling", Color.Black, 12, 132);
|
||||||
|
window.DrawString("Microsoft - .NET Runtime", Color.Black, 12, 156);
|
||||||
|
window.DrawString("Google Fonts - Font", Color.Black, 12, 180);
|
||||||
|
|
||||||
|
Button button = new Button(window, window.Width - 80 - 12, window.Height - 20 - 12, 80, 20);
|
||||||
|
button.Text = "OK";
|
||||||
|
button.OnClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(window);
|
||||||
|
};
|
||||||
|
wm.AddWindow(button);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
138
Gui/Apps/Logs.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.SmoothMono;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using CMLeonOS.Logger;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Logs : Process
|
||||||
|
{
|
||||||
|
internal Logs() : base("Logs", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Logs.Info.bmp")]
|
||||||
|
private static byte[] _iconBytes_Info;
|
||||||
|
internal static Bitmap Icon_Info = new Bitmap(_iconBytes_Info);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Logs.Warning.bmp")]
|
||||||
|
private static byte[] _iconBytes_Warning;
|
||||||
|
internal static Bitmap Icon_Warning = new Bitmap(_iconBytes_Warning);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Logs.Error.bmp")]
|
||||||
|
private static byte[] _iconBytes_Error;
|
||||||
|
internal static Bitmap Icon_Error = new Bitmap(_iconBytes_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddLogToTable(LogEntry log)
|
||||||
|
{
|
||||||
|
Bitmap icon;
|
||||||
|
switch (log.Priority)
|
||||||
|
{
|
||||||
|
case LogLevel.Info:
|
||||||
|
icon = Icons.Icon_Info;
|
||||||
|
break;
|
||||||
|
case LogLevel.Warning:
|
||||||
|
icon = Icons.Icon_Warning;
|
||||||
|
break;
|
||||||
|
case LogLevel.Error:
|
||||||
|
icon = Icons.Icon_Error;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
icon = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
table.Cells.Add(new TableCell(icon, $"{log.Date.ToString("HH:mm")} - {log.Source}: {log.Message}", log));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
window.Clear(Color.Gray);
|
||||||
|
|
||||||
|
string text = $"{Log.Logs.Count} messages";
|
||||||
|
window.DrawString(text, Color.White, window.Width - (FontData.Width * text.Length) - 12, window.Height - FontData.Height - 12);
|
||||||
|
|
||||||
|
table.Render();
|
||||||
|
table.ScrollToBottom();
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
|
||||||
|
if (UserSystem.CurrentLoggedInUser == null || !UserSystem.CurrentLoggedInUser.Admin)
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(Parent, Name, "You must be an admin to run this app.");
|
||||||
|
messageBox.Show();
|
||||||
|
|
||||||
|
TryStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window = new AppWindow(this, 256, 256, 512, 352);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Event Log").Icon;
|
||||||
|
window.Title = "Event Log";
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
table = new Table(window, 12, 12, window.Width - 24, window.Height - 24 - 16 - 12);
|
||||||
|
table.OnDoubleClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
if (table.SelectedCellIndex != -1)
|
||||||
|
{
|
||||||
|
LogEntry log = (LogEntry)table.Cells[table.SelectedCellIndex].Tag;
|
||||||
|
|
||||||
|
string priority = log.Priority switch
|
||||||
|
{
|
||||||
|
LogLevel.Info => "Info",
|
||||||
|
LogLevel.Warning => "Warning",
|
||||||
|
LogLevel.Error => "Error",
|
||||||
|
_ => "Unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.AppendLine($"Date: {log.Date.ToLongDateString()} {log.Date.ToLongTimeString()}");
|
||||||
|
builder.AppendLine($"Source: {log.Source}");
|
||||||
|
builder.AppendLine($"Priority: {priority}");
|
||||||
|
builder.AppendLine();
|
||||||
|
builder.Append(log.Message);
|
||||||
|
|
||||||
|
MessageBox messageBox = new MessageBox(this, $"{log.Source}: Log Event", builder.ToString());
|
||||||
|
messageBox.Show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wm.AddWindow(table);
|
||||||
|
|
||||||
|
table.Cells.Clear();
|
||||||
|
foreach (LogEntry log in Log.Logs)
|
||||||
|
{
|
||||||
|
AddLogToTable(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.LogEmittedReceivers.Add((LogEntry log) =>
|
||||||
|
{
|
||||||
|
AddLogToTable(log);
|
||||||
|
Update();
|
||||||
|
});
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
71
Gui/Apps/MemoryStatistics.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using CMLeonOS.Gui.SmoothMono;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class MemoryStatistics : Process
|
||||||
|
{
|
||||||
|
internal MemoryStatistics() : base("MemoryStatistics", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private int lastSecond;
|
||||||
|
|
||||||
|
private static int padding = 12;
|
||||||
|
private static int barHeight = 12;
|
||||||
|
private static Color barColour = Color.FromArgb(0, 155, 254);
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
window.Clear(Color.LightGray);
|
||||||
|
|
||||||
|
var statistics = MemoryStatisticsProvider.GetMemoryStatistics();
|
||||||
|
|
||||||
|
window.DrawString("Memory Statistics", Color.DarkBlue, padding, padding);
|
||||||
|
|
||||||
|
window.DrawString(string.Format(@"Total: {0} MB
|
||||||
|
Unavailable: {1} MB
|
||||||
|
Used: {2:d1} MB
|
||||||
|
Free: {3} MB
|
||||||
|
Percentage Used: {4:d1}%",
|
||||||
|
statistics.TotalMB,
|
||||||
|
statistics.UnavailableMB,
|
||||||
|
statistics.UsedMB,
|
||||||
|
statistics.FreeMB,
|
||||||
|
statistics.PercentUsed), Color.Black, padding, padding + FontData.Height + padding);
|
||||||
|
|
||||||
|
window.DrawFilledRectangle(0, window.Height - barHeight, window.Width, barHeight, Color.Black);
|
||||||
|
window.DrawFilledRectangle(0, window.Height - barHeight, (int)(window.Width * ((float)statistics.PercentUsed / 100f)), barHeight, barColour);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 256, 192);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Memory Statistics";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Memory Statistics").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
int second = DateTime.Now.Second;
|
||||||
|
if (lastSecond != second)
|
||||||
|
{
|
||||||
|
lastSecond = second;
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
226
Gui/Apps/Notepad.cs
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.SmoothMono;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using CMLeonOS.Utils;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Notepad : Process
|
||||||
|
{
|
||||||
|
internal Notepad() : base("Notepad", ProcessType.Application) { }
|
||||||
|
|
||||||
|
internal Notepad(string path) : base("Notepad", ProcessType.Application)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
SettingsService settingsService = ProcessManager.GetProcess<SettingsService>();
|
||||||
|
|
||||||
|
TextBox textBox;
|
||||||
|
|
||||||
|
ShortcutBar shortcutBar;
|
||||||
|
|
||||||
|
private string? path = null;
|
||||||
|
|
||||||
|
private bool modified = false;
|
||||||
|
|
||||||
|
private void TextChanged()
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
UpdateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowResized()
|
||||||
|
{
|
||||||
|
textBox.Resize(window.Width, window.Height - 20);
|
||||||
|
shortcutBar.Resize(window.Width, 20);
|
||||||
|
|
||||||
|
shortcutBar.Render();
|
||||||
|
|
||||||
|
textBox.MarkAllLines();
|
||||||
|
textBox.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTitle()
|
||||||
|
{
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
window.Title = "Untitled - Notepad";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
{
|
||||||
|
window.Title = $"{Path.GetFileName(path)}* - Notepad";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.Title = $"{Path.GetFileName(path)} - Notepad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Open(string newPath, bool readFile = true)
|
||||||
|
{
|
||||||
|
if (newPath == null) return;
|
||||||
|
|
||||||
|
if (!FileSecurity.CanAccess(path))
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(this, "Notepad", $"Access to '{Path.GetFileName(newPath)}' is unauthorised.");
|
||||||
|
messageBox.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readFile && !File.Exists(newPath))
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(this, "Notepad", $"No such file '{Path.GetFileName(newPath)}'.");
|
||||||
|
messageBox.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
path = newPath;
|
||||||
|
|
||||||
|
if (readFile)
|
||||||
|
{
|
||||||
|
textBox.Text = File.ReadAllText(path);
|
||||||
|
|
||||||
|
textBox.MarkAllLines();
|
||||||
|
textBox.Render();
|
||||||
|
|
||||||
|
modified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenFilePrompt()
|
||||||
|
{
|
||||||
|
PromptBox prompt = new PromptBox(this, "Open File", "Enter the path to open.", "Path", (string newPath) =>
|
||||||
|
{
|
||||||
|
if (!newPath.Contains(':'))
|
||||||
|
{
|
||||||
|
newPath = $@"0:\{newPath}";
|
||||||
|
}
|
||||||
|
Open(newPath);
|
||||||
|
});
|
||||||
|
prompt.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveAsPrompt()
|
||||||
|
{
|
||||||
|
PromptBox prompt = new PromptBox(this, "Save As", "Enter the path to save to.", "Path", (string newPath) =>
|
||||||
|
{
|
||||||
|
if (!newPath.Contains(':'))
|
||||||
|
{
|
||||||
|
newPath = $@"0:\{newPath}";
|
||||||
|
}
|
||||||
|
|
||||||
|
Open(newPath, readFile: false);
|
||||||
|
|
||||||
|
// Check if open succeeded.
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
prompt.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Save()
|
||||||
|
{
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
SaveAsPrompt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(path, textBox.Text);
|
||||||
|
|
||||||
|
modified = false;
|
||||||
|
UpdateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyTheme()
|
||||||
|
{
|
||||||
|
if (settingsService.DarkNotepad)
|
||||||
|
{
|
||||||
|
textBox.Background = Color.FromArgb(24, 24, 30);
|
||||||
|
textBox.Foreground = Color.White;
|
||||||
|
|
||||||
|
shortcutBar.Background = Color.FromArgb(56, 56, 71);
|
||||||
|
shortcutBar.Foreground = Color.White;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textBox.Background = Color.White;
|
||||||
|
textBox.Foreground = Color.Black;
|
||||||
|
|
||||||
|
shortcutBar.Background = Color.LightGray;
|
||||||
|
shortcutBar.Foreground = Color.Black;
|
||||||
|
}
|
||||||
|
|
||||||
|
textBox.MarkAllLines();
|
||||||
|
textBox.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenViewSettings()
|
||||||
|
{
|
||||||
|
AppWindow settingsWindow = new AppWindow(this, 320, 264, 256, 192);
|
||||||
|
settingsWindow.DrawString("Notepad Settings", Color.DarkBlue, 12, 12);
|
||||||
|
settingsWindow.DrawString($"Notepad v{Kernel.Version}", Color.DarkGray, 12, settingsWindow.Height - 12 - FontData.Height);
|
||||||
|
wm.AddWindow(settingsWindow);
|
||||||
|
settingsWindow.Title = "Notepad";
|
||||||
|
|
||||||
|
Switch darkSwitch = new Switch(settingsWindow, 12, 40, settingsWindow.Width - 16, 20);
|
||||||
|
darkSwitch.Text = "Dark theme";
|
||||||
|
darkSwitch.Checked = settingsService.DarkNotepad;
|
||||||
|
darkSwitch.CheckBoxChanged = (bool @checked) =>
|
||||||
|
{
|
||||||
|
settingsService.DarkNotepad = @checked;
|
||||||
|
ApplyTheme();
|
||||||
|
};
|
||||||
|
wm.AddWindow(darkSwitch);
|
||||||
|
|
||||||
|
wm.Update(settingsWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 320, 264, 384, 240);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
UpdateTitle();
|
||||||
|
window.Closing = TryStop;
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Notepad").Icon;
|
||||||
|
window.CanResize = true;
|
||||||
|
window.UserResized = WindowResized;
|
||||||
|
|
||||||
|
shortcutBar = new ShortcutBar(window, 0, 0, window.Width, 20);
|
||||||
|
shortcutBar.Cells.Add(new ShortcutBarCell("Open", OpenFilePrompt));
|
||||||
|
shortcutBar.Cells.Add(new ShortcutBarCell("Save", Save));
|
||||||
|
shortcutBar.Cells.Add(new ShortcutBarCell("Save As", SaveAsPrompt));
|
||||||
|
shortcutBar.Cells.Add(new ShortcutBarCell("View", OpenViewSettings));
|
||||||
|
shortcutBar.Render();
|
||||||
|
wm.AddWindow(shortcutBar);
|
||||||
|
|
||||||
|
textBox = new TextBox(window, 0, 20, window.Width, window.Height - 20);
|
||||||
|
textBox.MultiLine = true;
|
||||||
|
textBox.Changed = TextChanged;
|
||||||
|
wm.AddWindow(textBox);
|
||||||
|
|
||||||
|
ApplyTheme();
|
||||||
|
|
||||||
|
Open(path);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
Gui/Apps/Paint/ColourPicker.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint
|
||||||
|
{
|
||||||
|
internal class ColourPicker : Window
|
||||||
|
{
|
||||||
|
private Paint paintInstance;
|
||||||
|
|
||||||
|
private Table table;
|
||||||
|
|
||||||
|
internal readonly List<Color> Colours = new List<Color>()
|
||||||
|
{
|
||||||
|
Color.Black,
|
||||||
|
Color.White,
|
||||||
|
Color.Red,
|
||||||
|
Color.Blue,
|
||||||
|
Color.Orange,
|
||||||
|
Color.Green,
|
||||||
|
Color.Pink,
|
||||||
|
Color.Gray,
|
||||||
|
Color.Purple,
|
||||||
|
Color.DarkGoldenrod,
|
||||||
|
Color.DarkGray,
|
||||||
|
Color.DarkGreen,
|
||||||
|
Color.DarkCyan,
|
||||||
|
Color.Cyan,
|
||||||
|
Color.BlueViolet,
|
||||||
|
Color.AliceBlue,
|
||||||
|
Color.Brown,
|
||||||
|
Color.CornflowerBlue,
|
||||||
|
Color.Azure,
|
||||||
|
Color.Beige,
|
||||||
|
Color.DarkBlue,
|
||||||
|
Color.DarkSlateBlue,
|
||||||
|
Color.SeaGreen
|
||||||
|
};
|
||||||
|
|
||||||
|
private void TableClicked(int x, int y)
|
||||||
|
{
|
||||||
|
// Clear 'Selected' text on previously selected colour.
|
||||||
|
foreach (var cell in table.Cells)
|
||||||
|
{
|
||||||
|
cell.Text = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedCell = table.Cells[table.SelectedCellIndex];
|
||||||
|
Color color = (Color)selectedCell.Tag;
|
||||||
|
|
||||||
|
paintInstance.SelectedColor = color;
|
||||||
|
|
||||||
|
selectedCell.Text = "Selected";
|
||||||
|
|
||||||
|
table.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ColourPicker(Paint paint, int x, int y, int width, int height) : base(paint, x, y, width, height)
|
||||||
|
{
|
||||||
|
paintInstance = paint;
|
||||||
|
|
||||||
|
Clear(Color.FromArgb(107, 107, 107));
|
||||||
|
DrawString("Colours", Color.White, 8, 8);
|
||||||
|
|
||||||
|
table = new Table(this, 0, 32, Width, Height - 32);
|
||||||
|
table.AllowDeselection = false;
|
||||||
|
table.CellHeight = 20;
|
||||||
|
table.TextAlignment = Alignment.Middle;
|
||||||
|
table.OnClick = TableClicked;
|
||||||
|
|
||||||
|
foreach (Color colour in Colours)
|
||||||
|
{
|
||||||
|
TableCell cell = new(string.Empty, tag: colour);
|
||||||
|
cell.BackgroundColourOverride = colour;
|
||||||
|
cell.ForegroundColourOverride = colour.GetForegroundColour();
|
||||||
|
if (colour == paint.SelectedColor)
|
||||||
|
{
|
||||||
|
cell.Text = "Selected";
|
||||||
|
}
|
||||||
|
table.Cells.Add(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Render();
|
||||||
|
|
||||||
|
WM.AddWindow(this);
|
||||||
|
WM.AddWindow(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
Gui/Apps/Paint/Paint.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using Cosmos.System;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint
|
||||||
|
{
|
||||||
|
internal class Paint : Process
|
||||||
|
{
|
||||||
|
internal Paint() : base("Paint", ProcessType.Application)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Window canvas;
|
||||||
|
|
||||||
|
ToolBox toolBox;
|
||||||
|
|
||||||
|
ColourPicker colourPicker;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private bool down = false;
|
||||||
|
|
||||||
|
internal Color SelectedColor { get; set; } = Color.Black;
|
||||||
|
|
||||||
|
internal bool IsInBounds(int x, int y)
|
||||||
|
{
|
||||||
|
if (x >= canvas.Width || y >= canvas.Height) return false;
|
||||||
|
if (x < 0 || y < 0) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CanvasDown(int x, int y)
|
||||||
|
{
|
||||||
|
down = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 768, 448);
|
||||||
|
window.Title = "Paint";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Paint").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
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.RelativeTo = window;
|
||||||
|
canvas.OnDown = CanvasDown;
|
||||||
|
canvas.Clear(Color.White);
|
||||||
|
wm.AddWindow(canvas);
|
||||||
|
|
||||||
|
toolBox = new ToolBox(this, 0, 0, 128, window.Height);
|
||||||
|
toolBox.RelativeTo = window;
|
||||||
|
colourPicker = new ColourPicker(this, window.Width - 128, 0, 128, window.Height);
|
||||||
|
colourPicker.RelativeTo = window;
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
{
|
||||||
|
if (MouseManager.MouseState == MouseState.None)
|
||||||
|
{
|
||||||
|
down = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolBox.SelectedTool.Run(
|
||||||
|
this,
|
||||||
|
canvas,
|
||||||
|
MouseManager.MouseState,
|
||||||
|
(int)(MouseManager.X - canvas.ScreenX),
|
||||||
|
(int)(MouseManager.Y - canvas.ScreenY)
|
||||||
|
);
|
||||||
|
|
||||||
|
wm.Update(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Gui/Apps/Paint/Tool.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using Cosmos.System;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint
|
||||||
|
{
|
||||||
|
internal abstract class Tool
|
||||||
|
{
|
||||||
|
internal Tool(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract void Run(Paint paint, Window canvas, MouseState mouseState, int mouseX, int mouseY);
|
||||||
|
|
||||||
|
internal virtual void Selected()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void Deselected()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string Name { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
60
Gui/Apps/Paint/ToolBox.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint
|
||||||
|
{
|
||||||
|
internal class ToolBox : Window
|
||||||
|
{
|
||||||
|
private Paint paintInstance;
|
||||||
|
|
||||||
|
private Table table;
|
||||||
|
|
||||||
|
internal Tool SelectedTool;
|
||||||
|
|
||||||
|
internal readonly List<Tool> Tools = new List<Tool>()
|
||||||
|
{
|
||||||
|
new Tools.Pencil(),
|
||||||
|
new Tools.CircleBrush()
|
||||||
|
};
|
||||||
|
|
||||||
|
private void TableClicked(int x, int y)
|
||||||
|
{
|
||||||
|
Tool tool = table.Cells[table.SelectedCellIndex].Tag as Tool;
|
||||||
|
|
||||||
|
if (tool != SelectedTool)
|
||||||
|
{
|
||||||
|
SelectedTool.Deselected();
|
||||||
|
SelectedTool = tool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ToolBox(Paint paint, int x, int y, int width, int height) : base(paint, x, y, width, height)
|
||||||
|
{
|
||||||
|
paintInstance = paint;
|
||||||
|
|
||||||
|
|
||||||
|
Clear(Color.FromArgb(107, 107, 107));
|
||||||
|
DrawString("Toolbox", Color.White, 8, 8);
|
||||||
|
|
||||||
|
table = new Table(this, 0, 32, Width, Height - 32);
|
||||||
|
table.AllowDeselection = false;
|
||||||
|
table.CellHeight = 24;
|
||||||
|
table.TextAlignment = Alignment.Middle;
|
||||||
|
table.OnClick = TableClicked;
|
||||||
|
|
||||||
|
foreach (Tool tool in Tools)
|
||||||
|
{
|
||||||
|
table.Cells.Add(new TableCell(tool.Name, tool));
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectedTool = Tools[0];
|
||||||
|
table.SelectedCellIndex = 0;
|
||||||
|
|
||||||
|
table.Render();
|
||||||
|
|
||||||
|
WM.AddWindow(this);
|
||||||
|
WM.AddWindow(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Gui/Apps/Paint/Tools/CircleBrush.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Cosmos.System;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint.Tools
|
||||||
|
{
|
||||||
|
internal class CircleBrush : Tool
|
||||||
|
{
|
||||||
|
public CircleBrush() : base("Circle brush")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Run(Paint paint, Window canvas, MouseState mouseState, int mouseX, int mouseY)
|
||||||
|
{
|
||||||
|
if (mouseState == MouseState.Left)
|
||||||
|
{
|
||||||
|
canvas.DrawCircle(mouseX, mouseY, 5, paint.SelectedColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
Gui/Apps/Paint/Tools/Pencil.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Cosmos.System;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.Paint.Tools
|
||||||
|
{
|
||||||
|
internal class Pencil : Tool
|
||||||
|
{
|
||||||
|
public Pencil() : base("Pencil")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool joinLine;
|
||||||
|
private int joinX;
|
||||||
|
private int joinY;
|
||||||
|
|
||||||
|
internal override void Run(Paint paint, Window canvas, MouseState mouseState, int mouseX, int mouseY)
|
||||||
|
{
|
||||||
|
if (mouseState == MouseState.Left)
|
||||||
|
{
|
||||||
|
if (joinLine)
|
||||||
|
{
|
||||||
|
canvas.DrawLine(joinX, joinY, mouseX, mouseY, paint.SelectedColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
canvas.DrawPoint(mouseX, mouseY, paint.SelectedColor);
|
||||||
|
}
|
||||||
|
joinLine = true;
|
||||||
|
joinX = mouseX;
|
||||||
|
joinY = mouseY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
joinLine = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Deselected()
|
||||||
|
{
|
||||||
|
joinLine = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
296
Gui/Apps/Settings.cs
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Settings : Process
|
||||||
|
{
|
||||||
|
internal Settings() : base("Settings", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Window currentCategoryWindow;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
SettingsService settingsService = ProcessManager.GetProcess<SettingsService>();
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Settings.User.bmp")]
|
||||||
|
private static byte[] _iconBytes_User;
|
||||||
|
internal static Bitmap Icon_User = new Bitmap(_iconBytes_User);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Settings.Admin.bmp")]
|
||||||
|
private static byte[] _iconBytes_Admin;
|
||||||
|
internal static Bitmap Icon_Admin = new Bitmap(_iconBytes_Admin);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Settings.Info.bmp")]
|
||||||
|
private static byte[] _iconBytes_Info;
|
||||||
|
internal static Bitmap Icon_Info = new Bitmap(_iconBytes_Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CategorySelected(int index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ShowAppearanceCategory();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ShowDisplayCategory();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ShowDateTimeCategory();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ShowUsersCategory();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ShowMouseCategory();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LeftStartButtonChanged(bool @checked)
|
||||||
|
{
|
||||||
|
settingsService.LeftHandStartButton = @checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TwelveHourClockChanged(bool @checked)
|
||||||
|
{
|
||||||
|
settingsService.TwelveHourClock = @checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowFpsChanged(bool @checked)
|
||||||
|
{
|
||||||
|
settingsService.ShowFps = @checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MouseSensitivityChanged(float value)
|
||||||
|
{
|
||||||
|
settingsService.MouseSensitivity = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowAppearanceCategory()
|
||||||
|
{
|
||||||
|
if (currentCategoryWindow != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(currentCategoryWindow);
|
||||||
|
}
|
||||||
|
Window appearance = new Window(this, window, 128, 0, window.Width - 128, window.Height);
|
||||||
|
currentCategoryWindow = appearance;
|
||||||
|
appearance.DrawString("Appearance Settings", Color.DarkBlue, 12, 12);
|
||||||
|
wm.AddWindow(appearance);
|
||||||
|
|
||||||
|
Switch leftStartButton = new Switch(appearance, 12, 40, 244, 16);
|
||||||
|
leftStartButton.Text = "Left-hand start button";
|
||||||
|
leftStartButton.Checked = settingsService.LeftHandStartButton;
|
||||||
|
leftStartButton.CheckBoxChanged = LeftStartButtonChanged;
|
||||||
|
wm.AddWindow(leftStartButton);
|
||||||
|
|
||||||
|
Switch showFps = new Switch(appearance, 12, 68, 244, 16);
|
||||||
|
showFps.Text = "Show frames per second";
|
||||||
|
showFps.Checked = settingsService.ShowFps;
|
||||||
|
showFps.CheckBoxChanged = ShowFpsChanged;
|
||||||
|
wm.AddWindow(showFps);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowDateTimeCategory()
|
||||||
|
{
|
||||||
|
if (currentCategoryWindow != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(currentCategoryWindow);
|
||||||
|
}
|
||||||
|
Window dateTime = new Window(this, window, 128, 0, window.Width - 128, window.Height);
|
||||||
|
currentCategoryWindow = dateTime;
|
||||||
|
dateTime.DrawString("Date & Time Settings", Color.DarkBlue, 12, 12);
|
||||||
|
wm.AddWindow(dateTime);
|
||||||
|
|
||||||
|
Switch twelveHourClock = new Switch(dateTime, 12, 40, 244, 16);
|
||||||
|
twelveHourClock.Text = "12-hour clock";
|
||||||
|
twelveHourClock.Checked = settingsService.TwelveHourClock;
|
||||||
|
twelveHourClock.CheckBoxChanged = TwelveHourClockChanged;
|
||||||
|
wm.AddWindow(twelveHourClock);
|
||||||
|
|
||||||
|
AppMetadata calendarApp = AppManager.GetAppMetadata("Calendar");
|
||||||
|
Button openCalendar = new Button(dateTime, 12, 68, 160, 20);
|
||||||
|
openCalendar.Text = "Open Calendar";
|
||||||
|
openCalendar.Image = calendarApp.Icon.Resize(20, 20);
|
||||||
|
openCalendar.ImageLocation = Button.ButtonImageLocation.Left;
|
||||||
|
openCalendar.OnClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
calendarApp.Start(wm);
|
||||||
|
};
|
||||||
|
wm.AddWindow(openCalendar);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowDisplayCategory()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (currentCategoryWindow != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(currentCategoryWindow);
|
||||||
|
}
|
||||||
|
Window display = new Window(this, window, 128, 0, window.Width - 128, window.Height);
|
||||||
|
currentCategoryWindow = display;
|
||||||
|
display.DrawString("Display Settings", Color.DarkBlue, 12, 12);
|
||||||
|
wm.AddWindow(display);
|
||||||
|
|
||||||
|
Table resolutionsTable = new Table(display, 12, 40, display.Width - 24, display.Height - 12 - 16 - 12 - 12 - 16 - 12);
|
||||||
|
resolutionsTable.AllowDeselection = false;
|
||||||
|
for (int i = 0; i < wm.AvailableModes.Count; i++)
|
||||||
|
{
|
||||||
|
Mode mode = wm.AvailableModes[i];
|
||||||
|
resolutionsTable.Cells.Add(new TableCell($"{mode.Width}x{mode.Height}"));
|
||||||
|
if (mode.Equals(settingsService.Mode))
|
||||||
|
{
|
||||||
|
resolutionsTable.SelectedCellIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolutionsTable.Render();
|
||||||
|
resolutionsTable.TableCellSelected = (int index) =>
|
||||||
|
{
|
||||||
|
Mode mode = wm.AvailableModes[index];
|
||||||
|
settingsService.Mode = mode;
|
||||||
|
settingsService.Flush();
|
||||||
|
|
||||||
|
MessageBox messageBox = new MessageBox(this, "Restart Required", "Restart your PC to apply changes.");
|
||||||
|
messageBox.Show();
|
||||||
|
};
|
||||||
|
wm.AddWindow(resolutionsTable);
|
||||||
|
|
||||||
|
display.DrawImageAlpha(Icons.Icon_Info, 12, window.Height - 16 - 12);
|
||||||
|
display.DrawString("Select a screen resolution.", Color.Gray, 36, window.Height - 16 - 12);
|
||||||
|
|
||||||
|
wm.AddWindow(display);
|
||||||
|
|
||||||
|
wm.Update(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowUsersCategory()
|
||||||
|
{
|
||||||
|
if (currentCategoryWindow != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(currentCategoryWindow);
|
||||||
|
}
|
||||||
|
Window users = new Window(this, window, 128, 0, window.Width - 128, window.Height);
|
||||||
|
currentCategoryWindow = users;
|
||||||
|
users.DrawString("Users", Color.DarkBlue, 12, 12);
|
||||||
|
users.DrawImageAlpha(Icons.Icon_Info, 12, window.Height - 16 - 12);
|
||||||
|
users.DrawString("Double-click on a user for info.", Color.Gray, 36, window.Height - 16 - 12);
|
||||||
|
wm.AddWindow(users);
|
||||||
|
|
||||||
|
Table usersTable = new Table(users, 12, 40, users.Width - 24, users.Height - 40 - 12 - 16 - 12);
|
||||||
|
foreach (User user in UserSystem.GetUsers())
|
||||||
|
{
|
||||||
|
usersTable.Cells.Add(new TableCell(user.Admin ? Icons.Icon_Admin : Icons.Icon_User, user.Username, tag: user));
|
||||||
|
}
|
||||||
|
usersTable.OnDoubleClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
if (usersTable.SelectedCellIndex != -1)
|
||||||
|
{
|
||||||
|
User user = (User)usersTable.Cells[usersTable.SelectedCellIndex].Tag;
|
||||||
|
|
||||||
|
AppWindow userDetail = new AppWindow(this, 256, 256, 256, 192);
|
||||||
|
userDetail.Title = user.Username;
|
||||||
|
wm.AddWindow(userDetail);
|
||||||
|
|
||||||
|
userDetail.DrawFilledRectangle(0, 0, userDetail.Width, 40, Color.DarkBlue);
|
||||||
|
userDetail.DrawImageAlpha(user.Admin ? Icons.Icon_Admin : Icons.Icon_User, 12, 12);
|
||||||
|
userDetail.DrawString($"User: {user.Username}", Color.White, 36, 12);
|
||||||
|
|
||||||
|
userDetail.DrawString($"Role: {(user.Admin ? "Admin" : "User")}", Color.Black, 12, 48);
|
||||||
|
userDetail.DrawString($"Unread messages: {user.Messages.Count}", Color.Black, 12, 76);
|
||||||
|
|
||||||
|
Button ok = new Button(userDetail, userDetail.Width - 80 - 12, userDetail.Height - 20 - 12, 80, 20);
|
||||||
|
ok.Text = "OK";
|
||||||
|
ok.OnClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(userDetail);
|
||||||
|
};
|
||||||
|
wm.AddWindow(ok);
|
||||||
|
|
||||||
|
wm.Update(userDetail);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
usersTable.Render();
|
||||||
|
wm.AddWindow(usersTable);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowMouseCategory()
|
||||||
|
{
|
||||||
|
if (currentCategoryWindow != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(currentCategoryWindow);
|
||||||
|
}
|
||||||
|
Window mouse = new Window(this, window, 128, 0, window.Width - 128, window.Height);
|
||||||
|
currentCategoryWindow = mouse;
|
||||||
|
mouse.DrawString("Mouse Settings", Color.DarkBlue, 12, 12);
|
||||||
|
wm.AddWindow(mouse);
|
||||||
|
|
||||||
|
mouse.DrawString("Mouse sensitivity", Color.Gray, 12, 40);
|
||||||
|
|
||||||
|
RangeSlider mouseSensitivity = new RangeSlider(mouse, 12, 68, 244, 30, min: 0.25f, value: settingsService.MouseSensitivity, max: 2f);
|
||||||
|
mouseSensitivity.Changed = MouseSensitivityChanged;
|
||||||
|
wm.AddWindow(mouseSensitivity);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Process
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 448, 272);
|
||||||
|
window.Closing = TryStop;
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Settings").Icon;
|
||||||
|
wm.AddWindow(window);
|
||||||
|
|
||||||
|
window.Title = "Settings";
|
||||||
|
|
||||||
|
Table categoryTable = new Table(window, 0, 0, 128, window.Height);
|
||||||
|
|
||||||
|
categoryTable.TextAlignment = Alignment.Middle;
|
||||||
|
|
||||||
|
categoryTable.TableCellSelected = CategorySelected;
|
||||||
|
categoryTable.SelectedCellIndex = 0;
|
||||||
|
categoryTable.AllowDeselection = false;
|
||||||
|
|
||||||
|
categoryTable.CellHeight = 24;
|
||||||
|
|
||||||
|
/*categoryTable.Border = categoryTable.Background;
|
||||||
|
categoryTable.SelectedBorder = categoryTable.SelectedBackground;*/
|
||||||
|
|
||||||
|
categoryTable.Cells.Add(new TableCell("Appearance"));
|
||||||
|
categoryTable.Cells.Add(new TableCell("Display"));
|
||||||
|
categoryTable.Cells.Add(new TableCell("Date & Time"));
|
||||||
|
categoryTable.Cells.Add(new TableCell("Users"));
|
||||||
|
categoryTable.Cells.Add(new TableCell("Mouse"));
|
||||||
|
|
||||||
|
categoryTable.Render();
|
||||||
|
|
||||||
|
wm.AddWindow(categoryTable);
|
||||||
|
|
||||||
|
ShowAppearanceCategory();
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
161
Gui/Apps/Stopwatch.cs
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.SmoothMono;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Stopwatch : Process
|
||||||
|
{
|
||||||
|
internal Stopwatch() : base("Stopwatch", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Button startStopButton;
|
||||||
|
|
||||||
|
Button lapResetButton;
|
||||||
|
|
||||||
|
Table lapTable;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
private const string format = @"hh\:mm\:ss";
|
||||||
|
|
||||||
|
private readonly Color background = Color.FromArgb(56, 56, 71);
|
||||||
|
|
||||||
|
private bool stopwatchRunning = false;
|
||||||
|
|
||||||
|
DateTime startTime;
|
||||||
|
DateTime lastLap;
|
||||||
|
TimeSpan elapsed = TimeSpan.Zero;
|
||||||
|
int lastSecond;
|
||||||
|
|
||||||
|
private void UpdateWindow()
|
||||||
|
{
|
||||||
|
window.Clear(background);
|
||||||
|
|
||||||
|
string text;
|
||||||
|
text = elapsed.ToString(format);
|
||||||
|
window.DrawString(text, System.Drawing.Color.White, (window.Width / 2) - ((text.Length * FontData.Width) / 2), 8);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartStopwatch()
|
||||||
|
{
|
||||||
|
if (stopwatchRunning) return;
|
||||||
|
|
||||||
|
stopwatchRunning = true;
|
||||||
|
startTime = DateTime.Now;
|
||||||
|
lastLap = startTime;
|
||||||
|
lastSecond = startTime.Second;
|
||||||
|
|
||||||
|
startStopButton.Text = "Stop";
|
||||||
|
lapResetButton.Text = "Lap";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopStopwatch()
|
||||||
|
{
|
||||||
|
if (!stopwatchRunning) return;
|
||||||
|
|
||||||
|
stopwatchRunning = false;
|
||||||
|
UpdateWindow();
|
||||||
|
|
||||||
|
startStopButton.Text = "Start";
|
||||||
|
lapResetButton.Text = "Reset";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Lap()
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
|
TableCell cell = new TableCell((now - lastLap).ToString(format));
|
||||||
|
lapTable.Cells.Add(cell);
|
||||||
|
lapTable.ScrollToBottom();
|
||||||
|
lapTable.Render();
|
||||||
|
wm.Update(lapTable);
|
||||||
|
|
||||||
|
lastLap = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
elapsed = TimeSpan.Zero;
|
||||||
|
|
||||||
|
lapTable.Cells.Clear();
|
||||||
|
lapTable.Render();
|
||||||
|
wm.Update(lapTable);
|
||||||
|
|
||||||
|
UpdateWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 160, 160);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Stopwatch";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Stopwatch").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
startStopButton = new Button(window, window.Width / 2, window.Height - 24, window.Width / 2, 24);
|
||||||
|
startStopButton.Text = "Start";
|
||||||
|
startStopButton.OnClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
if (stopwatchRunning)
|
||||||
|
{
|
||||||
|
StopStopwatch();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartStopwatch();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wm.AddWindow(startStopButton);
|
||||||
|
|
||||||
|
lapResetButton = new Button(window, 0, window.Height - 24, window.Width / 2, 24);
|
||||||
|
lapResetButton.Text = "Reset";
|
||||||
|
lapResetButton.OnClick = (int x, int y) =>
|
||||||
|
{
|
||||||
|
if (stopwatchRunning)
|
||||||
|
{
|
||||||
|
Lap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wm.AddWindow(lapResetButton);
|
||||||
|
|
||||||
|
int lapTableY = 8 + FontData.Height + 8;
|
||||||
|
lapTable = new Table(window, 0, lapTableY, window.Width, window.Height - lapTableY - 24);
|
||||||
|
lapTable.Background = Color.FromArgb(80, 80, 102);
|
||||||
|
lapTable.Border = background;
|
||||||
|
lapTable.Foreground = Color.FromArgb(185, 185, 234);
|
||||||
|
lapTable.TextAlignment = Alignment.Middle;
|
||||||
|
lapTable.AllowSelection = false;
|
||||||
|
lapTable.CellHeight = 20;
|
||||||
|
lapTable.ScrollbarThickness = 15;
|
||||||
|
lapTable.Render();
|
||||||
|
wm.AddWindow(lapTable);
|
||||||
|
|
||||||
|
UpdateWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
int second = DateTime.Now.Second;
|
||||||
|
if (lastSecond != second)
|
||||||
|
{
|
||||||
|
lastSecond = second;
|
||||||
|
if (stopwatchRunning)
|
||||||
|
{
|
||||||
|
elapsed = DateTime.Now - startTime;
|
||||||
|
}
|
||||||
|
UpdateWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
82
Gui/Apps/Tasks.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps
|
||||||
|
{
|
||||||
|
internal class Tasks : Process
|
||||||
|
{
|
||||||
|
internal Tasks() : base("Tasks", ProcessType.Application) { }
|
||||||
|
|
||||||
|
AppWindow window;
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
|
int lastSecond = DateTime.Now.Second;
|
||||||
|
|
||||||
|
private void PopulateTable()
|
||||||
|
{
|
||||||
|
table.Cells.Clear();
|
||||||
|
foreach (Process process in ProcessManager.Processes)
|
||||||
|
{
|
||||||
|
table.Cells.Add(new TableCell(process.Name));
|
||||||
|
}
|
||||||
|
table.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndTaskClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (table.SelectedCellIndex != -1 && table.SelectedCellIndex < ProcessManager.Processes.Count)
|
||||||
|
{
|
||||||
|
if (UserSystem.CurrentLoggedInUser == null || !UserSystem.CurrentLoggedInUser.Admin)
|
||||||
|
{
|
||||||
|
MessageBox messageBox = new MessageBox(this, Name, "You must be an admin to end tasks.");
|
||||||
|
messageBox.Show();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessManager.Processes[table.SelectedCellIndex].TryStop();
|
||||||
|
ProcessManager.Sweep();
|
||||||
|
table.SelectedCellIndex = -1;
|
||||||
|
PopulateTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
window = new AppWindow(this, 256, 256, 384, 256);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
window.Title = "Tasks";
|
||||||
|
window.Icon = AppManager.GetAppMetadata("Tasks").Icon;
|
||||||
|
window.Closing = TryStop;
|
||||||
|
|
||||||
|
window.Clear(Color.Gray);
|
||||||
|
|
||||||
|
table = new Table(window, 12, 12, window.Width - 24, window.Height - 24 - 20 - 12);
|
||||||
|
PopulateTable();
|
||||||
|
wm.AddWindow(table);
|
||||||
|
|
||||||
|
Button endTask = new Button(window, window.Width - 100 - 12, window.Height - 20 - 12, 100, 20);
|
||||||
|
endTask.Text = "End Task";
|
||||||
|
endTask.OnClick = EndTaskClicked;
|
||||||
|
wm.AddWindow(endTask);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
if (lastSecond != now.Second)
|
||||||
|
{
|
||||||
|
PopulateTable();
|
||||||
|
lastSecond = now.Second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Gui/Asc16.cs
Normal file
49
Gui/BitmapExtensions.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui
|
||||||
|
{
|
||||||
|
internal static class BitmapExtensions
|
||||||
|
{
|
||||||
|
internal static Bitmap Resize(this Bitmap bmp, uint width, uint height)
|
||||||
|
{
|
||||||
|
if (bmp.Width == width && bmp.Height == height)
|
||||||
|
{
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bmp.Depth != ColorDepth.ColorDepth32)
|
||||||
|
{
|
||||||
|
throw new Exception("Resize can only resize images with a colour depth of 32.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap res = new Bitmap(width, height, ColorDepth.ColorDepth32);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
double xDouble = (double)x / (double)width;
|
||||||
|
double yDouble = (double)y / (double)height;
|
||||||
|
|
||||||
|
uint origX = (uint)((double)bmp.Width * xDouble);
|
||||||
|
uint origY = (uint)((double)bmp.Height * yDouble);
|
||||||
|
|
||||||
|
res.RawData[y * width + x] = bmp.RawData[(origY * bmp.Width) + origX];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap ResizeWidthKeepRatio(this Bitmap bmp, uint width)
|
||||||
|
{
|
||||||
|
return Resize(bmp, width, (uint)((double)bmp.Height * ((double)width / (double)bmp.Width)));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap ResizeHeightKeepRatio(this Bitmap bmp, uint height)
|
||||||
|
{
|
||||||
|
return Resize(bmp, (uint)((double)bmp.Width * ((double)height / (double)bmp.Height)), height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Gui/CursorType.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace CMLeonOS.Gui
|
||||||
|
{
|
||||||
|
internal enum CursorType
|
||||||
|
{
|
||||||
|
Cursor,
|
||||||
|
WaitCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
77
Gui/Gui.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Logger;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui
|
||||||
|
{
|
||||||
|
internal static class Gui
|
||||||
|
{
|
||||||
|
private static bool guiRunning = false;
|
||||||
|
private static WindowManager windowManager;
|
||||||
|
|
||||||
|
internal static bool StartGui()
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
|
||||||
|
windowManager = new WindowManager();
|
||||||
|
|
||||||
|
Logger.Logger.Instance.Info("Gui", "GUI starting.");
|
||||||
|
|
||||||
|
if (Cosmos.Core.CPU.GetAmountOfRAM() < 1000)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("Not enough system memory is available to run the GUI.");
|
||||||
|
Console.WriteLine("At least 1 GB should be allocated.");
|
||||||
|
Console.ResetColor();
|
||||||
|
Console.Write("Continue anyway? [y/N]");
|
||||||
|
|
||||||
|
if (Console.ReadKey(true).Key != ConsoleKey.Y)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Loading apps...");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
AppManager.LoadAllApps();
|
||||||
|
|
||||||
|
ProcessManager.AddProcess(windowManager);
|
||||||
|
|
||||||
|
ProcessManager.AddProcess(windowManager, new SettingsService()).Start();
|
||||||
|
|
||||||
|
windowManager.Start();
|
||||||
|
|
||||||
|
ProcessManager.AddProcess(windowManager, new Sound.SoundService()).Start();
|
||||||
|
|
||||||
|
Console.WriteLine("Starting lock screen...");
|
||||||
|
ProcessManager.AddProcess(windowManager, new ShellComponents.Lock()).Start();
|
||||||
|
|
||||||
|
guiRunning = true;
|
||||||
|
|
||||||
|
// 进入 GUI 事件循环
|
||||||
|
RunGuiLoop();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RunGuiLoop()
|
||||||
|
{
|
||||||
|
while (guiRunning)
|
||||||
|
{
|
||||||
|
ProcessManager.Yield();
|
||||||
|
System.Threading.Thread.Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void StopGui()
|
||||||
|
{
|
||||||
|
guiRunning = false;
|
||||||
|
if (windowManager != null)
|
||||||
|
{
|
||||||
|
windowManager.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Gui/Resources/AppIcons/Calculator.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Calendar.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Clock.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/CodeStudio.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Default.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/DemoLauncher.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Demos/Mandelbrot.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Demos/Starfield.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Files.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Info.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Logs.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/MemoryStatistics.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Notepad.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Paint.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Settings.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Stopwatch.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/AppIcons/Tasks.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/ButtonBackground.bmp
Normal file
|
After Width: | Height: | Size: 230 B |
BIN
Gui/Resources/Calculator/Display.bmp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
Gui/Resources/Calculator/GridButton.bmp
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
Gui/Resources/Check.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Clock/ClockBackground.bmp
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
Gui/Resources/Close.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Close_aero.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Close_flat.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/CodeStudio/Run.bmp
Normal file
|
After Width: | Height: | Size: 930 B |
BIN
Gui/Resources/CodeStudio/Splash.bmp
Normal file
|
After Width: | Height: | Size: 627 KiB |
BIN
Gui/Resources/Cursor.bmp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Gui/Resources/Cursor_noshadow.bmp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Gui/Resources/Dock/StartMenu.bmp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Gui/Resources/Files/Directory.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/Drive.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/File.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/File_Config.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/File_Rs.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/File_Text.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/Home.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Files/Up.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Lock/Background.bmp
Normal file
|
After Width: | Height: | Size: 648 KiB |
BIN
Gui/Resources/Lock/Background_small.bmp
Normal file
|
After Width: | Height: | Size: 390 KiB |
BIN
Gui/Resources/Lock/Gradient.bmp
Normal file
|
After Width: | Height: | Size: 662 B |
BIN
Gui/Resources/Lock/Key.bmp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Gui/Resources/Lock/ShutDown.bmp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Gui/Resources/Lock/User.bmp
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
Gui/Resources/Lock/UserArrow.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Logs/Error.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Logs/Info.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Logs/Warning.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Maximise.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Maximise_aero.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Maximise_flat.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Minimise.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Minimise_aero.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Minimise_flat.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Restore.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Restore_aero.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/Restore_flat.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/ScrollbarDown.bmp
Normal file
|
After Width: | Height: | Size: 390 B |
BIN
Gui/Resources/ScrollbarUp.bmp
Normal file
|
After Width: | Height: | Size: 390 B |
BIN
Gui/Resources/Settings/Admin.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Settings/Info.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Settings/User.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/Sounds/Alert.wav
Normal file
BIN
Gui/Resources/Sounds/Login.wav
Normal file
BIN
Gui/Resources/Start.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/StartMenu/User.bmp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Gui/Resources/Start_old.bmp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Gui/Resources/SwitchKnob.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Gui/Resources/SwitchOff.bmp
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Gui/Resources/SwitchOn.bmp
Normal file
|
After Width: | Height: | Size: 2.1 KiB |