2017-07-02 13:31:39 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
|
|
using ShiftOS.Engine;
|
|
|
|
|
using ShiftOS.Frontend.Desktop;
|
2017-07-02 21:48:10 -04:00
|
|
|
|
using ShiftOS.Frontend.GUI;
|
2017-07-02 13:31:39 -04:00
|
|
|
|
|
|
|
|
|
namespace ShiftOS.Frontend.GraphicsSubsystem
|
|
|
|
|
{
|
|
|
|
|
public static class UIManager
|
|
|
|
|
{
|
|
|
|
|
private static List<GUI.Control> topLevels = new List<GUI.Control>();
|
|
|
|
|
|
2017-07-02 21:48:10 -04:00
|
|
|
|
public static GUI.Control FocusedControl = null;
|
|
|
|
|
|
|
|
|
|
public static void LayoutUpdate()
|
|
|
|
|
{
|
|
|
|
|
foreach (var toplevel in topLevels)
|
|
|
|
|
toplevel.Layout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Animate(object owner, System.Reflection.PropertyInfo prop, double from, double to, int timeMs)
|
|
|
|
|
{
|
|
|
|
|
var t = new System.Threading.Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < timeMs; i++)
|
|
|
|
|
{
|
|
|
|
|
double value = ProgressBar.linear(i, 0, timeMs, from, to);
|
|
|
|
|
prop.SetValue(owner, value);
|
|
|
|
|
System.Threading.Thread.Sleep(1);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
t.IsBackground = true;
|
|
|
|
|
t.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-07-02 13:31:39 -04:00
|
|
|
|
public static void DrawControls(GraphicsDevice graphics, SpriteBatch batch)
|
|
|
|
|
{
|
2017-07-03 11:29:54 -04:00
|
|
|
|
foreach (var ctrl in topLevels.ToArray())
|
2017-07-02 13:31:39 -04:00
|
|
|
|
{
|
|
|
|
|
using(var bmp = new System.Drawing.Bitmap(ctrl.Width, ctrl.Height))
|
|
|
|
|
{
|
|
|
|
|
var gfx = System.Drawing.Graphics.FromImage(bmp);
|
|
|
|
|
ctrl.Paint(gfx);
|
2017-07-02 21:48:10 -04:00
|
|
|
|
bmp.SetOpacity((float)ctrl.Opacity);
|
2017-07-02 13:31:39 -04:00
|
|
|
|
//get the bits of the bitmap
|
|
|
|
|
var data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
|
byte[] rgb = new byte[Math.Abs(data.Stride) * data.Height];
|
|
|
|
|
Marshal.Copy(data.Scan0, rgb, 0, rgb.Length);
|
|
|
|
|
bmp.UnlockBits(data);
|
2017-07-02 21:48:10 -04:00
|
|
|
|
for(int i = 0; i < rgb.Length; i+=4)
|
|
|
|
|
{
|
|
|
|
|
byte r = rgb[i];
|
|
|
|
|
byte b = rgb[i + 2];
|
|
|
|
|
rgb[i] = b;
|
|
|
|
|
rgb[i + 2] = r;
|
|
|
|
|
}
|
2017-07-02 13:31:39 -04:00
|
|
|
|
var tex2 = new Texture2D(graphics, bmp.Width, bmp.Height);
|
|
|
|
|
tex2.SetData<byte>(rgb);
|
|
|
|
|
batch.Draw(tex2, new Rectangle(ctrl.X, ctrl.Y, ctrl.Width, ctrl.Height), Color.White);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void AddTopLevel(GUI.Control ctrl)
|
|
|
|
|
{
|
|
|
|
|
if (!topLevels.Contains(ctrl))
|
|
|
|
|
topLevels.Add(ctrl);
|
2017-07-02 21:48:10 -04:00
|
|
|
|
ctrl.Layout();
|
2017-07-02 13:31:39 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void ProcessMouseState(MouseState state)
|
|
|
|
|
{
|
2017-07-03 08:55:21 -04:00
|
|
|
|
foreach(var ctrl in topLevels.ToArray())
|
2017-07-02 13:31:39 -04:00
|
|
|
|
{
|
2017-07-02 21:48:10 -04:00
|
|
|
|
ctrl.ProcessMouseState(state);
|
2017-07-02 13:31:39 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-02 21:48:10 -04:00
|
|
|
|
public static void ProcessKeyEvent(KeyEvent e)
|
|
|
|
|
{
|
|
|
|
|
FocusedControl?.ProcessKeyEvent(e);
|
|
|
|
|
}
|
2017-07-02 13:31:39 -04:00
|
|
|
|
|
|
|
|
|
public static void DrawBackgroundLayer(GraphicsDevice graphics, SpriteBatch batch, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
if (SkinEngine.LoadedSkin == null)
|
|
|
|
|
SkinEngine.Init();
|
|
|
|
|
graphics.Clear(SkinEngine.LoadedSkin.DesktopColor.ToMonoColor());
|
|
|
|
|
var desktopbg = SkinEngine.GetImage("desktopbackground");
|
|
|
|
|
if(desktopbg != null)
|
|
|
|
|
{
|
|
|
|
|
var tex2 = new Texture2D(graphics, desktopbg.Width, desktopbg.Height);
|
|
|
|
|
tex2.SetData<byte>(SkinEngine.LoadedSkin.DesktopBackgroundImage);
|
|
|
|
|
batch.Draw(tex2, new Rectangle(0, 0, width, height), Color.White);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Color ToMonoColor(this System.Drawing.Color color)
|
|
|
|
|
{
|
|
|
|
|
return new Color(color.R, color.G, color.B, color.A);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void StopHandling(GUI.Control ctrl)
|
|
|
|
|
{
|
|
|
|
|
if (topLevels.Contains(ctrl))
|
|
|
|
|
topLevels.Remove(ctrl);
|
|
|
|
|
ctrl = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-02 21:48:10 -04:00
|
|
|
|
|
|
|
|
|
public class KeyEvent
|
|
|
|
|
{
|
|
|
|
|
public KeyEvent(bool control, bool alt, bool shift, Keys key)
|
|
|
|
|
{
|
|
|
|
|
ControlDown = control;
|
|
|
|
|
AltDown = alt;
|
|
|
|
|
ShiftDown = shift;
|
|
|
|
|
Key = key;
|
|
|
|
|
KeyChar = key.ToCharacter(shift);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool ControlDown { get; private set; }
|
|
|
|
|
public bool AltDown { get; private set; }
|
|
|
|
|
public bool ShiftDown { get; set; }
|
|
|
|
|
public Keys Key { get; private set; }
|
|
|
|
|
|
|
|
|
|
public char KeyChar { get; private set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class KeysExtensions
|
|
|
|
|
{
|
|
|
|
|
public static char ToCharacter(this Keys key, bool shift)
|
|
|
|
|
{
|
|
|
|
|
char c = ' ';
|
|
|
|
|
switch (key)
|
|
|
|
|
{
|
|
|
|
|
case Keys.Space:
|
|
|
|
|
c = ' ';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.A:
|
|
|
|
|
c = 'a';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.B:
|
|
|
|
|
c = 'b';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.C:
|
|
|
|
|
c = 'c';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D:
|
|
|
|
|
c = 'd';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.E:
|
|
|
|
|
c = 'e';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.F:
|
|
|
|
|
c = 'f';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.G:
|
|
|
|
|
c = 'g';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.H:
|
|
|
|
|
c = 'h';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.I:
|
|
|
|
|
c = 'i';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.J:
|
|
|
|
|
c = 'j';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.K:
|
|
|
|
|
c = 'k';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.L:
|
|
|
|
|
c = 'l';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.M:
|
|
|
|
|
c = 'm';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.N:
|
|
|
|
|
c = 'n';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.O:
|
|
|
|
|
c = 'o';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.P:
|
|
|
|
|
c = 'p';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.Q:
|
|
|
|
|
c = 'q';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.R:
|
|
|
|
|
c = 'r';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.S:
|
|
|
|
|
c = 's';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.T:
|
|
|
|
|
c = 't';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.U:
|
|
|
|
|
c = 'u';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.V:
|
|
|
|
|
c = 'v';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.W:
|
|
|
|
|
c = 'w';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.X:
|
|
|
|
|
c = 'x';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.Y:
|
|
|
|
|
c = 'y';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.Z:
|
|
|
|
|
c = 'z';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D0:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = ')';
|
|
|
|
|
else
|
|
|
|
|
c = '0';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D1:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '!';
|
|
|
|
|
else
|
|
|
|
|
c = '1';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D2:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '@';
|
|
|
|
|
else
|
|
|
|
|
c = '2';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D3:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '#';
|
|
|
|
|
else
|
|
|
|
|
c = '3';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D4:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '$';
|
|
|
|
|
else
|
|
|
|
|
c = '4';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D5:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '%';
|
|
|
|
|
else
|
|
|
|
|
c = '5';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D6:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '^';
|
|
|
|
|
else
|
|
|
|
|
c = '6';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D7:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '&';
|
|
|
|
|
else
|
|
|
|
|
c = '7';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D8:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '*';
|
|
|
|
|
else
|
|
|
|
|
c = '8';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.D9:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '(';
|
|
|
|
|
else
|
|
|
|
|
c = '9';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemBackslash:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '|';
|
|
|
|
|
else
|
|
|
|
|
c = '\\';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemCloseBrackets:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '}';
|
|
|
|
|
else
|
|
|
|
|
c = ']';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemComma:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '<';
|
|
|
|
|
else
|
|
|
|
|
c = ',';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemPeriod:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '>';
|
|
|
|
|
else
|
|
|
|
|
c = '.';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemQuestion:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '?';
|
|
|
|
|
else
|
|
|
|
|
c = '/';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemSemicolon:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = ':';
|
|
|
|
|
else
|
|
|
|
|
c = ';';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemQuotes:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '"';
|
|
|
|
|
else
|
|
|
|
|
c = '\'';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemTilde:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '~';
|
|
|
|
|
else
|
|
|
|
|
c = '`';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemMinus:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '_';
|
|
|
|
|
else
|
|
|
|
|
c = '-';
|
|
|
|
|
break;
|
|
|
|
|
case Keys.OemPlus:
|
|
|
|
|
if (shift)
|
|
|
|
|
c = '+';
|
|
|
|
|
else
|
|
|
|
|
c = '=';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (char.IsLetter(c))
|
|
|
|
|
if (shift)
|
|
|
|
|
c = char.ToUpper(c);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-02 13:31:39 -04:00
|
|
|
|
}
|