Created
March 31, 2012 17:30
-
-
Save musiKk/2266946 to your computer and use it in GitHub Desktop.
Draw arrow at cursor position in TextView in GTK3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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() |
Author
I love it. :)
Author
@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.
Dirty code talk. Awesome. 💗
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
New at both Python and GTK. Don't hate me. :)