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 7, 2012

Dirty code talk. Awesome. 💗

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