mirror of
https://git.alee14.me/shiftos-archive/ShiftOS_TheReturn.git
synced 2025-01-22 18:02:16 +00:00
I fixed and broke stuff at the same time!
This commit is contained in:
parent
659ccfb29d
commit
15b3b356b0
4 changed files with 163 additions and 73 deletions
|
@ -10,6 +10,7 @@ using ShiftOS.Frontend.GraphicsSubsystem;
|
|||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ShiftOS.Frontend.GUI
|
||||
{
|
||||
|
@ -36,6 +37,48 @@ namespace ShiftOS.Frontend.GUI
|
|||
private int _mouseX = 0;
|
||||
private int _mouseY = 0;
|
||||
private bool _captureMouse = false;
|
||||
|
||||
public bool RequiresPaint
|
||||
{
|
||||
get
|
||||
{
|
||||
bool requires_child_repaint = false;
|
||||
foreach (var child in _children)
|
||||
{
|
||||
requires_child_repaint = child.RequiresPaint;
|
||||
if (requires_child_repaint)
|
||||
break;
|
||||
}
|
||||
return _invalidated || requires_child_repaint;
|
||||
}
|
||||
}
|
||||
|
||||
public Image TextureCache
|
||||
{
|
||||
get
|
||||
{
|
||||
return _texCache;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] PaintCache
|
||||
{
|
||||
get
|
||||
{
|
||||
var data = _texCache.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
var rgb = new byte[Math.Abs(data.Stride) * data.Height];
|
||||
Marshal.Copy(data.Scan0, rgb, 0, rgb.Length);
|
||||
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;
|
||||
}
|
||||
_texCache.UnlockBits(data);
|
||||
return rgb;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CaptureMouse
|
||||
{
|
||||
|
@ -74,6 +117,9 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_anchor == value)
|
||||
return;
|
||||
|
||||
_anchor = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -96,6 +142,8 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_opacity == value)
|
||||
return;
|
||||
_opacity = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -164,6 +212,9 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_visible == value)
|
||||
return;
|
||||
|
||||
_visible = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -213,6 +264,8 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_x == value)
|
||||
return;
|
||||
_x = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -226,6 +279,8 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_y == value)
|
||||
return;
|
||||
_y = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -239,6 +294,8 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_w == value)
|
||||
return;
|
||||
_w = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -252,6 +309,8 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
set
|
||||
{
|
||||
if (_h == value)
|
||||
return;
|
||||
_h = value;
|
||||
Invalidate();
|
||||
}
|
||||
|
@ -329,7 +388,6 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
_invalidated = false;
|
||||
}
|
||||
gfx.DrawImage(_texCache, 0, 0);
|
||||
foreach (var child in _children)
|
||||
{
|
||||
if (child.Visible)
|
||||
|
@ -339,6 +397,10 @@ namespace ShiftOS.Frontend.GUI
|
|||
var cBmp = new Bitmap(child.Width, child.Height);
|
||||
child.Paint(System.Drawing.Graphics.FromImage(cBmp));
|
||||
cBmp.SetOpacity((float)child.Opacity);
|
||||
using(var cGfx = Graphics.FromImage(_texCache))
|
||||
{
|
||||
cGfx.DrawImage(child.TextureCache, child.X, child.Y);
|
||||
}
|
||||
child._invalidated = false;
|
||||
child._texCache = cBmp;
|
||||
gfx.DrawImage(cBmp, new System.Drawing.Point(child.X, child.Y));
|
||||
|
@ -352,7 +414,7 @@ namespace ShiftOS.Frontend.GUI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx.DrawImage(_texCache, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,21 @@ namespace ShiftOS.Frontend.GUI
|
|||
_index--;
|
||||
|
||||
}
|
||||
if(e.Key == Microsoft.Xna.Framework.Input.Keys.Back)
|
||||
{
|
||||
if(_index > 0)
|
||||
{
|
||||
_text = _text.Remove(_index - 1, 1);
|
||||
_index--;
|
||||
}
|
||||
}
|
||||
if(e.Key == Microsoft.Xna.Framework.Input.Keys.Delete)
|
||||
{
|
||||
if(_index < _text.Length - 1)
|
||||
{
|
||||
_text = _text.Remove(_index, 1);
|
||||
}
|
||||
}
|
||||
if (e.Key == Microsoft.Xna.Framework.Input.Keys.Right)
|
||||
if (_index < _text.Length)
|
||||
_index++;
|
||||
|
@ -36,52 +51,47 @@ namespace ShiftOS.Frontend.GUI
|
|||
Invalidate();
|
||||
base.OnKeyEvent(e);
|
||||
}
|
||||
|
||||
private int textInputOffset = 0;
|
||||
private int maxCanFit = 5;
|
||||
string visibleText = "";
|
||||
|
||||
float caretPos = 2f;
|
||||
|
||||
protected void CalculateVisibleText()
|
||||
{
|
||||
visibleText = "";
|
||||
caretPos = -1f;
|
||||
using (var gfx = Graphics.FromImage(new Bitmap(1, 1)))
|
||||
using(var gfx = Graphics.FromImage(new Bitmap(1, 1)))
|
||||
{
|
||||
for (int i = textInputOffset; i < _text.Length; i++)
|
||||
string toCaret = _text.Substring(0, _index);
|
||||
var measure = gfx.MeasureString(toCaret, _font);
|
||||
caretPos = 2 + measure.Width;
|
||||
while(caretPos - _textDrawOffset < 0)
|
||||
{
|
||||
visibleText += _text[i];
|
||||
var measure = gfx.MeasureString(visibleText, _font);
|
||||
if (measure.Width > Width)
|
||||
{
|
||||
maxCanFit = visibleText.Length;
|
||||
if(_index < textInputOffset)
|
||||
{
|
||||
textInputOffset = MathHelper.Clamp(_index - (maxCanFit / 2), 0, _text.Length - 1);
|
||||
|
||||
}
|
||||
if(_index > textInputOffset + maxCanFit)
|
||||
{
|
||||
textInputOffset = MathHelper.Clamp(_index + (maxCanFit / 2), 0, _text.Length - 1) - maxCanFit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Height = (int)measure.Height + 4;
|
||||
_textDrawOffset -= 0.01f;
|
||||
}
|
||||
while(caretPos - _textDrawOffset > Width)
|
||||
{
|
||||
_textDrawOffset += 0.01f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private float _textDrawOffset = 0;
|
||||
|
||||
protected override void OnPaint(Graphics gfx)
|
||||
{
|
||||
gfx.Clear(LoadedSkin.ControlColor);
|
||||
gfx.DrawString(visibleText, _font, new SolidBrush(LoadedSkin.ControlTextColor), 2, 2);
|
||||
gfx.DrawString(_text, _font, new SolidBrush(LoadedSkin.ControlTextColor), 2 - _textDrawOffset, 2);
|
||||
if (IsFocusedControl)
|
||||
{
|
||||
//Draw caret.
|
||||
gfx.FillRectangle(new SolidBrush(LoadedSkin.ControlTextColor), new RectangleF(caretPos, 2, 2, Height - 4));
|
||||
gfx.FillRectangle(new SolidBrush(LoadedSkin.ControlTextColor), new RectangleF(caretPos - _textDrawOffset, 2, 2, Height - 4));
|
||||
}
|
||||
gfx.DrawRectangle(new Pen(new SolidBrush(LoadedSkin.ControlTextColor), 1), new Rectangle(0, 0, Width - 1, Height - 1));
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(_text))
|
||||
{
|
||||
gfx.DrawString(_label, _font, Brushes.Gray, 2, 2);
|
||||
}
|
||||
}
|
||||
gfx.DrawRectangle(new Pen(new SolidBrush(LoadedSkin.ControlTextColor), 1), new System.Drawing.Rectangle(0, 0, Width - 1, Height - 1));
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ShiftOS.Frontend.GraphicsSubsystem
|
|||
|
||||
public static void LayoutUpdate()
|
||||
{
|
||||
foreach (var toplevel in topLevels)
|
||||
foreach (var toplevel in topLevels.ToArray())
|
||||
toplevel.Layout();
|
||||
}
|
||||
|
||||
|
@ -40,32 +40,26 @@ namespace ShiftOS.Frontend.GraphicsSubsystem
|
|||
t.Start();
|
||||
}
|
||||
|
||||
public static Dictionary<int, Texture2D> TextureCaches = new Dictionary<int, Texture2D>();
|
||||
|
||||
public static void DrawControls(GraphicsDevice graphics, SpriteBatch batch)
|
||||
{
|
||||
foreach (var ctrl in topLevels.ToArray())
|
||||
{
|
||||
using(var bmp = new System.Drawing.Bitmap(ctrl.Width, ctrl.Height))
|
||||
int hc = ctrl.GetHashCode();
|
||||
if (ctrl.RequiresPaint)
|
||||
{
|
||||
var gfx = System.Drawing.Graphics.FromImage(bmp);
|
||||
ctrl.Paint(gfx);
|
||||
bmp.SetOpacity((float)ctrl.Opacity);
|
||||
//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);
|
||||
for(int i = 0; i < rgb.Length; i+=4)
|
||||
var bmp = new System.Drawing.Bitmap(ctrl.Width, ctrl.Height);
|
||||
ctrl.Paint(System.Drawing.Graphics.FromImage(bmp));
|
||||
if (TextureCaches.ContainsKey(hc))
|
||||
{
|
||||
byte r = rgb[i];
|
||||
byte b = rgb[i + 2];
|
||||
rgb[i] = b;
|
||||
rgb[i + 2] = r;
|
||||
TextureCaches[hc].Dispose();
|
||||
TextureCaches.Remove(hc);
|
||||
}
|
||||
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);
|
||||
TextureCaches.Add(hc, new Texture2D(graphics, ctrl.Width, ctrl.Height));
|
||||
TextureCaches[hc].SetData<byte>(ctrl.PaintCache);
|
||||
}
|
||||
batch.Draw(TextureCaches[hc], new Rectangle(ctrl.X, ctrl.Y, ctrl.Width, ctrl.Height), Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +133,7 @@ namespace ShiftOS.Frontend.GraphicsSubsystem
|
|||
{
|
||||
public static char ToCharacter(this Keys key, bool shift)
|
||||
{
|
||||
char c = ' ';
|
||||
char c = '\0';
|
||||
switch (key)
|
||||
{
|
||||
case Keys.Space:
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace ShiftOS.Frontend
|
|||
}
|
||||
|
||||
private GUI.TextControl _titleLabel = null;
|
||||
private Keys lastKey = Keys.None;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows the game to perform any initialization it needs to before starting to run.
|
||||
|
@ -123,10 +125,16 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
textinput.Y = 0;
|
||||
UIManager.AddTopLevel(textinput);
|
||||
|
||||
framerate.Width = GraphicsDevice.PreferredBackBufferWidth;
|
||||
framerate.Height = GraphicsDevice.PreferredBackBufferHeight;
|
||||
framerate.TextAlign = GUI.TextAlign.BottomRight;
|
||||
|
||||
base.Initialize();
|
||||
|
||||
}
|
||||
|
||||
private Texture2D MouseTexture = null;
|
||||
|
||||
/// <summary>
|
||||
/// LoadContent will be called once per game and is the place to load
|
||||
/// all of your content.
|
||||
|
@ -137,6 +145,14 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
this.spriteBatch = new SpriteBatch(base.GraphicsDevice);
|
||||
|
||||
// TODO: use this.Content to load your game content here
|
||||
var bmp = Properties.Resources.cursor_9x_pointer;
|
||||
var _lock = 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(_lock.Stride) * _lock.Height];
|
||||
Marshal.Copy(_lock.Scan0, rgb, 0, rgb.Length);
|
||||
bmp.UnlockBits(_lock);
|
||||
MouseTexture = new Texture2D(GraphicsDevice.GraphicsDevice, bmp.Width, bmp.Height);
|
||||
MouseTexture.SetData<byte>(rgb);
|
||||
rgb = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -145,9 +161,11 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
/// </summary>
|
||||
protected override void UnloadContent()
|
||||
{
|
||||
MouseTexture = null;
|
||||
// TODO: Unload any non ContentManager content here
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows the game to run logic such as updating the world,
|
||||
/// checking for collisions, gathering input, and playing audio.
|
||||
|
@ -158,14 +176,14 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
//Let's get the mouse state
|
||||
var mouseState = Mouse.GetState(this.Window);
|
||||
|
||||
//Now let's process it.
|
||||
UIManager.ProcessMouseState(mouseState);
|
||||
//Now let's process it.
|
||||
UIManager.ProcessMouseState(mouseState);
|
||||
|
||||
//Cause layout update on all elements
|
||||
UIManager.LayoutUpdate();
|
||||
|
||||
//set framerate
|
||||
framerate.Text = "ShiftOS 1.0 Beta 4\r\nCopyright (c) 2017 ShiftOS\r\nFPS: " + (1 / gameTime.ElapsedGameTime.TotalSeconds);
|
||||
framerate.Text = "ShiftOS 1.0 Beta 4\r\nCopyright (c) 2017 ShiftOS\r\nFPS: " + (1000 / gameTime.ElapsedGameTime.TotalMilliseconds);
|
||||
|
||||
//So we have mouse input, and the UI layout system working...
|
||||
|
||||
|
@ -180,22 +198,34 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
var keys = keystate.GetPressedKeys();
|
||||
if (keys.Length > 0)
|
||||
{
|
||||
//Of course, we need modifier keys...
|
||||
//First for Control.
|
||||
bool controlDown = keys.Contains(Keys.LeftControl) || keys.Contains(Keys.RightControl);
|
||||
//Now SHIFT.
|
||||
bool shiftDown = keys.Contains(Keys.LeftShift) || keys.Contains(Keys.RightShift);
|
||||
//And ALT.
|
||||
bool altDown = keys.Contains(Keys.LeftAlt) || keys.Contains(Keys.RightAlt);
|
||||
|
||||
foreach(var key in keys)
|
||||
var key = keys.FirstOrDefault(x => x != Keys.LeftControl && x != Keys.RightControl && x != Keys.LeftShift && x != Keys.RightShift && x != Keys.LeftAlt && x != Keys.RightAlt);
|
||||
if (lastKey != key)
|
||||
{
|
||||
//This'll make it so we skip the modifier keys.
|
||||
if(key != Keys.LeftAlt && key != Keys.RightAlt && key != Keys.LeftControl && key != Keys.RightControl && key != Keys.LeftShift && key != Keys.RightShift)
|
||||
lastKey = key;
|
||||
//Of course, we need modifier keys...
|
||||
//First for Control.
|
||||
bool controlDown = keys.Contains(Keys.LeftControl) || keys.Contains(Keys.RightControl);
|
||||
//Now SHIFT.
|
||||
bool shiftDown = keys.Contains(Keys.LeftShift) || keys.Contains(Keys.RightShift);
|
||||
//And ALT.
|
||||
bool altDown = keys.Contains(Keys.LeftAlt) || keys.Contains(Keys.RightAlt);
|
||||
|
||||
var keyevent = new KeyEvent(controlDown, altDown, shiftDown, key);
|
||||
var t = new System.Threading.Thread(() =>
|
||||
{
|
||||
var keyevent = new KeyEvent(controlDown, altDown, shiftDown, key);
|
||||
UIManager.ProcessKeyEvent(keyevent);
|
||||
}
|
||||
lastKey = Keys.None;
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if(lastKey == keyevent.Key)
|
||||
while (Keyboard.GetState().IsKeyDown(keyevent.Key))
|
||||
{
|
||||
UIManager.ProcessKeyEvent(keyevent);
|
||||
System.Threading.Thread.Sleep(75);
|
||||
}
|
||||
lastKey = Keys.None;
|
||||
});
|
||||
t.Start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,15 +251,9 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type
|
|||
//Draw a mouse cursor
|
||||
|
||||
|
||||
var bmp = Properties.Resources.cursor_9x_pointer;
|
||||
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);
|
||||
|
||||
var mousepos = Mouse.GetState(this.Window).Position;
|
||||
var tex2 = new Texture2D(graphics, bmp.Width, bmp.Height);
|
||||
tex2.SetData<byte>(rgb);
|
||||
spriteBatch.Draw(tex2, new Rectangle(mousepos.X, mousepos.Y, bmp.Width, bmp.Height), Color.White);
|
||||
spriteBatch.Draw(MouseTexture, new Rectangle(mousepos.X, mousepos.Y, MouseTexture.Width, MouseTexture.Height), Color.White);
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue