1
|
|
|
import time |
2
|
|
|
import sys |
3
|
|
|
import os |
4
|
|
|
|
5
|
|
|
from pypen.drawing.primitives import PrimitivesDrawer |
6
|
|
|
from pyglet import clock, gl, image, window, canvas |
7
|
|
|
import cairo |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
# In order to display our Icon properly on Windows, |
11
|
|
|
# we need to have a "unique" (different from python's) app_id set |
12
|
|
|
if sys.platform == "win32": |
13
|
|
|
import ctypes |
14
|
|
|
app_id = "canvim.pypen" # arbitrary string |
15
|
|
|
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id) |
16
|
|
|
|
17
|
|
|
|
18
|
|
|
class PyPenWindow(window.Window): |
19
|
|
|
def __init__(self, user_sketch=None, window_title="Example", arguments={}): |
20
|
|
|
super().__init__(visible=False, resizable=True, caption=window_title, fullscreen=arguments.fullscreen) |
21
|
|
|
|
22
|
|
|
self.set_vsync(True) |
23
|
|
|
self._current_path = os.path.dirname(__file__) |
24
|
|
|
self.set_icon(image.load(os.path.join(self._current_path, "..", "resources", "icon.png"))) |
25
|
|
|
self.user_sketch = user_sketch |
26
|
|
|
self.window_title = window_title |
27
|
|
|
self.arguments = arguments |
28
|
|
|
self.passed_time = self.delta_time = self.frame_count = 0 |
29
|
|
|
|
30
|
|
|
if not arguments.fullscreen: |
31
|
|
|
self.set_size(self.user_sketch.settings.width, self.user_sketch.settings.height) |
32
|
|
|
else: |
33
|
|
|
display = canvas.Display() |
34
|
|
|
screen = display.get_default_screen() |
35
|
|
|
self.user_sketch.settings.width = screen.width |
36
|
|
|
self.user_sketch.settings.height = screen.height |
37
|
|
|
|
38
|
|
|
self.primitives_drawer = PrimitivesDrawer(self.user_sketch.settings) |
39
|
|
|
self.fix_primitive_functions() |
40
|
|
|
|
41
|
|
|
clock.schedule_once(self.call_user_start, 0) |
42
|
|
|
if self.arguments.timeout: |
43
|
|
|
clock.schedule_once(self.destroy, self.arguments.timeout/1000) |
44
|
|
|
|
45
|
|
|
def on_mouse_motion(self, x, y, dx, dy): |
46
|
|
|
self.user_sketch.MOUSE.x = x |
47
|
|
|
self.user_sketch.MOUSE.y = self.user_sketch.settings.height - y |
48
|
|
|
|
49
|
|
|
def destroy(self, *args): |
50
|
|
|
self.close() |
51
|
|
|
|
52
|
|
|
def on_draw(self): |
53
|
|
|
gl.glEnable(gl.GL_TEXTURE_2D) |
54
|
|
|
|
55
|
|
|
gl.glBindTexture(gl.GL_TEXTURE_2D, self.primitives_drawer.texture.id) |
56
|
|
|
gl.glTexImage2D(gl.GL_TEXTURE_2D, |
57
|
|
|
0, |
58
|
|
|
gl.GL_RGBA, |
59
|
|
|
self.primitives_drawer.settings.width, |
60
|
|
|
self.primitives_drawer.settings.height, |
61
|
|
|
0, |
62
|
|
|
gl.GL_BGRA, |
63
|
|
|
gl.GL_UNSIGNED_BYTE, |
64
|
|
|
self.primitives_drawer.surface_data) |
65
|
|
|
|
66
|
|
|
gl.glBegin(gl.GL_QUADS) |
67
|
|
|
gl.glTexCoord2f(0.0, 1.0) |
68
|
|
|
gl.glVertex2i(0, 0) |
69
|
|
|
gl.glTexCoord2f(1.0, 1.0) |
70
|
|
|
gl.glVertex2i(self.primitives_drawer.settings.width, 0) |
71
|
|
|
gl.glTexCoord2f(1.0, 0.0) |
72
|
|
|
gl.glVertex2i(self.primitives_drawer.settings.width, self.primitives_drawer.settings.height) |
73
|
|
|
gl.glTexCoord2f(0.0, 0.0) |
74
|
|
|
gl.glVertex2i(0, self.primitives_drawer.settings.height) |
75
|
|
|
gl.glEnd() |
76
|
|
|
|
77
|
|
|
def on_resize(self, width, height): |
78
|
|
|
super().on_resize(width, height) |
79
|
|
|
|
80
|
|
|
if width <= 0 or height <= 0: |
81
|
|
|
return |
82
|
|
|
|
83
|
|
|
self.user_sketch.settings.width = max(width, 1) |
84
|
|
|
self.user_sketch.settings.height = max(height, 1) |
85
|
|
|
self.primitives_drawer.update_settings(self.user_sketch.settings) |
86
|
|
|
|
87
|
|
|
def fix_primitive_functions(self): |
88
|
|
|
self.user_sketch.fill_screen = self.primitives_drawer.fill_screen |
89
|
|
|
self.user_sketch.clear_screen = self.primitives_drawer.clear_screen |
90
|
|
|
self.user_sketch.clear = self.primitives_drawer.clear |
91
|
|
|
|
92
|
|
|
self.user_sketch.rectangle = self.primitives_drawer.rectangle |
93
|
|
|
self.user_sketch.circle = self.primitives_drawer.circle |
94
|
|
|
self.user_sketch.arc = self.primitives_drawer.arc |
95
|
|
|
|
96
|
|
|
self.user_sketch.rotate = self.primitives_drawer.rotate |
97
|
|
|
self.user_sketch.translate = self.primitives_drawer.translate |
98
|
|
|
self.user_sketch.scale = self.primitives_drawer.scale |
99
|
|
|
self.user_sketch.save = self.primitives_drawer.save |
100
|
|
|
self.user_sketch.restore = self.primitives_drawer.restore |
101
|
|
|
|
102
|
|
|
def call_user_start(self, dt): |
103
|
|
|
if self.user_sketch.settings._user_has_start: |
104
|
|
|
self.user_sketch.start() |
105
|
|
|
if not self.arguments.fullscreen: |
106
|
|
|
self.set_size(self.user_sketch.settings.width, self.user_sketch.settings.height) |
107
|
|
|
|
108
|
|
|
self.set_visible() |
109
|
|
|
|
110
|
|
|
clock.schedule_interval_soft(self.pypen_loop, 1/self.user_sketch.settings.fps) |
111
|
|
|
|
112
|
|
|
def call_user_update(self): |
113
|
|
|
self.user_sketch.TIME = self.user_sketch.T = self.passed_time |
114
|
|
|
self.user_sketch.FRAME = self.user_sketch.F = self.frame_count |
115
|
|
|
self.user_sketch.DELTA_TIME = self.user_sketch.DT = self.delta_time |
116
|
|
|
self.user_sketch.FPS = clock.get_fps() |
117
|
|
|
|
118
|
|
|
self.user_sketch.WIDTH = self.user_sketch.settings.width |
119
|
|
|
self.user_sketch.HEIGHT = self.user_sketch.settings.height |
120
|
|
|
|
121
|
|
|
if self.user_sketch.settings._user_has_update: |
122
|
|
|
try: |
123
|
|
|
self.user_sketch.update() |
124
|
|
|
except KeyboardInterrupt as exception: |
125
|
|
|
sys.exit(self.destroy()) |
126
|
|
|
|
127
|
|
|
def pypen_loop(self, dt, *args): |
128
|
|
|
self.delta_time = dt |
129
|
|
|
self.passed_time += dt |
130
|
|
|
self.frame_count += 1 |
131
|
|
|
|
132
|
|
|
clock.unschedule(self.pypen_loop) |
133
|
|
|
self.call_user_update() |
134
|
|
|
clock.schedule_interval_soft(self.pypen_loop, 1/self.user_sketch.settings.fps) |
135
|
|
|
|