Skip to content

Instantly share code, notes, and snippets.

@musiKk
Created March 31, 2012 17:30
Show Gist options
  • Select an option

  • Save musiKk/2266946 to your computer and use it in GitHub Desktop.

Select an option

Save musiKk/2266946 to your computer and use it in GitHub Desktop.
Draw arrow at cursor position in TextView in GTK3
#!/usr/bin/env python2
from gi.repository import Gtk
ARROW_DISTANCE = 5
ARROW_LENGTH = 250
ARROW_TRIANGLE_LENGTH = 100
ARROW_TRIANGLE_WIDTH = 30
def get_cursor_coordinates(self):
text_buffer = self.get_buffer()
text_mark = text_buffer.get_insert()
text_iter = text_buffer.get_iter_at_mark(text_mark)
l = self.get_iter_location(text_iter)
coords = self.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, 0, 0)
return l.x + coords[0], l.y + coords[1], l.width, l.height
# don't know how pythonic this is but it sure is useful
Gtk.TextView.get_cursor_coordinates = get_cursor_coordinates
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title='Text test')
self.set_default_size(500, 250)
vbox = Gtk.Box(False, orientation=Gtk.Orientation.VERTICAL)
self.add(vbox)
scrolled_text_view = Gtk.ScrolledWindow()
text_view = Gtk.TextView()
vbox.pack_start(scrolled_text_view, True, True, 0)
scrolled_text_view.add(text_view)
text_view.connect('draw', self.on_draw_text_view)
text_view.connect('move-cursor', self.on_update_cursor)
text_view.get_buffer().connect('changed', self.on_update_cursor)
self.text_view = text_view
def on_update_cursor(self, *args):
# w/o this there are artifacts remaining if arrow is too large
self.text_view.queue_draw()
def on_draw_text_view(self, text_view, ctxt):
x, y, w, h = text_view.get_cursor_coordinates()
arrow_x = x + ARROW_DISTANCE
arrow_y = y + (h / 2)
ctxt.move_to(arrow_x, arrow_y)
ctxt.line_to(arrow_x + ARROW_LENGTH, arrow_y)
ctxt.move_to(arrow_x, arrow_y)
ctxt.line_to(arrow_x + ARROW_TRIANGLE_LENGTH, arrow_y - ARROW_TRIANGLE_WIDTH)
ctxt.move_to(arrow_x, arrow_y)
ctxt.line_to(arrow_x + ARROW_TRIANGLE_LENGTH, arrow_y + ARROW_TRIANGLE_WIDTH)
ctxt.stroke()
if __name__ == '__main__':
win = MyWindow()
win.connect('delete-event', Gtk.main_quit)
win.show_all()
Gtk.main()
@mlafeldt
Copy link

mlafeldt commented Apr 1, 2012

I love it. :)

@musiKk
Copy link
Author

musiKk commented Apr 6, 2012

@mlafeldt: You sure are gonna love the updated version where there is no constraint on the size of the arrow. You know... bigger is always better. Especially when it comes to pointless arrows.

@mlafeldt
Copy link

mlafeldt commented Apr 7, 2012

Dirty code talk. Awesome. 💗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment