summaryrefslogtreecommitdiffhomepage
path: root/host/inter/drawable.py
blob: 52f28dd5ef39f978caa3b60e111e151dda43dc9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from math import sqrt, degrees
import trans_matrix
import Tkinter

__all__ = ('Drawable', 'DrawableCanvas')

class Drawable:
    """Define a drawable area with embeded transformations."""

    def __init__ (self, onto):
	"""Initialise the drawable."""
	self.onto = onto
	self.trans_matrix = trans_matrix.TransMatrix ()
	self.items = [ ]
	self.trans_apply = self.trans_matrix.apply
	self.trans_apply_angle = self.trans_matrix.apply_angle
	self.trans_apply_distance = self.trans_matrix.apply_distance
	self.trans_rotate = self.trans_matrix.rotate
	self.trans_translate = self.trans_matrix.translate
	self.trans_scale = self.trans_matrix.scale

    def __draw_rectangle (self, p1, p2, **kw):
	p = self.trans_apply (p1, (p2[0], p1[1]), p2, (p1[0], p2[1]))
	return self.onto.__draw_polygon (*p, **kw)

    def __draw_line (self, *p, **kw):
	p = self.trans_apply (*p)
	return self.onto.__draw_line (*p, **kw)

    def __draw_polygon (self, *p, **kw):
	p = self.trans_apply (*p)
	return self.onto.__draw_polygon (*p, **kw)

    def __draw_circle (self, p, r, **kw):
	p = self.trans_apply (p)
	r = self.trans_apply_distance (r)
	return self.onto.__draw_circle (p, r, **kw)

    def __draw_arc (self, p, r, **kw):
	p = self.trans_apply (p)
	r = self.trans_apply_distance (r)
	if 'start' in kw:
	    kw = kw.copy ()
	    kw['start'] = self.trans_apply_angle (kw['start'])
	    import math
	return self.onto.__draw_arc (p, r, **kw)

    def draw_rectangle (self, *p, **kw):
	"""Draw a rectangle."""
	self.items.append (self.__draw_rectangle (*p, **kw))

    def draw_line (self, *p, **kw):
	"""Draw a line."""
	self.items.append (self.__draw_line (*p, **kw))

    def draw_polygon (self, *p, **kw):
	"""Draw a line."""
	self.items.append (self.__draw_polygon (*p, **kw))

    def draw_circle (self, p, r, **kw):
	"""Draw a circle of the given radius centered on p."""
	self.items.append (self.__draw_circle (p, r, **kw))

    def draw_arc (self, p, r, **kw):
	"""Draw a arc of the given radius centered on p."""
	self.items.append (self.__draw_arc (p, r, **kw))

    def trans_reset (self):
	"""Reset transformations."""
	self.trans_matrix.identity ()

    def reset (self):
	self.__delete (*self.items)
	self.items = [ ]
	self.trans_reset ()

    def __delete (self, *list):
	"""Delete a list of items."""
	self.onto.__delete (*list)


class DrawableCanvas(Tkinter.Canvas):
    """Extend a Tkinter.Canvas to use Drawable on it."""

    def _Drawable__draw_line (self, *p, **kw):
	return self.create_line (*p, **kw)

    def _Drawable__draw_polygon (self, *p, **kw):
	return self.create_polygon (*p, **kw)

    def _Drawable__draw_circle (self, p, r, **kw):
	p1 = (p[0] - r, p[1] - r)
	p2 = (p[0] + r, p[1] + r)
	return self.create_oval (p1, p2, **kw)

    def _Drawable__draw_arc (self, p, r, **kw):
	p1 = (p[0] - r, p[1] - r)
	p2 = (p[0] + r, p[1] + r)
	for k in ('start', 'extent'):
	    if k in kw:
		kw = kw.copy ()
		# Tk is working upside down.
		kw[k] = -degrees (kw[k])
	return self.create_arc (p1, p2, **kw)

    def _Drawable__delete (self, *list):
	self.delete (*list)