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
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef SCI_GFX_GFX_WIDGETS_H
#define SCI_GFX_GFX_WIDGETS_H
#include "common/rect.h"
#include "sci/engine/vm.h"
#include "sci/gfx/gfx_system.h"
#include "sci/gfx/operations.h"
namespace Sci {
/** @name Widget Graphical State Management */
/** @{ */
struct GfxState;
struct GfxBox;
struct GfxDynView;
struct GfxContainer;
struct GfxList;
struct GfxPort;
struct GfxPrimitive;
struct gfxw_snapshot_t;
struct GfxText;
struct GfxView;
struct GfxVisual;
struct GfxWidget;
/* Enable the next line to keep a list of pointers to all widgets, with up to the specified amount
** of members (/SLOW/) */
//#define GFXW_DEBUG_WIDGETS 2048
/* Terminology
**
** Two special terms are used in here: /equivalent/ and /clear/. Their meanings
** in this context are as follows:
**
** /clear/: Clearing a widget means overwriting the space it occupies in the back
** buffer with data from the static buffer. This affects both the visual and the
** priority buffer, the static buffer (and any effect the widget may have had on
** it) is not touched.
**
** /equivalent/: Two Widgets A and B are equivalent if and only if either of the
** following conditions is met:
** a) Both A and B are text widgets, and they occupy the same bounding rectangle.
** b) Both A and B are dynview widgets, and they have the same unique ID
** Note that /equivalent/ is not really an equivalence relation- while it is ob-
** viously transitive and symmetrical, it is not reflexive (e.g. a box widget
** is not /equivalent/ to itself), although this might be a nice addition for the
** future.
*/
/*********************************/
/* Fundamental widget operations */
/*********************************/
/* gfxw_point_zero is declared in gfx/widgets.cpp */
extern Common::Point gfxw_point_zero;
/*********************/
/* Widget operations */
/*********************/
/* These are for documentation purposes only. The actual declarations are in
** gfx_state_internal.h.
**
**
** **************************
** ** Container operations **
** **************************
**
**
** -- free_tagged(GfxContainer *self)
** Frees all tagged resources in the container
** Parameters: (GfxContainer *) self: self reference
** Returns : (int) 0
** The container itself is never freed in this way.
**
**
** -- free_contents(GfxContainer *self)
** Frees all resources contained in the container
** Parameters: (GfxContainer *) self: self reference
** Returns : (int) 0
**
**
** -- add_dirty_abs(GfxContainer *self, rect_t dirty, int propagate)
** Adds a dirty rectangle to the container's list of dirty rects
** Parameters: (GfxContainer *) self: self reference
** (rect_t) dirty: The rectangular screen area that is to be flagged
** as dirty, absolute to the screen
** (int) propagate: Whether the dirty rect should be propagated to the
** widget's parents
** Returns : (int) 0
** Transparent containers will usually pass this value to their next ancestor,
** because areas below them might have to be redrawn.
**
**
** -- add_dirty_rel(GfxContainer *self, rect_t dirty, int propagate)
** Adds a dirty rectangle to the container's list of dirty rects
** Parameters: (GfxContainer *) self: self reference
** (rect_t) dirty: The rectangular screen area that is to be flagged
** as dirty, relative to the widget
** (int) propagate: Whether the dirty rect should be propagated to the
** widget's parents
** Returns : (int) 0
** Transparent containers will usually pass this value to their next ancestor,
** because areas below them might have to be redrawn.
**
**
** -- add(GfxContainer *self, GfxWidget *widget)
** Adds a widget to the list of contained widgets
** Parameters: (GfxContainer *) self: self reference
** (GfxWidget *) widget: The widget to add
** Returns : (int) 0
** Sorted lists sort their content into the list rather than adding it to the
** end.
*/
/***************************/
/* Basic widget generation */
/***************************/
/*-- Primitive types --*/
/**
* Creates a new box
*
* The graphics state, if non-NULL, is used here for some optimizations.
*
* @param[in] state The (optional) state
* @param[in] area The box's dimensions, relative to its container
* widget
* @param[in] color1 The primary color
* @param[in] color2 The secondary color (ignored if shading is disabled)
* @param[in] shade_type The shade type for the box
* @return The resulting box widget
*/
GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type);
/**
* Creates a new rectangle
*
* @param[in] rect The rectangle area
* @param[in] color The rectangle's color
* @param[in] line_mode The line mode for the lines that make up the
* rectangle
* @param[in] line_style The rectangle's lines' style
* @return The newly allocated rectangle widget (a Primitive)
*/
GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color,
gfx_line_mode_t line_mode, gfx_line_style_t line_style);
/**
* Creates a new line
*
* @param[in] start The line's origin
* @param[in] end The line's end point
* @param[in] color The line's color
* @param[in] line_mode The line mode to use for drawing
* @param[in] line_style The line style
* @return The newly allocated line widget (a Primitive)
*/
GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end,
gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style);
/** View flags */
enum {
GFXW_VIEW_FLAG_STATIC = (1 << 0), /**< Whether the view should be static */
GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET = (1 << 1) /**< Whether the view should _not_ apply its x/y offset modifyers */
};
/**
* Creates a new view (a cel, actually)
*
* @param[in] state The graphics state
* @param[in] pos The position to place the view at
* @param[in] view The global cel ID
* @param[in] loop The global cel ID
* @param[in] cel The global cel ID
* @param[in] palette The palette to use
* @param[in] priority The priority to use for drawing, or -1 for none
* @param[in] control The value to write to the control map, or -1 for none
* @param[in] halign Horizontal cel alignment
* @param[in] valign Vertical cel alignment
* @param[in] flags Any combination of GFXW_VIEW_FLAGs
* @return A newly allocated cel according to the specs
*/
GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop,
int cel, int palette, int priority, int control, gfx_alignment_t halign,
gfx_alignment_t valign, int flags);
/**
* Creates a new dyn view
*
* Dynamic views are non-pic views with a unique global identifyer. This allows for drawing optimizations when they move or change shape.
*
* @param[in] state The graphics state
* @param[in] pos The position to place the dynamic view at
* @param[in] z The z coordinate
* @param[in] view The global cel ID
* @param[in] loop The global cel ID
* @param[in] cel The global cel ID
* @param[in] palette The palette to use
* @param[in] priority The priority to use for drawing, or -1 for none
* @param[in] control The value to write to the control map, or -1 for none
* @param[in] halign Horizontal cel alignment
* @param[in] valign Vertical cel alignment
* @param[in] sequence Sequence number: When sorting dynviews, this number is
* considered last for sorting (ascending order)
* @return A newly allocated cel according to the specs
*/
GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z,
int view, int loop, int cel, int palette, int priority, int control,
gfx_alignment_t halign, gfx_alignment_t valign, int sequence);
/**
* Creates a new text widget
*
* @param[in] state The state the text is to be calculated from
* @param[in] area The area the text is to be confined to (the yl value is
* only relevant for text aligment, though)
* @param[in] font The number of the font to use
* @param[in] text String to put in text widget
* @param[in] halign Horizontal text alignment
* @param[in] valign Vertical text alignment
* @param[in] color1 Text foreground colors (if not equal, the foreground is
* dithered between them)
* @param[in] color2 Text foreground colors (if not equal, the foreground is
* dithered between them)
* @param[in] bgcolor Text background color
* @param[in] flags GFXR_FONT_FLAGs, orred together (see gfx_resource.h)
* @return The resulting text widget
*/
GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text,
gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1,
gfx_color_t color2, gfx_color_t bgcolor, int flags);
/**
* Determines text widget meta-information
*
* @param[in] state The state to operate on
* @param[in] text The widget to query
* @param[out] lines_nr Number of lines used in the text
* @param[out] lineheight Pixel height (SCI scale) of each text line
* @param[out] offset Pixel offset (SCI scale) of the space after the last
* character in the last line
*/
void gfxw_text_info(GfxState *state, GfxText *text, int *lines_nr,
int *lineheight, int *offset);
/**
* Sets a widget's ID
*
* A widget ID is unique within the container it is stored in, if and only if it
* was added to that container with gfxw_add(). This function handles widget ==
* NULL gracefully (by doing nothing and returning NULL).
*
* @param[in] widget The widget whose ID should be set
* @param[in] ID The ID to set
* @param[in] subID The ID to set
* @return The widget
*/
GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID);
/**
* Finds a widget with a specific ID in a container and removes it from there
*
* Search is non-recursive; widgets with IDs hidden in subcontainers will not
* be found.
*
* @param[in] container The container to search in
* @param[in] ID The ID to look for
* @param[in] subID The subID to look for, or GFXW_NO_ID for any
* @return The resulting widget or NULL if no match was found
*/
GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID);
/**
* Initializes a dyn view's interpreter attributes
*
* @param[in] widget The widget affected
* @param[in] under_bits Interpreter-dependant data
* @param[in] under_bitsp Interpreter-dependant data
* @param[in] signal Interpreter-dependant data
* @param[in] signalp Interpreter-dependant data
* @return The widget
*/
GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits,
const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp);
/**
* Makes a widget invisible without removing it from the list of widgets
*
* Has no effect on invisible widgets
*
* @param[in] widget The widget to invisibilize
* @return The widget
*/
GfxWidget *gfxw_hide_widget(GfxWidget *widget);
/**
* Makes an invisible widget reappear
*
* Does not affect visible widgets
*
* @param[in] widget The widget to show again
* @return The widget
*/
GfxWidget *gfxw_show_widget(GfxWidget *widget);
/**
* Marks a widget as "abandoned"
*
* @param[in] widget The widget to abandon
* @return The widget
*/
GfxWidget *gfxw_abandon_widget(GfxWidget *widget);
/** Container types */
enum {
GFXW_LIST_UNSORTED = 0,
GFXW_LIST_SORTED = 1
};
/**
* Creates a new list widget
*
* List widgets are also referred to as Display Lists.
*
* @param[in] area The area covered by the list (absolute position)
* @param[in] sorted Whether the list should be a sorted list
* @return A newly allocated list widget
*/
GfxList *gfxw_new_list(rect_t area, int sorted);
/**
* Retrieves the default port from a visual
*
* The 'default port' is the last port to be instantiated; usually the topmost
* or highest-ranking port.
*
* @param[in] visual The visual the port should be retrieved from
* @return The default port, or NULL if no port is present
*/
GfxPort *gfxw_find_default_port(GfxVisual *visual);
/**
* Sets rectangle to be restored upon port removal
*
* @param[in] visual The visual to operate on
* @param[in] window The affected window
* @param[in] auto_rect The area to restore
*/
void gfxw_port_set_auto_restore(GfxVisual *visual, GfxPort *window, rect_t auto_rect);
/**
* Removes a port from a visual
*
* @param[in] visual The visual the port should be removed from
* @param[in] port The port to remove
* @return port's parent port, or NULL if it had none
*/
GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port);
/**
* Removes the widget from the specified port
*
* @param[in] container The container it should be removed from
* @param[in] widget The widget to remove
*/
void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget);
/**
* Makes a "snapshot" of a visual
*
* It's not really a full qualified snaphot, though. See gfxw_restore_snapshot
* for a full discussion. This operation also increases the global serial number
* counter by one.
*
* @param[in] visual The visual a snapshot is to be taken of
* @param[in] area The area a snapshot should be taken of
* @return The resulting, newly allocated snapshot
*/
gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area);
/**
* Predicate to test whether a widget would be destroyed by applying a snapshot
*
* @param[in] snapshot The snapshot to test against
* @param[in] widget The widget to test
* @return An appropriate boolean value
*/
int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget);
/**
* Restores a snapshot to a visual
*
* The snapshot is not really restored; only more recent widgets touching
* the snapshotted area are destroyed.
*
* @param[in] visual The visual to operate on
* @param[in] snapshot The snapshot to restore
* @return The snapshot (still needs to be freed)
*/
gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot);
/**
* As widget->widfree(widget), but destroys all overlapping widgets
*
* This operation calls widget->widfree(widget), but it also destroys all
* widgets with a higher or equal priority drawn after this widget.
*
* @param[in] widget The widget to use
*/
void gfxw_annihilate(GfxWidget *widget);
/**
* Turns a dynview into a picview
*
* The only changes are in function and type variables, actually.
*
* @param[in] dynview The victim
* @return The victim, after his transformation
*/
GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview);
/**
* Tags a window widget as automatically restoring the visual background
* upon removal.
*
* Also records the specified background rectangle, for later recovery.
*
* @param[in] visual The base visual
* @param[in] window The window to tag
* @param[in] auto_rect The background to remember
*/
void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window,
rect_t auto_rect);
/** @} */
} // End of namespace Sci
#endif // SCI_GFX_GFX_WIDGETS_H
|