Added text scrolling
authorChip Black <bytex64@bytex64.net>
Mon, 29 Sep 2008 07:34:30 +0000 (02:34 -0500)
committerChip Black <bytex64@bytex64.net>
Mon, 29 Sep 2008 07:34:30 +0000 (02:34 -0500)
TextDisplay.cs
TextDocument.cs

index 0abb9e9..9389f00 100644 (file)
@@ -5,10 +5,18 @@ using Gtk;
 
 public class TextDisplay : DrawingArea, IKeyPress {
        private TextDocument doc = null;
-       private FontDescription font;
+       private Font font;
+       // FIXME: Proportional fonts?
+       private float fontwidth;
+       private float fontheight;
 
        public TextDisplay() {
-               font = Pango.FontDescription.FromString("Courier 12");
+               FontDescription fd = Pango.FontDescription.FromString("Courier 12");
+               font = this.PangoContext.LoadFont(fd);
+               FontMetrics fm = font.GetMetrics(null);
+               fontheight = Pango.Units.ToPixels(fm.Ascent + fm.Descent);
+               fontwidth = fontheight * 0.5333f;
+               Console.WriteLine("Using {0} {1}pt ({2}x{3}px)", fd.Family, fd.Size, fontwidth, fontheight);
                ModifyBg(StateType.Normal, new Gdk.Color(0xFF, 0xFF, 0xFF));
        }
 
@@ -20,25 +28,18 @@ public class TextDisplay : DrawingArea, IKeyPress {
                if (doc == null) return;
 
                Pango.Layout layout = new Pango.Layout(this.PangoContext);
-               layout.Width = Pango.Units.FromPixels(width);
-               layout.FontDescription = font;
+               layout.Width = 0x7FFFFFFF; //Pango.Units.FromPixels(width);
+               layout.FontDescription = font.Describe();
 
                //gr.Operator = Operator.Atop;
                gr.SetSourceRGB(0,0,0);
-               int h = Pango.Units.ToPixels(layout.FontDescription.Size) + 1;
-               int y = 0;
-               int line = 0;
-               while (line < doc.Lines.Count && y < height) {
-                       layout.SetText((String)doc.Lines[line]);
-                       gr.MoveTo(0, y);
-                       Pango.CairoHelper.ShowLayout(gr, layout);
-                       y += h;
-                       line++;
-               }
+               layout.SetText(doc.GetTextWindow());
+               gr.MoveTo(0, 0);
+               Pango.CairoHelper.ShowLayout(gr, layout);
 
-               //gr.Operator = Operator.Xor;
+               gr.Operator = Operator.Xor;
                gr.NewPath();
-               gr.Rectangle(new Cairo.Rectangle(doc.cursor.x*8, doc.cursor.y*h, 8, h));
+               gr.Rectangle(new Cairo.Rectangle((doc.cursor.x - doc.textorigin.x)*fontwidth, (doc.cursor.y - doc.textorigin.y)*fontheight, fontwidth, fontheight));
                gr.Fill();
         }
 
@@ -70,6 +71,12 @@ public class TextDisplay : DrawingArea, IKeyPress {
                 return true;
         }
 
+       protected override void OnSizeAllocated(Gdk.Rectangle r) {
+               base.OnSizeAllocated(r);
+               if (doc != null)
+                       doc.SetPageSize((int)(r.Width / fontwidth) - 1, (int)(r.Height / fontheight) - 1);
+       }
+
        public void Update() {
                QueueDraw();
        }
@@ -78,25 +85,6 @@ public class TextDisplay : DrawingArea, IKeyPress {
         [GLib.ConnectBefore ()]
         public void KeyPress(object o, KeyPressEventArgs args) {
                if (doc == null) return;
-
-                if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                } else if ((args.Event.State & Gdk.ModifierType.Mod1Mask) != 0) {
-                } else {
-                        switch(args.Event.Key) {
-                        case Gdk.Key.Up:
-                        case Gdk.Key.Down:
-                        case Gdk.Key.Left:
-                        case Gdk.Key.Right:
-                        case Gdk.Key.Page_Up:
-                        case Gdk.Key.Page_Down:
-                        case Gdk.Key.Home:
-                        case Gdk.Key.End:
-                                doc.MoveCursor(args.Event.Key);
-                                break;
-                        default:
-                                doc.AddChar((int)args.Event.KeyValue);
-                                break;
-                        }
-                }
+               doc.KeyPress(o, args);
        }
 }
index e05e992..f554af7 100644 (file)
@@ -74,12 +74,16 @@ public class TextArray {
                if (y >= lines.Count) return;
 
                string s = (string)lines[y];
-               if (x >= s.Length) return;
-
-               if (s.Length == 0 && x == 0) {
+               if (x >= s.Length) {
+                       if (y == lines.Count - 1) return;
+                       if (x > s.Length)
+                               s = s.PadRight(x);
+                       lines[y] = s + (String)lines[y+1];
+                       lines.RemoveAt(y+1);
+               } else if (s.Length == 0 && x == 0) {
                        lines.RemoveAt(y);
                } else {
-                       s.Remove(x, 1);
+                       lines[y] = s.Remove(x, 1);
                }
        }
 
@@ -118,15 +122,11 @@ public class TextArray {
        }
 }
 
-public class TextDocument {
+public class TextDocument : IKeyPress {
        private TextArray text;
        public Cursor cursor;
-
-       public ArrayList Lines {
-               get {
-                       return text.Lines;
-               }
-       }
+       public Cursor textorigin;
+       private int pagewidth, pageheight;
 
        public TextDocument() {
                text = new TextArray();
@@ -136,6 +136,29 @@ public class TextDocument {
                text = new TextArray(filename);
        }
 
+       public string GetTextWindow() {
+               string s = "";
+
+               for (int i = textorigin.y; textorigin.y + i < text.Lines.Count && i < pageheight; i++) {
+                       String l = (String)text.Lines[i];
+                       s += l.Substring(textorigin.x) + "\n";
+               }
+               return s;
+       }
+
+       private void FixTextWindow() {
+               if (cursor.x < textorigin.x) textorigin.x = cursor.x;
+               if (cursor.y < textorigin.y) textorigin.y = cursor.y;
+               if (cursor.x > textorigin.x + pagewidth) textorigin.x = cursor.x - pagewidth;
+               if (cursor.y > textorigin.y + pageheight) textorigin.y = cursor.y - pageheight;
+       }
+
+       public void SetPageSize(int w, int h) {
+               pagewidth = w;
+               pageheight = h;
+               FixTextWindow();
+       }
+
        public void MoveCursor(Gdk.Key k) {
                switch(k) {
                case Gdk.Key.Up:
@@ -156,35 +179,64 @@ public class TextDocument {
                case Gdk.Key.Home:
                        cursor.x = 0;
                        break;
+               case Gdk.Key.Page_Up:
+                       cursor.y -= pageheight;
+                       break;
+               case Gdk.Key.Page_Down:
+                       cursor.y += pageheight;
+                       break;
                }
+               FixTextWindow();
        }
 
+       [GLib.ConnectBefore ()]
+       public void KeyPress(object o, Gtk.KeyPressEventArgs args) {
+               if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+               } else if ((args.Event.State & Gdk.ModifierType.Mod1Mask) != 0) {
+               } else {
+                       switch(args.Event.Key) {
+                       case Gdk.Key.Up:
+                       case Gdk.Key.Down:
+                       case Gdk.Key.Left:
+                       case Gdk.Key.Right:
+                       case Gdk.Key.Page_Up:
+                       case Gdk.Key.Page_Down:
+                       case Gdk.Key.Home:
+                       case Gdk.Key.End:
+                               MoveCursor(args.Event.Key);
+                               break;
+                       case Gdk.Key.Delete:
+                               text.Delete(cursor.x, cursor.y);
+                               break;
+                       case Gdk.Key.BackSpace:
+                               int l = 0;
+                               if (cursor.y > 0) l = text.LineLength(cursor.y-1);
+                               text.Backspace(cursor.x, cursor.y);
+                               if (cursor.x == 0) {
+                                       cursor.y--;
+                                       if (cursor.y >= text.Lines.Count) return;
+                                       cursor.x = l;
+                               } else {
+                                       cursor.x--;
+                               }
+                               break;
+                       case Gdk.Key.Return:
+                               text.Newline(cursor.x, cursor.y);
+                               cursor.x = 0;
+                               cursor.y++;
+                               break;
+                       default:
+                               AddChar((int)args.Event.KeyValue);
+                               break;
+                       }
+               }
+       }
+       
        public void AddChar(int c) {
                c = c & 0xFF;
                if (c > 128) return;
 
-               switch(c) {
-               case 8:
-                       int l = 0;
-                       if (cursor.y > 0) l = text.LineLength(cursor.y-1);
-                       text.Backspace(cursor.x, cursor.y);
-                       if (cursor.x == 0) {
-                               cursor.y--;
-                               if (cursor.y >= text.Lines.Count) return;
-                               cursor.x = l;
-                       } else {
-                               cursor.x--;
-                       }
-                       break;
-               case 13:
-                       text.Newline(cursor.x, cursor.y);
-                       cursor.x = 0;
-                       cursor.y++;
-                       break;
-               default:
-                       text.Insert(cursor.x, cursor.y, (char)c);
-                       cursor.x++;
-                       break;
-               }
+               text.Insert(cursor.x, cursor.y, (char)c);
+               cursor.x++;
        }
 }