10
10
11
11
12
12
class BaseKeys :
13
- """Generic constants here"""
13
+ """
14
+ Namespace for generic key constants
15
+ working across all window types.
16
+ """
14
17
ACTION_PRESS = 'ACTION_PRESS'
15
18
ACTION_RELEASE = 'ACTION_RELEASE'
16
19
17
20
18
21
class BaseWindow :
19
- keys = None
22
+ """
23
+ The base window we extend when adding new window types to the system.
24
+ """
25
+ keys = None #: The key class/namespace used by the window defining keyboard constants
20
26
21
27
def __init__ (self ):
22
28
"""
23
- Base window intializer
29
+ Base window intializer reading values from ``settings``.
30
+ If you need an initializer in your own window, always call
31
+ this methods using ``super().__init__()``
24
32
"""
25
33
self .frames = 0
26
34
self .width = settings .WINDOW ['size' ][0 ]
@@ -55,18 +63,43 @@ def __init__(self):
55
63
56
64
@property
57
65
def size (self ):
66
+ """
67
+ (width, height) tuple containing the window size.
68
+
69
+ Note that for certain displays we rely on :py:func:`buffer_size`
70
+ to get the actual window buffer size. This is fairly common
71
+ for retina and 4k displays where the UI scale is > 1.0
72
+ """
58
73
return (self .width , self .height )
59
74
60
75
@property
61
76
def buffer_size (self ):
77
+ """
78
+ (width, heigh) buffer size of the window.
79
+
80
+ This is the actual buffer size of the window
81
+ taking UI scale into account. A 1920 x 1080
82
+ window running in an environment with UI scale 2.0
83
+ would have a 3840 x 2160 window buffer.
84
+ """
62
85
return (self .buffer_width , self .buffer_height )
63
86
64
87
def draw (self , current_time , frame_time ):
88
+ """
89
+ Draws a frame. Internally it calls the
90
+ configured timeline's draw method.
91
+
92
+ Args:
93
+ current_time (float): The current time (preferrably always from the configured timer class)
94
+ frame_time (float): The duration of the previous frame in seconds
95
+ """
65
96
self .set_default_viewport ()
66
97
self .timeline .draw (current_time , frame_time , self .fbo )
67
98
68
99
def clear (self ):
69
- """Clear the scren"""
100
+ """
101
+ Clear the window buffer
102
+ """
70
103
self .ctx .fbo .clear (
71
104
red = self .clear_color [0 ],
72
105
green = self .clear_color [1 ],
@@ -76,34 +109,91 @@ def clear(self):
76
109
)
77
110
78
111
def clear_values (self , red = 0.0 , green = 0.0 , blue = 0.0 , alpha = 0.0 , depth = 1.0 ):
112
+ """
113
+ Sets the clear values for the window buffer.
114
+
115
+ Args:
116
+ red (float): red compoent
117
+ green (float): green compoent
118
+ blue (float): blue compoent
119
+ alpha (float): alpha compoent
120
+ depth (float): depth value
121
+ """
79
122
self .clear_color = (red , green , blue , alpha )
80
123
self .clear_depth = depth
81
124
82
125
def use (self ):
83
- """Render to this window"""
126
+ """
127
+ Set the window buffer as the current render target
128
+
129
+ Raises:
130
+ NotImplementedError
131
+ """
84
132
raise NotImplementedError ()
85
133
86
134
def swap_buffers (self ):
87
- """Swap frame buffer"""
135
+ """
136
+ Swap the buffers. Most windows have at least support for double buffering
137
+ cycling a back and front buffer.
138
+
139
+ Raises:
140
+ NotImplementedError
141
+ """
88
142
raise NotImplementedError ()
89
143
90
144
def resize (self , width , height ):
91
- """Resize window"""
145
+ """
146
+ Resize the window. Should normallty be overriden
147
+ when implementing a window as most window libraries need additional logic here.
148
+
149
+ Args:
150
+ width (int): Width of the window
151
+ height: (int): Height of the window
152
+ """
92
153
self .set_default_viewport ()
93
154
94
155
def close (self ):
95
- """Set the close state"""
156
+ """
157
+ Set the window in close state. This doesn't actually close the window,
158
+ but should make :py:func:`should_close` return ``True`` so the
159
+ main loop can exit gracefully.
160
+
161
+ Raises:
162
+ NotImplementedError
163
+ """
96
164
raise NotImplementedError ()
97
165
98
166
def should_close (self ):
99
- """Check if window should close"""
167
+ """
168
+ Check if window should close. This should always be checked in the main draw loop.
169
+
170
+ Raises:
171
+ NotImplementedError
172
+ """
100
173
raise NotImplementedError ()
101
174
102
175
def terminate (self ):
103
- """Cleanup after close"""
176
+ """
177
+ The actual teardown of the window.
178
+
179
+ Raises:
180
+ NotImplementedError
181
+ """
104
182
raise NotImplementedError ()
105
183
106
184
def keyboard_event (self , key , action , modifier ):
185
+ """
186
+ Handles the standard keyboard events such as camera movements,
187
+ taking a screenshot, closing the window etc.
188
+
189
+ Can be overriden add new keyboard events. Ensure this method
190
+ is also called if you want to keep the standard features.
191
+
192
+ Arguments:
193
+ key: The key that was pressed or released
194
+ action: The key action. Can be `ACTION_PRESS` or `ACTION_RELEASE`
195
+ modifier: Modifiers such as holding shift or ctrl
196
+ """
107
197
# The well-known standard key for quick exit
108
198
if key == self .keys .ESCAPE :
109
199
self .close ()
@@ -170,10 +260,23 @@ def keyboard_event(self, key, action, modifier):
170
260
self .timeline .key_event (key , action , modifier )
171
261
172
262
def cursor_event (self , x , y , dx , dy ):
263
+ """
264
+ The standard mouse movement event method.
265
+ Can be overriden to add new functionality.
266
+ By default this feeds the system camera with new values.
267
+
268
+ Args:
269
+ x: The current mouse x position
270
+ y: The current mouse y position
271
+ dx: Delta x postion (x position difference from the previous event)
272
+ dy: Delta y postion (y position difference from the previous event)
273
+ """
173
274
self .sys_camera .rot_state (x , y )
174
275
175
276
def print_context_info (self ):
176
- """Prints out context info"""
277
+ """
278
+ Prints moderngl context info.
279
+ """
177
280
print ("Context Version:" )
178
281
print ('ModernGL:' , moderngl .__version__ )
179
282
print ('vendor:' , self .ctx .info ['GL_VENDOR' ])
@@ -184,7 +287,10 @@ def print_context_info(self):
184
287
print ('code:' , self .ctx .version_code )
185
288
186
289
def set_default_viewport (self ):
187
- """Calculate viewport with correct aspect ratio"""
290
+ """
291
+ Calculates the viewport based on the configured aspect ratio in settings.
292
+ Will add black borders if the window do not match the viewport.
293
+ """
188
294
# The expected height with the current viewport width
189
295
expected_height = int (self .buffer_width / self .aspect_ratio )
190
296
0 commit comments