-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbox.py
147 lines (123 loc) · 3.58 KB
/
box.py
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
This module contains a Box class
"""
from colour import Colour
def _text_width(text: str) -> int:
"""
Return the width that this text takes up
"""
# TODO #1, take account of the fact that the text may be split into lines
char_width = 5
return len(text) * char_width
def _text_height(text: str) -> int:
"""
Return the width that this text takes up
"""
char_height = 5
lines = len(text.split("\n"))
return lines * char_height
class Box:
"""
The Box class is just what it says on the tin; it's a box!
"""
def __init__(
self,
x_pos: int,
y_pos: int,
text: str = "",
min_width: int = 10,
min_height: int = 10,
):
"""
Create a Box
Args:
x_pos: The x position of the box
y_pos: The y position of the box
text: The text to show in the box
min_width: The minimum width for the box
min_height: The minimum height for the box
"""
self.x_pos = x_pos
self.y_pos = y_pos
self.colour = Colour("black")
# These settings are ratios of how far up/across our anchor point
# is (0 => left, 0.5 => middle, 1 => right for x)
self.x_anchor = 0.5
self.y_anchor = 0.5
self._min_width = min_width
self._min_height = min_height
# Option to put text at the top of the box
self.text_top = False
# Setting the text will actually try to resize the box so we need to
# do this last to make sure the min and max have already been set
self.text = text
@property
def width(self) -> int:
"""
The width of the box
"""
return self._width
@width.setter
def width(self, value: int) -> None:
"""
Set the width but protect minimum
"""
self._width = max(self._min_width, value)
@property
def height(self) -> int:
"""
The height of the box
"""
return self._height
@height.setter
def height(self, value: int) -> None:
"""
Set the height but protect minimum
"""
self._height = max(self._min_height, value)
@property
def left(self):
"""
The x coord of the left of the box
"""
return int(float(self.x_pos) - (float(self.width) * float(self.x_anchor)))
@property
def right(self):
"""
The x coord of the right of the box
"""
return self.left + self.width
@property
def bottom(self):
"""
The y coord of the bottom of the box
"""
return int(float(self.y_pos) - (float(self.height) * float(self.y_anchor)))
@property
def top(self):
"""
The y coord of the top of the box
"""
return self.bottom + self.height
@property
def text(self) -> str:
"""
Get the text displayed in the box
"""
return self._text
@text.setter
def text(self, text: str) -> None:
"""
Setter for the text. Will try to resize the box to fit
"""
self._text = text
self.width = _text_width(text)
self.height = _text_height(text)
def draw(self, driver):
"""
Draw the box using the output driver provided
"""
driver.draw_box(self.left, self.bottom, self.right, self.top, self.colour)
text_y = self.top - 15 if self.text_top else self.bottom + (self.height) / 2.0
text_x = self.left + (self.width) / 2.0
driver.draw_text(self.text, text_x, text_y)