File: User-Defined_Displayables.html

package info (click to toggle)
renpy 6.10.2.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 19,468 kB
  • ctags: 5,383
  • sloc: python: 17,801; ansic: 7,116; makefile: 127; sh: 15
file content (438 lines) | stat: -rw-r--r-- 22,488 bytes parent folder | download
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
<html><head><title>User-Defined Displayables - Ren'Py Visual Novel Engine</title><link href="../shared.css" rel="stylesheet"><link href="../monobook.css" rel="stylesheet"><link href="../common.css" rel="stylesheet"><link href="../monobook2.css" rel="stylesheet"><link href="../docs.css" rel="stylesheet" /></link></link></link></link></head><body><div id="bodyContent">
			<p class="docnav"><a href="../index.html">documentation index</a> &#9702; <a href="Reference_Manual.html">reference manual</a> &#9702; <a href="Function_Index.html">function index</a></p><p><a id="User-Defined_Displayables" name="User-Defined_Displayables"></a></p>
<h1><span class="mw-headline">User-Defined Displayables</span></h1>
<p>It's possible for a user to define displayables that extend Ren'Py's behavior. This section will explain the steps that are involved in defining your own displayables, and how to use them with Ren'Py.</p>
<p>A displayable is an object that inherits from renpy.Displayable, a class that has several methods that can be overridden to control the behavior of the displayable. Probably the most important of these is render, a method that must be overridden to return a renpy.Render object, which contains the result of drawing the displayable. The event method can be overridden to respont to events, and to terminate the interaction when necessary. Other methods allow a displayable to respond to a variety of events.</p>
<p>Displayables must be capable of being serialized. This means that they must not contain references to objects that are incapable of being serialized. Of particular note is that the renpy.Render object is incapable of being serialized.</p>
<p>Displayables have a number of methods and fields, not all of which are documented here. We strongly recommend you use a unique prefix for the names of fields and methods you add, to minimize the chance of conflicts.</p>
<table class="toc" id="toc" summary="Contents">
<tr>
<td>
<div id="toctitle">
<h2>Contents</h2>
</div>
<ul>
<li class="toclevel-1"><a href="#User-Defined_Displayables"><span class="tocnumber">1</span> <span class="toctext">User-Defined Displayables</span></a>
<ul>
<li class="toclevel-2"><a href="#renpy.Displayable"><span class="tocnumber">1.1</span> <span class="toctext">renpy.Displayable</span></a></li>
<li class="toclevel-2"><a href="#renpy.Render"><span class="tocnumber">1.2</span> <span class="toctext">renpy.Render</span></a></li>
<li class="toclevel-2"><a href="#renpy.Container"><span class="tocnumber">1.3</span> <span class="toctext">renpy.Container</span></a></li>
<li class="toclevel-2"><a href="#Utility_Functions"><span class="tocnumber">1.4</span> <span class="toctext">Utility Functions</span></a></li>
<li class="toclevel-2"><a href="#Using_User-Defined_Displayables"><span class="tocnumber">1.5</span> <span class="toctext">Using User-Defined Displayables</span></a></li>
<li class="toclevel-2"><a href="#Defining_At-functions_and_Transitions"><span class="tocnumber">1.6</span> <span class="toctext">Defining At-functions and Transitions</span></a></li>
<li class="toclevel-2"><a href="#Notes"><span class="tocnumber">1.7</span> <span class="toctext">Notes</span></a></li>
</ul>
</li>
</ul>
</td>
</tr>
</table>
<script type="text/javascript">
//
 if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } 
//
</script>
<p><br /></p>
<p><a id="renpy.Displayable" name="renpy.Displayable"></a></p>
<h2><span class="mw-headline">renpy.Displayable</span></h2>
<p>This is the base class for user-defined displayables. It has the following fields and methods.</p>
<p>Since you will be implementing many of these methods, rather than calling them, we include the normally hidden self parameter in the definition.</p>
<p><span id="focusable" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>focusable</b></td>
<td valign="top">= False</td>
</tr>
</table>
<div class="renpy-doc">
<p>This field should be True if it's possible for the displayable to gain focus, and false otherwise.</p>
</div>
<p><span id="style" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>style</b></td>
<td valign="top">= ...</td>
</tr>
</table>
<div class="renpy-doc">
<p>The style of this displayable. This is automatically created by the default constructor.</p>
</div>
<p><span id="delay" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>delay</b></td>
<td valign="top">= <i>undefined</i></td>
</tr>
</table>
<div class="renpy-doc">
<p>If this displayable is used as a transition, then delay should be set to the number of seconds that the transition will take.</p>
</div>
<p><span id="renpy.Displayable.__init__" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.__init__</b></td>
<td valign="top">(self, default=False, focus=None, style='default', **properties):</td>
</tr>
</table>
<div class="renpy-doc">
<p>The __init__ method may be overridden with your own parameter list, but the default method must be called to properly initialize a Displayable. The parameters the default methods take are:</p>
<p><i>focus</i> - if given, a string giving the name of the focus group in the object. The focus group is used to determine which displayable should be focused after an interaction. For example, if the third displayable in focus group "foo" has focus at the end of an interaction, the third displayable in "foo" will have focus at the start of the next interaction, even if the two displayables are not the same.</p>
<p><i>default</i> - determines if this object can be focused by default. This is only used if no object with the same focus name is found in an interaction.</p>
<p><i>style</i> - The name of the default style, used to construct a style object that is placed in the <tt>style</tt> field.</p>
<p><i>properties</i> - Additional keyword arguments are treated as style properties when constructing the style.</p>
</div>
<p><span id="renpy.Displayable.focus" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.focus</b></td>
<td valign="top">(self, default=False):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Called to indicate that this displayable has been given the focus. <i>default</i> is true if the focus has been given to this displayable at the start of an interaction.</p>
<p>The default implementation sets the style prefix of this displayable and its children to 'hover_'.</p>
<p>If this returns a non-None value, the current interaction is terminated and the value is returned.</p>
</div>
<p><span id="renpy.Displayable.unfocus" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.unfocus</b></td>
<td valign="top">(self):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Called to indicate this displayable has lost focus.</p>
<p>The default implementation resets the style prefix of this displayable and its children to 'idle_'.</p>
<p>This should return None.</p>
</div>
<p><span id="renpy.Displayable.is_focused" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.is_focused</b></td>
<td valign="top">(self):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This method determines if the current displayable has focus. It probably doesn't make sense to override it.</p>
</div>
<p><span id="renpy.Displayable.set_style_prefix" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.set_style_prefix</b></td>
<td valign="top">(self, prefix):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Sets the style prefix of this displayable and its children to one of: "insensitive_", "idle_", "hover_", "activate_", "selected_insensitive_", "selected_idle_", "selected_hover_", or "selected_activate_".</p>
</div>
<p><span id="renpy.Displayable.render" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.render</b></td>
<td valign="top">(self, width, height, st, at):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This is responsible for drawing the displayable. This is done by creating a renpy.Render object, blitting other objects to that object in appropriate places, and then returning that Render.</p>
<p><i>width</i>, <i>height</i> - The area allocated to this displayable. The created displayable may be bigger or smaller than this, without consequence.</p>
<p><i>st</i> - The displayable timebase, the number of seconds this displayable has been shown for.</p>
<p><i>at</i> - The animation timebase, the number of seconds an image with the same tag as this displayable has been shown for.</p>
<p>This method should not be called directly on child displayables. (See renpy.render instead.)</p>
</div>
<p><span id="renpy.Displayable.event" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.event</b></td>
<td valign="top">(self, ev, x, y, st):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This is called when an event occurs.</p>
<p><i>ev</i> - The pygame event object. This can be read to get the type of event and other parameters.</p>
<p><i>x</i>, <i>y</i> - The position of the mouse at the time of the event. This is relative to the upper-left corner of this displayable, and should be used in preference to similar data contained in <i>ev</i>.</p>
<p><i>st</i> - The displayable timebase.</p>
<p>If this method returns a non-None value, then that value is returned from <a href="../reference/functions/ui.interact.html" title="renpy/doc/reference/functions/ui.interact">ui.interact</a>. If it returns None, processing of the event is continued by the other displayables. If renpy.IgnoreEvent is raised, then no other displayables will see the event.</p>
<p>It may make sense to call this method on child displayables.</p>
</div>
<p><span id="renpy.Displayable.get_placement" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.get_placement</b></td>
<td valign="top">(self):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Returns a tuple of (xpos, ypos, xalign, yalign, xoffset, yoffset), that is used to place this displayable on the screen.</p>
<p>This defaults to getting the proper values out of style.</p>
</div>
<p><span id="renpy.Displayable.visit" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.visit</b></td>
<td valign="top">(self):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This should be overridden to return a list of all the child displayables fo this displayable.</p>
</div>
<p><span id="renpy.Displayable.per_interact" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Displayable.per_interact</b></td>
<td valign="top">(self):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This is called once per interaction, to inform the displayable that a new interaction has begun.</p>
<p>Often, this should call renpy.redraw(self, 0), to make sure that the displayable is redrawn for each interaction. This is especially useful if the displayable participates in rollback.</p>
</div>
<p><a id="renpy.Render" name="renpy.Render"></a></p>
<h2><span class="mw-headline">renpy.Render</span></h2>
<p>Since one will not be subclassing renpy.Render, we omit the self parameter from method descriptions.</p>
<p><br />
<span id="renpy.Render" /></p>
<table>
<tr>
<td valign="top">Function:</td>
<td valign="top"><b><a href="../reference/functions/renpy.Render_(constructor).html" title="renpy/doc/reference/functions/renpy.Render (constructor)">renpy.Render</a></b></td>
<td valign="top">(width, height):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Constructs a new render object with the given width and height.</p>
</div>
<p><br />
<span id="renpy.Render.blit" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.blit</b></td>
<td valign="top">(source, pos):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Copies the contents of the <i>source</i> render to this one. <i>Pos</i> is a 2-element tuple giving the position of the upper-left-hand corner of the source render, relative to the upper-left-hand corner of this render, in pixels.</p>
</div>
<p><span id="renpy.Render.fill" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.fill</b></td>
<td valign="top">(color):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Fills the render with the given color, which should be an RGBA tuple.</p>
</div>
<p><span id="renpy.Render.get_size" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.get_size</b></td>
<td valign="top">():</td>
</tr>
</table>
<div class="renpy-doc">
<p>Returns the width and height of this render as a pair.</p>
</div>
<p><span id="renpy.Render.kill" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.kill</b></td>
<td valign="top">():</td>
</tr>
</table>
<div class="renpy-doc">
<p>Deallocates the memory used by this Render. This must be called on a Render returned by renpy.render or renpy.Render.subsurface if the render is not blitted to another Render. Once this is called, the render should not be blitted to a surface or have any other method called. It is safe to call this on a Render that has been blitted somewhere, as these calls are ignored.</p>
</div>
<p><span id="renpy.Render.subsurface" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.subsurface</b></td>
<td valign="top">(pos):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Returns a render that is a subsurface of this render. Pos should be an (x,y,w,h) tuple, where x and y are the coordinates of the upper-left corner of the subsurface, w is the width, and h is the height of the subsurface.</p>
</div>
<p><span id="renpy.Render.add_focus" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.add_focus</b></td>
<td valign="top">(displayable, arg, x, y, w, h, mx=None, my=None, mask=None):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This is used to indicate that a sub-region of this Render is eligible for being focused.</p>
<p><i>displayable</i> - The displayable that will be focused. <i>arg</i> - Ignored, should be None. <i>x</i>, <i>y</i>, <i>w</i>, <i>h</i> - If not None, a rectangular subregion of this Render that will be focused. If all are None, this displayable has full-screen focus. <i>mx</i>, <i>my</i> - If not None, offsets of the focus mask from the upper-left hand corner of this Render. <i>mask</i> - A Render that is used as a focus mask when mouse focus is needed. The mouse will only focus the displayable when it is over a non-transparent pixel in the mask.</p>
</div>
<p><span id="renpy.Render.canvas" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Render.canvas</b></td>
<td valign="top">():</td>
</tr>
</table>
<div class="renpy-doc">
<p>This function returns a canvas object that has methods corresponding to the <a class="external text" href="http://www.pygame.org/docs/ref/draw.html" rel="nofollow" title="http://www.pygame.org/docs/ref/draw.html">pygame.draw</a> functions, except that the first argument (the surface) is omitted. For example, instead of calling pygame.draw.line(surface, (255, 255, 255, 255), (100, 100), (200, 200)), one would call c.line((255, 255, 255, 255), (100, 100), (200, 200)).</p>
<p>Code that uses a canvas may not be portable to non-pygame platforms, should we choose to support them in the future.</p>
</div>
<p><a id="renpy.Container" name="renpy.Container"></a></p>
<h2><span class="mw-headline">renpy.Container</span></h2>
<p>The renpy.Container class implements a displayable that positions its children using style properties, in a manner similar to <a href="../reference/functions/Fixed.html" title="renpy/doc/reference/functions/Fixed">Fixed</a> and <a href="../reference/functions/ui.fixed.html" title="renpy/doc/reference/functions/ui.fixed">ui.fixed</a>. Unlike the displayable returned by those functions, renpy.Container supports adding and removing children, and it may be subclassed to change its behavior (including the behavior of the render and event methods).</p>
<p>A renpy.Container implements all of the methods of a renpy.Displayable. These methods may be overridden in a subclass, and this is often done with for the render and event methods. A container has three additional fields:</p>
<p><span id="children" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>children</b></td>
<td valign="top">= []</td>
</tr>
</table>
<div class="renpy-doc">
<p>A list of the children of this container.</p>
</div>
<p><span id="children" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>children</b></td>
<td valign="top">= None</td>
</tr>
</table>
<div class="renpy-doc">
<p>The last child added to this container and not removed, or None if there are no children in this container.</p>
</div>
<p><span id="offsets" /></p>
<table>
<tr>
<td valign="top">Field:</td>
<td valign="top"><b>offsets</b></td>
<td valign="top">= []</td>
</tr>
</table>
<div class="renpy-doc">
<p>A list of (x, y) tuples giving the coordinates of the upper-left corners of the children of this displayable.</p>
</div>
<p>It also has three methods. (We give these without the self parameter, as we expect them to be called, and only rarely overridden.)</p>
<p><span id="renpy.Container.add" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Container.add</b></td>
<td valign="top">(d):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Add a <i>d</i> to this container.</p>
</div>
<p><span id="renpy.Container.remove" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Container.remove</b></td>
<td valign="top">(d):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Remove the first instance of <i>d</i> from this container.</p>
</div>
<p><span id="renpy.Container.update" /></p>
<table>
<tr>
<td valign="top">Method:</td>
<td valign="top"><b>renpy.Container.update</b></td>
<td valign="top">():</td>
</tr>
</table>
<div class="renpy-doc">
<p>This should be called after add or remove, to indicate that the container has changed and should be redrawn.</p>
</div>
<p><a id="Utility_Functions" name="Utility_Functions"></a></p>
<h2><span class="mw-headline">Utility Functions</span></h2>
<p><span id="renpy.render" /></p>
<table>
<tr>
<td valign="top">Function:</td>
<td valign="top"><b><a href="../reference/functions/renpy.render.html" title="renpy/doc/reference/functions/renpy.render">renpy.render</a></b></td>
<td valign="top">(displayable, width, height, st, at):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Call this function to get a Render from a displayable. It takes care of calling the render method on that displayable, and then caching the results when nothing has changed.</p>
</div>
<p><span id="renpy.redraw" /></p>
<table>
<tr>
<td valign="top">Function:</td>
<td valign="top"><b><a href="../reference/functions/renpy.redraw.html" title="renpy/doc/reference/functions/renpy.redraw">renpy.redraw</a></b></td>
<td valign="top">(displayable, time):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Causes the supplied displayable to be redrawn after <i>time</i> seconds have elapsed. <i>Time</i> may be zero to ensure an immediate redraw.</p>
</div>
<p><br />
<span id="renpy.timeout" /></p>
<table>
<tr>
<td valign="top">Function:</td>
<td valign="top"><b><a href="../reference/functions/renpy.timeout.html" title="renpy/doc/reference/functions/renpy.timeout">renpy.timeout</a></b></td>
<td valign="top">(time):</td>
</tr>
</table>
<div class="renpy-doc">
<p>Causes an event to occur in <i>time</i> seconds. The type of the event is undefined.</p>
</div>
<p><br />
<span id="renpy.easy_displayable" /></p>
<table>
<tr>
<td valign="top">Function:</td>
<td valign="top"><b><a href="../reference/functions/renpy.easy_displayable.html" title="renpy/doc/reference/functions/renpy.easy displayable">renpy.easy_displayable</a></b></td>
<td valign="top">(d, none=False):</td>
</tr>
</table>
<div class="renpy-doc">
<p>This takes an "easy displayable", and returns a <a href="../reference/Displayables.html" title="renpy/doc/reference/Displayables">Displayable</a>. Easy displayables may be Displayables, or may be strings. If a string, then:</p>
<ul>
<li>If the string starts with #, a <a href="../reference/functions/Solid.html" title="renpy/doc/reference/functions/Solid">Solid</a> of the given color is returned.</li>
<li>Otherwise, an <a href="../reference/functions/Image.html" title="renpy/doc/reference/functions/Image">Image</a> is returned.</li>
</ul>
<p>If <i>none</i> is True and d is None, then None is returned. Otherwise, if d is None, an exception is thrown.</p>
</div>
<p><br /></p>
<p><a id="Using_User-Defined_Displayables" name="Using_User-Defined_Displayables"></a></p>
<h2><span class="mw-headline">Using User-Defined Displayables</span></h2>
<p>Once a user-defined displayable class has been defined, objects of that class can be created. Such an object can be shown with a show statement, or added to the transient layer with <a href="../reference/functions/ui.add.html" title="renpy/doc/reference/functions/ui.add">ui.add</a>.</p>
<p><a id="Defining_At-functions_and_Transitions" name="Defining_At-functions_and_Transitions"></a></p>
<h2><span class="mw-headline">Defining At-functions and Transitions</span></h2>
<p>An At-function is a function that is suitable for use in an at-list, as part of a show statement. These are functions that take a displayable as an argument, and return a second displayable. (User-defined or not.)</p>
<p>Transitions take two keyword arguments, new_widget and old_widget, representing the new and old scenes, respectively. They return a displayable that performs the transition, which should have its delay fields set to the duration of the transition.</p>
<p><a id="Notes" name="Notes"></a></p>
<h2><span class="mw-headline">Notes</span></h2>
<p>Although we will do our best to avoid breaking code unnecessarily, we reserve the right to change the displayable API as necessary to support the future development of Ren'Py. As a result, code using the displayable API may not be forward-compatible with future versions of Ren'Py.</p>




<div class="visualClear" />
		<hr /><p class="docnav"><a href="../index.html">documentation index</a> &#9702; <a href="Reference_Manual.html">reference manual</a> &#9702; <a href="Function_Index.html">function index</a></p></div>
	</body></html>