Home2L - C/C++ API v1.4-0-g38cc (2024-05-25)
Smart Tools for a Private Home
ui_base.H
Go to the documentation of this file.
1/*
2 * This file is part of the Home2L project.
3 *
4 * (C) 2015-2024 Gundolf Kiefer
5 *
6 * Home2L is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Home2L is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Home2L. If not, see <https://www.gnu.org/licenses/>.
18 *
19 */
20
21
22#ifndef _UI_BASE_
23#define _UI_BASE_
24
25
39#include <SDL.h>
40#include <SDL_ttf.h>
41
42#include "env.H"
43
44
45
46
47
48// *************************** Screen resolution *******************************
49
50
51#define UI_RES_X 1024
52#define UI_RES_Y 600
53
54
55
56
57
58// *************************** General *****************************************
59
60
63
64
65extern SDL_Renderer *uiSdlRenderer;
66
67
68void UiInit (const char *windowTitle = "Home2L");
69void UiDone ();
70
71static inline SDL_Renderer *UiGetSdlRenderer () { return uiSdlRenderer; }
72
73void UiGetWindowSize (int *w, int *h);
74
75#if ANDROID == 0
76
77void UiSetWindowSize (int w, int h);
78
79bool UiGetWindowFullScreen ();
80void UiSetWindowFullScreen (bool _fullScreen);
81void UiToggleWindowFullScreen ();
82
83bool UiGetWindowResizable ();
84void UiSetWindowResizable (bool _resizable);
85void UiToggleWindowResizable ();
86
87
88#endif // ANDROID == 0
89
90
92
93
94
95
96
97// *************************** Events ******************************************
98
99
102
103
104enum EUserEvent {
105 evMainThreadCallback = 0,
106 evSystemModeChanged, // (int) data1 = new mode, (int) data2 = previous mode
107 evEND
108};
109
110
111void UiIterate (bool noWait = false);
122static inline void UiIterateNoWait () { UiIterate (true); }
125
126
127void UiQuit ();
128bool UiIsClosed ();
129
130void UiPushUserEvent (EUserEvent code, void *data1 = NULL, void *data2 = NULL);
131
132static inline void MainThreadCallback (void (*func) (void *), void *data = NULL) { UiPushUserEvent (evMainThreadCallback, (void *) func, data); }
134
135
137
138
139
140
141
142// *************************** SDL audio ***************************************
143
144
152
153
154#define AUDIO_FOREVER -1
155
156
157void AudioStart (const char *fileName, int repetitions = 1, TTicks repetitionGap = 0);
163void AudioStop ();
165
169
170
172
173
174
175
176
177// *************************** SDL_Color helpers *******************************
178
179
182
183
184#define SELECTED_SDL_PIXELFORMAT SDL_PIXELFORMAT_ARGB8888
194
195
196#if SELECTED_SDL_PIXELFORMAT==SDL_PIXELFORMAT_ARGB8888
197
198
199struct TColor {
200 Uint8 b : 8;
201 Uint8 g : 8;
202 Uint8 r : 8;
203 Uint8 a : 8;
204}; // __attribute__((packed))__
205
206
207#define COL_MASK_R 0x00FF0000
208#define COL_MASK_G 0x0000FF00
209#define COL_MASK_B 0x000000FF
210#define COL_MASK_A 0xFF000000
211#define COL_MASK_RGB (COL_MASK_R | COL_MASK_G | COL_MASK_B)
212
213
214static inline TColor ToColor (Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255) {
215 TColor ret;
216 ret.r = r; ret.g = g; ret.b = b; ret.a = a;
217 return ret;
218}
219
220
221static inline TColor ToColor (Uint32 val) {
222 union { Uint32 i; TColor c; } ret;
223 ret.i = val;
224 return ret.c;
225 //TColor ret;
226 //memcpy (&ret, &val, sizeof (TColor));
227 //return ret;
228}
229
230
231static inline Uint32 ToUint32 (TColor color) {
232 union { Uint32 i; TColor c; } ret;
233 ret.c = color;
234 return ret.i;
235}
236
237
238static inline Uint32 ToUint32 (Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255) {
239 return ToUint32 (ToColor (r, g, b, a));
240}
241
242
243static inline TColor ToColor (SDL_Color sdlCol) {
244 TColor ret;
245 ret.r = sdlCol.r; ret.g = sdlCol.g; ret.b = sdlCol.b; ret.a = sdlCol.a;
246 return ret;
247}
248
249
250static inline bool operator == (const TColor &col1, const TColor &col2) { return ToUint32 (col1) == ToUint32 (col2); }
251static inline bool operator != (const TColor &col1, const TColor &col2) { return ToUint32 (col1) != ToUint32 (col2); }
252
253
254static inline SDL_Color ToSDL_Color (TColor color) {
255 SDL_Color ret = { .r = color.r, .g = color.g, .b = color.b, .a = color.a };
256 return ret;
257}
258
259
260#endif
261
262
263TColor ColorSum (TColor col1, TColor col2);
265TColor ColorBrighter (TColor color, int d);
267static inline TColor ColorDarker (TColor color, int d) { return ColorBrighter (color, -d); }
269TColor ColorScale (TColor color, int factor);
271TColor ColorBlend (TColor color0, TColor color1, int weight1);
273
274
276
277
280
281#define WHITE ToColor (0xff, 0xff, 0xff)
282#define LIGHT_GREY ToColor (0xc0, 0xc0, 0xc0)
283#define GREY ToColor (0x80, 0x80, 0x80)
284#define DARK_GREY ToColor (0x40, 0x40, 0x40)
285#define DARK_DARK_GREY ToColor (0x20, 0x20, 0x20)
286#define BLACK ToColor (0x00, 0x00, 0x00)
287
288#define RED ToColor (0xff, 0x00, 0x00)
289#define GREEN ToColor (0x00, 0xff, 0x00)
290#define BLUE ToColor (0x00, 0x00, 0xff)
291#define CYAN ToColor (0x00, 0xff, 0xff)
292#define MAGENTA ToColor (0xff, 0x00, 0xff)
293#define YELLOW ToColor (0xff, 0xff, 0x00)
294
295#define DARK_RED ToColor (0x80, 0x00, 0x00)
296#define DARK_GREEN ToColor (0x00, 0x80, 0x00)
297#define DARK_BLUE ToColor (0x00, 0x00, 0x80)
298#define DARK_CYAN ToColor (0x00, 0x80, 0x80)
299#define DARK_MAGENTA ToColor (0x80, 0x00, 0x80)
300#define DARK_YELLOW ToColor (0x80, 0x80, 0x00)
301
302#define LIGHT_RED ToColor (0xff, 0x80, 0x80)
303#define LIGHT_GREEN ToColor (0x80, 0xff, 0x80)
304#define LIGHT_BLUE ToColor (0x80, 0x80, 0xff)
305#define LIGHT_CYAN ToColor (0x80, 0xff, 0xff)
306#define LIGHT_MAGENTA ToColor (0xff, 0x80, 0xff)
307#define LIGHT_YELLOW ToColor (0xff, 0xff, 0x80)
308
309#define BROWN ToColor (0x80, 0x40, 0x00)
310#define LIGHT_BROWN ToColor (0xc0, 0x80, 0x40)
311
312#define ORANGE ToColor (0xc0, 0x40, 0x00)
313
314#define TRANSPARENT ToColor (0x00, 0x00, 0x00, 0x00)
315
317
318
319
320
321
322// *************************** SDL_Rect helpers ********************************
323
324
327
328
329static inline SDL_Rect Rect (int x, int y, int w, int h) {
330 SDL_Rect ret = { .x = x, .y = y, .w = w, .h = h };
331 return ret;
332}
333
334
335static inline SDL_Rect Rect (int w, int h) {
336 SDL_Rect ret = { .x = 0, .y = 0, .w = w, .h = h };
337 return ret;
338}
339
340
341static inline SDL_Rect Rect (SDL_Surface *surf) {
342 SDL_Rect ret = { .x = 0, .y = 0, .w = surf->w, .h = surf->h };
343 return ret;
344}
345
346
347static inline SDL_Rect Rect (SDL_Texture *tex) {
348 SDL_Rect ret;
349 ret.x = ret.y = 0;
350 SDL_QueryTexture (tex, NULL, NULL, &ret.w, &ret.h);
351 return ret;
352}
353
354
355static inline SDL_Rect RectScreen () { return Rect (0, 0, UI_RES_X, UI_RES_Y); }
357
358
359static inline void RectMove (SDL_Rect *rect, int dx, int dy) {
360 rect->x += dx;
361 rect->y += dy;
362}
363
364
365static inline void RectGrow (SDL_Rect *rect, int dx, int dy) {
366 rect->x -= dx;
367 rect->y -= dy;
368 rect->w += 2 * dx;
369 rect->h += 2 * dy;
370}
371
372
373void RectAlign (SDL_Rect *rect, SDL_Rect container, int hAlign = -1, int vAlign = -1);
379
380
381static inline void RectCenter (SDL_Rect *rect, SDL_Rect container) { RectAlign (rect, container, 0, 0); }
383
384
385static inline bool RectContains (SDL_Rect *rect, int x, int y) {
386 return x >= rect->x && x < rect->x+rect->w && y >= rect->y && y < rect->y+rect->h;
387}
388
389
391
392
393
394
395
396// *************************** Surface helpers *********************************
397
398
402
403
404#define ORIENT(FLIPH, ROT) (((FLIPH) ? 4 : 0) | ((ROT) & 3))
406#define ORIENT_WITH_FLIPV(FLIPH, ROT) (((FLIPH) ? 0 : 4) | (((ROT) + 2) & 3))
408
409#define ORIENT_FLIPH(ORI) (((ORI) & 4) ? true : false)
411#define ORIENT_ROT(ORI) ((ORI) & 3)
414
415#if SELECTED_SDL_PIXELFORMAT==SDL_PIXELFORMAT_ARGB8888
417static inline SDL_Surface *CreateSurface (int w, int h) { return SDL_CreateRGBSurfaceWithFormat (0, w, h, 32, SELECTED_SDL_PIXELFORMAT); }
418static inline SDL_Surface *CreateSurface (SDL_Rect r) { return CreateSurface (r.w, r.h); }
419static inline SDL_Surface *CreateSurface (SDL_Rect *r) { return CreateSurface (r->w, r->h); }
420
421static inline SDL_Surface *CreateSurfaceFrom (int w, int h, void *_pixels, int _pitch) { return SDL_CreateRGBSurfaceFrom (_pixels, w, h, 32, _pitch, COL_MASK_R, COL_MASK_G, COL_MASK_B, COL_MASK_A); }
422
423#endif
424
425
426static inline SDL_Surface *SurfaceSet (SDL_Surface **pSurf, SDL_Surface *newSurf) { if (*pSurf) SDL_FreeSurface (*pSurf); *pSurf = newSurf; return newSurf; }
427static inline void SurfaceFree (SDL_Surface **pSurf) { SurfaceSet (pSurf, NULL); }
428static inline void SurfaceFree (SDL_Surface *surf) { SDL_FreeSurface (surf); }
429
430static inline SDL_Surface *SurfaceDup (SDL_Surface *src) { return SDL_ConvertSurface (src, src->format, 0); }
431
432void SurfaceNormalize (SDL_Surface **pSurf);
434
435void SurfaceRecolor (SDL_Surface *surf, TColor color);
437SDL_Surface *SurfaceGetOpaqueCopy (SDL_Surface *surf, TColor backColor);
439void SurfaceMakeTransparentMono (SDL_Surface *surf, Uint8 opaqueLevel = 0xff);
444
445void SurfaceBlit (SDL_Surface *src, SDL_Rect *srcRect, SDL_Surface *dst, SDL_Rect *dstRect = NULL, int hAlign = 0, int vAlign = 0, SDL_BlendMode blendMode = SDL_BLENDMODE_NONE);
454static inline void SurfaceFill (SDL_Surface *surf, TColor col) { SDL_FillRect (surf, NULL, ToUint32 (col)); }
455static inline void SurfaceFillRect (SDL_Surface *surf, SDL_Rect r, TColor col) { SDL_FillRect (surf, &r, ToUint32 (col)); }
456static inline void SurfaceFillRect (SDL_Surface *surf, SDL_Rect *r, TColor col) { SDL_FillRect (surf, r, ToUint32 (col)); }
457
458SDL_Surface *SurfaceGetScaledDownCopy (SDL_Surface *surf, int factor, bool preserveThinLines = false);
464SDL_Surface *SurfaceGetFlippedAndRotatedCopy (SDL_Surface *surf, int orient);
467
468SDL_Surface *SurfaceReadBmp (const char *fileName);
473
474
475
476// ********** CNetpbmReader **********
477
478
479#define NETPBM_IDLE -3
480#define NETPBM_ERROR -2
481#define NETPBM_SUCCESS -1
482
489class CNetpbmReader {
490 public:
491 CNetpbmReader () { surf = NULL; state = NETPBM_IDLE; }
492 ~CNetpbmReader () { Clear (); }
496 void Clear ();
497 void Put (const char *line);
499
502 int State () { return state; }
503 bool Running () { return state >= 0; }
504 bool Error () { return state == NETPBM_ERROR; }
505 bool Success () { return state == NETPBM_SUCCESS; }
506
507 SDL_Surface *Surface () { return Success () ? surf : NULL; }
514
517 bool ReadFile (const char *fileName);
518 bool ReadStream (int fd);
519 bool ReadShell (CShell *shell);
521
522 protected:
523 SDL_Surface *surf;
524 int format; // 2 or 3 (the number behind the 'P')
525 int w, h;
526 int state; // Number of words read (1 => 'Pn' was just read; < 0: no reading in progress)
527};
528
529
531
532
533
534
535
536// *************************** Texture helpers *********************************
537
538
541
542
543static inline SDL_Texture *CreateTexture (SDL_Surface *surf) { return SDL_CreateTextureFromSurface (uiSdlRenderer, surf); }
544
545static inline void TextureSet (SDL_Texture **pTex, SDL_Texture *newTex) { if (*pTex) SDL_DestroyTexture (*pTex); *pTex = newTex; }
546static inline void TextureFree (SDL_Texture **pTex) { TextureSet (pTex, NULL); }
547
548static inline void TextureRender (SDL_Texture *tex, SDL_Rect *srcRect = NULL, SDL_Rect *dstRect = NULL) { SDL_RenderCopy (uiSdlRenderer, tex, srcRect, dstRect); }
549
550
552
553
554
555
556
557// *************************** Icon handling ***********************************
558
559
562
563
564SDL_Surface *IconGet (const char *name, TColor color = WHITE, TColor bgColor = TRANSPARENT, int scaleDown = 1, int orient = 0, bool preserveThinLines = false);
570
571
573
574
575
576
577
578// *************************** Font handling ***********************************
579
580
583
584
586enum EFontStyle {
587 fntNormal = 0,
588 fntBold,
589 fntItalic,
596 fntEND
600TTF_Font *FontGet (EFontStyle style, int size);
602
603SDL_Surface *FontRenderText (TTF_Font *font, const char *text, TColor color);
607SDL_Surface *FontRenderText (TTF_Font *font, const char *text, TColor color, TColor bgColor);
612
613static inline int FontGetLineSkip (TTF_Font *font) { return TTF_FontLineSkip (font); }
614
615static inline int FontGetHeight (TTF_Font *font) { return TTF_FontHeight (font); }
616int FontGetWidth (TTF_Font *font, const char *text, int textLen = -1);
617
618
620
621
622
623
624
625// *************************** Complex text formatting *************************
626
627
631
632
635class CTextFormat {
636 public:
637 CTextFormat () { font = NULL; }
638 CTextFormat (TTF_Font *_font, TColor _color, TColor _bgColor = TRANSPARENT,
639 int _hAlign = -1, int _vAlign = -1,
640 int _hSpace = 0, int _vSpace = 0,
641 int _maxWidth = 0, int _maxHeigth = 0) {
642 font = _font; color = _color; bgColor = _bgColor;
643 hAlign = _hAlign; vAlign = _vAlign;
644 hSpace = _hSpace; vSpace = _vSpace;
645 maxWidth = _maxWidth;
646 maxHeight = _maxHeigth;
647 }
648
649 // Parameters ...
650 TTF_Font *font;
651 TColor color, bgColor;
652 int hAlign, vAlign;
653 int vSpace, hSpace;
654 int maxWidth, maxHeight;
659class CTextSet {
660 public:
661 CTextSet () { surface = NULL; firstItem = NULL; height = 0; }
662 ~CTextSet () { Clear (); }
664 void Clear ();
666 void AddLines (const char *text, CTextFormat fmt, bool *retAbbreviated = NULL);
670 int GetHeight ();
672
673 SDL_Surface *Render (SDL_Surface *dst = NULL, SDL_Rect *dstRect = NULL);
683
684 protected:
685 SDL_Surface *surface;
686 class CTextItem *firstItem;
687 int height;
688};
689
690
691// Easy-to-use function(s)...
692SDL_Surface *TextRender (const char *text, CTextFormat fmt, SDL_Surface *dst = NULL, SDL_Rect *dstRect = NULL, bool *retAbbreviated = NULL);
694
695
697
698
699
700
701
707#endif
Reader for Netpbm image files.
Definition: ui_base.H:493
void Put(const char *line)
Put a text line.
SDL_Surface * Surface()
Return surface on success or NULL in all other cases.
Definition: ui_base.H:511
void Clear()
Reset reader (not necessary at the first time).
Abstract base class for shells that can execute system commands.
Definition: base.H:1872
int hSpace
Vertical and horizontal space in pixels.
Definition: ui_base.H:657
TColor bgColor
Foreground and background color; 'bgColor' == 'TRANSPARENT' selects "blended mode" in font rendering.
Definition: ui_base.H:655
int maxHeight
Maximum width in pixels (for automatic line breaking).
Definition: ui_base.H:658
int vAlign
Alignment: -1 = left/up, 0 = center, +1 = right/down.
Definition: ui_base.H:656
TTF_Font * font
Text font.
Definition: ui_base.H:654
Typesetter for longer formatted texts.
Definition: ui_base.H:663
SDL_Surface * Render(SDL_Surface *dst=NULL, SDL_Rect *dstRect=NULL)
Render everything and return a new surface containing the text.
int GetHeight()
Accumulated height in pixels according to all previous AddLines() invocations.
void AddLines(const char *text, CTextFormat fmt, bool *retAbbreviated=NULL)
Add text with a given format. If the 'maxHeight' parameter is set in 'fmt', the text is automatically...
void Clear()
Clear everything.
int64_t TTicks
Time value (relative, absolute, or monotonic).
Definition: base.H:1378
#define UI_RES_Y
UI resolution in pixels (Y)
Definition: ui_base.H:52
void SurfaceMakeTransparentMono(SDL_Surface *surf, Uint8 opaqueLevel=0xff)
Copy the R values to the A channel and make all RGB values white.
#define NETPBM_ERROR
State code "error" for CNetpbmReader.
Definition: ui_base.H:484
void UiQuit()
Quit the application.
static TColor ColorDarker(TColor color, int d)
Decreas all color components by d with saturation; d may be negative.
Definition: ui_base.H:267
EFontStyle
Supported font styles.
Definition: ui_base.H:590
SDL_Surface * SurfaceGetScaledDownCopy(SDL_Surface *surf, int factor, bool preserveThinLines=false)
Get a copy of the surface, scaled down by a factor in both dimensions.
void SurfaceBlit(SDL_Surface *src, SDL_Rect *srcRect, SDL_Surface *dst, SDL_Rect *dstRect=NULL, int hAlign=0, int vAlign=0, SDL_BlendMode blendMode=SDL_BLENDMODE_NONE)
Blit a surface; It is allowed to leave 'src == NULL', in which case nothing happens.
bool UiIsClosed()
Is the application quitting?
static SDL_Rect RectScreen()
Rectangle representing the whole UI screen.
Definition: ui_base.H:355
SDL_Surface * TextRender(const char *text, CTextFormat fmt, SDL_Surface *dst=NULL, SDL_Rect *dstRect=NULL, bool *retAbbreviated=NULL)
Easy-to-use function to typeset a text with a single format.
static void RectCenter(SDL_Rect *rect, SDL_Rect container)
Center the rectangle 'rect' with respect to an outer rectangle 'container'.
Definition: ui_base.H:381
void RectAlign(SDL_Rect *rect, SDL_Rect container, int hAlign=-1, int vAlign=-1)
Align the rectangle 'rect' with an outer rectangle 'container'.
#define NETPBM_IDLE
State code "idle" for CNetpbmReader.
Definition: ui_base.H:483
void SurfaceRecolor(SDL_Surface *surf, TColor color)
Replace all RGB values with the passed color while leaving alpha values untouched.
TColor ColorSum(TColor col1, TColor col2)
Add two colors (with saturation).
SDL_Surface * SurfaceGetOpaqueCopy(SDL_Surface *surf, TColor backColor)
Create an opaque copy; caller becomes owner of returned surface.
SDL_Surface * FontRenderText(TTF_Font *font, const char *text, TColor color)
Render a text using 'blended' mode of the SDL2_ttf library. The returned surface is a new surface of ...
TColor ColorScale(TColor color, int factor)
Multiply all components with a factor. 'factor' is a fixed point number with 8 fractional bits (1....
TColor ColorBrighter(TColor color, int d)
Increase all color components by d with saturation; d may be negative.
void SurfaceNormalize(SDL_Surface **pSurf)
Normalize pixel format to SELECTED_SDL_PIXELFORMAT.
SDL_Surface * SurfaceGetFlippedAndRotatedCopy(SDL_Surface *surf, int orient)
Get a copy of the surface, which is eventually flipped and then rotated in 90° steps clockwise 'surf'...
void UiIterate(bool noWait=false)
#define NETPBM_SUCCESS
State code "success" for CNetpbmReader.
Definition: ui_base.H:485
SDL_Surface * IconGet(const char *name, TColor color=WHITE, TColor bgColor=TRANSPARENT, int scaleDown=1, int orient=0, bool preserveThinLines=false)
Get a reference to an icon from the application's 'etc/icons/' or 'share/icons/' folder.
#define SELECTED_SDL_PIXELFORMAT
Selected (SDL) pixel format.
Definition: ui_base.H:184
static void UiIterateNoWait()
Iterate the application's main event loop; Does not sleep, but returns immediately ("yield"-functiona...
Definition: ui_base.H:122
SDL_Surface * SurfaceReadBmp(const char *fileName)
Read a .bmp file.
void AudioStop()
Stop playing audio immediately.
bool AudioIsPlaying()
Query if audio is still playing. If 'false' is returned, the audio device is surely in a stopped stat...
#define UI_RES_X
UI resolution in pixels (X)
Definition: ui_base.H:51
TTF_Font * FontGet(EFontStyle style, int size)
Get a reference to a font of a specific style and size.
void AudioStart(const char *fileName, int repetitions=1, TTicks repetitionGap=0)
Start playing audio.
TColor ColorBlend(TColor color0, TColor color1, int weight1)
Blend two colors; 'weight' is a fixed point number with 8 fractional bits (1.0 == 0x100) and refers t...
static void MainThreadCallback(void(*func)(void *), void *data=NULL)
Request function 'func' to be called by main thread at next occasion.
Definition: ui_base.H:132
@ fntMonoItalic
Monotype, italic.
Definition: ui_base.H:598
@ fntMonoBold
Monotype, bold.
Definition: ui_base.H:597
@ fntMonoBoldItalic
Monotype, bold and italic.
Definition: ui_base.H:599
@ fntNormal
Normal.
Definition: ui_base.H:591
@ fntItalic
Italic.
Definition: ui_base.H:593
@ fntBoldItalic
Bold and italic.
Definition: ui_base.H:594
@ fntBold
Bold.
Definition: ui_base.H:592
@ fntLight
Light.
Definition: ui_base.H:595
@ fntMono
Monotype.
Definition: ui_base.H:596