Skip to content

Instantly share code, notes, and snippets.

@Frooxius
Created June 5, 2018 08:47
Show Gist options
  • Save Frooxius/7fb03eb935ab3934c3bfec88130852c1 to your computer and use it in GitHub Desktop.
Save Frooxius/7fb03eb935ab3934c3bfec88130852c1 to your computer and use it in GitHub Desktop.
Virtual Keyboard
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrooxEngine.UI;
namespace FrooxEngine
{
public class VirtualKey : Component, IButtonReceiver
{
// TODO!!! Simulate key
public readonly Sync<Key> TargetKey;
public readonly Sync<string> AppendString;
public readonly Sync<Key> ShiftTargetKey;
public readonly Sync<string> ShiftAppendString;
public readonly RelayRef<VirtualShift> ShiftKey;
Text text;
public void Pressed(Button button)
{
if(button.PressingUser.IsLocal)
{
string append;
Key key;
if(ShiftKey.Target == null || !ShiftKey.Target.Shift)
{
append = AppendString.Value;
key = TargetKey.Value;
}
else
{
append = ShiftAppendString.Value;
key = ShiftTargetKey.Value;
}
if(key != Key.None)
Input.SimulatePress(key);
if(append != null && append.Length > 0)
Input.TypeAppend(append);
ShiftKey.Target?.KeyPressed();
}
}
public void Released(Button button) { }
protected override void OnChanges()
{
if(ShiftKey.Target != null)
{
if (text == null)
text = Slot.GetComponentInChildren<Text>();
// update shift status
text.Content_Field.Value = ShiftKey.Target.Shift ? ShiftAppendString.Value : AppendString.Value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrooxEngine.UI;
using BaseX;
namespace FrooxEngine
{
public class VirtualKeyboard : Component
{
const string loweralpha = @"1234567890-=qwertyuiop[]asdfghjkl;'\zxcvbnm,./";
const string upperalpha = "!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"|ZXCVBNM<>?";
const string numeric = @"7894561230.-+*/";
public bool IsShown
{
get => Slot.ActiveSelf;
set => Slot.ActiveSelf = value;
}
protected override void OnAttach()
{
var grabbable = Slot.AttachComponent<Grabbable>();
grabbable.Scalable = true;
grabbable.ShouldPreserveUp.Value = false;
// build the keyboard
var ui = new UIBuilder(Slot, 640, 160, 0.001f);
ui.Image(new color(1f, 1f, 1f, 0.2f));
ui.Nest();
var panels = ui.SplitHorizontally(0.1f, 0.6f, 0.15f, 0.15f);
// Setup individual panels
VirtualKey virtualKey;
Button keyButton;
// Leftmost, Escape, tab shift
ui = new UIBuilder(panels[0].Slot);
ui.GridLayout(new float2(62, 30), new float2(2f, 2f)).PaddingTop.Value = 2;
keyButton = ui.Button("Esc");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.TargetKey.Value = Key.Escape;
//ui.Empty("Filler");
ui.Button("<i>(hide)</i>", new color(1f, 0.5f), HidePressed);
keyButton = ui.Button("Tab");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = "\t";
virtualKey.TargetKey.Value = Key.Tab;
keyButton = ui.Button("Shift");
var shiftKey = keyButton.Slot.AttachComponent<VirtualShift>();
// Alphanumeric
ui = new UIBuilder(panels[1].Slot);
ui.VerticalLayout(2f);
ui.GridLayout(float2.One * 30, new float2(2f, 2f)).PaddingTop.Value = 2;
for (int i = 0; i < loweralpha.Length; i++)
{
keyButton = ui.Button(loweralpha[i].ToString());
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = loweralpha[i].ToString();
virtualKey.ShiftAppendString.Value = upperalpha[i].ToString();
virtualKey.ShiftKey.Target = shiftKey;
// TODO!!! Mapping to a key
}
ui.NestOut();
ui.Style.PreferredHeight = 30;
ui.Panel();
keyButton = ui.Button();
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = " ";
virtualKey.TargetKey.Value = Key.Space;
var rect = keyButton.Slot.GetComponent<RectTransform>();
rect.AnchorMin.Value = new float2(0.1f, 0f);
rect.AnchorMax.Value = new float2(0.9f, 1f);
// Special section
ui = new UIBuilder(panels[2].Slot);
var vertLayout = ui.VerticalLayout(2f);
vertLayout.PaddingTop.Value = 2;
vertLayout.PaddingRight.Value = 2;
ui.Style.PreferredWidth = 32 * 3 - 2;
ui.Style.PreferredHeight = 30;
keyButton = ui.Button("<-- Backspace");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = "\b";
virtualKey.TargetKey.Value = Key.Backspace;
ui.Style.PreferredHeight = 30 + 32;
keyButton = ui.Button("Enter\n⏎");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = "\n";
virtualKey.TargetKey.Value = Key.Return;
ui.Style.PreferredHeight = 32;
ui.GridLayout(new float2(30f, 30f), new float2(2f, 2f));
ui.Empty("Filler");
keyButton = ui.Button("↑");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.TargetKey.Value = Key.UpArrow;
ui.Empty("Filler");
keyButton = ui.Button("←");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.TargetKey.Value = Key.LeftArrow;
keyButton = ui.Button("↓");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.TargetKey.Value = Key.DownArrow;
keyButton = ui.Button("→");
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.TargetKey.Value = Key.RightArrow;
// Numeric
ui = new UIBuilder(panels[3].Slot);
ui.GridLayout(float2.One * 30, new float2(2f, 2f)).PaddingTop.Value = 2;
for (int i = 0; i < numeric.Length; i++)
{
keyButton = ui.Button(numeric[i].ToString());
virtualKey = keyButton.Slot.AttachComponent<VirtualKey>();
virtualKey.AppendString.Value = numeric[i].ToString();
}
}
void HidePressed(Button button)
{
IsShown = false;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrooxEngine.UI;
using BaseX;
namespace FrooxEngine
{
public class VirtualShift : Component, IButtonReceiver
{
public bool Shift { get { return _shift; } }
readonly Sync<bool> _shift;
readonly Sync<bool> _hold;
readonly Sync<double> _lastPress;
Button _button;
public void KeyPressed()
{
if (!_hold.Value)
_shift.Value = false;
}
public void Pressed(Button button)
{
if(button.PressingUser.IsLocal)
{
if (_button == null)
_button = Slot.GetComponentInChildren<Button>();
if (!_shift.Value)
_shift.Value = true;
else if (!_hold.Value && (Time.WorldTime - _lastPress.Value < 0.5f))
{
_hold.Value = true;
_button.NormalColor.Value = color.Yellow;
}
else
{
_shift.Value = false;
_hold.Value = false;
_button.NormalColor.Value = color.White;
}
_lastPress.Value = Time.WorldTime;
}
}
public void Released(Button button) { }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment