Josh,
How about this issue with no change of disabled font color? Or am I doing something wrong?
Next case - I’m trying to create my own popping up numerical keyboard. At the moment I have something like this (pre-pre-alpha ;)):
Window.txt resource:
<Glide Version="0.2.1">
<Window Name="window" Width="320" Height="240" BackColor="000000">
<TextBox Name="Box" X="58" Y="32" Width="84" Height="32" Alpha="255" Text="base octave" TextAlign="Center" Font="2" FontColor="000000"/>
<TextBox Name="Box2" X="58" Y="80" Width="84" Height="32" Alpha="255" Text="bpm" TextAlign="Center" Font="2" FontColor="000000"/>
</Window>
</Glide>
Program.cs:
using System.Threading;
using GHIElectronics.NETMF.Glide;
using GHIElectronics.NETMF.Glide.Display;
using GHIElectronics.NETMF.Glide.UI;
using Microsoft.SPOT;
namespace FEZ_Cobra_Console_Application4
{
public static class Program
{
private static Window _window;
private static TextBox _recentlyEdited;
private static int _boxValue;
public static void Main()
{
_window = GlideLoader.LoadWindow(Resources.GetString(Resources.StringResources.Window));
GlideTouch.Initialize();
InitWin();
Glide.MainWindow = _window;
Thread.Sleep(-1);
}
static void InitWin()
{
var box = (TextBox)_window.GetChildByName("Box");
box.ValueChangedEvent += BoxValueChangedEvent;
box.TapEvent += BoxTapEvent;
var box2 = (TextBox)_window.GetChildByName("Box2");
box2.ValueChangedEvent += BoxValueChangedEvent;
box2.TapEvent += Box2TapEvent;
var kb = new NumericalKeyboard(_window);
kb.MaxDigits = 3;
kb.MaxValue = 998;
kb.ZeroAccepted = false;
_window.AddChildAt(2, kb);
}
static void BoxTapEvent(object sender)
{
_recentlyEdited = (TextBox)sender;
var kb = (NumericalKeyboard)_window.GetChildByName("NumericalKeyboard");
kb.DisabledButtons = new[] { "0", "9", "BKSP", "CLR" };
kb.OneDigit = true;
kb.Open(sender);
}
private static void Box2TapEvent(object sender)
{
_recentlyEdited = (TextBox)sender;
var kb = (NumericalKeyboard)_window.GetChildByName("NumericalKeyboard");
kb.DisabledButtons = null;
kb.OneDigit = false;
kb.Open(sender);
}
static void BoxValueChangedEvent(object sender)
{
_boxValue = int.Parse(_recentlyEdited.Text);
Debug.Print(_boxValue.ToString());
}
}
}
And NumericalKeyboard.cs:
using System;
using System.Collections;
using GHIElectronics.NETMF.Glide;
using GHIElectronics.NETMF.Glide.Display;
using GHIElectronics.NETMF.Glide.Geom;
using GHIElectronics.NETMF.Glide.UI;
namespace FEZ_Cobra_Console_Application4
{
sealed class NumericalKeyboard : DisplayObjectContainer
{
private int _tempValue;
private bool _firstChange;
public bool OneDigit;
public bool ZeroAccepted;
public int DefaultValue;
public int MaxDigits;
public int MaxValue;
public string[] DisabledButtons = new string[10];
private TextBox _relatedObject;
//todo: if there is one digit left to get to maxdigits look at maxvalue - if some buttons will make the number reach this value, disable them
//todo: or some other possibility to check/inform the user whether the value is valid at specific point or not
//my _toggledButtons from NIW will have to be managed from the outside
//todo: comma/dot for double values and minus for sub-zero values
private readonly ArrayList _buttons = new ArrayList
{
new Button("1", 255, 87, 58, 48, 32),
new Button("2", 255, 136, 58, 48, 32),
new Button("3", 255, 185, 58, 48, 32),
new Button("4", 255, 87, 91, 48, 32),
new Button("5", 255, 136, 91, 48, 32),
new Button("6", 255, 185, 91, 48, 32),
new Button("7", 255, 87, 124, 48, 32),
new Button("8", 255, 136, 124, 48, 32),
new Button("9", 255, 185, 124, 48, 32),
new Button("0", 255, 136, 157, 48, 32),
new Button("CLR", 255, 87, 157, 48, 32), //clear
new Button("BKSP", 255, 185, 157, 48, 32), //bksp
new Button("Ok", 255, 101, 193, 48, 32), //ok
new Button("Cancel", 255, 174, 193, 48, 32), //cancel
};
private readonly TextBox _valueDisplay = new TextBox("ValueDisplay", 255, 120, 22, 80, 32);
private readonly Canvas _drawer = new Canvas { X = 0, Y = 0, Width = 320, Height = 240, Name = "Drawer" };
public NumericalKeyboard(DisplayObjectContainer window)
{
Name = "NumericalKeyboard";
Parent = window;
Visible = false;
X = 0;
Y = 0;
Width = 320;
Height = 240;
DefaultValue = 0;
ZeroAccepted = false;
Rect = new Rectangle(0, 0, 320, 240); //is this needed?
CombineDrawer();
CombineDisplay();
CombineButtons();
}
private void CombineDrawer()
{
_drawer.Parent = this;
AddChild(_drawer);
//_drawer.DrawRectangle(Colors.DarkGray, 0, 0, 0, 320, 240, 0, 0, Colors.DarkGray, 0, 0, Colors.DarkGray, 320, 240, 160); //I wanted to make everything on the parent window looking darker or disabled-like
_drawer.DrawRectangle(Colors.White, 1, 76, 16, 168, 214, 0, 0, Colors.LightGray, 76, 16, Colors.Black, 84, 64, 255); //things on the window below rectangle are interactive if there is nothing more above - maybe I have to use an image instead
//the outline must be different than White because after hiding the keyboard the outline is still there - Window BackColor is #ffffff; something with netmf
//if the gradient is spread over whole Rectangle there might be seen some thick "lines" - like there are too few steps for usage like filling the whole big component background
}
private void CombineDisplay()
{
_valueDisplay.Parent = this;
AddChild(_valueDisplay);
_valueDisplay.TextAlign = 32;
_valueDisplay.Font = FontManager.GetFont(FontManager.FontType.droid_reg10);
}
private void CombineButtons()
{
for (int i = 0; i < _buttons.Count; i++)
{
var foo = ((Button)_buttons[i]);
AddChild(foo);
foo.Parent = this;
foo.Text = foo.Name;
foo.Font = FontManager.GetFont(FontManager.FontType.droid_reg10);
foo.TapEvent += NumKbTapEvent;
}
}
private void NumKbTapEvent(object sender)
{
sender.GetType();
var tappedBtn = ((Button)sender).Name;
try
{
var tappedNum = int.Parse(tappedBtn);
if (OneDigit)
_tempValue = tappedNum;
else
{
if (!_firstChange)
{
if (_tempValue.ToString().Length == MaxDigits)
return;
if (_tempValue*10+tappedNum >= MaxValue)
return;
_tempValue = _tempValue*10+tappedNum;
}
else
{
_tempValue = tappedNum;
_firstChange = false;
}
}
Update();
}
catch (Exception) //clr/bksp/ok/cancel tapped
{
var tappedFn = tappedBtn;
switch (tappedFn)
{
case "CLR":
{
_tempValue = 0;
Update();
break;
}
case "BKSP":
{
if (_tempValue.ToString().Length == 0)
return;
_tempValue = _tempValue / 10;
Update();
break;
}
case "Ok":
{
_relatedObject.Text = _tempValue.ToString();
Hide();
break;
}
case "Cancel":
{
Hide();
break;
}
}
}
}
private void Update()
{
_valueDisplay.Text = _tempValue.ToString();
_valueDisplay.Invalidate();
if (_tempValue != 0)
ToggleOK(true);
if (_tempValue == 0 && !ZeroAccepted)
ToggleOK(false);
}
private void ToggleOK(bool enabled)
{
((Button)_buttons[12]).Enabled = enabled;
((Window)Parent).FillRect(((Button)_buttons[12]).Rect);
((Button)_buttons[12]).Invalidate();
}
public void Open(object sender)
{
_relatedObject = (TextBox)sender;
try
{
_tempValue = int.Parse(_relatedObject.Text);
}
catch(Exception)
{
_tempValue = DefaultValue; //for the first time 0 doesn't disable the Ok button and it might be treated as useful
} //but this might be changed and if you want to have different default values for different textBoxes
//you should create a NumericalKeyboard for each of them
_firstChange = true;
if (DisabledButtons != null)
DisableButtons();
_valueDisplay.Text = _tempValue.ToString();
Show();
}
private void EnableButtons()
{
foreach (var button in _buttons)
if (((Button)button).Enabled == false)
((Button)button).Enabled = true;
}
private void DisableButtons()
{
foreach (var buttonName in DisabledButtons)
foreach (var button in _buttons)
if (((Button)button).Name == buttonName)
((Button)button).Enabled = false;
}
private void Show() //it should disable everything below but something like Parent.Interactive = false; doesn't work
{
Visible = true;
Parent.Invalidate();
}
private void Hide()
{
Visible = false;
Parent.Invalidate();
EnableButtons();
}
}
}
Please take a look at it, how can this be made better and how to solve some of the issues mentioned within comments.
Also for such purpose maybe it would be nice to make a rectangle with cornerRadius > 0 but still with gradient - or maybe an image with transparent corners as a keyboard background is a better (with better performance) solution to this issue.
Regards,
Tomasz
Edit: after pressing the Clear and Backspace buttons the textBox is refreshing with noticeable delay. Well, I would be a good FEZ Turtle programmer x_x.
Edit2: No way, it’s because it is in debug mode and it takes time to print the exception info after parse fails! ^^’