Fixed help file parsing
[Nebula.git] / TextDisplay.cs
1 using System;
2 using System.Timers;
3 using Cairo;
4 using Pango;
5 using Gdk;
6 using Gtk;
7
8 public class TextDisplay : DrawingArea, IKeyPress {
9         private TextDocument doc = null;
10         private Pango.Font font;
11         // FIXME: Proportional fonts?
12         private float fontWidth;
13         private float fontHeight;
14
15         private Timer helpTimer;
16         private HelpBox controlHelp;
17         private bool showHelp;
18
19         public TextDisplay() {
20                 FontDescription fd = Pango.FontDescription.FromString("Courier 12");
21                 font = this.PangoContext.LoadFont(fd);
22                 FontMetrics fm = font.GetMetrics(null);
23                 fontHeight = Pango.Units.ToPixels(fm.Ascent + fm.Descent);
24                 fontWidth = fontHeight * 0.5333f;
25                 Console.WriteLine("Using {0} {1}pt ({2}x{3}px)", fd.Family, fd.Size, fontWidth, fontHeight);
26
27                 controlHelp = new HelpBox(this.PangoContext, "control_help");
28                 ModifyBg(StateType.Normal, new Gdk.Color(0xFF, 0xFF, 0xFF));
29         }
30
31         public void SetDocument(TextDocument doc) {
32                 this.doc = doc;
33         }
34
35         void draw(Cairo.Context gr, int width, int height) {
36                 if (doc == null) return;
37
38                 Pango.Layout layout = new Pango.Layout(this.PangoContext);
39                 layout.Width = 0x7FFFFFFF; //Pango.Units.FromPixels(width);
40                 layout.FontDescription = font.Describe();
41
42                 //gr.Operator = Operator.Atop;
43                 gr.SetSourceRGB(0,0,0);
44                 layout.SetText(doc.GetTextWindow());
45                 gr.MoveTo(0, 0);
46                 Pango.CairoHelper.ShowLayout(gr, layout);
47
48                 gr.SetSourceRGB(0.0, 0.0, 0.0);
49                 gr.NewPath();
50                 gr.Rectangle((doc.cursor.x - doc.textorigin.x)*fontWidth, (doc.cursor.y - doc.textorigin.y)*fontHeight, fontWidth, fontHeight);
51                 gr.Fill();
52
53                 if (showHelp) {
54                         controlHelp.draw(gr, width, height);
55                 }
56         }
57
58         protected override bool OnExposeEvent(Gdk.EventExpose args) {
59                 Gdk.Window win = args.Window;                
60
61                 #if OLD_SYSTEMS
62                 //
63                 // For old versions of Gtk# (before 2.8), you need the helper class
64                 // available in gtk-sharp/sample/GtkCairo.cs
65                 //
66                 Cairo.Context g = Gdk.Graphics.CreateDrawable (win);
67                 #else
68                 //
69                 // Starting with Gtk 2.8 Gtk has direct support for
70                 // Cairo, as its built on top of it, on older
71                 // versions, a helper routine is used
72                 //
73                 Cairo.Context g = Gdk.CairoHelper.Create (args.Window);
74                 #endif
75
76                 int x, y, w, h, d;
77                 win.GetGeometry(out x, out y, out w, out h, out d);
78
79                 draw (g, w, h);
80                 ((IDisposable) g.Target).Dispose();
81                 ((IDisposable) g).Dispose();
82                 return true;
83         }
84
85         protected override void OnSizeAllocated(Gdk.Rectangle r) {
86                 base.OnSizeAllocated(r);
87                 if (doc != null)
88                         doc.SetPageSize((int)(r.Width / fontWidth) - 1, (int)(r.Height / fontHeight) - 1);
89         }
90
91         public void Update() {
92                 QueueDraw();
93         }
94
95         public void ShowHelp() {
96                 showHelp = true;
97                 helpTimer = null;
98                 QueueDraw();
99         }
100
101         public void HideHelp() {
102                 if (helpTimer != null) {
103                         helpTimer.Stop();
104                         helpTimer = null;
105                 }
106                 if (showHelp)
107                         showHelp = false;
108                 QueueDraw();
109         }
110
111         [GLib.ConnectBefore ()]
112         public void KeyPress(object o, KeyPressEventArgs args) {
113                 if (doc == null) return;
114                 if ((args.Event.State & ModifierType.ControlMask) != 0) {
115                         switch(args.Event.Key) {
116                         default:
117                                 HideHelp();
118                                 break;
119                         }
120                 } else {
121                         switch(args.Event.Key) {
122                         case Gdk.Key.Control_L:
123                         case Gdk.Key.Control_R:
124                                 helpTimer = new Timer();
125                                 helpTimer.Elapsed += delegate(object o2, ElapsedEventArgs e) {
126                                         ShowHelp();
127                                 };
128                                 helpTimer.AutoReset = false;
129                                 helpTimer.Interval = 1000;
130                                 helpTimer.Start();
131                                 break;
132                         }
133                 }
134                 doc.KeyPress(o, args);
135         }
136
137         public void KeyRelease(object o, KeyReleaseEventArgs e) {
138                 switch(e.Event.Key) {
139                 case Gdk.Key.Control_L:
140                 case Gdk.Key.Control_R:
141                         HideHelp();
142                         break;
143                 }
144         }
145 }