blob: 886a5d3b05439c6915096347ac114c8e3ff509d5 [file] [log] [blame]
John Park91e69732019-03-03 13:12:43 -08001#!/usr/bin/python3
Parker Schuh19b93b12018-03-02 23:26:58 -08002import gi
Ravago Jones5127ccc2022-07-31 16:32:45 -07003
Parker Schuh19b93b12018-03-02 23:26:58 -08004gi.require_version('Gtk', '3.0')
5from gi.repository import Gtk
6from gi.repository import GLib
7from gi.repository import Gdk
8from gi.repository import GdkX11
9import cairo
Maxwell Henderson196ca0d2023-02-04 12:33:25 -080010from frc971.control_loops.python.constants import *
Parker Schuh19b93b12018-03-02 23:26:58 -080011
12identity = cairo.Matrix()
13
Ravago Jones26f7ad02021-02-05 15:45:59 -080014
Parker Schuh19b93b12018-03-02 23:26:58 -080015# Override the matrix of a cairo context.
16class OverrideMatrix(object):
Ravago Jones5127ccc2022-07-31 16:32:45 -070017
Parker Schuhdc682952018-03-03 18:24:01 -080018 def __init__(self, cr, matrix):
19 self.cr = cr
20 self.matrix = matrix
Parker Schuh19b93b12018-03-02 23:26:58 -080021
Parker Schuhdc682952018-03-03 18:24:01 -080022 def __enter__(self):
23 self.cr.save()
24 self.cr.set_matrix(self.matrix)
25
26 def __exit__(self, type, value, traceback):
27 self.cr.restore()
28
Parker Schuh19b93b12018-03-02 23:26:58 -080029
30mainloop = GLib.MainLoop()
31
Ravago Jones26f7ad02021-02-05 15:45:59 -080032
Tabitha Jarvis1007a132018-12-12 21:47:54 -080033def set_color(cr, color):
34 if color.a == 1.0:
35 cr.set_source_rgb(color.r, color.g, color.b)
36 else:
37 cr.set_source_rgba(color.r, color.g, color.b, color.a)
Parker Schuhdc682952018-03-03 18:24:01 -080038
Ravago Jones26f7ad02021-02-05 15:45:59 -080039
Parker Schuh19b93b12018-03-02 23:26:58 -080040def quit_main_loop(*args):
Parker Schuhdc682952018-03-03 18:24:01 -080041 mainloop.quit()
42
Ravago Jones26f7ad02021-02-05 15:45:59 -080043
Parker Schuh19b93b12018-03-02 23:26:58 -080044def RunApp():
Parker Schuhdc682952018-03-03 18:24:01 -080045 try:
46 mainloop.run()
47 except KeyboardInterrupt:
48 print('\nCtrl+C hit, quitting')
49 mainloop.quit()
50
Parker Schuh19b93b12018-03-02 23:26:58 -080051
52# Create a GTK+ widget on which we will draw using Cairo
53class BaseWindow(Gtk.DrawingArea):
Parker Schuh19b93b12018-03-02 23:26:58 -080054
Parker Schuhdc682952018-03-03 18:24:01 -080055 # Draw in response to an expose-event
56 def __init__(self):
57 super(BaseWindow, self).__init__()
Parker Schuh19b93b12018-03-02 23:26:58 -080058
Ravago Jones26f7ad02021-02-05 15:45:59 -080059 self.set_size_request(2 * SCREEN_SIZE, SCREEN_SIZE)
Parker Schuhdc682952018-03-03 18:24:01 -080060 self.center = (0, 0)
Ravago Jones26f7ad02021-02-05 15:45:59 -080061 self.shape = (2 * SCREEN_SIZE, SCREEN_SIZE)
Parker Schuhdc682952018-03-03 18:24:01 -080062 self.needs_redraw = False
Parker Schuh19b93b12018-03-02 23:26:58 -080063
Parker Schuhdc682952018-03-03 18:24:01 -080064 def get_current_scale(self):
65 w_w, w_h = self.window_shape
66 w, h = self.shape
67 return min((w_w / w), (w_h / h))
Parker Schuh19b93b12018-03-02 23:26:58 -080068
Parker Schuhdc682952018-03-03 18:24:01 -080069 def init_extents(self, center, shape):
70 self.center = center
71 self.shape = shape
Parker Schuh19b93b12018-03-02 23:26:58 -080072
Parker Schuhdc682952018-03-03 18:24:01 -080073 # The gtk system creates cr which is a cairo_context_t (in the c docs), and then it
74 # passes it as a function argument to the "draw" event. do_draw is the default name.
75 def do_draw(self, cr):
76 cr.save()
77 cr.set_font_size(20)
78 cr.translate(self.window_shape[0] / 2, self.window_shape[1] / 2)
79 scale = self.get_current_scale()
80 cr.scale(scale, -scale)
81 cr.translate(-self.center[0], -self.center[1])
Ravago Jonesb7e46f72021-01-16 15:43:29 -080082 cr.reset_clip()
Parker Schuhdc682952018-03-03 18:24:01 -080083 self.needs_redraw = False
84 self.handle_draw(cr)
85 cr.restore()
Parker Schuh19b93b12018-03-02 23:26:58 -080086
Parker Schuhdc682952018-03-03 18:24:01 -080087 # Handle the expose-event by drawing
88 def handle_draw(self, cr):
89 pass