Added text scrolling
[Nebula.git] / TextDisplay.cs
1 using System;
2 using Cairo;
3 using Pango;
4 using Gtk;
5
6 public class TextDisplay : DrawingArea, IKeyPress {
7         private TextDocument doc = null;
8         private Font font;
9         // FIXME: Proportional fonts?
10         private float fontwidth;
11         private float fontheight;
12
13         public TextDisplay() {
14                 FontDescription fd = Pango.FontDescription.FromString("Courier 12");
15                 font = this.PangoContext.LoadFont(fd);
16                 FontMetrics fm = font.GetMetrics(null);
17                 fontheight = Pango.Units.ToPixels(fm.Ascent + fm.Descent);
18                 fontwidth = fontheight * 0.5333f;
19                 Console.WriteLine("Using {0} {1}pt ({2}x{3}px)", fd.Family, fd.Size, fontwidth, fontheight);
20                 ModifyBg(StateType.Normal, new Gdk.Color(0xFF, 0xFF, 0xFF));
21         }
22
23         public void SetDocument(TextDocument doc) {
24                 this.doc = doc;
25         }
26
27         void draw(Cairo.Context gr, int width, int height) {
28                 if (doc == null) return;
29
30                 Pango.Layout layout = new Pango.Layout(this.PangoContext);
31                 layout.Width = 0x7FFFFFFF; //Pango.Units.FromPixels(width);
32                 layout.FontDescription = font.Describe();
33
34                 //gr.Operator = Operator.Atop;
35                 gr.SetSourceRGB(0,0,0);
36                 layout.SetText(doc.GetTextWindow());
37                 gr.MoveTo(0, 0);
38                 Pango.CairoHelper.ShowLayout(gr, layout);
39
40                 gr.Operator = Operator.Xor;
41                 gr.NewPath();
42                 gr.Rectangle(new Cairo.Rectangle((doc.cursor.x - doc.textorigin.x)*fontwidth, (doc.cursor.y - doc.textorigin.y)*fontheight, fontwidth, fontheight));
43                 gr.Fill();
44         }
45
46         protected override bool OnExposeEvent(Gdk.EventExpose args)
47         {
48                 Gdk.Window win = args.Window;                
49
50                 #if OLD_SYSTEMS
51                 //
52                 // For old versions of Gtk# (before 2.8), you need the helper class
53                 // available in gtk-sharp/sample/GtkCairo.cs
54                 //
55                 Cairo.Context g = Gdk.Graphics.CreateDrawable (win);
56                 #else
57                 //
58                 // Starting with Gtk 2.8 Gtk has direct support for
59                 // Cairo, as its built on top of it, on older
60                 // versions, a helper routine is used
61                 //
62                 Cairo.Context g = Gdk.CairoHelper.Create (args.Window);
63                 #endif
64
65                 int x, y, w, h, d;
66                 win.GetGeometry(out x, out y, out w, out h, out d);
67
68                 draw (g, w, h);
69                 ((IDisposable) g.Target).Dispose();
70                 ((IDisposable) g).Dispose();
71                 return true;
72         }
73
74         protected override void OnSizeAllocated(Gdk.Rectangle r) {
75                 base.OnSizeAllocated(r);
76                 if (doc != null)
77                         doc.SetPageSize((int)(r.Width / fontwidth) - 1, (int)(r.Height / fontheight) - 1);
78         }
79
80         public void Update() {
81                 QueueDraw();
82         }
83
84
85         [GLib.ConnectBefore ()]
86         public void KeyPress(object o, KeyPressEventArgs args) {
87                 if (doc == null) return;
88                 doc.KeyPress(o, args);
89         }
90 }