-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.pyw
227 lines (185 loc) · 8.45 KB
/
main.pyw
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
"""
ELEKTRON (c) 2022
Written by melektron (Matteo Reiter) and MrFlunter (Florian Unterpertinger)
www.elektron.work
02.05.22 18:44
Main file for gravity sim
"""
import sys
# check version
if sys.version_info < (3, 10):
print("PyGravi requires Python 3.10.0 or newer.")
print(f"Current version: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
print("To use this software, please use a compatible Python version")
sys.exit()
# check required modules
try:
import requests
except ImportError:
print("PyGravi requires the 'requests' module to be installed.")
print("Installation instructions: '<python interpreter> -m pip install requests'")
sys.exit()
import platform
import tkinter.ttk as ttk
import tkinter as tk
import classes.config as config
from classes.sim_space import sim_space
import classes.render_frame
import classes.config_frame
import classes.edit_frame
import classes.antiblurr
import classes.planets
import classes.events as events
class Window(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# don't allow window config changes to be saved just jet
self.wnd_save_config_flag = False
self.title("PyGravi v1.1")
if config.dyn.platform.startswith("windows"):
self.iconbitmap('resource/pygravi_logo.ico')
elif config.dyn.platform.startswith("linux"):
self.iconbitmap('@resource/pygravi_logo.xbm')
self.columnconfigure(1, weight=3)
#self.columnconfigure(2, weight=0)
self.rowconfigure(1, weight=1)
self.edit_frame = classes.edit_frame.EditFrame(self, width=350)
self.edit_frame.grid(row=1, column=0, sticky="NSEW", padx=5, pady=5)
self.edit_frame.grid_propagate(0) # keep left column fixed size (width)
self.render_frame = classes.render_frame.RenderFrame(self, width=300)
self.render_frame.grid(row=1, column=1, sticky="NSEW", padx=5, pady=5)
self.config_frame = classes.config_frame.ConfigFrame(self, width=350)
self.config_frame.grid(row=1, column=2, sticky="NS", padx=5, pady=5)
self.config_frame.grid_propagate(0) # keep right column fixed size (width)
# === register global keyboard shortcuts
if config.dyn.platform.startswith("windows") or config.dyn.platform.startswith("linux"):
self.bind_all("<Control-e>", self.ccb_e, "+")
self.bind_all("<Control-n>", self.ccb_n, "+")
self.bind_all("<Control-BackSpace>", self.ccb_del, "+")
self.bind_all("<Delete>", self.ccb_del, "+")
self.bind_all("<Control-m>", self.ccb_m, "+")
self.bind_all("<Control-c>", self.ccb_c, "+")
self.bind_all("<Control-v>", self.ccb_v, "+")
self.bind_all("<Control-d>", self.ccb_d, "+")
self.bind_all("<F11>", self.ccb_f11, "+")
elif config.dyn.platform.startswith("darwin"):
self.bind_all("<Control-e>", self.ccb_e, "+")
self.bind_all("<Control-n>", self.ccb_n, "+")
self.bind_all("<Control-BackSpace>", self.ccb_del, "+")
self.bind_all("<Delete>", self.ccb_del, "+")
self.bind_all("<Control-m>", self.ccb_m, "+")
self.bind_all("<Control-c>", self.ccb_c, "+")
self.bind_all("<Control-v>", self.ccb_v, "+")
self.bind_all("<Control-d>", self.ccb_d, "+")
self.bind_all("<Command-Control-f>", self.ccb_f11, "+")
#self.bind_all("<Command-q>", self.ccb_quit, "+")
# window config change to store the last position and size
self.bind("<Configure>", self.wnd_cfg)
self.after(config.dyn.visual_framedelay, self.render_objects)
# load last geometry from file and configure window in the same way
self.geometry(f"{config.dyn.geometry['w']}x{config.dyn.geometry['h']}+{config.dyn.geometry['x']}+{config.dyn.geometry['y']}")
self.set_fs(config.dyn.geometry['fullscreen'])
# save window size and position changes from now on
self.wnd_save_config_flag = True
def ccb_s(self, event=...):
pass
def ccb_e(self, event=...):
config.dyn.tool = "select"
events.tool_change.trigger()
pass
def ccb_n(self, event=...):
config.dyn.tool = "new"
events.tool_change.trigger()
pass
def ccb_del(self, event=...):
if self.render_frame.tool_action_active: return # if an action is active, stop
if sim_space.selected_object is not ...:
if sim_space.selected_object in sim_space.objects:
sim_space.objects.remove(sim_space.selected_object)
events.objects_change.trigger()
sim_space.selected_object = ...
events.selection_change.trigger()
else:
config.dyn.tool = "delete"
events.tool_change.trigger()
def ccb_m(self, event=...):
if self.render_frame.tool_action_active: return # if an action is active, stop
if sim_space.selected_object is not ...:
self.render_frame.initiate_move(sim_space.selected_object)
else:
config.dyn.tool = "move"
events.tool_change.trigger()
pass
def ccb_c(self, event=...):
if self.render_frame.tool_action_active: return # if an action is active, stop
if sim_space.selected_object is not ...:
self.render_frame.copy_selection()
else:
config.dyn.tool = "copy"
events.tool_change.trigger()
pass
def ccb_v(self, event=...):
if self.render_frame.tool_action_active: return # if an action is active, stop
if sim_space.clipboard_object is not ...:
self.render_frame.initiate_paste()
else:
config.dyn.tool = "paste"
events.tool_change.trigger()
pass
def ccb_d(self, event=...):
if self.render_frame.tool_action_active: return # if an action is active, stop
if sim_space.selected_object is not ...:
self.render_frame.copy_selection()
self.render_frame.initiate_paste()
else:
config.dyn.tool = "duplicate"
events.tool_change.trigger()
pass
def ccb_f11(self, event=...):
config.dyn.geometry["fullscreen"] = not config.dyn.geometry["fullscreen"]
self.set_fs(config.dyn.geometry["fullscreen"])
def ccb_quit(self, event=...):
sim_space.stop_simulation()
sim_space.exec_pool.shutdown(wait=True)
def set_fs(self, val: bool):
if config.dyn.platform.startswith("windows") or config.dyn.platform.startswith("linux"):
self.attributes("-fullscreen", bool(val))
elif config.dyn.platform.startswith("darwin"):
self.attributes("-fullscreen", bool(val))
config.dyn.geometry["fullscreen"] = bool(val)
def wnd_cfg(self, event: tk.Event=...):
if self.wnd_save_config_flag:
if event.widget == self: # only if the values apply to the main window
# save the position
config.dyn.geometry["x"] = event.x
config.dyn.geometry["y"] = event.x
config.dyn.geometry["w"] = event.width
config.dyn.geometry["h"] = event.height
def render_objects(self) -> None:
# Render Start
self.render_frame.render_objects(sim_space.objects)
# Render End
# recall render after x time
self.after(config.dyn.visual_framedelay, self.render_objects)
if __name__ == "__main__":
# load the platform
config.dyn.platform = platform.system().lower()
# load propper mouse scrolling devider
if config.dyn.platform.startswith("windows") or config.dyn.platform.startswith("linux"):
config.dyn.mouse_scrl_div = 120
elif config.dyn.platform.startswith("darwin"):
config.dyn.mouse_scrl_div = 18
#myobj = classes.planets.Planets.planet_to_object(classes.planets.Planets.request_planet_data("earth")[0])
#sim_space.append_object(myobj)
sim_space.load_objects(config.user.objects)
sim_space.load_default_object(config.user.default_object)
events.objects_change.trigger() # notify about object change
mywindow = Window()
#mywindow.state("zoomed")
#mywindow.geometry("1600x800")
mywindow.mainloop()
sim_space.stop_simulation()
# save the config
config.user.save()
config.dyn.save()
# const cannot be saved