mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-03-03 15:30:27 +00:00
GUI桌面环境
This commit is contained in:
22
Gui/ShellComponents/Dock/AppDockIcon.cs
Normal file
22
Gui/ShellComponents/Dock/AppDockIcon.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using CMLeonOS;
|
||||
using CMLeonOS.Gui.UILib;
|
||||
|
||||
namespace CMLeonOS.Gui.ShellComponents.Dock
|
||||
{
|
||||
internal class AppDockIcon : BaseDockIcon
|
||||
{
|
||||
internal AppDockIcon(AppWindow appWindow) : base(
|
||||
image: appWindow.Icon,
|
||||
doAnimation: true)
|
||||
{
|
||||
AppWindow = appWindow;
|
||||
}
|
||||
|
||||
internal AppWindow AppWindow { get; init; }
|
||||
|
||||
internal override void Clicked()
|
||||
{
|
||||
ProcessManager.GetProcess<WindowManager>().Focus = AppWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Gui/ShellComponents/Dock/BaseDockIcon.cs
Normal file
82
Gui/ShellComponents/Dock/BaseDockIcon.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using Cosmos.System.Graphics;
|
||||
|
||||
namespace CMLeonOS.Gui.ShellComponents.Dock
|
||||
{
|
||||
internal abstract class BaseDockIcon
|
||||
{
|
||||
internal BaseDockIcon(Bitmap image, bool doAnimation = true)
|
||||
{
|
||||
if (doAnimation)
|
||||
{
|
||||
Size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip to the end of the animation.
|
||||
Size = Dock.IconSize;
|
||||
}
|
||||
|
||||
Image = image;
|
||||
}
|
||||
|
||||
private double _size;
|
||||
internal double Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
set
|
||||
{
|
||||
_size = value;
|
||||
|
||||
if (_image != null)
|
||||
{
|
||||
SizedImage = _image.ResizeWidthKeepRatio((uint)Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap _image;
|
||||
internal Bitmap Image
|
||||
{
|
||||
get
|
||||
{
|
||||
return _image;
|
||||
}
|
||||
set
|
||||
{
|
||||
_image = value;
|
||||
SizedImage = value.ResizeWidthKeepRatio((uint)Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal Bitmap SizedImage { get; private set; }
|
||||
|
||||
internal bool Closing { get; set; } = false;
|
||||
|
||||
internal bool CloseAnimationComplete
|
||||
{
|
||||
get
|
||||
{
|
||||
return Closing && (int)_size == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run the dock icon's animation.
|
||||
/// </summary>
|
||||
/// <returns>If the dock needs to be rerendered.</returns>
|
||||
internal bool RunAnimation()
|
||||
{
|
||||
int oldSize = (int)Size;
|
||||
int goalSize = Closing ? 1 : Dock.IconSize;
|
||||
Size += (goalSize - Size) / 16;
|
||||
|
||||
return (int)Size != (int)oldSize;
|
||||
}
|
||||
|
||||
internal abstract void Clicked();
|
||||
}
|
||||
}
|
||||
190
Gui/ShellComponents/Dock/Dock.cs
Normal file
190
Gui/ShellComponents/Dock/Dock.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using Cosmos.System.Graphics;
|
||||
using CMLeonOS;
|
||||
using CMLeonOS.Gui.UILib;
|
||||
using CMLeonOS.UILib.Animations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CMLeonOS.Gui.ShellComponents.Dock
|
||||
{
|
||||
internal class Dock : Process
|
||||
{
|
||||
internal Dock() : base("Dock", ProcessType.Application)
|
||||
{
|
||||
}
|
||||
|
||||
internal static Dock CurrentDock
|
||||
{
|
||||
get
|
||||
{
|
||||
Dock dock = ProcessManager.GetProcess<Dock>();
|
||||
return dock;
|
||||
}
|
||||
}
|
||||
|
||||
Window window;
|
||||
|
||||
List<BaseDockIcon> Icons = new List<BaseDockIcon>();
|
||||
|
||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||
|
||||
SettingsService settingsService = ProcessManager.GetProcess<SettingsService>();
|
||||
|
||||
internal static readonly int IconSize = 64;
|
||||
internal static readonly int IconImageMaxSize = 48;
|
||||
|
||||
private void Render()
|
||||
{
|
||||
int newDockWidth = 0;
|
||||
foreach (var icon in Icons)
|
||||
{
|
||||
newDockWidth += (int)icon.Size;
|
||||
}
|
||||
|
||||
if (newDockWidth != window.Width)
|
||||
{
|
||||
window.MoveAndResize((int)(wm.ScreenWidth / 2 - newDockWidth / 2), window.Y, newDockWidth, window.Height);
|
||||
}
|
||||
|
||||
window.Clear(Color.FromArgb(130, 202, 255));
|
||||
|
||||
int x = 0;
|
||||
foreach (var icon in Icons)
|
||||
{
|
||||
if (icon.Image != null)
|
||||
{
|
||||
Bitmap resizedImage = icon.Image.ResizeWidthKeepRatio((uint)Math.Min(IconImageMaxSize, icon.Size));
|
||||
|
||||
int imageX = (int)(x + ((icon.Size / 2) - (resizedImage.Width / 2)));
|
||||
window.DrawImageAlpha(resizedImage, imageX, (int)((window.Height / 2) - (resizedImage.Height / 2)));
|
||||
}
|
||||
|
||||
x += (int)icon.Size;
|
||||
}
|
||||
|
||||
wm.Update(window);
|
||||
}
|
||||
|
||||
internal int GetDockHeight()
|
||||
{
|
||||
return window.Height;
|
||||
}
|
||||
|
||||
internal void UpdateWindows()
|
||||
{
|
||||
// Add new windows and update icons.
|
||||
foreach (var window in wm.Windows)
|
||||
{
|
||||
if (window is not AppWindow appWindow)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
foreach (BaseDockIcon icon in Icons)
|
||||
{
|
||||
if (icon is AppDockIcon appDockIcon && appDockIcon.AppWindow == appWindow)
|
||||
{
|
||||
icon.Image = appWindow.Icon;
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
Icons.Add(new AppDockIcon(appWindow));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove deleted windows.
|
||||
foreach (BaseDockIcon icon in Icons)
|
||||
{
|
||||
if (icon is not AppDockIcon appDockIcon)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
foreach (Window window in wm.Windows)
|
||||
{
|
||||
if (window == appDockIcon.AppWindow)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
icon.Closing = true;
|
||||
}
|
||||
}
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
private void DockClick(int x, int y)
|
||||
{
|
||||
int end = 0;
|
||||
foreach (var icon in Icons)
|
||||
{
|
||||
end += (int)icon.Size;
|
||||
|
||||
if (x < end)
|
||||
{
|
||||
icon.Clicked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
window = new Window(this, (int)(wm.ScreenWidth / 2), (int)(wm.ScreenHeight + IconSize), IconSize, IconSize);
|
||||
window.OnClick = DockClick;
|
||||
wm.AddWindow(window);
|
||||
|
||||
Icons.Add(new StartMenuDockIcon());
|
||||
|
||||
Render();
|
||||
|
||||
MovementAnimation animation = new MovementAnimation(window)
|
||||
{
|
||||
From = new Rectangle(window.X, window.Y, window.Width, window.Height),
|
||||
To = new Rectangle(window.X, (int)(wm.ScreenHeight - IconSize), window.Width, window.Height),
|
||||
Duration = 10
|
||||
};
|
||||
animation.Start();
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
bool rerenderNeeded = false;
|
||||
|
||||
for (int i = Icons.Count - 1; i >= 0; i--)
|
||||
{
|
||||
BaseDockIcon icon = Icons[i];
|
||||
|
||||
if (icon.RunAnimation())
|
||||
{
|
||||
rerenderNeeded = true;
|
||||
}
|
||||
|
||||
if (icon.CloseAnimationComplete)
|
||||
{
|
||||
Icons.Remove(icon);
|
||||
}
|
||||
}
|
||||
|
||||
if (rerenderNeeded)
|
||||
{
|
||||
Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Gui/ShellComponents/Dock/StartMenuDockIcon.cs
Normal file
22
Gui/ShellComponents/Dock/StartMenuDockIcon.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Cosmos.System.Graphics;
|
||||
|
||||
namespace CMLeonOS.Gui.ShellComponents.Dock
|
||||
{
|
||||
internal class StartMenuDockIcon : BaseDockIcon
|
||||
{
|
||||
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Dock.StartMenu.bmp")]
|
||||
private static byte[] _iconBytes_StartMenu;
|
||||
internal static Bitmap Icon_StartMenu = new Bitmap(_iconBytes_StartMenu);
|
||||
|
||||
internal StartMenuDockIcon() : base(
|
||||
image: Icon_StartMenu,
|
||||
doAnimation: false)
|
||||
{
|
||||
}
|
||||
|
||||
internal override void Clicked()
|
||||
{
|
||||
StartMenu.CurrentStartMenu.ToggleStartMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user