2010-07-16

Quite a few of my coding projects have a large text field where the user is expected to do a lot of typing. Actually, it would appear that none of my projects have a large text field. I suppose I should make markdowner and scripsi official jezra.net projects. Anyway, both of the previously mentioned apps have a large text field where the user types and types and types( hey, they are text editing programs ).

  • scripsi is a special purpose dual paned text editor written in Vala
  • markdowner is a special purpose text editor written in Python

Both applications use the GTK+ toolkit to create the user interface.

The Problem


When a GTK TextView widget is used to create a large text input area, if the user's cursor travels past the viewable area of the TextView, which happens when typing to the bottom of the screen, the cursor is below the visible area and the user will need to stop typing and scroll the TextView until it is visible. If the user were a typing ninja then I suppose they wouldn't care about typing without knowing what text is showing up in the TextView. Well, I am not a typing ninja.

The Solution


There is probably a more elegant solution to the problem, but I couldn't find it so you are stuck with what I figured out, and this is my solution:

When the text changes, get the coordinates of the cursor and scroll to those coordinates. This will ensure that the cursor is always visible to the user. How would you like to see a working example in Vala?

Enter the Vala

/* woohoo */
using Gtk;
public static void mainstring[] args) {
  //initialize gtk
  Gtk.init(ref args);
  //make a window
  Window window new Window();
  //make a textbuffer
  TextBuffer textBuffer new TextBuffer(null);
  //make a textview with our buffer
  TextView textViewnew TextView.with_buffer(textBuffer);
  //let the textview wrap at word or char
  textView.set_wrap_mode(WrapMode.WORD_CHAR);
  //we need to know when the text buffer changes
  textBuffer.changed.connect( ()=>{
    //make a textiterator
    TextIter iter TextIter();
    //what is the cursors x coordinate?
    int textView.virtual_cursor_x;
    //what is the cursors y coordinate?
    int textView.virtual_cursor_y;
    //get the text iter at the cursor's coordinates
    textView.get_iter_at_location(out iter,x,y);
    //scroll to the cursor's text iter
    textView.scroll_to_iter(iter,0,false,0,0);
  });
  //make a scrolledwindow to hold the textviw
  ScrolledWindow scroll new ScrolledWindow (nullnull);
  //set the scrollwindow's scrolling policy
  scroll.set_policy (PolicyType.AUTOMATICPolicyType.AUTOMATIC);
  //add the textview to the scollwindow
  scroll.add (textView);
  //add the scrollwindow to our window
  window.add(scroll);
  //show all the widgets
  window.show_all();
  //run the gtk main loop
  Gtk.main();
}

Save the above code in a file named "cursor.vala" and compile with

valac --pkg=gtk+-2.0 cursor.vala -o cursor

Now I need to port the code to Python and implement the change in markdowner.

Now quit reading, and go fix a problem with a dirty hack.

Comments
2010-07-16 x1101:
Have you considered combining the two apps, and simply having different modes? I know, I know you hate features, but just a thought for the betterment for jezracorp
2010-07-16 jezra:
combining the apps would require rewriting markdowner in Vala (because I would prefer to have the app in Vala) and I'm too lazy to port the markdown library to Vala.
2010-07-25 Windigo:
Just a note - raw Markdown is getting pushed to the planet through your RSS feed. Not necessarily a bad thing, but it always gives me the feeling I'm watching you write in your underwear. :s

Also, I'm still working on that FOSScon blog post; depending on how things go, you might even see it today!
2010-10-20 jezra:
yea, this is crap and unnecessary when using ScrollWindow.add(child).
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
1 plus 2
Answer:
required
subscribe
 
2019
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008