e2D 1.3.7__tar.gz → 1.3.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {e2D-1.3.7 → e2D-1.3.9}/PKG-INFO +1 -1
- {e2D-1.3.7 → e2D-1.3.9}/e2D/envs.py +1 -1
- e2D-1.3.9/e2D/plots.py +355 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D.egg-info/PKG-INFO +1 -1
- {e2D-1.3.7 → e2D-1.3.9}/setup.cfg +1 -1
- e2D-1.3.7/e2D/plots.py +0 -274
- {e2D-1.3.7 → e2D-1.3.9}/LICENSE +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/README.md +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D/__init__.py +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D/utils.py +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D.egg-info/SOURCES.txt +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D.egg-info/dependency_links.txt +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D.egg-info/requires.txt +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/e2D.egg-info/top_level.txt +0 -0
- {e2D-1.3.7 → e2D-1.3.9}/pyproject.toml +0 -0
{e2D-1.3.7 → e2D-1.3.9}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: e2D
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.9
|
|
4
4
|
Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
|
|
5
5
|
Home-page: https://github.com/marick-py/e2D
|
|
6
6
|
Author: Riccardo Mariani
|
|
@@ -25,7 +25,7 @@ pg.font.init()
|
|
|
25
25
|
font_arial_16 = pg.font.SysFont("Arial", 16)
|
|
26
26
|
font_arial_32 = pg.font.SysFont("Arial", 32)
|
|
27
27
|
font_arial_64 = pg.font.SysFont("Arial", 64)
|
|
28
|
-
|
|
28
|
+
create_arial_font_size = lambda size: pg.font.SysFont("Arial", size)
|
|
29
29
|
|
|
30
30
|
TEXT_FIXED_SIDES_TOP_LEFT = 0
|
|
31
31
|
TEXT_FIXED_SIDES_TOP_MIDDLE = 1
|
e2D-1.3.9/e2D/plots.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from .envs import *
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
def no_error_complex_function(function, args) -> V2|Vector2D:
|
|
6
|
+
res :complex= function(args)
|
|
7
|
+
return V2(res.real, res.imag)
|
|
8
|
+
|
|
9
|
+
sign = lambda value: -1 if value < 0 else (1 if value > 0 else 0)
|
|
10
|
+
|
|
11
|
+
class Function:
|
|
12
|
+
def __init__(self, function, color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
|
|
13
|
+
self.plot : Plot
|
|
14
|
+
self.color = color
|
|
15
|
+
self.function = function
|
|
16
|
+
self.__layer_surface__ :pg.Surface= None #type: ignore
|
|
17
|
+
|
|
18
|
+
def update_points(self) -> None:
|
|
19
|
+
self.update_function(self.function)
|
|
20
|
+
|
|
21
|
+
def get_points(self) -> list:
|
|
22
|
+
signs_self = np.sign(self.function(*self.plot.meshgrid))
|
|
23
|
+
signs_sum = signs_self + np.roll(signs_self, axis=1, shift=1) + np.roll(signs_self, axis=0, shift=-1) + np.roll(signs_self, axis=(1,0), shift=(1,-1))
|
|
24
|
+
return np.column_stack(np.where(((-4 < signs_sum) & (signs_sum < 4))[:-1, 1:])[::-1]) / self.plot.scale()
|
|
25
|
+
|
|
26
|
+
def update_function(self, new_function) -> None:
|
|
27
|
+
self.function = new_function
|
|
28
|
+
self.points = self.get_points()
|
|
29
|
+
self.render()
|
|
30
|
+
|
|
31
|
+
def get_derivative(self, delta:float=.01, color:None|list[float]|tuple[float,float,float]=None) -> Function:
|
|
32
|
+
return Function(lambda x,y: (self.function(x + delta, y) - self.function(x,y))/delta - y, color if color != None else self.color)
|
|
33
|
+
|
|
34
|
+
def render(self) -> None:
|
|
35
|
+
self.__layer_surface__.fill((0,0,0,0))
|
|
36
|
+
offset = self.plot.dragging - self.plot.start_dragging if (self.plot.dragging != None) and (not self.plot.settings.get("use_real_time_rendering")) else V2z
|
|
37
|
+
if any(x < 1 for x in self.plot.scale):
|
|
38
|
+
# draw rects
|
|
39
|
+
for point in self.points:
|
|
40
|
+
pg.draw.rect(self.__layer_surface__, self.color, (point.tolist() + offset)() + self.plot.pixel_size()) #type: ignore
|
|
41
|
+
else:
|
|
42
|
+
# draw points
|
|
43
|
+
for point in self.points:
|
|
44
|
+
point = point.astype(int).tolist()
|
|
45
|
+
if self.plot.dragging != None:
|
|
46
|
+
point = round(point + offset)()
|
|
47
|
+
self.__layer_surface__.set_at(point, self.color)
|
|
48
|
+
|
|
49
|
+
def draw(self) -> None:
|
|
50
|
+
self.plot.canvas.blit(self.__layer_surface__, (0,0))
|
|
51
|
+
|
|
52
|
+
# class ComplexFunction:
|
|
53
|
+
# def __init__(self, function, plot:"Plot", starting_t:float=-10, ending_t:float=10, step=.01, color=(255,255,255), auto_connect_treshold=float("inf"), points_radius=2, points_color=None) -> None:
|
|
54
|
+
# self.auto_connect_treshold = auto_connect_treshold
|
|
55
|
+
# self.plot = plot
|
|
56
|
+
# self.starting_t = starting_t
|
|
57
|
+
# self.ending_t = ending_t
|
|
58
|
+
# self.color = color
|
|
59
|
+
# self.step = step
|
|
60
|
+
# self.points_color = points_color
|
|
61
|
+
# self.points_radius = points_radius
|
|
62
|
+
# self.update_function(function)
|
|
63
|
+
|
|
64
|
+
# def update_points(self) -> None:
|
|
65
|
+
# self.update_function(self.function)
|
|
66
|
+
|
|
67
|
+
# def update_function(self, new_function) -> None:
|
|
68
|
+
# self.function = new_function
|
|
69
|
+
# self.points :list[V2|Vector2D]= [point for t in range(int(self.starting_t / self.step), int(self.ending_t / self.step)) if (self.plot.bottom_right_y < (point:=no_error_complex_function(new_function, t * self.step)).y < self.plot.top_left_y) and (self.plot.top_left_x < point.x < self.plot.bottom_right_x)]
|
|
70
|
+
# self.full_auto_connect = not any(point.distance_to(self.points[i]) > self.auto_connect_treshold for i,point in enumerate(self.points[1:]))
|
|
71
|
+
|
|
72
|
+
# def draw(self) -> None:
|
|
73
|
+
# if self.points_radius:
|
|
74
|
+
# for point in self.points:
|
|
75
|
+
# pg.draw.circle(self.plot.canvas, self.color if self.points_color == None else self.points_color, self.plot.__plot2real__(point)(), self.points_radius)
|
|
76
|
+
|
|
77
|
+
# if len(self.points) < 2: return
|
|
78
|
+
# if self.full_auto_connect:
|
|
79
|
+
# pg.draw.lines(self.plot.canvas, self.color, False, [self.plot.__plot2real__(point)() for point in self.points])
|
|
80
|
+
# else:
|
|
81
|
+
# real_points = [self.plot.__plot2real__(point)() for point in self.points]
|
|
82
|
+
# for i,(point, real_point) in enumerate(zip(self.points[1:], real_points[1:])):
|
|
83
|
+
# if point.distance_to(self.points[i]) < self.auto_connect_treshold:
|
|
84
|
+
# pg.draw.line(self.plot.canvas, self.color, real_points[i], real_point) #type: ignore
|
|
85
|
+
|
|
86
|
+
class __PlotSettings__:
|
|
87
|
+
def __init__(self, plot:Plot) -> None:
|
|
88
|
+
self.plot = plot
|
|
89
|
+
self.settings :dict= {
|
|
90
|
+
# axes
|
|
91
|
+
"distance_to_axis_for_scalar_zoom" : 10,
|
|
92
|
+
|
|
93
|
+
# cursor
|
|
94
|
+
"show_cursor_coords" : False,
|
|
95
|
+
"zoom_on_center" : False,
|
|
96
|
+
|
|
97
|
+
# plot visual options
|
|
98
|
+
# plot system
|
|
99
|
+
"use_inter_pixel_correction" : True,
|
|
100
|
+
"use_real_time_rendering" : True,
|
|
101
|
+
|
|
102
|
+
# axes
|
|
103
|
+
"change_axes_colors_on_mouse_hover" : True,
|
|
104
|
+
"mouse_hover_axes_color" : rgb(200, 200, 200),
|
|
105
|
+
"show_axes" : True,
|
|
106
|
+
"show_x_axis" : True,
|
|
107
|
+
"show_y_axis" : True,
|
|
108
|
+
"axes_default_color" : rgb(100, 100, 100),
|
|
109
|
+
"x_axis_color" : None,
|
|
110
|
+
"y_axis_color" : None,
|
|
111
|
+
"axes_default_width" : 5,
|
|
112
|
+
"x_axis_width" : None,
|
|
113
|
+
"y_axis_width" : None,
|
|
114
|
+
"render_axes_on_top" : False,
|
|
115
|
+
|
|
116
|
+
# grid
|
|
117
|
+
"show_grid" : True,
|
|
118
|
+
"grid_step" : V2(PI, 1),
|
|
119
|
+
"grid_color" : rgb(17, 65, 68),
|
|
120
|
+
"grid_width" : 1,
|
|
121
|
+
|
|
122
|
+
# pointer
|
|
123
|
+
"show_pointer" : True,
|
|
124
|
+
"pointer_radius" : 15,
|
|
125
|
+
"pointer_color" : rgb(255, 255, 255),
|
|
126
|
+
|
|
127
|
+
#rect
|
|
128
|
+
"render_bg" : True,
|
|
129
|
+
"bg_color" : rgb(28, 29, 34),
|
|
130
|
+
"draw_rect" : True,
|
|
131
|
+
"rect_color" : rgb(255, 255, 255),
|
|
132
|
+
"rect_width" : 5,
|
|
133
|
+
"show_corners_coords" : True,
|
|
134
|
+
|
|
135
|
+
# info options
|
|
136
|
+
"show_zoom_info": True,
|
|
137
|
+
"top_left_info_position" : self.plot.position + V2(20, 100),
|
|
138
|
+
"info_interline_space" : V2(0, 32),
|
|
139
|
+
"info_precision" : 2,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
def print_current_settings(self) -> None:
|
|
143
|
+
longest_key = max(map(len, self.settings))
|
|
144
|
+
longest_type = max(map(lambda setting: len(str(type(setting)).split("'")[1]), self.settings.values()))
|
|
145
|
+
split_string = "'"
|
|
146
|
+
texts = [
|
|
147
|
+
f"{setting}{' '*(longest_key-len(setting))} :{str(type(self.settings[setting])).split(split_string)[1]}{' '*(longest_type-len(str(type(self.settings[setting])).split(split_string)[1]))}=\t{self.settings[setting]}"
|
|
148
|
+
for setting in self.settings
|
|
149
|
+
]
|
|
150
|
+
longest_text = max(map(len , texts))
|
|
151
|
+
print("=" * longest_text)
|
|
152
|
+
for text in texts:
|
|
153
|
+
print(text)
|
|
154
|
+
print("=" * longest_text)
|
|
155
|
+
|
|
156
|
+
def toggle(self, key:str) -> None:
|
|
157
|
+
self.set(key, not self.get(key))
|
|
158
|
+
|
|
159
|
+
def set(self, key:str, new_value) -> None:
|
|
160
|
+
if not (key in self.settings): raise ValueError(f"The key [{key}] does not exist...")
|
|
161
|
+
self.settings[key] = new_value
|
|
162
|
+
|
|
163
|
+
def multiple_set(self, new_key_and_values_dict:dict) -> None:
|
|
164
|
+
self.settings.update(new_key_and_values_dict)
|
|
165
|
+
|
|
166
|
+
def get(self, key:str) -> bool|V2|Vector2D|int|float:
|
|
167
|
+
return self.settings[key]
|
|
168
|
+
|
|
169
|
+
def multiple_get(self, keys:list[str]) -> list[bool|V2|Vector2D|int|float]:
|
|
170
|
+
return [self.get(key) for key in keys]
|
|
171
|
+
|
|
172
|
+
class Plot:
|
|
173
|
+
__y_axis_multiplier__ = V2(1, -1)
|
|
174
|
+
def __init__(self, rootEnv:"RootEnv", plot_position:V2|Vector2D, plot_size:V2|Vector2D, top_left_plot_coord:V2|Vector2D, bottom_right_plot_coord: V2|Vector2D, scale:V2|Vector2D=V2one) -> None:
|
|
175
|
+
self.rootEnv = rootEnv
|
|
176
|
+
|
|
177
|
+
self.top_left_plot_coord = top_left_plot_coord
|
|
178
|
+
self.bottom_right_plot_coord = bottom_right_plot_coord
|
|
179
|
+
|
|
180
|
+
self.position = plot_position
|
|
181
|
+
self.size = plot_size
|
|
182
|
+
self.scale = scale
|
|
183
|
+
|
|
184
|
+
self.settings = __PlotSettings__(self)
|
|
185
|
+
|
|
186
|
+
self.current_zoom = V2one * -np.log2(10)*10
|
|
187
|
+
self.current_offset = V2(0,0)
|
|
188
|
+
self.update_grid(True)
|
|
189
|
+
|
|
190
|
+
self.functions :list[Function]= []
|
|
191
|
+
|
|
192
|
+
self.canvas = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
|
|
193
|
+
self.dragging = None
|
|
194
|
+
self.start_dragging = V2z
|
|
195
|
+
self.is_mouse_in_rect = False
|
|
196
|
+
self.mouse_scalar = V2one.copy()
|
|
197
|
+
|
|
198
|
+
def set_borders_by_position_and_zoom(self) -> None:
|
|
199
|
+
self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
|
|
200
|
+
self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
|
|
201
|
+
self.top_left_x, self.top_left_y = self.top_left_plot_coord
|
|
202
|
+
self.bottom_right_x, self.bottom_right_y = self.bottom_right_plot_coord
|
|
203
|
+
|
|
204
|
+
def update_grid(self, update_step_grid=False) -> None:
|
|
205
|
+
self.set_borders_by_position_and_zoom()
|
|
206
|
+
if update_step_grid:
|
|
207
|
+
self.step = (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size / self.scale
|
|
208
|
+
X, Y = np.arange(self.top_left_plot_coord.x, self.bottom_right_plot_coord.x, self.step.x), np.arange(self.top_left_plot_coord.y, self.bottom_right_plot_coord.y, self.step.y)
|
|
209
|
+
self.meshgrid = np.meshgrid(X, Y)
|
|
210
|
+
self.pixel_size = abs(self.size / (self.bottom_right_plot_coord - self.top_left_plot_coord) * (self.step * -1))
|
|
211
|
+
if self.settings.get("use_inter_pixel_correction"):
|
|
212
|
+
self.pixel_size += V2one
|
|
213
|
+
|
|
214
|
+
def load_function(self, function:Function) -> None:
|
|
215
|
+
function.plot = self
|
|
216
|
+
function.__layer_surface__ = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
|
|
217
|
+
function.update_function(function.function)
|
|
218
|
+
self.functions.append(function)
|
|
219
|
+
|
|
220
|
+
def __plot2real__(self, plot_position:V2|Vector2D) -> V2|Vector2D:
|
|
221
|
+
return (plot_position + self.top_left_plot_coord * -1) * self.size / (self.bottom_right_plot_coord - self.top_left_plot_coord)
|
|
222
|
+
|
|
223
|
+
def __real2plot__(self, real_position:V2|Vector2D) -> V2|Vector2D:
|
|
224
|
+
return (real_position - self.position) * (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size + self.top_left_plot_coord
|
|
225
|
+
|
|
226
|
+
def render(self) -> None:
|
|
227
|
+
# fill canvas with alpha zero color
|
|
228
|
+
self.canvas.fill((0,0,0,0))
|
|
229
|
+
|
|
230
|
+
# draw grid
|
|
231
|
+
if self.settings.get("show_grid"):
|
|
232
|
+
grid_step = self.settings.get("grid_step")
|
|
233
|
+
grid_color = self.settings.get("grid_color")
|
|
234
|
+
grid_width = self.settings.get("grid_width")
|
|
235
|
+
clamped_top_left = grid_step * (self.top_left_plot_coord / grid_step).__ceil__()
|
|
236
|
+
clamped_bottom_right = grid_step * (self.bottom_right_plot_coord / grid_step).__ceil__()
|
|
237
|
+
for x_value in np.arange(clamped_top_left.x, clamped_bottom_right.x, grid_step.x):
|
|
238
|
+
pg.draw.line( self.canvas, grid_color, self.__plot2real__((x_value, self.top_left_y))(), self.__plot2real__((x_value, self.bottom_right_y))(), grid_width)
|
|
239
|
+
for y_value in np.arange(clamped_bottom_right.y, clamped_top_left.y, grid_step.y):
|
|
240
|
+
pg.draw.line(self.canvas, grid_color, self.__plot2real__((self.top_left_x, y_value))(), self.__plot2real__((self.bottom_right_x, y_value))(), grid_width)
|
|
241
|
+
|
|
242
|
+
# draw functions
|
|
243
|
+
for function in self.functions: function.draw()
|
|
244
|
+
|
|
245
|
+
# draw rect, pointer and corner coords
|
|
246
|
+
if self.settings.get("draw_rect"):
|
|
247
|
+
pg.draw.rect(self.canvas, self.settings.get("rect_color"), V2z() + self.size(), self.settings.get("rect_width"))
|
|
248
|
+
|
|
249
|
+
if self.settings.get("show_pointer"):
|
|
250
|
+
center = self.size * .5
|
|
251
|
+
aimer_radius = self.settings.get("pointer_radius")
|
|
252
|
+
pointer_color = self.settings.get("pointer_color")
|
|
253
|
+
pg.draw.line(self.canvas, pointer_color, (center + aimer_radius)(), (center - aimer_radius)(), 1)
|
|
254
|
+
pg.draw.line(self.canvas, pointer_color, (center + self.__y_axis_multiplier__ * aimer_radius)(), (center - self.__y_axis_multiplier__ * aimer_radius)(), 1)
|
|
255
|
+
pg.draw.circle(self.canvas, pointer_color, (self.size * .5)(), 15, 1)
|
|
256
|
+
|
|
257
|
+
if self.settings.get("show_corners_coords"):
|
|
258
|
+
self.rootEnv.print(str(self.top_left_plot_coord), V2z.copy(), bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
259
|
+
self.rootEnv.print(str(V2(self.top_left_plot_coord.x, self.bottom_right_plot_coord.y)), self.size * V2(0, 1), fixed_sides=TEXT_FIXED_SIDES_BOTTOM_LEFT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
260
|
+
self.rootEnv.print(str(self.bottom_right_plot_coord), self.size.copy(), fixed_sides=TEXT_FIXED_SIDES_BOTTOM_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
261
|
+
self.rootEnv.print(str(V2(self.bottom_right_plot_coord.x, self.top_left_plot_coord.y)), self.size * V2(1, 0), fixed_sides=TEXT_FIXED_SIDES_TOP_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
262
|
+
|
|
263
|
+
def update(self) -> None:
|
|
264
|
+
# update mouse and center positions
|
|
265
|
+
self.plot_mouse_position = self.__real2plot__(self.rootEnv.mouse.position)
|
|
266
|
+
self.plot_center_real_position = self.__plot2real__(V2z) + self.position
|
|
267
|
+
|
|
268
|
+
self.is_mouse_in_rect = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
|
|
269
|
+
self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
|
|
270
|
+
|
|
271
|
+
# render the functions when i stop dragging (when i release the left mouse key)
|
|
272
|
+
if self.rootEnv.mouse.just_released[0] and self.dragging != None:
|
|
273
|
+
self.dragging = None
|
|
274
|
+
self.update_grid(True)
|
|
275
|
+
for function in self.functions:
|
|
276
|
+
function.update_points()
|
|
277
|
+
self.render()
|
|
278
|
+
|
|
279
|
+
if self.is_mouse_in_rect:
|
|
280
|
+
# mouse scalar is needed for checking if the mouse is hovering an axis, in case it is the opposite one zoom value has to be multiplied by 0 so nullifying it.
|
|
281
|
+
self.mouse_scalar = V2(0 if abs(self.plot_center_real_position.x - self.rootEnv.mouse.position.x) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1, 0 if abs(self.plot_center_real_position.y - self.rootEnv.mouse.position.y) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1) #type: ignore
|
|
282
|
+
if self.mouse_scalar.x == self.mouse_scalar.y == 0: self.mouse_scalar = V2one
|
|
283
|
+
for event in self.rootEnv.events:
|
|
284
|
+
if event.type == pg.MOUSEWHEEL:
|
|
285
|
+
if self.settings.get("zoom_on_center"):
|
|
286
|
+
# this will always zoom exactly in the middle of the canvas, according to the current plot offset
|
|
287
|
+
self.current_zoom += event.y * self.mouse_scalar
|
|
288
|
+
else:
|
|
289
|
+
# this will get the pre plot mouse position, calculate the zoom and with the "after" mouse position calculate the offset that i will add to the current plot offset
|
|
290
|
+
pre = self.__real2plot__(self.rootEnv.mouse.position)
|
|
291
|
+
self.current_zoom += event.y * self.mouse_scalar
|
|
292
|
+
# i have to update the corners of the plot here to use the real2plot function correctly (i cant use shortcuts)
|
|
293
|
+
self.update_grid(False)
|
|
294
|
+
self.current_offset += pre - self.__real2plot__(self.rootEnv.mouse.position)
|
|
295
|
+
self.update_grid(True)
|
|
296
|
+
for function in self.functions:
|
|
297
|
+
function.update_points()
|
|
298
|
+
self.render()
|
|
299
|
+
|
|
300
|
+
# start dragging whenever mouse left button is just pressed
|
|
301
|
+
if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
|
|
302
|
+
self.dragging = self.rootEnv.mouse.position.copy()
|
|
303
|
+
self.start_dragging = self.dragging.copy()
|
|
304
|
+
|
|
305
|
+
# update the canvas if im dragging
|
|
306
|
+
if self.dragging:
|
|
307
|
+
offset = (self.dragging - self.rootEnv.mouse.position)* V2(1, -1) * (abs(self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size)
|
|
308
|
+
self.dragging = self.rootEnv.mouse.position.copy()
|
|
309
|
+
self.current_offset += offset
|
|
310
|
+
|
|
311
|
+
# with real time rendering i update the function render each frame whnever im dragging the canvs around
|
|
312
|
+
if self.settings.get("use_real_time_rendering"):
|
|
313
|
+
self.update_grid(True)
|
|
314
|
+
for function in self.functions: function.update_points()
|
|
315
|
+
else:
|
|
316
|
+
self.update_grid()
|
|
317
|
+
self.render()
|
|
318
|
+
|
|
319
|
+
def draw(self) -> None:
|
|
320
|
+
# fill canvas with bg color
|
|
321
|
+
if self.settings.get("render_bg"):
|
|
322
|
+
self.rootEnv.screen.fill(self.settings.get("bg_color"), self.position() + self.size())
|
|
323
|
+
|
|
324
|
+
# render functions before axes
|
|
325
|
+
if render_axes_on_top:=self.settings.get("render_axes_on_top"): self.rootEnv.screen.blit(self.canvas, self.position())
|
|
326
|
+
|
|
327
|
+
# render axes
|
|
328
|
+
if self.top_left_x < 0 < self.bottom_right_x and (self.settings.get("show_x_axis") and self.settings.get("show_axes")):
|
|
329
|
+
pg.draw.line(self.rootEnv.screen,
|
|
330
|
+
(self.settings.get("axes_default_color") if (x_color:=self.settings.get("x_axis_color"))==None else x_color) if self.mouse_scalar.x else (self.settings.get("mouse_hover_axes_color")),
|
|
331
|
+
(self.__plot2real__(V2(0, self.top_left_y)) + self.position)(),
|
|
332
|
+
(self.__plot2real__(V2(0, self.bottom_right_y)) + self.position)(),
|
|
333
|
+
self.settings.get("axes_default_width") if (x_width:=self.settings.get("x_axis_width"))==None else x_width) #type: ignore
|
|
334
|
+
if self.bottom_right_y < 0 < self.top_left_y and (self.settings.get("show_y_axis") and self.settings.get("show_axes")):
|
|
335
|
+
pg.draw.line(self.rootEnv.screen,
|
|
336
|
+
(self.settings.get("axes_default_color") if (y_color:=self.settings.get("y_axis_color"))==None else y_color) if self.mouse_scalar.y else (self.settings.get("mouse_hover_axes_color")),
|
|
337
|
+
(self.__plot2real__(V2(self.top_left_x, 0)) + self.position)(),
|
|
338
|
+
(self.__plot2real__(V2(self.bottom_right_x, 0)) + self.position)(),
|
|
339
|
+
self.settings.get("axes_default_width") if (y_width:=self.settings.get("y_axis_width"))==None else y_width) #type: ignore
|
|
340
|
+
|
|
341
|
+
# render functions after axes
|
|
342
|
+
if not render_axes_on_top: self.rootEnv.screen.blit(self.canvas, self.position())
|
|
343
|
+
|
|
344
|
+
if self.is_mouse_in_rect and self.settings.get("show_cursor_coords"):
|
|
345
|
+
self.rootEnv.print(str(self.plot_mouse_position), self.rootEnv.mouse.position, fixed_sides=TEXT_FIXED_SIDES_BOTTOM_MIDDLE) #type: ignore
|
|
346
|
+
|
|
347
|
+
data = [
|
|
348
|
+
[f"ZOOM:", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
349
|
+
[f" x: {(.5**(.1*self.current_zoom.x)):.{self.settings.get('info_precision')}f};", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
350
|
+
[f" y: {(.5**(.1*self.current_zoom.y)):.{self.settings.get('info_precision')}f};", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
for i, (d, fixed_side, show) in enumerate(data):
|
|
354
|
+
if show:
|
|
355
|
+
self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("info_interline_space") * i, fixed_sides=fixed_side) #type: ignore
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: e2D
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.9
|
|
4
4
|
Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
|
|
5
5
|
Home-page: https://github.com/marick-py/e2D
|
|
6
6
|
Author: Riccardo Mariani
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = e2D
|
|
3
|
-
version = 1.3.
|
|
3
|
+
version = 1.3.9
|
|
4
4
|
author = Riccardo Mariani
|
|
5
5
|
author_email = ricomari2006@gmail.com
|
|
6
6
|
description = Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
|
e2D-1.3.7/e2D/plots.py
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from .envs import *
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
def no_error_complex_function(function, args) -> V2|Vector2D:
|
|
6
|
-
res :complex= function(args)
|
|
7
|
-
return V2(res.real, res.imag)
|
|
8
|
-
|
|
9
|
-
sign = lambda value: -1 if value < 0 else (1 if value > 0 else 0)
|
|
10
|
-
|
|
11
|
-
class Function:
|
|
12
|
-
def __init__(self, function, color) -> None:
|
|
13
|
-
self.plot : Plot
|
|
14
|
-
self.color = color
|
|
15
|
-
self.function = function
|
|
16
|
-
self.__layer_surface__ :pg.Surface= None #type: ignore
|
|
17
|
-
|
|
18
|
-
def update_points(self) -> None:
|
|
19
|
-
self.update_function(self.function)
|
|
20
|
-
|
|
21
|
-
def get_points(self) -> list:
|
|
22
|
-
signs_self = np.sign(self.function(*self.plot.meshgrid))
|
|
23
|
-
signs_sum = signs_self + np.roll(signs_self, axis=1, shift=1) + np.roll(signs_self, axis=0, shift=-1) + np.roll(signs_self, axis=(1,0), shift=(1,-1))
|
|
24
|
-
return np.column_stack(np.where(((-4 < signs_sum) & (signs_sum < 4))[:-1, 1:])[::-1]) / self.plot.scale()
|
|
25
|
-
|
|
26
|
-
def update_function(self, new_function) -> None:
|
|
27
|
-
self.function = new_function
|
|
28
|
-
self.points = self.get_points()
|
|
29
|
-
self.render()
|
|
30
|
-
|
|
31
|
-
def render(self) -> None:
|
|
32
|
-
self.__layer_surface__.fill((0,0,0,0))
|
|
33
|
-
offset = self.plot.dragging - self.plot.start_dragging if (self.plot.dragging != None) and (not self.plot.settings.get("use_real_time_rendering")) else None
|
|
34
|
-
if any(x < 1 for x in self.plot.scale):
|
|
35
|
-
for point in self.points:
|
|
36
|
-
# radius = max(min(self.plot.pixel_size)*.5, 1)
|
|
37
|
-
# pg.draw.circle(self.plot.canvas, self.color, (point + self.plot.pixel_size*.5)(), radius)
|
|
38
|
-
pg.draw.rect(self.__layer_surface__, self.color, (point.tolist() + (offset if offset != None else V2z))() + self.plot.pixel_size()) #type: ignore
|
|
39
|
-
else:
|
|
40
|
-
for point in self.points:
|
|
41
|
-
point = point.astype(int).tolist()
|
|
42
|
-
if self.plot.dragging != None:
|
|
43
|
-
point = round(point + offset)()
|
|
44
|
-
self.__layer_surface__.set_at(point, self.color)
|
|
45
|
-
|
|
46
|
-
def draw(self) -> None:
|
|
47
|
-
self.plot.canvas.blit(self.__layer_surface__, (0,0))
|
|
48
|
-
|
|
49
|
-
# class ComplexFunction:
|
|
50
|
-
# def __init__(self, function, plot:"Plot", starting_t:float=-10, ending_t:float=10, step=.01, color=(255,255,255), auto_connect_treshold=float("inf"), points_radius=2, points_color=None) -> None:
|
|
51
|
-
# self.auto_connect_treshold = auto_connect_treshold
|
|
52
|
-
# self.plot = plot
|
|
53
|
-
# self.starting_t = starting_t
|
|
54
|
-
# self.ending_t = ending_t
|
|
55
|
-
# self.color = color
|
|
56
|
-
# self.step = step
|
|
57
|
-
# self.points_color = points_color
|
|
58
|
-
# self.points_radius = points_radius
|
|
59
|
-
# self.update_function(function)
|
|
60
|
-
|
|
61
|
-
# def update_points(self) -> None:
|
|
62
|
-
# self.update_function(self.function)
|
|
63
|
-
|
|
64
|
-
# def update_function(self, new_function) -> None:
|
|
65
|
-
# self.function = new_function
|
|
66
|
-
# self.points :list[V2|Vector2D]= [point for t in range(int(self.starting_t / self.step), int(self.ending_t / self.step)) if (self.plot.bottom_right_y < (point:=no_error_complex_function(new_function, t * self.step)).y < self.plot.top_left_y) and (self.plot.top_left_x < point.x < self.plot.bottom_right_x)]
|
|
67
|
-
# self.full_auto_connect = not any(point.distance_to(self.points[i]) > self.auto_connect_treshold for i,point in enumerate(self.points[1:]))
|
|
68
|
-
|
|
69
|
-
# def draw(self) -> None:
|
|
70
|
-
# if self.points_radius:
|
|
71
|
-
# for point in self.points:
|
|
72
|
-
# pg.draw.circle(self.plot.canvas, self.color if self.points_color == None else self.points_color, self.plot.__plot2real__(point)(), self.points_radius)
|
|
73
|
-
|
|
74
|
-
# if len(self.points) < 2: return
|
|
75
|
-
# if self.full_auto_connect:
|
|
76
|
-
# pg.draw.lines(self.plot.canvas, self.color, False, [self.plot.__plot2real__(point)() for point in self.points])
|
|
77
|
-
# else:
|
|
78
|
-
# real_points = [self.plot.__plot2real__(point)() for point in self.points]
|
|
79
|
-
# for i,(point, real_point) in enumerate(zip(self.points[1:], real_points[1:])):
|
|
80
|
-
# if point.distance_to(self.points[i]) < self.auto_connect_treshold:
|
|
81
|
-
# pg.draw.line(self.plot.canvas, self.color, real_points[i], real_point) #type: ignore
|
|
82
|
-
|
|
83
|
-
class __PlotSettings__:
|
|
84
|
-
def __init__(self, plot:Plot) -> None:
|
|
85
|
-
self.plot = plot
|
|
86
|
-
self.settings :dict= {
|
|
87
|
-
"use_real_time_rendering" : True,
|
|
88
|
-
"show_corners_coords" : True,
|
|
89
|
-
|
|
90
|
-
"use_inter_pixel_correction" : True,
|
|
91
|
-
|
|
92
|
-
"show_zoom_info": True,
|
|
93
|
-
"top_left_info_position" : self.plot.position + V2(20, 100),
|
|
94
|
-
"info_spacing" : V2(0, 32),
|
|
95
|
-
"info_precision" : 2,
|
|
96
|
-
|
|
97
|
-
"distance_to_axis_for_scalar_zoom" : 10,
|
|
98
|
-
|
|
99
|
-
"bg_color" : (25, 25, 25),
|
|
100
|
-
"axes_default_color" : (100, 100, 100),
|
|
101
|
-
"x_axis_color" : None,
|
|
102
|
-
"y_axis_color" : None,
|
|
103
|
-
|
|
104
|
-
"axes_default_width" : 5,
|
|
105
|
-
"x_axis_width" : None,
|
|
106
|
-
"y_axis_width" : None,
|
|
107
|
-
|
|
108
|
-
"show_cursor_coords" : False,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
def print_current_settings(self) -> None:
|
|
112
|
-
longest_key = max(map(len, self.settings))
|
|
113
|
-
longest_type = max(map(lambda setting: len(str(type(setting)).split("'")[1]), self.settings.values()))
|
|
114
|
-
split_string = '"'
|
|
115
|
-
for setting in self.settings:
|
|
116
|
-
print(f"{setting}{' '*(longest_key-len(setting))} :{str(type(self.settings[setting])).split(split_string)[1]}{' '*(longest_type-len(str(type(self.settings[setting])).split(split_string)[1]))}=\t{self.settings[setting]}")
|
|
117
|
-
|
|
118
|
-
def set(self, key:str, new_value) -> None:
|
|
119
|
-
if not (key in self.settings): raise ValueError(f"The key [{key}] does not exist...")
|
|
120
|
-
self.settings[key] = new_value
|
|
121
|
-
|
|
122
|
-
def multiple_set(self, keys:list[str], new_values:list) -> None:
|
|
123
|
-
for key, new_value in zip(keys, new_values):
|
|
124
|
-
self.set(key, new_value)
|
|
125
|
-
|
|
126
|
-
def get(self, key:str) -> bool|V2|Vector2D|int|float:
|
|
127
|
-
return self.settings[key]
|
|
128
|
-
|
|
129
|
-
def multiple_get(self, keys:list[str]) -> list[bool|V2|Vector2D|int|float]:
|
|
130
|
-
return [self.get(key) for key in keys]
|
|
131
|
-
|
|
132
|
-
class Plot:
|
|
133
|
-
__top_left_multiplier__ = V2(1, -1)
|
|
134
|
-
__bottop_right_multiplier__ = V2(1, -1)
|
|
135
|
-
def __init__(self, rootEnv:"RootEnv", plot_position:V2|Vector2D, plot_size:V2|Vector2D, top_left_plot_coord:V2|Vector2D, bottom_right_plot_coord: V2|Vector2D, scale:V2|Vector2D=V2one) -> None:
|
|
136
|
-
self.rootEnv = rootEnv
|
|
137
|
-
|
|
138
|
-
self.top_left_plot_coord = top_left_plot_coord
|
|
139
|
-
self.bottom_right_plot_coord = bottom_right_plot_coord
|
|
140
|
-
|
|
141
|
-
self.position = plot_position
|
|
142
|
-
self.size = plot_size
|
|
143
|
-
self.scale = scale
|
|
144
|
-
|
|
145
|
-
self.settings = __PlotSettings__(self)
|
|
146
|
-
|
|
147
|
-
self.current_zoom = V2one * -np.log2(10)*10
|
|
148
|
-
self.current_offset = V2(0,0)
|
|
149
|
-
self.update_grid(True)
|
|
150
|
-
|
|
151
|
-
self.functions :list[Function]= []
|
|
152
|
-
|
|
153
|
-
self.canvas = pg.Surface(self.size())
|
|
154
|
-
self.dragging = None
|
|
155
|
-
self.start_dragging = V2z
|
|
156
|
-
self.is_mouse_in_rect = False
|
|
157
|
-
|
|
158
|
-
def set_borders_by_position_and_zoom(self) -> None:
|
|
159
|
-
self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.__top_left_multiplier__
|
|
160
|
-
self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.__bottop_right_multiplier__
|
|
161
|
-
self.top_left_x, self.top_left_y = self.top_left_plot_coord
|
|
162
|
-
self.bottom_right_x, self.bottom_right_y = self.bottom_right_plot_coord
|
|
163
|
-
|
|
164
|
-
def update_grid(self, update_step_grid=False) -> None:
|
|
165
|
-
self.set_borders_by_position_and_zoom()
|
|
166
|
-
if update_step_grid:
|
|
167
|
-
self.step = (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size / self.scale
|
|
168
|
-
X, Y = np.arange(self.top_left_plot_coord.x, self.bottom_right_plot_coord.x, self.step.x), np.arange(self.top_left_plot_coord.y, self.bottom_right_plot_coord.y, self.step.y)
|
|
169
|
-
self.meshgrid = np.meshgrid(X, Y)
|
|
170
|
-
self.pixel_size = abs(self.size / (self.bottom_right_plot_coord - self.top_left_plot_coord) * (self.step * -1))
|
|
171
|
-
if self.settings.get("use_inter_pixel_correction"):
|
|
172
|
-
self.pixel_size += V2one
|
|
173
|
-
|
|
174
|
-
def load_function(self, function:Function) -> None:
|
|
175
|
-
function.plot = self
|
|
176
|
-
function.__layer_surface__ = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
|
|
177
|
-
function.update_function(function.function)
|
|
178
|
-
self.functions.append(function)
|
|
179
|
-
|
|
180
|
-
def __plot2real__(self, plot_position:V2|Vector2D) -> V2|Vector2D:
|
|
181
|
-
return (plot_position + self.top_left_plot_coord * -1) * self.size / (self.bottom_right_plot_coord - self.top_left_plot_coord)
|
|
182
|
-
|
|
183
|
-
def __real2plot__(self, real_position:V2|Vector2D) -> V2|Vector2D:
|
|
184
|
-
return (real_position - self.position) * (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size + self.top_left_plot_coord
|
|
185
|
-
|
|
186
|
-
def render(self) -> None:
|
|
187
|
-
self.canvas.fill(self.settings.get("bg_color")) #type: ignore
|
|
188
|
-
if self.top_left_x < 0 < self.bottom_right_x:
|
|
189
|
-
pg.draw.line(self.canvas,
|
|
190
|
-
self.settings.get("axes_default_color") if (x_color:=self.settings.get("x_axis_color"))==None else x_color, #type: ignore
|
|
191
|
-
self.__plot2real__(V2(0, self.top_left_y))(),
|
|
192
|
-
self.__plot2real__(V2(0, self.bottom_right_y))(),
|
|
193
|
-
self.settings.get("axes_default_width") if (x_width:=self.settings.get("x_axis_width"))==None else x_width) #type: ignore
|
|
194
|
-
if self.bottom_right_y < 0 < self.top_left_y:
|
|
195
|
-
pg.draw.line(self.canvas,
|
|
196
|
-
self.settings.get("axes_default_color") if (y_color:=self.settings.get("y_axis_color"))==None else y_color, #type: ignore
|
|
197
|
-
self.__plot2real__(V2(self.top_left_x, 0))(),
|
|
198
|
-
self.__plot2real__(V2(self.bottom_right_x, 0))(),
|
|
199
|
-
self.settings.get("axes_default_width") if (y_width:=self.settings.get("y_axis_width"))==None else y_width) #type: ignore
|
|
200
|
-
|
|
201
|
-
for function in self.functions: function.draw()
|
|
202
|
-
|
|
203
|
-
pg.draw.rect(self.canvas, (255,255,255), V2z() + self.size(), 5) #type: ignore
|
|
204
|
-
|
|
205
|
-
center = self.size * .5
|
|
206
|
-
aimer_radius = 15
|
|
207
|
-
pg.draw.line(self.canvas, (100,100,100), (center + aimer_radius)(), (center - aimer_radius)(), 1)
|
|
208
|
-
pg.draw.line(self.canvas, (100,100,100), (center + self.__top_left_multiplier__ * aimer_radius)(), (center - self.__top_left_multiplier__ * aimer_radius)(), 1)
|
|
209
|
-
pg.draw.circle(self.canvas, (100,100,100), (self.size * .5)(), 15, 1)
|
|
210
|
-
|
|
211
|
-
if self.settings.get("show_corners_coords"):
|
|
212
|
-
self.rootEnv.print(str(self.top_left_plot_coord.__round__(.1)), V2z.copy(), bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
213
|
-
self.rootEnv.print(str(V2(self.top_left_plot_coord.x, self.bottom_right_plot_coord.y).__round__(.1)), self.size * V2(0, 1), fixed_sides=TEXT_FIXED_SIDES_BOTTOM_LEFT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
214
|
-
self.rootEnv.print(str(self.bottom_right_plot_coord.__round__(.1)), self.size.copy(), fixed_sides=TEXT_FIXED_SIDES_BOTTOM_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
215
|
-
self.rootEnv.print(str(V2(self.bottom_right_plot_coord.x, self.top_left_plot_coord.y).__round__(.1)), self.size * V2(1, 0), fixed_sides=TEXT_FIXED_SIDES_TOP_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
216
|
-
|
|
217
|
-
def update(self) -> None:
|
|
218
|
-
self.plot_mouse_position = self.__real2plot__(self.rootEnv.mouse.position)
|
|
219
|
-
self.plot_center_real_position = self.__plot2real__(V2z) + self.position
|
|
220
|
-
|
|
221
|
-
self.is_mouse_in_rect = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
|
|
222
|
-
self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
|
|
223
|
-
|
|
224
|
-
if self.rootEnv.mouse.just_released[0] and self.dragging != None:
|
|
225
|
-
self.dragging = None
|
|
226
|
-
self.update_grid(True)
|
|
227
|
-
for function in self.functions:
|
|
228
|
-
function.update_points()
|
|
229
|
-
self.render()
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if self.is_mouse_in_rect:
|
|
233
|
-
for event in self.rootEnv.events:
|
|
234
|
-
if event.type == pg.MOUSEWHEEL:
|
|
235
|
-
|
|
236
|
-
range_n = self.settings.get("distance_to_axis_for_scalar_zoom")
|
|
237
|
-
scalar = V2(0 if abs(self.plot_center_real_position.x - self.rootEnv.mouse.position.x) < range_n else 1, 0 if abs(self.plot_center_real_position.y - self.rootEnv.mouse.position.y) < range_n else 1) #type: ignore
|
|
238
|
-
self.current_zoom += event.y * scalar
|
|
239
|
-
|
|
240
|
-
self.update_grid(True)
|
|
241
|
-
for function in self.functions:
|
|
242
|
-
function.update_points()
|
|
243
|
-
self.render()
|
|
244
|
-
|
|
245
|
-
if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
|
|
246
|
-
self.dragging = self.rootEnv.mouse.position.copy()
|
|
247
|
-
self.start_dragging = self.dragging.copy()
|
|
248
|
-
|
|
249
|
-
if self.dragging:
|
|
250
|
-
offset = (self.dragging - self.rootEnv.mouse.position)* V2(1, -1) * (abs(self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size)
|
|
251
|
-
self.dragging = self.rootEnv.mouse.position.copy()
|
|
252
|
-
self.current_offset += offset
|
|
253
|
-
|
|
254
|
-
if self.settings.get("use_real_time_rendering"):
|
|
255
|
-
self.update_grid(True)
|
|
256
|
-
for function in self.functions: function.update_points()
|
|
257
|
-
else:
|
|
258
|
-
self.update_grid()
|
|
259
|
-
self.render()
|
|
260
|
-
|
|
261
|
-
def draw(self) -> None:
|
|
262
|
-
self.rootEnv.screen.blit(self.canvas, self.position())
|
|
263
|
-
if self.is_mouse_in_rect and self.settings.get("show_cursor_coords"):
|
|
264
|
-
self.rootEnv.print(str(round(self.plot_mouse_position, .1)), self.rootEnv.mouse.position, fixed_sides=TEXT_FIXED_SIDES_BOTTOM_MIDDLE) #type: ignore
|
|
265
|
-
|
|
266
|
-
data = [
|
|
267
|
-
[f"ZOOM:", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
268
|
-
[f" x: {self.current_zoom.x:.{self.settings.get('info_precision')}f};", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
269
|
-
[f" y: {self.current_zoom.y:.{self.settings.get('info_precision')}f};", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
270
|
-
]
|
|
271
|
-
|
|
272
|
-
for i, (d, fixed_side, show) in enumerate(data):
|
|
273
|
-
if show:
|
|
274
|
-
self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("info_spacing") * i, fixed_sides=fixed_side) #type: ignore
|
{e2D-1.3.7 → e2D-1.3.9}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|