public TouchNumberInput(bool timeInput = false, Window parent = null) : base("Input", parent, DialogFlags.DestroyWithParent)
        {
            Name           = "AquaPic.Keyboard.Input";
            Title          = "Input";
            WindowPosition = (WindowPosition)4;
            DefaultWidth   = 205;
            DefaultHeight  = 290;
            KeepAbove      = true;

#if RPI_BUILD
            Decorated = false;

            ExposeEvent += (o, args) => {
                using (Context cr = Gdk.CairoHelper.Create(GdkWindow)) {
                    cr.MoveTo(Allocation.Left, Allocation.Top);
                    cr.LineTo(Allocation.Right, Allocation.Top);
                    cr.LineTo(Allocation.Right, Allocation.Bottom);
                    cr.LineTo(Allocation.Left, Allocation.Bottom);
                    cr.ClosePath();
                    cr.LineWidth = 1.8;
                    TouchColor.SetSource(cr, "grey4");
                    cr.Stroke();
                }
            };
#endif

            fix = new Fixed();
            fix.WidthRequest  = 205;
            fix.HeightRequest = 290;

            ModifyBg(StateType.Normal, TouchColor.NewGtkColor("grey0"));

            entry = new Entry();
            entry.WidthRequest  = 145;
            entry.HeightRequest = 30;
            entry.CanFocus      = true;
            entry.ModifyFont(Pango.FontDescription.FromString("Sans 11"));
            entry.ModifyBase(StateType.Normal, TouchColor.NewGtkColor("grey4"));
            entry.ModifyText(StateType.Normal, TouchColor.NewGtkColor("black"));
            entry.Activated += (sender, e) => {
                if (entry.Text.IsNotEmpty())
                {
                    TextSetEventArgs args = new TextSetEventArgs(entry.Text);
                    TextSetEvent?.Invoke(this, args);

                    if (args.keepText)
                    {
                        Destroy();
                    }
                }
                else
                {
                    Destroy();
                }
            };

            fix.Put(entry, 5, 5);
            entry.GrabFocus();

            var b = new TouchButton();
            b.HeightRequest       = 30;
            b.ButtonReleaseEvent += (o, args) => {
                if (vkb == null)
                {
                    fix.WidthRequest = 710;
                    fix.QueueDraw();

                    SetSizeRequest(710, 290);
                    Show();

                    entry.WidthRequest = 700;
                    entry.QueueDraw();

                    b.Destroy();

                    vkb = new VirtualKeyboard(entry, OnButtonRelease);
                    fix.Put(vkb, 205, 60);
                    vkb.Show();
                }
            };
            fix.Put(b, 155, 5);
            b.Show();

            int x, y;
            var buttons = new KeyButton[10];
            for (int i = 0; i < buttons.Length; ++i)
            {
                buttons[i] = new KeyButton(i.ToString(), OnButtonRelease);

                if (i == 0)
                {
                    x = 55;
                    y = 190;
                }
                else
                {
                    if (i <= 3)
                    {
                        x = ((i - 1) * 50) + 5;
                        y = 40;
                    }
                    else if (i <= 6)
                    {
                        x = ((i - 4) * 50) + 5;
                        y = 90;
                    }
                    else
                    {
                        x = ((i - 7) * 50) + 5;
                        y = 140;
                    }
                }

                fix.Put(buttons[i], x, y);
            }

            KeyButton plusMinus = new KeyButton("-", null);
            plusMinus.ButtonReleaseEvent += (o, args) => {
                if (plusMinus.text == "-")
                {
                    int pos = 0;
                    entry.InsertText("-", ref pos);
                    ++entry.Position;
                    plusMinus.text = "+";
                }
                else
                {
                    entry.DeleteText(0, 1);
                    plusMinus.text = "-";
                }

                plusMinus.text = plusMinus.text.ToString();
                plusMinus.QueueDraw();
            };
            fix.Put(plusMinus, 5, 190);

            KeyButton period = new KeyButton(".", OnButtonRelease);
            fix.Put(period, 105, 190);

            KeyButton delete = new KeyButton(Convert.ToChar(0x232B).ToString(), null);    //02FF, 25C0
            delete.ButtonReleaseEvent += (o, args) => {
                int pos = entry.Position;
                entry.DeleteText(entry.Position - 1, entry.Position);
            };
            fix.Put(delete, 155, 40);

            KeyButton clear = new KeyButton("C", null);
            clear.ButtonReleaseEvent += (o, args) => {
                plusMinus.text = "-";
                entry.Text     = string.Empty;
            };
            fix.Put(clear, 155, 90);

            KeyButton semi;
            if (timeInput)
            {
                semi = new KeyButton(":", OnButtonRelease);
            }
            else
            {
                semi             = new KeyButton(":", null);
                semi.buttonColor = "grey1";
            }
            fix.Put(semi, 5, 240);

            KeyButton pm = new KeyButton("PM", null);
            if (timeInput)
            {
                pm.ButtonReleaseEvent += (o, args) => {
                    int len = entry.Text.Length;
                    if (len >= 3)
                    {
                        string last = entry.Text.Substring(len - 2);
                        if (last == "AM")
                        {
                            int pos = entry.Text.Length - 2;
                            entry.DeleteText(pos, pos + 2);
                            entry.InsertText("PM", ref pos);
                        }
                        else if (last == "PM")
                        {
                            int pos = entry.Text.Length - 3;
                            entry.DeleteText(pos, pos + 3);
                        }
                        else
                        {
                            int pos = entry.Text.Length;
                            entry.InsertText(" PM", ref pos);
                        }
                    }
                    else
                    {
                        int pos = entry.Text.Length;
                        entry.InsertText(" PM", ref pos);
                    }
                };
            }
            else
            {
                pm.buttonColor = "grey1";
            }
            fix.Put(pm, 55, 240);

            KeyButton am = new KeyButton("AM", null);
            if (timeInput)
            {
                am.ButtonReleaseEvent += (o, args) => {
                    int len = entry.Text.Length;
                    if (len >= 3)
                    {
                        string last = entry.Text.Substring(len - 2);
                        if (last == "PM")
                        {
                            int pos = entry.Text.Length - 2;
                            entry.DeleteText(pos, pos + 2);
                            entry.InsertText("AM", ref pos);
                        }
                        else if (last == "AM")
                        {
                            int pos = entry.Text.Length - 3;
                            entry.DeleteText(pos, pos + 3);
                        }
                        else
                        {
                            int pos = entry.Text.Length;
                            entry.InsertText(" AM", ref pos);
                        }
                    }
                    else
                    {
                        int pos = entry.Text.Length;
                        entry.InsertText(" AM", ref pos);
                    }
                };
            }
            else
            {
                am.buttonColor = "grey1";
            }
            fix.Put(am, 105, 240);

            KeyButton cancel = new KeyButton("Cancel", null);
            cancel.textSize            = 9;
            cancel.ButtonReleaseEvent += (o, args) => {
                Destroy();
            };
            fix.Put(cancel, 155, 240);

            TouchButton enter = new TouchButton();
            enter.text                = Convert.ToChar(0x23CE).ToString();
            enter.HeightRequest       = 95;
            enter.ButtonReleaseEvent += (o, a) => {
                var args = new TextSetEventArgs(entry.Text);
                TextSetEvent?.Invoke(this, args);

                if (args.keepText)
                {
                    Destroy();
                }
            };
            fix.Put(enter, 155, 140);

            foreach (Widget w in Children)
            {
                Remove(w);
                w.Dispose();
            }

            Add(fix);
            fix.ShowAll();
            Show();
        }