aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/gfx/gfx_widgets.h
blob: d30af8ce4e194921bd9d68fc56a3b3e2958b17a3 (plain)
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
474
475
476
477
/* 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$
 *
 */

#include "sci/sci.h"	// for INCLUDE_OLDGFX
#ifdef INCLUDE_OLDGFX

#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

#endif