1 /**
2  * File name: Rk.h
3  * Project: Redkite (A small GUI toolkit)
4  *
5  * Copyright (C) 2019 Iurie Nistor <http://iuriepage.wordpress.com>
6  *
7  * This file is part of Redkite.
8  *
9  * Redkite is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #ifndef RK_GLOBAL_H
25 #define RK_GLOBAL_H
26 
27 #define RK_VERSION 0x010300
28 #define RK_MAJOR   0x01
29 #define RK_MINOR   0x03
30 #define RK_PATCH   0x01
31 
32 #include <utility>
33 #include <memory>
34 #include <vector>
35 #include <string>
36 #include <list>
37 #include <memory>
38 #include <thread>
39 #include <chrono>
40 #include <functional>
41 #include <unordered_map>
42 #include <unordered_set>
43 #include <mutex>
44 #include <array>
45 #include <iostream>
46 #include <sstream>
47 
48 #define RK_UNUSED(expr) (void)expr
49 
50 #ifdef RK_OS_WIN
51 #define RK_NO_EXPORT
52 #ifdef RK_EXPORT_INTERFACE
53 // Export Redkite interface
54 #define RK_EXPORT  __declspec(dllexport)
55 #else
56 #define RK_EXPORT
57 #endif
58 #elif RK_OS_MAC
59 #error not implemented for Mac
60 #else // RK_OS_GNU
61 #define RK_NO_EXPORT __attribute__((visibility("hidden")))
62 #ifdef RK_EXPORT_INTERFACE
63 // Export Redkite interface
64 #define RK_EXPORT __attribute__((visibility("default")))
65 #else
66 #define RK_EXPORT
67 #endif
68 #endif
69 
70 #define RK_DECLARE_IMPL(Class) \
71   class Class##Impl; \
72   std::unique_ptr<Class##Impl> o_ptr
73 
74 #define RK_DELCATE_IMPL_PTR(Class) \
75   class Class##Impl; \
76   Class##Impl *impl_ptr
77 
78 #define RK_DECALRE_INTERFACE_PTR(Class) Class *inf_ptr
79 
80 #define RK_CLASS_INFO(name, value) virtual std::string rk__property_ ##name () const { return std::string( #value ); }
81 #define RK_SET_CLASS_INFO(name, value) virtual std::string rk__property_ ##name () const override { return std::string( #value ); }
82 
83 #define RK_DISABLE_COPY(Class) \
84           Class(const Class &other) = delete; \
85           Class& operator=(const Class &other) = delete
86 
87 #define RK_DISABLE_MOVE(Class) \
88           Class(Class &&other) = delete; \
89           Class& operator=(Class &&other) = delete
90 
91 #if defined(RK_OS_WIN) && !defined(RK_FOR_SHARED)
92 int rkMain(int, char **);
93 #define main rkMain
94 #endif // RK_OS_WIN && !RK_FOR_SHARED
95 
96 #if defined(RK_SINGLE_PRECISION)
97 using rk_real = float;
98 #else
99 using rk_real = double;
100 #endif // RK_SINGLE_PRECISION
101 
102 namespace Rk {
103         enum class Alignment : int {
104                 AlignLeft   = 1,
105                 AlignRight  = 2,
106 		AlignCenter = 3,
107 		AlignTop    = 4,
108 		AlignBottom = 5
109         };
110 
111         enum class Orientation : int {
112                 Horizontal = 0,
113                 Vertical = 1
114         };
115 
116         enum class WindowFlags: int {
117                 Widget = 0x00000000,
118                 Dialog = 0x00000001,
119                 Popup  = 0x00000002
120         };
121 
122         enum class Modality : int {
123                 NonModal = 0,
124 
125                 // Disable input for parent and all its children
126                 // except the current modal one.
127                 ModalParent = 1,
128 
129                 // Disable input for all widgets hierarhy
130                 // of the top widget, including top widget,
131                 // except the current modal one.
132                 ModalTopWidget = 2
133         };
134 
135         enum class WidgetAttribute : int {
136                 NoAttributes = 0x00000000,
137                 KeyInputEnabled = 0x00000001,
138                 MouseInputEnabled = 0x00000002,
139                 CloseInputEnabled = 0x00000004
140         };
141 
142         enum class Key : int {
143                 Key_None        = 0x00000000,
144 
145                 /**
146                  * Group: key modifiers, as bit flags.
147                  */
148                 Key_Shift_Left    = 0x00010000,
149                 Key_Shift_Right   = 0x00020000,
150                 Key_Control_Left  = 0x00040000,
151                 Key_Control_Right = 0x00080000,
152                 Key_Caps_Lock     = 0x00100000,
153                 Key_Shift_Lock    = 0x00200000,
154                 Key_Meta_Left     = 0x00400000,
155                 Key_Meta_Right    = 0x00800000,
156                 Key_Alt_Left      = 0x01000000,
157                 Key_Alt_Right     = 0x02000000,
158                 Key_Super_Left    = 0x04000000,
159                 Key_Super_Right   = 0x08000000,
160                 Key_Hyper_Left    = 0x10000000,
161                 Key_Hyper_Right   = 0x20000000,
162 
163                 /**
164                  * Group: Cursor control keys.
165                  * Range: 0x00500000 - 0x005f0000
166                  */
167                 Key_Home      = 0x00500000,
168                 Key_Left      = 0x00510000,
169                 Key_Up        = 0x00520000,
170                 Key_Right     = 0x00530000,
171                 Key_Down      = 0x00540000,
172                 Key_Page_Up   = 0x00550000,
173                 Key_Page_Down = 0x00560000,
174                 Key_End       = 0x00570000,
175                 Key_Begin     = 0x00580000,
176 
177                 /**
178                  * Group: Other edit keys.
179                  * Range: 0x00590000 - 0x00620000
180                  */
181                 Key_BackSpace   = 0x00590000,
182                 Key_Tab         = 0x005a0000,
183                 Key_Linefeed    = 0x005b0000,
184                 Key_Clear       = 0x005c0000,
185                 Key_Return      = 0x005d0000,
186                 Key_Pause       = 0x005e0000,
187                 Key_Scroll_Lock = 0x005f0000,
188                 Key_Sys_Req     = 0x00600000,
189                 Key_Escape      = 0x00610000,
190                 Key_Delete      = 0x00620000,
191 
192                 /**
193                  * Group: LATIN1
194                  * Rnage: 0x00000020 - 0x000000ff
195                  */
196                 Key_Space          = 0x00000020,
197                 Key_Exclam         = 0x00000021,
198                 Key_Quotedbl       = 0x00000022,
199                 Key_Numbersign     = 0x00000023,
200                 Key_Dollar         = 0x00000024,
201                 Key_Percent        = 0x00000025,
202                 Key_Ampersand      = 0x00000026,
203                 Key_Apostrophe     = 0x00000027,
204                 Key_Quoteright     = 0x00000027,
205                 Key_Parenleft      = 0x00000028,
206                 Key_Parenright     = 0x00000029,
207                 Key_Asterisk       = 0x0000002a,
208                 Key_Plus           = 0x0000002b,
209                 Key_Comma          = 0x0000002c,
210                 Key_Minus          = 0x0000002d,
211                 Key_Period         = 0x0000002e,
212                 Key_Slash          = 0x0000002f,
213                 Key_0              = 0x00000030,
214                 Key_1              = 0x00000031,
215                 Key_2              = 0x00000032,
216                 Key_3              = 0x00000033,
217                 Key_4              = 0x00000034,
218                 Key_5              = 0x00000035,
219                 Key_6              = 0x00000036,
220                 Key_7              = 0x00000037,
221                 Key_8              = 0x00000038,
222                 Key_9              = 0x00000039,
223                 Key_Colon          = 0x0000003a,
224                 Key_Semicolon      = 0x0000003b,
225                 Key_Less           = 0x0000003c,
226                 Key_Equal          = 0x0000003d,
227                 Key_Greater        = 0x0000003e,
228                 Key_Question       = 0x0000003f,
229                 Key_At             = 0x00000040,
230                 Key_A              = 0x00000041,
231                 Key_B              = 0x00000042,
232                 Key_C              = 0x00000043,
233                 Key_D              = 0x00000044,
234                 Key_E              = 0x00000045,
235                 Key_F              = 0x00000046,
236                 Key_G              = 0x00000047,
237                 Key_H              = 0x00000048,
238                 Key_I              = 0x00000049,
239                 Key_J              = 0x0000004a,
240                 Key_K              = 0x0000004b,
241                 Key_L              = 0x0000004c,
242                 Key_M              = 0x0000004d,
243                 Key_N              = 0x0000004e,
244                 Key_O              = 0x0000004f,
245                 Key_P              = 0x00000050,
246                 Key_Q              = 0x00000051,
247                 Key_R              = 0x00000052,
248                 Key_S              = 0x00000053,
249                 Key_T              = 0x00000054,
250                 Key_U              = 0x00000055,
251                 Key_V              = 0x00000056,
252                 Key_W              = 0x00000057,
253                 Key_X              = 0x00000058,
254                 Key_Y              = 0x00000059,
255                 Key_Z              = 0x0000005a,
256                 Key_Bracketleft    = 0x0000005b,
257                 Key_Backslash      = 0x0000005c,
258                 Key_Bracketright   = 0x0000005d,
259                 Key_Asciicircum    = 0x0000005e,
260                 Key_Underscore     = 0x0000005f,
261                 Key_Grave          = 0x00000060,
262                 Key_Quoteleft      = 0x00000060,
263                 Key_a              = 0x00000061,
264                 Key_b              = 0x00000062,
265                 Key_c              = 0x00000063,
266                 Key_d              = 0x00000064,
267                 Key_e              = 0x00000065,
268                 Key_f              = 0x00000066,
269                 Key_g              = 0x00000067,
270                 Key_h              = 0x00000068,
271                 Key_i              = 0x00000069,
272                 Key_j              = 0x0000006a,
273                 Key_k              = 0x0000006b,
274                 Key_l              = 0x0000006c,
275                 Key_m              = 0x0000006d,
276                 Key_n              = 0x0000006e,
277                 Key_o              = 0x0000006f,
278                 Key_p              = 0x00000070,
279                 Key_q              = 0x00000071,
280                 Key_r              = 0x00000072,
281                 Key_s              = 0x00000073,
282                 Key_t              = 0x00000074,
283                 Key_u              = 0x00000075,
284                 Key_v              = 0x00000076,
285                 Key_w              = 0x00000077,
286                 Key_x              = 0x00000078,
287                 Key_y              = 0x00000079,
288                 Key_z              = 0x0000007a,
289                 Key_Braceleft      = 0x0000007b,
290                 Key_Bar            = 0x0000007c,
291                 Key_Braceright     = 0x0000007d,
292                 Key_Asciitilde     = 0x0000007e,
293                 Key_Nobreakspace   = 0x000000a0,
294                 Key_Exclamdown     = 0x000000a1,
295                 Key_Cent           = 0x000000a2,
296                 Key_Sterling       = 0x000000a3,
297                 Key_Currency       = 0x000000a4,
298                 Key_Yen            = 0x000000a5,
299                 Key_Brokenbar      = 0x000000a6,
300                 Key_Section        = 0x000000a7,
301                 Key_Diaeresis      = 0x000000a8,
302                 Key_Copyright      = 0x000000a9,
303                 Key_Ordfeminine    = 0x000000aa,
304                 Key_Guillemotleft  = 0x000000ab,
305                 Key_Notsign        = 0x000000ac,
306                 Key_Hyphen         = 0x000000ad,
307                 Key_Registered     = 0x000000ae,
308                 Key_Macron         = 0x000000af,
309                 Key_Degree         = 0x000000b0,
310                 Key_Plusminus      = 0x000000b1,
311                 Key_Twosuperior    = 0x000000b2,
312                 Key_Threesuperior  = 0x000000b3,
313                 Key_Acute          = 0x000000b4,
314                 Key_Mu             = 0x000000b5,
315                 Key_Paragraph      = 0x000000b6,
316                 Key_Periodcentered = 0x000000b7,
317                 Key_Cedilla        = 0x000000b8,
318                 Key_Onesuperior    = 0x000000b9,
319                 Key_Masculine      = 0x000000ba,
320                 Key_Guillemotright = 0x000000bb,
321                 Key_Onequarter     = 0x000000bc,
322                 Key_Onehalf        = 0x000000bd,
323                 Key_Threequarters  = 0x000000be,
324                 Key_Questiondown   = 0x000000bf,
325                 Key_Agrave         = 0x000000c0,
326                 Key_Aacute         = 0x000000c1,
327                 Key_Acircumflex    = 0x000000c2,
328                 Key_Atilde         = 0x000000c3,
329                 Key_Adiaeresis     = 0x000000c4,
330                 Key_Aring          = 0x000000c5,
331                 Key_Ae             = 0x000000c6,
332                 Key_Ccedilla       = 0x000000c7,
333                 Key_Egrave         = 0x000000c8,
334                 Key_Eacute         = 0x000000c9,
335                 Key_Ecircumflex    = 0x000000ca,
336                 Key_Ediaeresis     = 0x000000cb,
337                 Key_Igrave         = 0x000000cc,
338                 Key_Iacute         = 0x000000cd,
339                 Key_Icircumflex    = 0x000000ce,
340                 Key_Idiaeresis     = 0x000000cf,
341                 Key_Eth            = 0x000000d0,
342                 Key_Ntilde         = 0x000000d1,
343                 Key_Ograve         = 0x000000d2,
344                 Key_Oacute         = 0x000000d3,
345                 Key_Ocircumflex    = 0x000000d4,
346                 Key_Otilde         = 0x000000d5,
347                 Key_Odiaeresis     = 0x000000d6,
348                 Key_Multiply       = 0x000000d7,
349                 Key_Oslash         = 0x000000d8,
350                 Key_Ooblique       = 0x000000d8,
351                 Key_Ugrave         = 0x000000d9,
352                 Key_Uacute         = 0x000000da,
353                 Key_Ucircumflex    = 0x000000db,
354                 Key_Udiaeresis     = 0x000000dc,
355                 Key_Yacute         = 0x000000dd,
356                 Key_Thorn          = 0x000000de,
357                 Key_Ssharp         = 0x000000df,
358                 Key_agrave         = 0x000000e0,
359                 Key_aacute         = 0x000000e1,
360                 Key_acircumflex    = 0x000000e2,
361                 Key_atilde         = 0x000000e3,
362                 Key_adiaeresis     = 0x000000e4,
363                 Key_aring          = 0x000000e5,
364                 Key_ae             = 0x000000e6,
365                 Key_ccedilla       = 0x000000e7,
366                 Key_egrave         = 0x000000e8,
367                 Key_eacute         = 0x000000e9,
368                 Key_ecircumflex    = 0x000000ea,
369                 Key_ediaeresis     = 0x000000eb,
370                 Key_igrave         = 0x000000ec,
371                 Key_iacute         = 0x000000ed,
372                 Key_icircumflex    = 0x000000ee,
373                 Key_idiaeresis     = 0x000000ef,
374                 Key_eth            = 0x000000f0,
375                 Key_ntilde         = 0x000000f1,
376                 Key_ograve         = 0x000000f2,
377                 Key_oacute         = 0x000000f3,
378                 Key_ocircumflex    = 0x000000f4,
379                 Key_otilde         = 0x000000f5,
380                 Key_odiaeresis     = 0x000000f6,
381                 Key_division       = 0x000000f7,
382                 Key_oslash         = 0x000000f8,
383                 Key_ooblique       = 0x000000f8,
384                 Key_ugrave         = 0x000000f9,
385                 Key_uacute         = 0x000000fa,
386                 Key_ucircumflex    = 0x000000fb,
387                 Key_udiaeresis     = 0x000000fc,
388                 Key_yacute         = 0x000000fd,
389                 Key_thorn          = 0x000000fe,
390                 Key_Ydiaeresis     = 0x000000ff
391         };
392 
393         enum class KeyModifiers: int {
394                 NoModifier    = 0x0000,
395                 Shift_Left    = 0x0001,
396                 Shift_Right   = 0x0002,
397                 Shift         = Shift_Left | Shift_Right,
398                 Control_Left  = 0x0004,
399                 Control_Right = 0x0008,
400                 Control       = Control_Left | Control_Right,
401                 Caps_Lock     = 0x0010,
402                 Shift_Lock    = 0x0020,
403                 Meta_Left     = 0x0040,
404                 Meta_Right    = 0x0080,
405                 Meta          = Meta_Left | Meta_Right,
406                 Alt_Left      = 0x0100,
407                 Alt_Right     = 0x0200,
408                 Alt           = Alt_Left | Alt_Right,
409                 Super_Left    = 0x0400,
410                 Super_Right   = 0x0800,
411                 Super         = Super_Left | Super_Right,
412                 Hyper_Left    = 0x1000,
413                 Hyper_Right   = 0x2000,
414                 Hyper         = Hyper_Left | Hyper_Right
415         };
416 
417         enum class PointerShape: int {
418                 NoShape = 0,
419                 Arrow = 1,
420                 UpArrow = 2,
421                 Cross = 3,
422                 Wait = 4,
423                 WhatsThis = 5,
424                 IBeam = 6,
425                 SizeVertical = 7,
426                 SizeHorizontal = 8,
427                 SizeTLDiagonal = 9,
428                 SizeTRDiagonal = 10,
429                 SizeAll = 11,
430                 SplitVertical = 12,
431                 SplitHorizontal = 13,
432                 PointingHand = 14,
433                 OpenHand = 15,
434                 ClosedHand = 16,
435                 Forbidden = 17,
436                 Busy = 18
437         };
438 
439         enum class ObjectType : int {
440                 Object = 0,
441                 Widget = 1
442         };
443 }
444 
445 #define RK_ACT_ARGS(arg, ...) arg, ##__VA_ARGS__
446 #define RK_ARG_TYPE(type, ...) type, ##__VA_ARGS__
447 #define RK_ARG_VAL(val, ...) val, ##__VA_ARGS__
448 
449 #define RK_DECL_ACT(name, prot, type, val) \
450         class rk__observer_##name : public RkObserver { \
451         public: \
452                 rk__observer_ ##name (RkObject *obj, const std::function<void(type)> &cb) \
453                         : RkObserver(obj), \
454                           observerCallback{cb} {} \
455                 rk__observer_##name () = default; \
456                 std::function<void(type)> observerCallback; \
457         }; \
458         \
459         void prot \
460         { \
461                 for (const auto& ob: rk__observers()) {                  \
462                         auto observer = dynamic_cast<rk__observer_ ##name *>(ob.get()); \
463                         if (observer) \
464                                 observer->observerCallback(val); \
465                 } \
466         } \
467         void rk__add_action_cb_##name (RkObject *obj, const std::function<void(type)> &cb) \
468         { \
469                 rk__add_observer(std::make_unique<rk__observer_##name >(obj, cb)); \
470         }
471 
472 #define RK_ACT_BIND(obj1, act, act_args, obj2, callback) \
473         obj1->rk__add_action_cb_##act (obj2, [=](act_args){ obj2->callback; }); \
474         obj2->rk__add_bound_object(obj1)
475 
476 // Bind lamda functions to object actions.
477 #define RK_ACT_BINDL(obj1, act, act_args, lamda)   \
478         obj1->rk__add_action_cb_##act (nullptr, lamda)
479 
480 #define action
481 
482 #define RK_DECLARE_IMAGE_RC(name) extern const unsigned char rk__ ## name ## _png[]
483 #define RK_IMAGE_RC(name) rk__ ## name ## _png
484 
485 using RkString = std::string;
486 
487 #endif // RK_GLOBAL_H
488