source: mainline/uspace/lib/ui/src/resource.c@ 6df564c

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6df564c was 6df564c, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Custom colors for selected text in text entry

In text mode, swapping 'background' and 'text' color does not work,
they are the same. Looks better in graphics mode, too.

  • Property mode set to 100644
File size: 17.1 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libui
30 * @{
31 */
32/**
33 * @file UI resources
34 */
35
36#include <errno.h>
37#include <gfx/color.h>
38#include <gfx/context.h>
39#include <gfx/font.h>
40#include <gfx/render.h>
41#include <gfx/typeface.h>
42#include <stdlib.h>
43#include <str.h>
44#include <ui/resource.h>
45#include "../private/resource.h"
46
47static const char *ui_typeface_path = "/data/font/helena.tpf";
48
49/** Create new UI resource in graphics mode.
50 *
51 * @param gc Graphic context
52 * @param rresource Place to store pointer to new UI resource
53 * @return EOK on success, ENOMEM if out of memory
54 */
55static errno_t ui_resource_create_gfx(gfx_context_t *gc,
56 ui_resource_t **rresource)
57{
58 ui_resource_t *resource;
59 gfx_typeface_t *tface = NULL;
60 gfx_font_t *font = NULL;
61 gfx_font_info_t *finfo;
62 gfx_color_t *btn_frame_color = NULL;
63 gfx_color_t *btn_face_color = NULL;
64 gfx_color_t *btn_text_color = NULL;
65 gfx_color_t *btn_highlight_color = NULL;
66 gfx_color_t *btn_shadow_color = NULL;
67 gfx_color_t *wnd_face_color = NULL;
68 gfx_color_t *wnd_text_color = NULL;
69 gfx_color_t *wnd_sel_text_color = NULL;
70 gfx_color_t *wnd_sel_text_bg_color = NULL;
71 gfx_color_t *wnd_frame_hi_color = NULL;
72 gfx_color_t *wnd_frame_sh_color = NULL;
73 gfx_color_t *wnd_highlight_color = NULL;
74 gfx_color_t *wnd_shadow_color = NULL;
75 gfx_color_t *tbar_act_bg_color = NULL;
76 gfx_color_t *tbar_inact_bg_color = NULL;
77 gfx_color_t *tbar_act_text_color = NULL;
78 gfx_color_t *tbar_inact_text_color = NULL;
79 gfx_color_t *entry_fg_color = NULL;
80 gfx_color_t *entry_bg_color = NULL;
81 gfx_color_t *entry_act_bg_color = NULL;
82 gfx_color_t *entry_sel_text_fg_color = NULL;
83 gfx_color_t *entry_sel_text_bg_color = NULL;
84 errno_t rc;
85
86 resource = calloc(1, sizeof(ui_resource_t));
87 if (resource == NULL)
88 return ENOMEM;
89
90 rc = gfx_typeface_open(gc, ui_typeface_path, &tface);
91 if (rc != EOK)
92 goto error;
93
94 finfo = gfx_typeface_first_font(tface);
95 if (finfo == NULL) {
96 rc = EIO;
97 goto error;
98 }
99
100 rc = gfx_font_open(finfo, &font);
101 if (rc != EOK)
102 goto error;
103
104 rc = gfx_color_new_rgb_i16(0, 0, 0, &btn_frame_color);
105 if (rc != EOK)
106 goto error;
107
108 rc = gfx_color_new_rgb_i16(0xc8c8, 0xc8c8, 0xc8c8, &btn_face_color);
109 if (rc != EOK)
110 goto error;
111
112 rc = gfx_color_new_rgb_i16(0, 0, 0, &btn_text_color);
113 if (rc != EOK)
114 goto error;
115
116 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
117 &btn_highlight_color);
118 if (rc != EOK)
119 goto error;
120
121 rc = gfx_color_new_rgb_i16(0x8888, 0x8888, 0x8888, &btn_shadow_color);
122 if (rc != EOK)
123 goto error;
124
125 rc = gfx_color_new_rgb_i16(0xc8c8, 0xc8c8, 0xc8c8, &wnd_face_color);
126 if (rc != EOK)
127 goto error;
128
129 rc = gfx_color_new_rgb_i16(0, 0, 0, &wnd_text_color);
130 if (rc != EOK)
131 goto error;
132
133 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &wnd_sel_text_color);
134 if (rc != EOK)
135 goto error;
136
137 rc = gfx_color_new_rgb_i16(0x5858, 0x6a6a, 0xc4c4,
138 &wnd_sel_text_bg_color);
139 if (rc != EOK)
140 goto error;
141
142 rc = gfx_color_new_rgb_i16(0x8888, 0x8888, 0x8888, &wnd_frame_hi_color);
143 if (rc != EOK)
144 goto error;
145
146 rc = gfx_color_new_rgb_i16(0x4444, 0x4444, 0x4444, &wnd_frame_sh_color);
147 if (rc != EOK)
148 goto error;
149
150 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
151 &wnd_highlight_color);
152 if (rc != EOK)
153 goto error;
154
155 rc = gfx_color_new_rgb_i16(0x8888, 0x8888, 0x8888, &wnd_shadow_color);
156 if (rc != EOK)
157 goto error;
158
159 rc = gfx_color_new_rgb_i16(0x5858, 0x6a6a, 0xc4c4, &tbar_act_bg_color);
160 if (rc != EOK)
161 goto error;
162
163 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
164 &tbar_act_text_color);
165 if (rc != EOK)
166 goto error;
167
168 rc = gfx_color_new_rgb_i16(0xdddd, 0xdddd, 0xdddd,
169 &tbar_inact_bg_color);
170 if (rc != EOK)
171 goto error;
172
173 rc = gfx_color_new_rgb_i16(0x5858, 0x5858, 0x5858,
174 &tbar_inact_text_color);
175 if (rc != EOK)
176 goto error;
177
178 rc = gfx_color_new_rgb_i16(0, 0, 0, &entry_fg_color);
179 if (rc != EOK)
180 goto error;
181
182 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &entry_bg_color);
183 if (rc != EOK)
184 goto error;
185
186 rc = gfx_color_new_rgb_i16(0xc8c8, 0xc8c8, 0xc8c8, &entry_act_bg_color);
187 if (rc != EOK)
188 goto error;
189
190 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
191 &entry_sel_text_fg_color);
192 if (rc != EOK)
193 goto error;
194
195 rc = gfx_color_new_rgb_i16(0, 0, 0xffff, &entry_sel_text_bg_color);
196 if (rc != EOK)
197 goto error;
198
199 resource->gc = gc;
200 resource->tface = tface;
201 resource->font = font;
202 resource->textmode = false;
203
204 resource->btn_frame_color = btn_frame_color;
205 resource->btn_face_color = btn_face_color;
206 resource->btn_text_color = btn_text_color;
207 resource->btn_highlight_color = btn_highlight_color;
208 resource->btn_shadow_color = btn_shadow_color;
209
210 resource->wnd_face_color = wnd_face_color;
211 resource->wnd_text_color = wnd_text_color;
212 resource->wnd_sel_text_color = wnd_sel_text_color;
213 resource->wnd_sel_text_bg_color = wnd_sel_text_bg_color;
214 resource->wnd_frame_hi_color = wnd_frame_hi_color;
215 resource->wnd_frame_sh_color = wnd_frame_sh_color;
216 resource->wnd_highlight_color = wnd_highlight_color;
217 resource->wnd_shadow_color = wnd_shadow_color;
218
219 resource->tbar_act_bg_color = tbar_act_bg_color;
220 resource->tbar_act_text_color = tbar_act_text_color;
221 resource->tbar_inact_bg_color = tbar_inact_bg_color;
222 resource->tbar_inact_text_color = tbar_inact_text_color;
223
224 resource->entry_fg_color = entry_fg_color;
225 resource->entry_bg_color = entry_bg_color;
226 resource->entry_act_bg_color = entry_act_bg_color;
227 resource->entry_sel_text_fg_color = entry_sel_text_fg_color;
228 resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
229
230 *rresource = resource;
231 return EOK;
232error:
233 if (btn_frame_color != NULL)
234 gfx_color_delete(btn_frame_color);
235 if (btn_face_color != NULL)
236 gfx_color_delete(btn_face_color);
237 if (btn_text_color != NULL)
238 gfx_color_delete(btn_text_color);
239 if (btn_highlight_color != NULL)
240 gfx_color_delete(btn_highlight_color);
241 if (btn_shadow_color != NULL)
242 gfx_color_delete(btn_shadow_color);
243
244 if (wnd_face_color != NULL)
245 gfx_color_delete(wnd_face_color);
246 if (wnd_text_color != NULL)
247 gfx_color_delete(wnd_text_color);
248 if (wnd_sel_text_color != NULL)
249 gfx_color_delete(wnd_sel_text_color);
250 if (wnd_sel_text_bg_color != NULL)
251 gfx_color_delete(wnd_sel_text_bg_color);
252 if (wnd_frame_hi_color != NULL)
253 gfx_color_delete(wnd_frame_hi_color);
254 if (wnd_frame_sh_color != NULL)
255 gfx_color_delete(wnd_frame_sh_color);
256 if (wnd_highlight_color != NULL)
257 gfx_color_delete(wnd_highlight_color);
258 if (wnd_shadow_color != NULL)
259 gfx_color_delete(wnd_shadow_color);
260
261 if (tbar_act_bg_color != NULL)
262 gfx_color_delete(tbar_act_bg_color);
263 if (tbar_act_text_color != NULL)
264 gfx_color_delete(tbar_act_text_color);
265 if (tbar_inact_bg_color != NULL)
266 gfx_color_delete(tbar_inact_bg_color);
267 if (tbar_inact_text_color != NULL)
268 gfx_color_delete(tbar_inact_text_color);
269
270 if (entry_fg_color != NULL)
271 gfx_color_delete(entry_fg_color);
272 if (entry_bg_color != NULL)
273 gfx_color_delete(entry_bg_color);
274 if (entry_sel_text_fg_color != NULL)
275 gfx_color_delete(entry_sel_text_fg_color);
276 if (entry_sel_text_bg_color != NULL)
277 gfx_color_delete(entry_sel_text_bg_color);
278 if (entry_act_bg_color != NULL)
279 gfx_color_delete(entry_act_bg_color);
280
281 if (tface != NULL)
282 gfx_typeface_destroy(tface);
283 free(resource);
284 return rc;
285}
286
287/** Create new UI resource in text mode.
288 *
289 * @param gc Graphic context
290 * @param rresource Place to store pointer to new UI resource
291 * @return EOK on success, ENOMEM if out of memory
292 */
293static errno_t ui_resource_create_text(gfx_context_t *gc,
294 ui_resource_t **rresource)
295{
296 ui_resource_t *resource;
297 gfx_typeface_t *tface = NULL;
298 gfx_font_t *font = NULL;
299 gfx_color_t *btn_frame_color = NULL;
300 gfx_color_t *btn_face_color = NULL;
301 gfx_color_t *btn_text_color = NULL;
302 gfx_color_t *btn_highlight_color = NULL;
303 gfx_color_t *btn_shadow_color = NULL;
304 gfx_color_t *wnd_face_color = NULL;
305 gfx_color_t *wnd_text_color = NULL;
306 gfx_color_t *wnd_sel_text_color = NULL;
307 gfx_color_t *wnd_sel_text_bg_color = NULL;
308 gfx_color_t *wnd_frame_hi_color = NULL;
309 gfx_color_t *wnd_frame_sh_color = NULL;
310 gfx_color_t *wnd_highlight_color = NULL;
311 gfx_color_t *wnd_shadow_color = NULL;
312 gfx_color_t *tbar_act_bg_color = NULL;
313 gfx_color_t *tbar_inact_bg_color = NULL;
314 gfx_color_t *tbar_act_text_color = NULL;
315 gfx_color_t *tbar_inact_text_color = NULL;
316 gfx_color_t *entry_fg_color = NULL;
317 gfx_color_t *entry_bg_color = NULL;
318 gfx_color_t *entry_sel_text_fg_color = NULL;
319 gfx_color_t *entry_sel_text_bg_color = NULL;
320 gfx_color_t *entry_act_bg_color = NULL;
321 errno_t rc;
322
323 resource = calloc(1, sizeof(ui_resource_t));
324 if (resource == NULL)
325 return ENOMEM;
326
327 /* Create dummy font for text mode */
328 rc = gfx_typeface_create(gc, &tface);
329 if (rc != EOK)
330 goto error;
331
332 rc = gfx_font_create_textmode(tface, &font);
333 if (rc != EOK)
334 goto error;
335
336 rc = gfx_color_new_ega(0x07, &btn_frame_color);
337 if (rc != EOK)
338 goto error;
339
340 rc = gfx_color_new_ega(0x20, &btn_face_color);
341 if (rc != EOK)
342 goto error;
343
344 rc = gfx_color_new_ega(0x20, &btn_text_color);
345 if (rc != EOK)
346 goto error;
347
348 rc = gfx_color_new_ega(0x20, &btn_highlight_color);
349 if (rc != EOK)
350 goto error;
351
352 rc = gfx_color_new_ega(0x01, &btn_shadow_color);
353 if (rc != EOK)
354 goto error;
355
356 rc = gfx_color_new_ega(0x70, &wnd_face_color);
357 if (rc != EOK)
358 goto error;
359
360 rc = gfx_color_new_ega(0x70, &wnd_text_color);
361 if (rc != EOK)
362 goto error;
363
364 rc = gfx_color_new_ega(0x07, &wnd_sel_text_color);
365 if (rc != EOK)
366 goto error;
367
368 rc = gfx_color_new_ega(0x07, &wnd_sel_text_bg_color);
369 if (rc != EOK)
370 goto error;
371
372 rc = gfx_color_new_ega(0x70, &wnd_frame_hi_color);
373 if (rc != EOK)
374 goto error;
375
376 rc = gfx_color_new_ega(0x01, &wnd_frame_sh_color);
377 if (rc != EOK)
378 goto error;
379
380 rc = gfx_color_new_ega(0x70, &wnd_highlight_color);
381 if (rc != EOK)
382 goto error;
383
384 rc = gfx_color_new_ega(0x01, &wnd_shadow_color);
385 if (rc != EOK)
386 goto error;
387
388 rc = gfx_color_new_ega(0x70, &tbar_act_bg_color);
389 if (rc != EOK)
390 goto error;
391
392 rc = gfx_color_new_ega(0x70, &tbar_act_text_color);
393 if (rc != EOK)
394 goto error;
395
396 rc = gfx_color_new_ega(0x07, &tbar_inact_bg_color);
397 if (rc != EOK)
398 goto error;
399
400 rc = gfx_color_new_ega(0x07, &tbar_inact_text_color);
401 if (rc != EOK)
402 goto error;
403
404 rc = gfx_color_new_ega(0x1b, &entry_fg_color);
405 if (rc != EOK)
406 goto error;
407
408 rc = gfx_color_new_ega(0x1b, &entry_bg_color);
409 if (rc != EOK)
410 goto error;
411
412 rc = gfx_color_new_ega(0x20, &entry_sel_text_fg_color);
413 if (rc != EOK)
414 goto error;
415
416 rc = gfx_color_new_ega(0x20, &entry_sel_text_bg_color);
417 if (rc != EOK)
418 goto error;
419
420 rc = gfx_color_new_ega(0x37, &entry_act_bg_color);
421 if (rc != EOK)
422 goto error;
423
424 resource->gc = gc;
425 resource->tface = tface;
426 resource->font = font;
427 resource->textmode = true;
428
429 resource->btn_frame_color = btn_frame_color;
430 resource->btn_face_color = btn_face_color;
431 resource->btn_text_color = btn_text_color;
432 resource->btn_highlight_color = btn_highlight_color;
433 resource->btn_shadow_color = btn_shadow_color;
434
435 resource->wnd_face_color = wnd_face_color;
436 resource->wnd_text_color = wnd_text_color;
437 resource->wnd_sel_text_color = wnd_sel_text_color;
438 resource->wnd_sel_text_bg_color = wnd_sel_text_bg_color;
439 resource->wnd_frame_hi_color = wnd_frame_hi_color;
440 resource->wnd_frame_sh_color = wnd_frame_sh_color;
441 resource->wnd_highlight_color = wnd_highlight_color;
442 resource->wnd_shadow_color = wnd_shadow_color;
443
444 resource->tbar_act_bg_color = tbar_act_bg_color;
445 resource->tbar_act_text_color = tbar_act_text_color;
446 resource->tbar_inact_bg_color = tbar_inact_bg_color;
447 resource->tbar_inact_text_color = tbar_inact_text_color;
448
449 resource->entry_fg_color = entry_fg_color;
450 resource->entry_bg_color = entry_bg_color;
451 resource->entry_act_bg_color = entry_act_bg_color;
452 resource->entry_sel_text_fg_color = entry_sel_text_fg_color;
453 resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
454
455 *rresource = resource;
456 return EOK;
457error:
458 if (btn_frame_color != NULL)
459 gfx_color_delete(btn_frame_color);
460 if (btn_face_color != NULL)
461 gfx_color_delete(btn_face_color);
462 if (btn_text_color != NULL)
463 gfx_color_delete(btn_text_color);
464 if (btn_highlight_color != NULL)
465 gfx_color_delete(btn_highlight_color);
466 if (btn_shadow_color != NULL)
467 gfx_color_delete(btn_shadow_color);
468
469 if (wnd_face_color != NULL)
470 gfx_color_delete(wnd_face_color);
471 if (wnd_text_color != NULL)
472 gfx_color_delete(wnd_text_color);
473 if (wnd_sel_text_color != NULL)
474 gfx_color_delete(wnd_sel_text_color);
475 if (wnd_sel_text_bg_color != NULL)
476 gfx_color_delete(wnd_sel_text_bg_color);
477 if (wnd_frame_hi_color != NULL)
478 gfx_color_delete(wnd_frame_hi_color);
479 if (wnd_frame_sh_color != NULL)
480 gfx_color_delete(wnd_frame_sh_color);
481 if (wnd_highlight_color != NULL)
482 gfx_color_delete(wnd_highlight_color);
483 if (wnd_shadow_color != NULL)
484 gfx_color_delete(wnd_shadow_color);
485
486 if (tbar_act_bg_color != NULL)
487 gfx_color_delete(tbar_act_bg_color);
488 if (tbar_act_text_color != NULL)
489 gfx_color_delete(tbar_act_text_color);
490 if (tbar_inact_bg_color != NULL)
491 gfx_color_delete(tbar_inact_bg_color);
492 if (tbar_inact_text_color != NULL)
493 gfx_color_delete(tbar_inact_text_color);
494
495 if (entry_fg_color != NULL)
496 gfx_color_delete(entry_fg_color);
497 if (entry_bg_color != NULL)
498 gfx_color_delete(entry_bg_color);
499 if (entry_act_bg_color != NULL)
500 gfx_color_delete(entry_act_bg_color);
501 if (entry_sel_text_fg_color != NULL)
502 gfx_color_delete(entry_sel_text_fg_color);
503 if (entry_sel_text_bg_color != NULL)
504 gfx_color_delete(entry_sel_text_bg_color);
505
506 if (tface != NULL)
507 gfx_typeface_destroy(tface);
508 free(resource);
509 return rc;
510}
511
512/** Create new UI resource.
513 *
514 * @param gc Graphic context
515 * @param textmode @c true if running in text mode
516 * @param rresource Place to store pointer to new UI resource
517 * @return EOK on success, ENOMEM if out of memory
518 */
519errno_t ui_resource_create(gfx_context_t *gc, bool textmode,
520 ui_resource_t **rresource)
521{
522 if (textmode)
523 return ui_resource_create_text(gc, rresource);
524 else
525 return ui_resource_create_gfx(gc, rresource);
526}
527
528/** Destroy UI resource.
529 *
530 * @param resource UI resource or @c NULL
531 */
532void ui_resource_destroy(ui_resource_t *resource)
533{
534 if (resource == NULL)
535 return;
536
537 gfx_color_delete(resource->btn_frame_color);
538 gfx_color_delete(resource->btn_face_color);
539 gfx_color_delete(resource->btn_text_color);
540 gfx_color_delete(resource->btn_highlight_color);
541 gfx_color_delete(resource->btn_shadow_color);
542
543 gfx_color_delete(resource->wnd_face_color);
544 gfx_color_delete(resource->wnd_text_color);
545 gfx_color_delete(resource->wnd_sel_text_color);
546 gfx_color_delete(resource->wnd_sel_text_bg_color);
547 gfx_color_delete(resource->wnd_frame_hi_color);
548 gfx_color_delete(resource->wnd_frame_sh_color);
549 gfx_color_delete(resource->wnd_highlight_color);
550 gfx_color_delete(resource->wnd_shadow_color);
551
552 gfx_color_delete(resource->tbar_act_bg_color);
553 gfx_color_delete(resource->tbar_act_text_color);
554 gfx_color_delete(resource->tbar_inact_bg_color);
555 gfx_color_delete(resource->tbar_inact_text_color);
556
557 gfx_color_delete(resource->entry_fg_color);
558 gfx_color_delete(resource->entry_bg_color);
559 gfx_color_delete(resource->entry_act_bg_color);
560 gfx_color_delete(resource->entry_sel_text_fg_color);
561 gfx_color_delete(resource->entry_sel_text_bg_color);
562
563 gfx_font_close(resource->font);
564 gfx_typeface_destroy(resource->tface);
565 free(resource);
566}
567
568/** Set UI resource expose callback.
569 *
570 * @param resource Resource
571 * @param cb Callback
572 * @param arg Callback argument
573 */
574void ui_resource_set_expose_cb(ui_resource_t *resource,
575 ui_expose_cb_t cb, void *arg)
576{
577 resource->expose_cb = cb;
578 resource->expose_arg = arg;
579}
580
581/** Force UI repaint after an area has been exposed.
582 *
583 * This is called when a popup disappears, which could have exposed some
584 * other UI elements. It causes complete repaint of the UI.
585 *
586 * NOTE Ideally we could specify the exposed rectangle and then limit
587 * the repaint to just that. That would, however, require means of
588 * actually clipping the repaint operation.
589 */
590void ui_resource_expose(ui_resource_t *resource)
591{
592 if (resource->expose_cb != NULL)
593 resource->expose_cb(resource->expose_arg);
594}
595
596/** @}
597 */
Note: See TracBrowser for help on using the repository browser.