blob: 7d93fe1fb8d7f718ef2f924ac6ef7e2ea24f1fb7 [file] [log] [blame]
Parker Schuh19b93b12018-03-02 23:26:58 -08001import gi
2gi.require_version('Gtk', '3.0')
3from gi.repository import Gtk
4from gi.repository import GLib
5from gi.repository import Gdk
6from gi.repository import GdkX11
7import cairo
8
9identity = cairo.Matrix()
10
11# Override the matrix of a cairo context.
12class OverrideMatrix(object):
13 def __init__(self, cr, matrix):
14 self.cr = cr
15 self.matrix = matrix
16 def __enter__(self):
17 self.cr.save()
18 self.cr.set_matrix(self.matrix)
19
20 def __exit__(self, type, value, traceback):
21 self.cr.restore();
22
23mainloop = GLib.MainLoop()
24
25def quit_main_loop(*args):
26 mainloop.quit()
27
28def RunApp():
29 try:
30 mainloop.run();
31 except KeyboardInterrupt:
32 print('\nCtrl+C hit, quitting')
33 mainloop.quit()
34
35# Create a GTK+ widget on which we will draw using Cairo
36class BaseWindow(Gtk.DrawingArea):
37 def method_connect(self, event, cb):
38 def handler(obj, *args):
39 cb(*args)
40 self.window.connect(event, handler)
41
42 # Draw in response to an expose-event
43 def __init__(self):
44 super().__init__()
45 self.window = Gtk.Window()
46 self.window.set_title("DrawingArea")
47 self.window.connect("destroy", quit_main_loop)
48 self.window.set_events(Gdk.EventMask.BUTTON_PRESS_MASK |
49 Gdk.EventMask.BUTTON_RELEASE_MASK |
50 Gdk.EventMask.POINTER_MOTION_MASK |
51 Gdk.EventMask.SCROLL_MASK |
52 Gdk.EventMask.KEY_PRESS_MASK
53 )
54 self.method_connect("key-press-event", self.do_key_press)
55 self.method_connect("button-press-event", self._do_button_press_internal)
56 self.method_connect("configure-event", self._do_configure)
57
58 self.set_size_request(640, 400) #640 * 2, 1229)
59 self.window.add(self)
60 self.window.show_all()
61 self.center = (0, 0)
62 self.shape = (640, 400)
63 self.needs_redraw = False
64
65 def get_current_scale(self):
66 w_w, w_h = self.window_shape
67 w, h = self.shape
68 return min((w_w / w), (w_h / h))
69
70 def init_extents(self, center, shape):
71 self.center = center
72 self.shape = shape
73
74 # The gtk system creates cr which is a cairo_context_t (in the c docs), and then it
75 # passes it as a function argument to the "draw" event. do_draw is the default name.
76 def do_draw(self, cr):
77 cr.save()
78 cr.set_font_size(20)
79 cr.translate(self.window_shape[0] / 2, self.window_shape[1] / 2)
80 scale = self.get_current_scale()
81 cr.scale(scale, -scale)
82 cr.translate(-self.center[0], -self.center[1])
83 self.needs_redraw = False
84 self.handle_draw(cr)
85 cr.restore()
86
87 # Handle the expose-event by drawing
88 def handle_draw(self, cr):
89 pass
90
91 def do_key_press(self, event):
92 pass
93
94 def _do_button_press_internal(self, event):
95 o_x = event.x
96 o_y = event.y
97 x = event.x - self.window_shape[0] / 2
98 y = self.window_shape[1] / 2 - event.y
99 scale = self.get_current_scale()
100 event.x = x / scale + self.center[0]
101 event.y = y / scale + self.center[1]
102 self.do_button_press(event)
103 event.x = o_x
104 event.y = o_y
105
106 def do_button_press(self, event):
107 pass
108
109 def _do_configure(self, event):
110 self.window_shape = (event.width, event.height)
111
112 def redraw(self):
113 if not self.needs_redraw:
114 self.needs_redraw = True
115 self.window.queue_draw()