/TextInput.cs
using System;
using Cairo;
using Pango;
using Gtk;
using Gdk;
public class TextInputEventArgs : EventArgs {
public string Value;
public TextInputEventArgs(string s) {
Value = s;
}
}
public class TextInput : DrawingArea, IKeyPress {
public string Value;
protected int cursor;
private string killring = null;
Pango.FontDescription font;
public delegate void SelectHandler(object o, TextInputEventArgs s);
public event SelectHandler Selected;
public TextInput() : this("") { }
public TextInput(string Value) {
this.Value = Value;
cursor = Value.Length;
font = Pango.FontDescription.FromString("Courier 12");
SetSizeRequest(-1, 12);
ModifyBg(StateType.Normal, new Gdk.Color(0xFF, 0xFF, 0xFF));
}
protected virtual void draw (Cairo.Context gr, int width, int height) {
gr.SetSourceRGB(0,0,0);
gr.NewPath();
gr.Rectangle(new Cairo.Rectangle(0, 0, width, height));
gr.Stroke();
Pango.Layout layout = new Pango.Layout(this.PangoContext);
layout.Width = Pango.Units.FromPixels(width);
layout.Alignment = Pango.Alignment.Left;
layout.FontDescription = font;
layout.SetText(Value);
Pango.CairoHelper.ShowLayout(gr, layout);
gr.NewPath();
int h = Pango.Units.ToPixels(layout.FontDescription.Size) + 1;
gr.Rectangle(cursor*8, 0, 7, h);
gr.Fill();
}
protected override bool OnExposeEvent (Gdk.EventExpose args) {
Gdk.Window win = args.Window;
Cairo.Context g = Gdk.CairoHelper.Create (args.Window);
int x, y, w, h, d;
win.GetGeometry(out x, out y, out w, out h, out d);
draw(g, w, h);
((IDisposable) g.Target).Dispose();
((IDisposable) g).Dispose();
return true;
}
[GLib.ConnectBefore ()]
public virtual void KeyPress(object o, KeyPressEventArgs args) {
if ((args.Event.State & ModifierType.ControlMask) != 0) {
switch(args.Event.Key) {
case Gdk.Key.u:
killring = Value.Substring(0, cursor);
Value = Value.Substring(cursor);
cursor = 0;
break;
case Gdk.Key.k:
killring = Value.Substring(cursor);
Value = Value.Substring(0, cursor);
break;
case Gdk.Key.w:
int ws = Value.LastIndexOfAny(" ".ToCharArray());
if (ws == -1) {
killring = Value;
Value = "";
} else {
killring = Value.Substring(ws + 1);
Value = Value.Substring(0, ws);
}
cursor = Value.Length;
break;
case Gdk.Key.y:
if (killring == null) return;
Value = Value.Insert(cursor, killring);
cursor += killring.Length;
break;
}
} else {
switch(args.Event.Key) {
case Gdk.Key.BackSpace:
if (cursor == 0) return;
cursor--;
Value = Value.Remove(cursor, 1);
break;
case Gdk.Key.Return:
if (Selected != null) {
TextInputEventArgs t = new TextInputEventArgs(Value);
Selected(this, t);
Selected = null;
}
break;
case Gdk.Key.Left:
if (cursor > 0) cursor--;
break;
case Gdk.Key.Right:
if (cursor < Value.Length) cursor++;
break;
case Gdk.Key.Escape:
if (Selected != null) {
TextInputEventArgs t = new TextInputEventArgs(null);
Selected(this, t);
Selected = null;
}
break;
default:
if (args.Event.KeyValue > 128) return;
Value = Value.Insert(cursor, new String((char)args.Event.KeyValue, 1));
cursor++;
break;
}
}
QueueDraw();
}
}