1 module raygui;
2 
3 import dynalib : expandEnum;
4 
5 @nogc nothrow __gshared extern(C):
6 
7     /*******************************************************************************************
8     *
9     *   raygui v3.0 - A simple and easy-to-use immediate-mode gui library
10     *
11     *   DESCRIPTION:
12     *
13     *   raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also
14     *   available as a standalone library, as long as input and drawing functions are provided.
15     *
16     *   Controls provided:
17     *
18     *   # Container/separators Controls
19     *       - WindowBox
20     *       - GroupBox
21     *       - Line
22     *       - Panel
23     *
24     *   # Basic Controls
25     *       - Label
26     *       - Button
27     *       - LabelButton   --> Label
28     *       - Toggle
29     *       - ToggleGroup   --> Toggle
30     *       - CheckBox
31     *       - ComboBox
32     *       - DropdownBox
33     *       - TextBox
34     *       - TextBoxMulti
35     *       - ValueBox      --> TextBox
36     *       - Spinner       --> Button, ValueBox
37     *       - Slider
38     *       - SliderBar     --> Slider
39     *       - ProgressBar
40     *       - StatusBar
41     *       - ScrollBar
42     *       - ScrollPanel
43     *       - DummyRec
44     *       - Grid
45     *
46     *   # Advance Controls
47     *       - ListView
48     *       - ColorPicker   --> ColorPanel, ColorBarHue
49     *       - MessageBox    --> Window, Label, Button
50     *       - TextInputBox  --> Window, Label, TextBox, Button
51     *
52     *   It also provides a set of functions for styling the controls based on its properties (size, color).
53     *
54     *
55     *   GUI STYLE (guiStyle):
56     *
57     *   raygui uses a global data array for all gui style properties (allocated on data segment by default),
58     *   when a new style is loaded, it is loaded over the global style... but a default gui style could always be
59     *   recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one
60     *
61     *   The global style array size is fixed and depends on the number of controls and properties:
62     *
63     *       uint guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
64     *
65     *   guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
66     *
67     *   Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
68     *   used for all controls, when any of those base values is set, it is automatically populated to all
69     *   controls, so, specific control values overwriting generic style should be set after base values.
70     *
71     *   After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those
72     *   properties are actually common to all controls and can not be overwritten individually (like BASE ones)
73     *   Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR
74     *
75     *   Custom control properties can be defined using the EXTENDED properties for each independent control.
76     *
77     *   TOOL: rGuiStyler is a visual tool to customize raygui style.
78     *
79     *
80     *   GUI ICONS (guiIcons):
81     *
82     *   raygui could use a global array containing icons data (allocated on data segment by default),
83     *   a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set
84     *   must be same RICON_SIZE and no more than RICON_MAX_ICONS will be loaded
85     *
86     *   Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon
87     *   requires 8 integers (16*16/32) to be stored in memory.
88     *
89     *   When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set.
90     *
91     *   The global icons array size is fixed and depends on the number of icons and size:
92     *
93     *       uint guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS];
94     *
95     *   guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
96     *
97     *   TOOL: rGuiIcons is a visual tool to customize raygui icons.
98     *
99     *
100     *   CONFIGURATION:
101     *
102     *   #define RAYGUI_IMPLEMENTATION
103     *       Generates the implementation of the library into the included file.
104     *       If not defined, the library is in header only mode and can be included in other headers
105     *       or source files without problems. But only ONE file should hold the implementation.
106     *
107     *   #define RAYGUI_STANDALONE
108     *       Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined
109     *       internally in the library and input management and drawing functions must be provided by
110     *       the user (check library implementation for further details).
111     *
112     *   #define RAYGUI_NO_RICONS
113     *       Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB)
114     *
115     *   #define RAYGUI_CUSTOM_RICONS
116     *       Includes custom ricons.h header defining a set of custom icons,
117     *       this file can be generated using rGuiIcons tool
118     *
119     *
120     *   VERSIONS HISTORY:
121     *
122     *       3.0 (xx-Sep-2021) Integrated ricons data to avoid external file
123     *                         REDESIGNED: GuiTextBoxMulti()
124     *                         REMOVED: GuiImageButton*()
125     *                         Multiple minor tweaks and bugs corrected
126     *       2.9 (17-Mar-2021) REMOVED: Tooltip API
127     *       2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle()
128     *       2.7 (20-Feb-2020) ADDED: Possible tooltips API
129     *       2.6 (09-Sep-2019) ADDED: GuiTextInputBox()
130     *                         REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox()
131     *                         REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle()
132     *                         Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties
133     *                         ADDED: 8 new custom styles ready to use
134     *                         Multiple minor tweaks and bugs corrected
135     *       2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner()
136     *       2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed
137     *                         Refactor all controls drawing mechanism to use control state
138     *       2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls
139     *       2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string
140     *                         REDESIGNED: Style system (breaking change)
141     *       2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts
142     *                         REVIEWED: GuiComboBox(), GuiListView()...
143     *       1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()...
144     *       1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout
145     *       1.5 (21-Jun-2017) Working in an improved styles system
146     *       1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones)
147     *       1.3 (12-Jun-2017) Complete redesign of style system
148     *       1.1 (01-Jun-2017) Complete review of the library
149     *       1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria.
150     *       0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria.
151     *       0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
152     *
153     *
154     *   CONTRIBUTORS:
155     *
156     *       Ramon Santamaria:   Supervision, review, redesign, update and maintenance
157     *       Vlad Adrian:        Complete rewrite of GuiTextBox() to support extended features (2019)
158     *       Sergio Martinez:    Review, testing (2015) and redesign of multiple controls (2018)
159     *       Adria Arranz:       Testing and Implementation of additional controls (2018)
160     *       Jordi Jorba:        Testing and Implementation of additional controls (2018)
161     *       Albert Martos:      Review and testing of the library (2015)
162     *       Ian Eito:           Review and testing of the library (2015)
163     *       Kevin Gato:         Initial implementation of basic components (2014)
164     *       Daniel Nicolas:     Initial implementation of basic components (2014)
165     *
166     *
167     *   LICENSE: zlib/libpng
168     *
169     *   Copyright (c) 2014-2021 Ramon Santamaria (@raysan5)
170     *
171     *   This software is provided "as-is", without any express or implied warranty. In no event
172     *   will the authors be held liable for any damages arising from the use of this software.
173     *
174     *   Permission is granted to anyone to use this software for any purpose, including commercial
175     *   applications, and to alter it and redistribute it freely, subject to the following restrictions:
176     *
177     *     1. The origin of this software must not be misrepresented; you must not claim that you
178     *     wrote the original software. If you use this software in a product, an acknowledgment
179     *     in the product documentation would be appreciated but is not required.
180     *
181     *     2. Altered source versions must be plainly marked as such, and must not be misrepresented
182     *     as being the original software.
183     *
184     *     3. This notice may not be removed or altered from any source distribution.
185     *
186     **********************************************************************************************/
187 
188     enum RAYGUI_VERSION = "3.0";
189 
190     import raylib;
191 
192     //----------------------------------------------------------------------------------
193     // Defines and Macros
194     //----------------------------------------------------------------------------------
195 
196     // Allow custom memory allocators
197     alias RAYGUI_MALLOC = malloc;
198     alias RAYGUI_CALLOC = calloc;
199     alias RAYGUI_FREE   = free;
200 
201     //----------------------------------------------------------------------------------
202     // Types and Structures Definition
203     //----------------------------------------------------------------------------------
204 
205     // Style property
206     struct GuiStyleProp {
207         ushort controlId;
208         ushort propertyId;
209         int    propertyValue;
210     }
211 
212     // Gui control state
213     enum GuiControlState {
214         GUI_STATE_NORMAL = 0,
215         GUI_STATE_FOCUSED,
216         GUI_STATE_PRESSED,
217         GUI_STATE_DISABLED,
218     } mixin(expandEnum!GuiControlState);
219 
220     // Gui control text alignment
221     enum GuiTextAlignment{
222         GUI_TEXT_ALIGN_LEFT = 0,
223         GUI_TEXT_ALIGN_CENTER,
224         GUI_TEXT_ALIGN_RIGHT,
225     } mixin(expandEnum!GuiTextAlignment);
226 
227     // Gui controls
228     enum GuiControl {
229         DEFAULT = 0,    // Generic control -> populates to all controls when set
230         LABEL,          // Used also for: LABELBUTTON
231         BUTTON,
232         TOGGLE,         // Used also for: TOGGLEGROUP
233         SLIDER,         // Used also for: SLIDERBAR
234         PROGRESSBAR,
235         CHECKBOX,
236         COMBOBOX,
237         DROPDOWNBOX,
238         TEXTBOX,        // Used also for: TEXTBOXMULTI
239         VALUEBOX,
240         SPINNER,
241         LISTVIEW,
242         COLORPICKER,
243         SCROLLBAR,
244         STATUSBAR
245     } mixin(expandEnum!GuiControl);
246 
247     // Gui base properties for every control
248     // NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties)
249     enum GuiControlProperty {
250         BORDER_COLOR_NORMAL = 0,
251         BASE_COLOR_NORMAL,
252         TEXT_COLOR_NORMAL,
253         BORDER_COLOR_FOCUSED,
254         BASE_COLOR_FOCUSED,
255         TEXT_COLOR_FOCUSED,
256         BORDER_COLOR_PRESSED,
257         BASE_COLOR_PRESSED,
258         TEXT_COLOR_PRESSED,
259         BORDER_COLOR_DISABLED,
260         BASE_COLOR_DISABLED,
261         TEXT_COLOR_DISABLED,
262         BORDER_WIDTH,
263         TEXT_PADDING,
264         TEXT_ALIGNMENT,
265         RESERVED
266     } mixin(expandEnum!GuiControlProperty);
267 
268     // Gui extended properties depend on control
269     // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default 8 properties)
270 
271     // DEFAULT extended properties
272     // NOTE: Those properties are actually common to all controls
273     enum GuiDefaultProperty {
274         TEXT_SIZE = 16,
275         TEXT_SPACING,
276         LINE_COLOR,
277         BACKGROUND_COLOR,
278     } mixin(expandEnum!GuiDefaultProperty);
279 
280     // Label
281     //enum { } GuiLabelProperty;
282 
283     // Button
284     //enum { } GuiButtonProperty;
285 
286     // Toggle/ToggleGroup
287     enum GuiToggleProperty {
288         GROUP_PADDING = 16,
289     } mixin(expandEnum!GuiToggleProperty);
290 
291     // Slider/SliderBar
292     enum GuiSliderProperty {
293         SLIDER_WIDTH = 16,
294         SLIDER_PADDING
295     } mixin(expandEnum!GuiSliderProperty);
296 
297     // ProgressBar
298     enum GuiProgressBarProperty {
299         PROGRESS_PADDING = 16,
300     } mixin(expandEnum!GuiProgressBarProperty);
301 
302     // CheckBox
303     enum GuiCheckBoxProperty {
304         CHECK_PADDING = 16
305     } mixin(expandEnum!GuiCheckBoxProperty);
306 
307     // ComboBox
308     enum GuiComboBoxProperty{
309         COMBO_BUTTON_WIDTH = 16,
310         COMBO_BUTTON_PADDING
311     } mixin(expandEnum!GuiComboBoxProperty);
312 
313     // DropdownBox
314     enum GuiDropdownBoxProperty {
315         ARROW_PADDING = 16,
316         DROPDOWN_ITEMS_PADDING
317     } mixin(expandEnum!GuiDropdownBoxProperty);
318 
319     // TextBox/TextBoxMulti/ValueBox/Spinner
320     enum GuiTextBoxProperty {
321         TEXT_INNER_PADDING = 16,
322         TEXT_LINES_PADDING,
323         COLOR_SELECTED_FG,
324         COLOR_SELECTED_BG
325     } mixin(expandEnum!GuiTextBoxProperty);
326 
327     // Spinner
328     enum GuiSpinnerProperty {
329         SPIN_BUTTON_WIDTH = 16,
330         SPIN_BUTTON_PADDING,
331     } mixin(expandEnum!GuiSpinnerProperty);
332 
333     // ScrollBar
334     enum GuiScrollBarProperty {
335         ARROWS_SIZE = 16,
336         ARROWS_VISIBLE,
337         SCROLL_SLIDER_PADDING,
338         SCROLL_SLIDER_SIZE,
339         SCROLL_PADDING,
340         SCROLL_SPEED,
341     } mixin(expandEnum!GuiScrollBarProperty);
342 
343     // ScrollBar side
344     enum GuiScrollBarSide {
345         SCROLLBAR_LEFT_SIDE = 0,
346         SCROLLBAR_RIGHT_SIDE
347     } mixin(expandEnum!GuiScrollBarSide);
348 
349     // ListView
350     enum GuiListViewProperty {
351         LIST_ITEMS_HEIGHT = 16,
352         LIST_ITEMS_PADDING,
353         SCROLLBAR_WIDTH,
354         SCROLLBAR_SIDE,
355     } mixin(expandEnum!GuiListViewProperty);
356 
357     // ColorPicker
358     enum GuiColorPickerProperty {
359         COLOR_SELECTOR_SIZE = 16,
360         HUEBAR_WIDTH,                  // Right hue bar width
361         HUEBAR_PADDING,                // Right hue bar separation from panel
362         HUEBAR_SELECTOR_HEIGHT,        // Right hue bar selector height
363         HUEBAR_SELECTOR_OVERFLOW       // Right hue bar selector overflow
364     } mixin(expandEnum!GuiColorPickerProperty);
365 
366     //----------------------------------------------------------------------------------
367     // Global Variables Definition
368     //----------------------------------------------------------------------------------
369     
370     // ...
371 
372     /***********************************************************************************
373     *
374     *   RAYGUI IMPLEMENTATION
375     *
376     ************************************************************************************/
377 
378     import core.stdc.stdio;                             // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
379     import core.stdc.stdlib;                            // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()]
380     import core.stdc.string;                            // Required for: strlen() [GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()], memset(), memcpy()
381     import core.stdc.stdarg;                            // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()]
382     import core.stdc.math;                              // Required for: roundf() [GuiColorPicker()]
383 
384     version(RAYGUI_NO_RICONS) {} else
385     {
386 
387         version(RAYGUI_CUSTOM_RICONS)
388             import ricons;                    // External icons data provided, it can be generated with rGuiIcons tool
389         else                                            // Embedded raygui icons, no external file provided
390         {
391             enum RICON_SIZE            =  16; // Size of icons (squared)
392             enum RICON_MAX_ICONS       = 256; // Maximum number of icons
393             enum RICON_MAX_NAME_LENGTH =  32; // Maximum length of icon name id
394 
395             // Icons data is defined by bit array (every bit represents one pixel)
396             // Those arrays are stored as uint data arrays, so every array
397             // element defines 32 pixels (bits) of information
398             // Number of elemens depend on RICON_SIZE (by default 16x16 pixels)
399             enum RICON_DATA_ELEMENTS   = (RICON_SIZE*RICON_SIZE/32);
400 
401             //----------------------------------------------------------------------------------
402             // Icons enumeration
403             //----------------------------------------------------------------------------------
404             enum guiIconName {
405                 RICON_NONE                     = 0,
406                 RICON_FOLDER_FILE_OPEN         = 1,
407                 RICON_FILE_SAVE_CLASSIC        = 2,
408                 RICON_FOLDER_OPEN              = 3,
409                 RICON_FOLDER_SAVE              = 4,
410                 RICON_FILE_OPEN                = 5,
411                 RICON_FILE_SAVE                = 6,
412                 RICON_FILE_EXPORT              = 7,
413                 RICON_FILE_NEW                 = 8,
414                 RICON_FILE_DELETE              = 9,
415                 RICON_FILETYPE_TEXT            = 10,
416                 RICON_FILETYPE_AUDIO           = 11,
417                 RICON_FILETYPE_IMAGE           = 12,
418                 RICON_FILETYPE_PLAY            = 13,
419                 RICON_FILETYPE_VIDEO           = 14,
420                 RICON_FILETYPE_INFO            = 15,
421                 RICON_FILE_COPY                = 16,
422                 RICON_FILE_CUT                 = 17,
423                 RICON_FILE_PASTE               = 18,
424                 RICON_CURSOR_HAND              = 19,
425                 RICON_CURSOR_POINTER           = 20,
426                 RICON_CURSOR_CLASSIC           = 21,
427                 RICON_PENCIL                   = 22,
428                 RICON_PENCIL_BIG               = 23,
429                 RICON_BRUSH_CLASSIC            = 24,
430                 RICON_BRUSH_PAINTER            = 25,
431                 RICON_WATER_DROP               = 26,
432                 RICON_COLOR_PICKER             = 27,
433                 RICON_RUBBER                   = 28,
434                 RICON_COLOR_BUCKET             = 29,
435                 RICON_TEXT_T                   = 30,
436                 RICON_TEXT_A                   = 31,
437                 RICON_SCALE                    = 32,
438                 RICON_RESIZE                   = 33,
439                 RICON_FILTER_POINT             = 34,
440                 RICON_FILTER_BILINEAR          = 35,
441                 RICON_CROP                     = 36,
442                 RICON_CROP_ALPHA               = 37,
443                 RICON_SQUARE_TOGGLE            = 38,
444                 RICON_SYMMETRY                 = 39,
445                 RICON_SYMMETRY_HORIZONTAL      = 40,
446                 RICON_SYMMETRY_VERTICAL        = 41,
447                 RICON_LENS                     = 42,
448                 RICON_LENS_BIG                 = 43,
449                 RICON_EYE_ON                   = 44,
450                 RICON_EYE_OFF                  = 45,
451                 RICON_FILTER_TOP               = 46,
452                 RICON_FILTER                   = 47,
453                 RICON_TARGET_POINT             = 48,
454                 RICON_TARGET_SMALL             = 49,
455                 RICON_TARGET_BIG               = 50,
456                 RICON_TARGET_MOVE              = 51,
457                 RICON_CURSOR_MOVE              = 52,
458                 RICON_CURSOR_SCALE             = 53,
459                 RICON_CURSOR_SCALE_RIGHT       = 54,
460                 RICON_CURSOR_SCALE_LEFT        = 55,
461                 RICON_UNDO                     = 56,
462                 RICON_REDO                     = 57,
463                 RICON_REREDO                   = 58,
464                 RICON_MUTATE                   = 59,
465                 RICON_ROTATE                   = 60,
466                 RICON_REPEAT                   = 61,
467                 RICON_SHUFFLE                  = 62,
468                 RICON_EMPTYBOX                 = 63,
469                 RICON_TARGET                   = 64,
470                 RICON_TARGET_SMALL_FILL        = 65,
471                 RICON_TARGET_BIG_FILL          = 66,
472                 RICON_TARGET_MOVE_FILL         = 67,
473                 RICON_CURSOR_MOVE_FILL         = 68,
474                 RICON_CURSOR_SCALE_FILL        = 69,
475                 RICON_CURSOR_SCALE_RIGHT_FILL  = 70,
476                 RICON_CURSOR_SCALE_LEFT_FILL   = 71,
477                 RICON_UNDO_FILL                = 72,
478                 RICON_REDO_FILL                = 73,
479                 RICON_REREDO_FILL              = 74,
480                 RICON_MUTATE_FILL              = 75,
481                 RICON_ROTATE_FILL              = 76,
482                 RICON_REPEAT_FILL              = 77,
483                 RICON_SHUFFLE_FILL             = 78,
484                 RICON_EMPTYBOX_SMALL           = 79,
485                 RICON_BOX                      = 80,
486                 RICON_BOX_TOP                  = 81,
487                 RICON_BOX_TOP_RIGHT            = 82,
488                 RICON_BOX_RIGHT                = 83,
489                 RICON_BOX_BOTTOM_RIGHT         = 84,
490                 RICON_BOX_BOTTOM               = 85,
491                 RICON_BOX_BOTTOM_LEFT          = 86,
492                 RICON_BOX_LEFT                 = 87,
493                 RICON_BOX_TOP_LEFT             = 88,
494                 RICON_BOX_CENTER               = 89,
495                 RICON_BOX_CIRCLE_MASK          = 90,
496                 RICON_POT                      = 91,
497                 RICON_ALPHA_MULTIPLY           = 92,
498                 RICON_ALPHA_CLEAR              = 93,
499                 RICON_DITHERING                = 94,
500                 RICON_MIPMAPS                  = 95,
501                 RICON_BOX_GRID                 = 96,
502                 RICON_GRID                     = 97,
503                 RICON_BOX_CORNERS_SMALL        = 98,
504                 RICON_BOX_CORNERS_BIG          = 99,
505                 RICON_FOUR_BOXES               = 100,
506                 RICON_GRID_FILL                = 101,
507                 RICON_BOX_MULTISIZE            = 102,
508                 RICON_ZOOM_SMALL               = 103,
509                 RICON_ZOOM_MEDIUM              = 104,
510                 RICON_ZOOM_BIG                 = 105,
511                 RICON_ZOOM_ALL                 = 106,
512                 RICON_ZOOM_CENTER              = 107,
513                 RICON_BOX_DOTS_SMALL           = 108,
514                 RICON_BOX_DOTS_BIG             = 109,
515                 RICON_BOX_CONCENTRIC           = 110,
516                 RICON_BOX_GRID_BIG             = 111,
517                 RICON_OK_TICK                  = 112,
518                 RICON_CROSS                    = 113,
519                 RICON_ARROW_LEFT               = 114,
520                 RICON_ARROW_RIGHT              = 115,
521                 RICON_ARROW_DOWN               = 116,
522                 RICON_ARROW_UP                 = 117,
523                 RICON_ARROW_LEFT_FILL          = 118,
524                 RICON_ARROW_RIGHT_FILL         = 119,
525                 RICON_ARROW_DOWN_FILL          = 120,
526                 RICON_ARROW_UP_FILL            = 121,
527                 RICON_AUDIO                    = 122,
528                 RICON_FX                       = 123,
529                 RICON_WAVE                     = 124,
530                 RICON_WAVE_SINUS               = 125,
531                 RICON_WAVE_SQUARE              = 126,
532                 RICON_WAVE_TRIANGULAR          = 127,
533                 RICON_CROSS_SMALL              = 128,
534                 RICON_PLAYER_PREVIOUS          = 129,
535                 RICON_PLAYER_PLAY_BACK         = 130,
536                 RICON_PLAYER_PLAY              = 131,
537                 RICON_PLAYER_PAUSE             = 132,
538                 RICON_PLAYER_STOP              = 133,
539                 RICON_PLAYER_NEXT              = 134,
540                 RICON_PLAYER_RECORD            = 135,
541                 RICON_MAGNET                   = 136,
542                 RICON_LOCK_CLOSE               = 137,
543                 RICON_LOCK_OPEN                = 138,
544                 RICON_CLOCK                    = 139,
545                 RICON_TOOLS                    = 140,
546                 RICON_GEAR                     = 141,
547                 RICON_GEAR_BIG                 = 142,
548                 RICON_BIN                      = 143,
549                 RICON_HAND_POINTER             = 144,
550                 RICON_LASER                    = 145,
551                 RICON_COIN                     = 146,
552                 RICON_EXPLOSION                = 147,
553                 RICON_1UP                      = 148,
554                 RICON_PLAYER                   = 149,
555                 RICON_PLAYER_JUMP              = 150,
556                 RICON_KEY                      = 151,
557                 RICON_DEMON                    = 152,
558                 RICON_TEXT_POPUP               = 153,
559                 RICON_GEAR_EX                  = 154,
560                 RICON_CRACK                    = 155,
561                 RICON_CRACK_POINTS             = 156,
562                 RICON_STAR                     = 157,
563                 RICON_DOOR                     = 158,
564                 RICON_EXIT                     = 159,
565                 RICON_MODE_2D                  = 160,
566                 RICON_MODE_3D                  = 161,
567                 RICON_CUBE                     = 162,
568                 RICON_CUBE_FACE_TOP            = 163,
569                 RICON_CUBE_FACE_LEFT           = 164,
570                 RICON_CUBE_FACE_FRONT          = 165,
571                 RICON_CUBE_FACE_BOTTOM         = 166,
572                 RICON_CUBE_FACE_RIGHT          = 167,
573                 RICON_CUBE_FACE_BACK           = 168,
574                 RICON_CAMERA                   = 169,
575                 RICON_SPECIAL                  = 170,
576                 RICON_LINK_NET                 = 171,
577                 RICON_LINK_BOXES               = 172,
578                 RICON_LINK_MULTI               = 173,
579                 RICON_LINK                     = 174,
580                 RICON_LINK_BROKE               = 175,
581                 RICON_TEXT_NOTES               = 176,
582                 RICON_NOTEBOOK                 = 177,
583                 RICON_SUITCASE                 = 178,
584                 RICON_SUITCASE_ZIP             = 179,
585                 RICON_MAILBOX                  = 180,
586                 RICON_MONITOR                  = 181,
587                 RICON_PRINTER                  = 182,
588                 RICON_PHOTO_CAMERA             = 183,
589                 RICON_PHOTO_CAMERA_FLASH       = 184,
590                 RICON_HOUSE                    = 185,
591                 RICON_HEART                    = 186,
592                 RICON_CORNER                   = 187,
593                 RICON_VERTICAL_BARS            = 188,
594                 RICON_VERTICAL_BARS_FILL       = 189,
595                 RICON_LIFE_BARS                = 190,
596                 RICON_INFO                     = 191,
597                 RICON_CROSSLINE                = 192,
598                 RICON_HELP                     = 193,
599                 RICON_FILETYPE_ALPHA           = 194,
600                 RICON_FILETYPE_HOME            = 195,
601                 RICON_LAYERS_VISIBLE           = 196,
602                 RICON_LAYERS                   = 197,
603                 RICON_WINDOW                   = 198,
604                 RICON_HIDPI                    = 199,
605                 RICON_200                      = 200,
606                 RICON_201                      = 201,
607                 RICON_202                      = 202,
608                 RICON_203                      = 203,
609                 RICON_204                      = 204,
610                 RICON_205                      = 205,
611                 RICON_206                      = 206,
612                 RICON_207                      = 207,
613                 RICON_208                      = 208,
614                 RICON_209                      = 209,
615                 RICON_210                      = 210,
616                 RICON_211                      = 211,
617                 RICON_212                      = 212,
618                 RICON_213                      = 213,
619                 RICON_214                      = 214,
620                 RICON_215                      = 215,
621                 RICON_216                      = 216,
622                 RICON_217                      = 217,
623                 RICON_218                      = 218,
624                 RICON_219                      = 219,
625                 RICON_220                      = 220,
626                 RICON_221                      = 221,
627                 RICON_222                      = 222,
628                 RICON_223                      = 223,
629                 RICON_224                      = 224,
630                 RICON_225                      = 225,
631                 RICON_226                      = 226,
632                 RICON_227                      = 227,
633                 RICON_228                      = 228,
634                 RICON_229                      = 229,
635                 RICON_230                      = 230,
636                 RICON_231                      = 231,
637                 RICON_232                      = 232,
638                 RICON_233                      = 233,
639                 RICON_234                      = 234,
640                 RICON_235                      = 235,
641                 RICON_236                      = 236,
642                 RICON_237                      = 237,
643                 RICON_238                      = 238,
644                 RICON_239                      = 239,
645                 RICON_240                      = 240,
646                 RICON_241                      = 241,
647                 RICON_242                      = 242,
648                 RICON_243                      = 243,
649                 RICON_244                      = 244,
650                 RICON_245                      = 245,
651                 RICON_246                      = 246,
652                 RICON_247                      = 247,
653                 RICON_248                      = 248,
654                 RICON_249                      = 249,
655                 RICON_250                      = 250,
656                 RICON_251                      = 251,
657                 RICON_252                      = 252,
658                 RICON_253                      = 253,
659                 RICON_254                      = 254,
660                 RICON_255                      = 255,
661             } mixin(expandEnum!guiIconName);
662 
663             //----------------------------------------------------------------------------------
664             // Icons data for all gui possible icons (allocated on data segment by default)
665             //
666             // NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so,
667             // every 16x16 icon requires 8 integers (16*16/32) to be stored
668             //
669             // NOTE 2: A new icon set could be loaded over this array using GuiLoadIcons(),
670             // but loaded icons set must be same RICON_SIZE and no more than RICON_MAX_ICONS
671             //
672             // guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
673             //----------------------------------------------------------------------------------
674             uint[RICON_MAX_ICONS*RICON_DATA_ELEMENTS] guiIcons = [
675                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_NONE
676                 0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe,     // RICON_FOLDER_FILE_OPEN
677                 0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe,     // RICON_FILE_SAVE_CLASSIC
678                 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100,     // RICON_FOLDER_OPEN
679                 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000,     // RICON_FOLDER_SAVE
680                 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc,     // RICON_FILE_OPEN
681                 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc,     // RICON_FILE_SAVE
682                 0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc,     // RICON_FILE_EXPORT
683                 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc,     // RICON_FILE_NEW
684                 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc,     // RICON_FILE_DELETE
685                 0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc,     // RICON_FILETYPE_TEXT
686                 0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc,     // RICON_FILETYPE_AUDIO
687                 0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc,     // RICON_FILETYPE_IMAGE
688                 0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc,     // RICON_FILETYPE_PLAY
689                 0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4,     // RICON_FILETYPE_VIDEO
690                 0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc,     // RICON_FILETYPE_INFO
691                 0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0,     // RICON_FILE_COPY
692                 0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000,     // RICON_FILE_CUT
693                 0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0,     // RICON_FILE_PASTE
694                 0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_CURSOR_HAND
695                 0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000,     // RICON_CURSOR_POINTER
696                 0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000,     // RICON_CURSOR_CLASSIC
697                 0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000,     // RICON_PENCIL
698                 0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000,     // RICON_PENCIL_BIG
699                 0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8,     // RICON_BRUSH_CLASSIC
700                 0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080,     // RICON_BRUSH_PAINTER
701                 0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000,     // RICON_WATER_DROP
702                 0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000,     // RICON_COLOR_PICKER
703                 0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000,     // RICON_RUBBER
704                 0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040,     // RICON_COLOR_BUCKET
705                 0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000,     // RICON_TEXT_T
706                 0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f,     // RICON_TEXT_A
707                 0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e,     // RICON_SCALE
708                 0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe,     // RICON_RESIZE
709                 0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000,     // RICON_FILTER_POINT
710                 0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000,     // RICON_FILTER_BILINEAR
711                 0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002,     // RICON_CROP
712                 0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000,     // RICON_CROP_ALPHA
713                 0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002,     // RICON_SQUARE_TOGGLE
714                 0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000,     // RICON_SIMMETRY
715                 0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100,     // RICON_SIMMETRY_HORIZONTAL
716                 0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180,     // RICON_SIMMETRY_VERTICAL
717                 0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000,     // RICON_LENS
718                 0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000,     // RICON_LENS_BIG
719                 0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000,     // RICON_EYE_ON
720                 0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000,     // RICON_EYE_OFF
721                 0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100,     // RICON_FILTER_TOP
722                 0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0,     // RICON_FILTER
723                 0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000,     // RICON_TARGET_POINT
724                 0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000,     // RICON_TARGET_SMALL
725                 0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000,     // RICON_TARGET_BIG
726                 0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280,     // RICON_TARGET_MOVE
727                 0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280,     // RICON_CURSOR_MOVE
728                 0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e,     // RICON_CURSOR_SCALE
729                 0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000,     // RICON_CURSOR_SCALE_RIGHT
730                 0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000,     // RICON_CURSOR_SCALE_LEFT
731                 0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000,     // RICON_UNDO
732                 0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000,     // RICON_REDO
733                 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000,     // RICON_REREDO
734                 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000,     // RICON_MUTATE
735                 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020,     // RICON_ROTATE
736                 0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000,     // RICON_REPEAT
737                 0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000,     // RICON_SHUFFLE
738                 0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe,     // RICON_EMPTYBOX
739                 0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000,     // RICON_TARGET
740                 0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000,     // RICON_TARGET_SMALL_FILL
741                 0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000,     // RICON_TARGET_BIG_FILL
742                 0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380,     // RICON_TARGET_MOVE_FILL
743                 0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380,     // RICON_CURSOR_MOVE_FILL
744                 0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e,     // RICON_CURSOR_SCALE_FILL
745                 0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000,     // RICON_CURSOR_SCALE_RIGHT
746                 0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000,     // RICON_CURSOR_SCALE_LEFT
747                 0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000,     // RICON_UNDO_FILL
748                 0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000,     // RICON_REDO_FILL
749                 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000,     // RICON_REREDO_FILL
750                 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000,     // RICON_MUTATE_FILL
751                 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020,     // RICON_ROTATE_FILL
752                 0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000,     // RICON_REPEAT_FILL
753                 0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000,     // RICON_SHUFFLE_FILL
754                 0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000,     // RICON_EMPTYBOX_SMALL
755                 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX
756                 0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_TOP
757                 0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_TOP_RIGHT
758                 0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_RIGHT
759                 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000,     // RICON_BOX_BOTTOM_RIGHT
760                 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000,     // RICON_BOX_BOTTOM
761                 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000,     // RICON_BOX_BOTTOM_LEFT
762                 0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_LEFT
763                 0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_TOP_LEFT
764                 0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000,     // RICON_BOX_CIRCLE_MASK
765                 0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe,     // RICON_BOX_CENTER
766                 0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff,     // RICON_POT
767                 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe,     // RICON_ALPHA_MULTIPLY
768                 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe,     // RICON_ALPHA_CLEAR
769                 0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe,     // RICON_DITHERING
770                 0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0,     // RICON_MIPMAPS
771                 0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000,     // RICON_BOX_GRID
772                 0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248,     // RICON_GRID
773                 0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000,     // RICON_BOX_CORNERS_SMALL
774                 0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e,     // RICON_BOX_CORNERS_BIG
775                 0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000,     // RICON_FOUR_BOXES
776                 0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000,     // RICON_GRID_FILL
777                 0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e,     // RICON_BOX_MULTISIZE
778                 0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e,     // RICON_ZOOM_SMALL
779                 0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e,     // RICON_ZOOM_MEDIUM
780                 0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e,     // RICON_ZOOM_BIG
781                 0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e,     // RICON_ZOOM_ALL
782                 0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000,     // RICON_ZOOM_CENTER
783                 0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000,     // RICON_BOX_DOTS_SMALL
784                 0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000,     // RICON_BOX_DOTS_BIG
785                 0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe,     // RICON_BOX_CONCENTRIC
786                 0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000,     // RICON_BOX_GRID_BIG
787                 0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000,     // RICON_OK_TICK
788                 0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000,     // RICON_CROSS
789                 0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000,     // RICON_ARROW_LEFT
790                 0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000,     // RICON_ARROW_RIGHT
791                 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000,     // RICON_ARROW_DOWN
792                 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000,     // RICON_ARROW_UP
793                 0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000,     // RICON_ARROW_LEFT_FILL
794                 0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000,     // RICON_ARROW_RIGHT_FILL
795                 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000,     // RICON_ARROW_DOWN_FILL
796                 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000,     // RICON_ARROW_UP_FILL
797                 0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000,     // RICON_AUDIO
798                 0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000,     // RICON_FX
799                 0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000,     // RICON_WAVE
800                 0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000,     // RICON_WAVE_SINUS
801                 0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000,     // RICON_WAVE_SQUARE
802                 0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000,     // RICON_WAVE_TRIANGULAR
803                 0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000,     // RICON_CROSS_SMALL
804                 0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000,     // RICON_PLAYER_PREVIOUS
805                 0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000,     // RICON_PLAYER_PLAY_BACK
806                 0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000,     // RICON_PLAYER_PLAY
807                 0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000,     // RICON_PLAYER_PAUSE
808                 0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000,     // RICON_PLAYER_STOP
809                 0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000,     // RICON_PLAYER_NEXT
810                 0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000,     // RICON_PLAYER_RECORD
811                 0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000,     // RICON_MAGNET
812                 0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000,     // RICON_LOCK_CLOSE
813                 0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000,     // RICON_LOCK_OPEN
814                 0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770,     // RICON_CLOCK
815                 0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70,     // RICON_TOOLS
816                 0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180,     // RICON_GEAR
817                 0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180,     // RICON_GEAR_BIG
818                 0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8,     // RICON_BIN
819                 0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000,     // RICON_HAND_POINTER
820                 0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000,     // RICON_LASER
821                 0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000,     // RICON_COIN
822                 0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000,     // RICON_EXPLOSION
823                 0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000,     // RICON_1UP
824                 0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240,     // RICON_PLAYER
825                 0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000,     // RICON_PLAYER_JUMP
826                 0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0,     // RICON_KEY
827                 0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0,     // RICON_DEMON
828                 0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000,     // RICON_TEXT_POPUP
829                 0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000,     // RICON_GEAR_EX
830                 0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000,     // RICON_CRACK
831                 0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000,     // RICON_CRACK_POINTS
832                 0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808,     // RICON_STAR
833                 0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8,     // RICON_DOOR
834                 0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0,     // RICON_EXIT
835                 0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000,     // RICON_MODE_2D
836                 0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000,     // RICON_MODE_3D
837                 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe,     // RICON_CUBE
838                 0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe,     // RICON_CUBE_FACE_TOP
839                 0x7fe00000, 0x50386030, 0x47fe483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe,     // RICON_CUBE_FACE_LEFT
840                 0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe,     // RICON_CUBE_FACE_FRONT
841                 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3ff27fe2, 0x0ffe1ffa, 0x000007fe,     // RICON_CUBE_FACE_BOTTOM
842                 0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe,     // RICON_CUBE_FACE_RIGHT
843                 0x7fe00000, 0x7fe87ff0, 0x7ffe7fe4, 0x7fe27fe2, 0x7fe27fe2, 0x24127fe2, 0x0c06140a, 0x000007fe,     // RICON_CUBE_FACE_BACK
844                 0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000,     // RICON_CAMERA
845                 0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000,     // RICON_SPECIAL
846                 0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800,     // RICON_LINK_NET
847                 0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00,     // RICON_LINK_BOXES
848                 0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000,     // RICON_LINK_MULTI
849                 0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00,     // RICON_LINK
850                 0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00,     // RICON_LINK_BROKE
851                 0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc,     // RICON_TEXT_NOTES
852                 0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc,     // RICON_NOTEBOOK
853                 0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000,     // RICON_SUITCASE
854                 0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000,     // RICON_SUITCASE_ZIP
855                 0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000,     // RICON_MAILBOX
856                 0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000,     // RICON_MONITOR
857                 0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000,     // RICON_PRINTER
858                 0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000,     // RICON_PHOTO_CAMERA
859                 0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000,     // RICON_PHOTO_CAMERA_FLASH
860                 0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000,     // RICON_HOUSE
861                 0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000,     // RICON_HEART
862                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000,     // RICON_CORNER
863                 0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000,     // RICON_VERTICAL_BARS
864                 0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000,     // RICON_VERTICAL_BARS_FILL
865                 0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000,     // RICON_LIFE_BARS
866                 0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc,     // RICON_INFO
867                 0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002,     // RICON_CROSSLINE
868                 0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000,     // RICON_HELP
869                 0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc,     // RICON_FILETYPE_ALPHA
870                 0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc,     // RICON_FILETYPE_HOME
871                 0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0,     // RICON_LAYERS_VISIBLE
872                 0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0,     // RICON_LAYERS
873                 0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000,     // RICON_WINDOW
874                 0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000,     // RICON_HIDPI
875                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_200
876                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_201
877                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_202
878                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_203
879                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_204
880                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_205
881                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_206
882                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_207
883                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_208
884                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_209
885                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_210
886                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_211
887                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_212
888                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_213
889                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_214
890                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_215
891                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_216
892                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_217
893                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_218
894                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_219
895                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_220
896                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_221
897                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_222
898                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_223
899                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_224
900                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_225
901                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_226
902                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_227
903                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_228
904                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_229
905                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_230
906                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_231
907                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_232
908                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_233
909                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_234
910                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_235
911                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_236
912                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_237
913                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_238
914                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_239
915                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_240
916                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_241
917                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_242
918                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_243
919                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_244
920                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_245
921                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_246
922                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_247
923                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_248
924                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_249
925                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_250
926                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_251
927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_252
928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_253
929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_254
930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,     // RICON_255
931             ];
932         }
933     }
934 
935     enum RAYGUI_MAX_CONTROLS          =  16;             // Maximum number of standard controls
936     enum RAYGUI_MAX_PROPS_BASE        =  16;             // Maximum number of standard properties
937     enum RAYGUI_MAX_PROPS_EXTENDED    =   8;             // Maximum number of extended properties
938     
939     // Internal stuff from functions since defines don't work.
940     enum WINDOW_STATUSBAR_HEIGHT      =  22;
941 
942     enum MESSAGEBOX_BUTTON_HEIGHT     =  24;
943     enum MESSAGEBOX_BUTTON_PADDING    =  10;
944 
945     enum GROUPBOX_LINE_THICK          =   1;
946     enum GROUPBOX_TEXT_PADDING        =  10;
947 
948     enum LINE_TEXT_PADDING            =  10;
949 
950     enum PANEL_BORDER_WIDTH           =   1;
951 
952     enum TOGGLEGROUP_MAX_ELEMENTS     =  32;
953 
954     enum VALUEBOX_MAX_CHARS           =  32;
955 
956     enum COLORBARALPHA_CHECKED_SIZE   =  10;
957 
958     enum TEXTINPUTBOX_BUTTON_HEIGHT   =  24;
959     enum TEXTINPUTBOX_BUTTON_PADDING  =  10;
960     enum TEXTINPUTBOX_HEIGHT          =  30;
961     enum TEXTINPUTBOX_MAX_TEXT_LENGTH =  256;
962 
963     enum GRID_COLOR_ALPHA             = 0.15f;          // Grid lines alpha amount
964     enum RICON_TEXT_PADDING           =    4;
965     enum TEXTSPLIT_MAX_TEXT_LENGTH    = 1024;
966     enum TEXTSPLIT_MAX_TEXT_ELEMENTS  =  128;
967 
968     //----------------------------------------------------------------------------------
969     // Types and Structures Definition
970     //----------------------------------------------------------------------------------
971     
972     // Gui control property style color element
973     enum GuiPropertyElement { BORDER = 0, BASE, TEXT, OTHER }
974     mixin(expandEnum!GuiPropertyElement);
975 
976     //----------------------------------------------------------------------------------
977     // Global Variables Definition
978     //----------------------------------------------------------------------------------
979     
980     GuiControlState guiState = GUI_STATE_NORMAL;
981 
982     Font guiFont = Font();                    // Gui current font (WARNING: highly coupled to raylib)
983     bool guiLocked = false;                   // Gui lock state (no inputs processed)
984     float guiAlpha = 1.0f;                    // Gui element transpacency on drawing
985 
986     //----------------------------------------------------------------------------------
987     // Style data array for all gui style properties (allocated on data segment by default)
988     //
989     // NOTE 1: First set of BASE properties are generic to all controls but could be individually
990     // overwritten per control, first set of EXTENDED properties are generic to all controls and
991     // can not be overwritten individually but custom EXTENDED properties can be used by control
992     //
993     // NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(),
994     // but default gui style could always be recovered with GuiLoadStyleDefault()
995     //
996     // guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
997     //----------------------------------------------------------------------------------
998     
999     uint[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]
1000          guiStyle;
1001 
1002     bool guiStyleLoaded = false;              // Style loaded flag for lazy style initialization
1003 
1004     //----------------------------------------------------------------------------------
1005     // Gui Setup Functions Definition
1006     //----------------------------------------------------------------------------------
1007     
1008     // Enable gui controls (global state)
1009     void GuiEnable() { guiState = GUI_STATE_NORMAL; }
1010 
1011     // Disable gui controls (global state)
1012     void GuiDisable() { guiState = GUI_STATE_DISABLED; }
1013 
1014     // Lock gui controls (global state)
1015     void GuiLock() { guiLocked = true; }
1016 
1017     // Unlock gui controls (global state)
1018     void GuiUnlock() { guiLocked = false; }
1019 
1020     // Check if gui is locked (global state)
1021     bool GuiIsLocked() { return guiLocked; }
1022 
1023     // Set gui controls alpha (global state)
1024     void GuiFade(float alpha)
1025     {
1026         if (alpha < 0.0f) alpha = 0.0f;
1027         else if (alpha > 1.0f) alpha = 1.0f;
1028 
1029         guiAlpha = alpha;
1030     }
1031 
1032     // Set gui state (global state)
1033     void GuiSetState(int state) { guiState = cast(GuiControlState)state; }
1034 
1035     // Get gui state (global state)
1036     int GuiGetState() { return guiState; }
1037 
1038     // Set custom gui font
1039     // NOTE: Font loading/unloading is external to raygui
1040     void GuiSetFont(Font font)
1041     {
1042         if (font.texture.id > 0)
1043         {
1044             // NOTE: If we try to setup a font but default style has not been
1045             // lazily loaded before, it will be overwritten, so we need to force
1046             // default style loading first
1047             if (!guiStyleLoaded) GuiLoadStyleDefault();
1048 
1049             guiFont = font;
1050             GuiSetStyle(DEFAULT, TEXT_SIZE, font.baseSize);
1051         }
1052     }
1053 
1054     // Get custom gui font
1055     Font GuiGetFont() { return guiFont; }
1056 
1057     // Set control style property value
1058     void GuiSetStyle(int control, int property, int value)
1059     {
1060         if (!guiStyleLoaded) GuiLoadStyleDefault();
1061         guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
1062 
1063         // Default properties are propagated to all controls
1064         if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE))
1065         {
1066             for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
1067         }
1068     }
1069 
1070     // Get control style property value
1071     int GuiGetStyle(int control, int property)
1072     {
1073         if (!guiStyleLoaded) GuiLoadStyleDefault();
1074         return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property];
1075     }
1076 
1077     //----------------------------------------------------------------------------------
1078     // Gui Controls Functions Definition
1079     //----------------------------------------------------------------------------------
1080 
1081     // Window Box control
1082     bool GuiWindowBox(Rectangle bounds, const(char)* title)
1083     {
1084         //GuiControlState state = guiState;
1085         bool clicked = false;
1086 
1087         int statusBarHeight = WINDOW_STATUSBAR_HEIGHT + 2*GuiGetStyle(STATUSBAR, BORDER_WIDTH);
1088         statusBarHeight += (statusBarHeight%2);
1089 
1090         Rectangle statusBar = Rectangle(bounds.x, bounds.y, bounds.width, cast(float)statusBarHeight);
1091         if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f;
1092 
1093         Rectangle windowPanel = Rectangle(bounds.x, bounds.y + cast(float)statusBarHeight - 1, bounds.width, bounds.height - cast(float)statusBarHeight);
1094         Rectangle closeButtonRec = Rectangle(statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - 20,
1095                                     statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18);
1096 
1097         // Update control
1098         //--------------------------------------------------------------------
1099         // NOTE: Logic is directly managed by button
1100         //--------------------------------------------------------------------
1101 
1102         // Draw control
1103         //--------------------------------------------------------------------
1104         GuiStatusBar(statusBar, title); // Draw window header as status bar
1105         GuiPanel(windowPanel);          // Draw window base
1106 
1107         // Draw window close button
1108         int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
1109         int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
1110         GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
1111         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
1112 
1113         version(RAYGUI_NO_RICONS)
1114             clicked = GuiButton(closeButtonRec, "x");
1115         else
1116             clicked = GuiButton(closeButtonRec, GuiIconText(RICON_CROSS_SMALL, null));
1117 
1118         GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
1119         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment);
1120         //--------------------------------------------------------------------
1121 
1122         return clicked;
1123     }
1124 
1125     // Group Box control with text name
1126     void GuiGroupBox(Rectangle bounds, const(char)* text)
1127     {
1128         GuiControlState state = guiState;
1129 
1130         // Draw control
1131         //--------------------------------------------------------------------
1132         GuiDrawRectangle(Rectangle(bounds.x, bounds.y, GROUPBOX_LINE_THICK, bounds.height), 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
1133         GuiDrawRectangle(Rectangle(bounds.x, bounds.y + bounds.height - 1, bounds.width, GROUPBOX_LINE_THICK), 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
1134         GuiDrawRectangle(Rectangle(bounds.x + bounds.width - 1, bounds.y, GROUPBOX_LINE_THICK, bounds.height), 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
1135 
1136         GuiLine(Rectangle(bounds.x, bounds.y, bounds.width, 1), text);
1137         //--------------------------------------------------------------------
1138     }
1139 
1140     // Line control
1141     void GuiLine(Rectangle bounds, const(char)* text)
1142     {
1143         GuiControlState state = guiState;
1144 
1145         Color color = Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha);
1146 
1147         // Draw control
1148         //--------------------------------------------------------------------
1149         if (text == null) GuiDrawRectangle(Rectangle(bounds.x, bounds.y + bounds.height/2, bounds.width, 1), 0, BLANK, color);
1150         else
1151         {
1152             Rectangle textBounds;
1153             textBounds.width = cast(float)GetTextWidth(text);
1154             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
1155             textBounds.x = bounds.x + LINE_TEXT_PADDING;
1156             textBounds.y = bounds.y - cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
1157 
1158             // Draw line with embedded text label: "--- text --------------"
1159             GuiDrawRectangle(Rectangle(bounds.x, bounds.y, LINE_TEXT_PADDING - 2, 1), 0, BLANK, color);
1160             GuiLabel(textBounds, text);
1161             GuiDrawRectangle(Rectangle(bounds.x + LINE_TEXT_PADDING + textBounds.width + 4, bounds.y, bounds.width - textBounds.width - LINE_TEXT_PADDING - 4, 1), 0, BLANK, color);
1162         }
1163         //--------------------------------------------------------------------
1164     }
1165 
1166     // Panel control
1167     void GuiPanel(Rectangle bounds)
1168     {
1169         GuiControlState state = guiState;
1170 
1171         // Draw control
1172         //--------------------------------------------------------------------
1173         GuiDrawRectangle(bounds, PANEL_BORDER_WIDTH, Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BORDER_COLOR_DISABLED: LINE_COLOR)), guiAlpha),
1174                         Fade(GetColor(GuiGetStyle(DEFAULT, (state == GUI_STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR)), guiAlpha));
1175         //--------------------------------------------------------------------
1176     }
1177 
1178     // Scroll Panel control
1179     Rectangle GuiScrollPanel(Rectangle bounds, Rectangle content, Vector2 *scroll)
1180     {
1181         GuiControlState state = guiState;
1182 
1183         Vector2 scrollPos = Vector2(0.0f, 0.0f);
1184         if (scroll != null) scrollPos = *scroll;
1185 
1186         bool hasHorizontalScrollBar = (content.width > bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
1187         bool hasVerticalScrollBar = (content.height > bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
1188 
1189         // Recheck to account for the other scrollbar being visible
1190         if (!hasHorizontalScrollBar) hasHorizontalScrollBar = (hasVerticalScrollBar && (content.width > (bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
1191         if (!hasVerticalScrollBar) hasVerticalScrollBar = (hasHorizontalScrollBar && (content.height > (bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
1192 
1193         const int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
1194         const int verticalScrollBarWidth =  hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
1195         const Rectangle horizontalScrollBar = Rectangle(cast(float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? cast(float)bounds.x + verticalScrollBarWidth : cast(float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), cast(float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), cast(float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), cast(float)horizontalScrollBarWidth);
1196         const Rectangle verticalScrollBar = Rectangle(cast(float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? cast(float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : cast(float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), cast(float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), cast(float)verticalScrollBarWidth, cast(float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH));
1197 
1198         // Calculate view area (area without the scrollbars)
1199         Rectangle view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)?
1200                     Rectangle(bounds.x + verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth) :
1201                     Rectangle(bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth);
1202 
1203         // Clip view area to the actual content size
1204         if (view.width > content.width) view.width = content.width;
1205         if (view.height > content.height) view.height = content.height;
1206 
1207         const(float) horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? cast(float)-verticalScrollBarWidth : 0) - cast(float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : ((cast(float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? cast(float)-verticalScrollBarWidth : 0) - cast(float)GuiGetStyle(DEFAULT, BORDER_WIDTH);
1208         const(float) horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + cast(float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - ((cast(float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? cast(float)verticalScrollBarWidth : 0) : cast(float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
1209         const(float) verticalMin = hasVerticalScrollBar? cast(float)-GuiGetStyle(DEFAULT, BORDER_WIDTH) : cast(float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
1210         const(float) verticalMax = hasVerticalScrollBar? content.height - bounds.height + cast(float)horizontalScrollBarWidth + cast(float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : cast(float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
1211 
1212         // Update control
1213         //--------------------------------------------------------------------
1214         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1215         {
1216             Vector2 mousePoint = GetMousePosition();
1217 
1218             // Check button state
1219             if (CheckCollisionPointRec(mousePoint, bounds))
1220             {
1221                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1222                 else state = GUI_STATE_FOCUSED;
1223 
1224                 if (hasHorizontalScrollBar)
1225                 {
1226                     if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
1227                     if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
1228                 }
1229 
1230                 if (hasVerticalScrollBar)
1231                 {
1232                     if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
1233                     if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
1234                 }
1235 
1236                 float wheelMove = GetMouseWheelMove();
1237 
1238                 // Horizontal scroll (Shift + Mouse wheel)
1239                 if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT))) scrollPos.x += wheelMove*20;
1240                 else scrollPos.y += wheelMove*20; // Vertical scroll
1241             }
1242         }
1243 
1244         // Normalize scroll values
1245         if (scrollPos.x > -horizontalMin) scrollPos.x = -horizontalMin;
1246         if (scrollPos.x < -horizontalMax) scrollPos.x = -horizontalMax;
1247         if (scrollPos.y > -verticalMin) scrollPos.y = -verticalMin;
1248         if (scrollPos.y < -verticalMax) scrollPos.y = -verticalMax;
1249         //--------------------------------------------------------------------
1250 
1251         // Draw control
1252         //--------------------------------------------------------------------
1253         GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));        // Draw background
1254 
1255         // Save size of the scrollbar slider
1256         const int slider = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
1257 
1258         // Draw horizontal scrollbar if visible
1259         if (hasHorizontalScrollBar)
1260         {
1261             // Change scrollbar slider size to show the diff in size between the content width and the widget width
1262             GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, cast(int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/cast(int)content.width)*(cast(int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)));
1263             scrollPos.x = cast(float)-GuiScrollBar(horizontalScrollBar, cast(int)-scrollPos.x, cast(int)horizontalMin, cast(int)horizontalMax);
1264         }
1265 
1266         // Draw vertical scrollbar if visible
1267         if (hasVerticalScrollBar)
1268         {
1269             // Change scrollbar slider size to show the diff in size between the content height and the widget height
1270             GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, cast(int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/cast(int)content.height)*(cast(int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)));
1271             scrollPos.y = cast(float)-GuiScrollBar(verticalScrollBar, cast(int)-scrollPos.y, cast(int)verticalMin, cast(int)verticalMax);
1272         }
1273 
1274         // Draw detail corner rectangle if both scroll bars are visible
1275         if (hasHorizontalScrollBar && hasVerticalScrollBar)
1276         {
1277             Rectangle corner = Rectangle((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE) ? (bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) + 2) : (horizontalScrollBar.x + horizontalScrollBar.width + 2), verticalScrollBar.y + verticalScrollBar.height + 2, cast(float)horizontalScrollBarWidth - 4, cast(float)verticalScrollBarWidth - 4);
1278             GuiDrawRectangle(corner, 0, BLANK, Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT + (state*3))), guiAlpha));
1279         }
1280 
1281         // Draw scrollbar lines depending on current state
1282         GuiDrawRectangle(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), guiAlpha), BLANK);
1283 
1284         // Set scrollbar slider size back to the way it was before
1285         GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider);
1286         //--------------------------------------------------------------------
1287 
1288         if (scroll != null) *scroll = scrollPos;
1289 
1290         return view;
1291     }
1292 
1293     // Label control
1294     void GuiLabel(Rectangle bounds, const(char)* text)
1295     {
1296         GuiControlState state = guiState;
1297 
1298         // Update control
1299         //--------------------------------------------------------------------
1300         // ...
1301         //--------------------------------------------------------------------
1302 
1303         // Draw control
1304         //--------------------------------------------------------------------
1305         GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LABEL, (state == GUI_STATE_DISABLED)? TEXT_COLOR_DISABLED : TEXT_COLOR_NORMAL)), guiAlpha));
1306         //--------------------------------------------------------------------
1307     }
1308 
1309     // Button control, returns true when clicked
1310     bool GuiButton(Rectangle bounds, const(char)* text)
1311     {
1312         GuiControlState state = guiState;
1313         bool pressed = false;
1314 
1315         // Update control
1316         //--------------------------------------------------------------------
1317         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1318         {
1319             Vector2 mousePoint = GetMousePosition();
1320 
1321             // Check button state
1322             if (CheckCollisionPointRec(mousePoint, bounds))
1323             {
1324                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1325                 else state = GUI_STATE_FOCUSED;
1326 
1327                 if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
1328             }
1329         }
1330         //--------------------------------------------------------------------
1331 
1332         // Draw control
1333         //--------------------------------------------------------------------
1334         GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(BUTTON, BASE + (state*3))), guiAlpha));
1335         GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))), guiAlpha));
1336         //------------------------------------------------------------------
1337 
1338         return pressed;
1339     }
1340 
1341     // Label button control
1342     bool GuiLabelButton(Rectangle bounds, const(char)* text)
1343     {
1344         GuiControlState state = guiState;
1345         bool pressed = false;
1346 
1347         // NOTE: We force bounds.width to be all text
1348         float textWidth = MeasureTextEx(guiFont, text, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), cast(float)GuiGetStyle(DEFAULT, TEXT_SPACING)).x;
1349         if (bounds.width < textWidth) bounds.width = textWidth;
1350 
1351         // Update control
1352         //--------------------------------------------------------------------
1353         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1354         {
1355             Vector2 mousePoint = GetMousePosition();
1356 
1357             // Check checkbox state
1358             if (CheckCollisionPointRec(mousePoint, bounds))
1359             {
1360                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1361                 else state = GUI_STATE_FOCUSED;
1362 
1363                 if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
1364             }
1365         }
1366         //--------------------------------------------------------------------
1367 
1368         // Draw control
1369         //--------------------------------------------------------------------
1370         GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
1371         //--------------------------------------------------------------------
1372 
1373         return pressed;
1374     }
1375 
1376     // Toggle Button control, returns true when active
1377     bool GuiToggle(Rectangle bounds, const(char)* text, bool active)
1378     {
1379         GuiControlState state = guiState;
1380 
1381         // Update control
1382         //--------------------------------------------------------------------
1383         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1384         {
1385             Vector2 mousePoint = GetMousePosition();
1386 
1387             // Check toggle button state
1388             if (CheckCollisionPointRec(mousePoint, bounds))
1389             {
1390                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1391                 else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
1392                 {
1393                     state = GUI_STATE_NORMAL;
1394                     active = !active;
1395                 }
1396                 else state = GUI_STATE_FOCUSED;
1397             }
1398         }
1399         //--------------------------------------------------------------------
1400 
1401         // Draw control
1402         //--------------------------------------------------------------------
1403         if (state == GUI_STATE_NORMAL)
1404         {
1405             GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TOGGLE, (active? BORDER_COLOR_PRESSED : (BORDER + state*3)))), guiAlpha), Fade(GetColor(GuiGetStyle(TOGGLE, (active? BASE_COLOR_PRESSED : (BASE + state*3)))), guiAlpha));
1406             GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, (active? TEXT_COLOR_PRESSED : (TEXT + state*3)))), guiAlpha));
1407         }
1408         else
1409         {
1410             GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(TOGGLE, BASE + state*3)), guiAlpha));
1411             GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + state*3)), guiAlpha));
1412         }
1413         //--------------------------------------------------------------------
1414 
1415         return active;
1416     }
1417 
1418     // Toggle Group control, returns toggled button index
1419     int GuiToggleGroup(Rectangle bounds, const(char)* text, int active)
1420     {
1421         float initBoundsX = bounds.x;
1422 
1423         // Get substrings items from text (items pointers)
1424         int[TOGGLEGROUP_MAX_ELEMENTS] rows;
1425         int itemCount = 0;
1426         const(char)** items = GuiTextSplit(text, &itemCount, cast(int*)rows);
1427 
1428         int prevRow = rows[0];
1429 
1430         for (int i = 0; i < itemCount; i++)
1431         {
1432             if (prevRow != rows[i])
1433             {
1434                 bounds.x = initBoundsX;
1435                 bounds.y += (bounds.height + GuiGetStyle(TOGGLE, GROUP_PADDING));
1436                 prevRow = rows[i];
1437             }
1438 
1439             if (i == active) GuiToggle(bounds, items[i], true);
1440             else if (GuiToggle(bounds, items[i], false) == true) active = i;
1441 
1442             bounds.x += (bounds.width + GuiGetStyle(TOGGLE, GROUP_PADDING));
1443         }
1444 
1445         return active;
1446     }
1447 
1448     // Check Box control, returns true when active
1449     bool GuiCheckBox(Rectangle bounds, const(char)* text, bool checked)
1450     {
1451         GuiControlState state = guiState;
1452 
1453         Rectangle textBounds;
1454 
1455         if (text != null)
1456         {
1457             textBounds.width = cast(float)GetTextWidth(text);
1458             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
1459             textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING);
1460             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
1461             if (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(CHECKBOX, TEXT_PADDING);
1462         }
1463 
1464         // Update control
1465         //--------------------------------------------------------------------
1466         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1467         {
1468             Vector2 mousePoint = GetMousePosition();
1469 
1470             Rectangle totalBounds = Rectangle(
1471                 (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_LEFT)? textBounds.x : bounds.x,
1472                 bounds.y,
1473                 bounds.width + textBounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING),
1474                 bounds.height,
1475             );
1476 
1477             // Check checkbox state
1478             if (CheckCollisionPointRec(mousePoint, totalBounds))
1479             {
1480                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1481                 else state = GUI_STATE_FOCUSED;
1482 
1483                 if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) checked = !checked;
1484             }
1485         }
1486         //--------------------------------------------------------------------
1487 
1488         // Draw control
1489         //--------------------------------------------------------------------
1490         GuiDrawRectangle(bounds, GuiGetStyle(CHECKBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(CHECKBOX, BORDER + (state*3))), guiAlpha), BLANK);
1491 
1492         if (checked)
1493         {
1494             Rectangle check = Rectangle(bounds.x + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
1495                                         bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
1496                                         bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)),
1497                                         bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)));
1498             GuiDrawRectangle(check, 0, BLANK, Fade(GetColor(GuiGetStyle(CHECKBOX, TEXT + state*3)), guiAlpha));
1499         }
1500 
1501         GuiDrawText(text, textBounds, (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_RIGHT)? GUI_TEXT_ALIGN_LEFT : GUI_TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
1502         //--------------------------------------------------------------------
1503 
1504         return checked;
1505     }
1506 
1507     // Combo Box control, returns selected item index
1508     int GuiComboBox(Rectangle bounds, const(char)* text, int active)
1509     {
1510         GuiControlState state = guiState;
1511 
1512         bounds.width -= (GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH) + GuiGetStyle(COMBOBOX, COMBO_BUTTON_PADDING));
1513 
1514         Rectangle selector = Rectangle(cast(float)bounds.x + bounds.width + GuiGetStyle(COMBOBOX, COMBO_BUTTON_PADDING),
1515                             cast(float)bounds.y, cast(float)GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH), cast(float)bounds.height);
1516 
1517         // Get substrings items from text (items pointers, lengths and count)
1518         int itemCount = 0;
1519         const(char)** items = GuiTextSplit(text, &itemCount, null);
1520 
1521         if (active < 0) active = 0;
1522         else if (active > itemCount - 1) active = itemCount - 1;
1523 
1524         // Update control
1525         //--------------------------------------------------------------------
1526         if ((state != GUI_STATE_DISABLED) && !guiLocked && (itemCount > 1))
1527         {
1528             Vector2 mousePoint = GetMousePosition();
1529 
1530             if (CheckCollisionPointRec(mousePoint, bounds) ||
1531                 CheckCollisionPointRec(mousePoint, selector))
1532             {
1533                 if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
1534                 {
1535                     active += 1;
1536                     if (active >= itemCount) active = 0;
1537                 }
1538 
1539                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1540                 else state = GUI_STATE_FOCUSED;
1541             }
1542         }
1543         //--------------------------------------------------------------------
1544 
1545         // Draw control
1546         //--------------------------------------------------------------------
1547         // Draw combo box main
1548         GuiDrawRectangle(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE + (state*3))), guiAlpha));
1549         GuiDrawText(items[active], GetTextBounds(COMBOBOX, bounds), GuiGetStyle(COMBOBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT + (state*3))), guiAlpha));
1550 
1551         // Draw selector using a custom button
1552         // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
1553         int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
1554         int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
1555         GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
1556         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
1557 
1558         GuiButton(selector, TextFormat("%i/%i", active + 1, itemCount));
1559 
1560         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
1561         GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
1562         //--------------------------------------------------------------------
1563 
1564         return active;
1565     }
1566 
1567     // Dropdown Box control
1568     // NOTE: Returns mouse click
1569     bool GuiDropdownBox(Rectangle bounds, const(char)* text, int* active, bool editMode)
1570     {
1571         GuiControlState state = guiState;
1572         int itemSelected = *active;
1573         int itemFocused = -1;
1574 
1575         // Get substrings items from text (items pointers, lengths and count)
1576         int itemCount = 0;
1577         const(char)** items = GuiTextSplit(text, &itemCount, null);
1578 
1579         Rectangle boundsOpen = bounds;
1580         boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_PADDING));
1581 
1582         Rectangle itemBounds = bounds;
1583 
1584         bool pressed = false;       // Check mouse button pressed
1585 
1586         // Update control
1587         //--------------------------------------------------------------------
1588         if ((state != GUI_STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1))
1589         {
1590             Vector2 mousePoint = GetMousePosition();
1591 
1592             if (editMode)
1593             {
1594                 state = GUI_STATE_PRESSED;
1595 
1596                 // Check if mouse has been pressed or released outside limits
1597                 if (!CheckCollisionPointRec(mousePoint, boundsOpen))
1598                 {
1599                     if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
1600                 }
1601 
1602                 // Check if already selected item has been pressed again
1603                 if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
1604 
1605                 // Check focused and selected item
1606                 for (int i = 0; i < itemCount; i++)
1607                 {
1608                     // Update item rectangle y position for next item
1609                     itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_PADDING));
1610 
1611                     if (CheckCollisionPointRec(mousePoint, itemBounds))
1612                     {
1613                         itemFocused = i;
1614                         if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
1615                         {
1616                             itemSelected = i;
1617                             pressed = true;     // Item selected, change to editMode = false
1618                         }
1619                         break;
1620                     }
1621                 }
1622 
1623                 itemBounds = bounds;
1624             }
1625             else
1626             {
1627                 if (CheckCollisionPointRec(mousePoint, bounds))
1628                 {
1629                     if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
1630                     {
1631                         pressed = true;
1632                         state = GUI_STATE_PRESSED;
1633                     }
1634                     else state = GUI_STATE_FOCUSED;
1635                 }
1636             }
1637         }
1638         //--------------------------------------------------------------------
1639 
1640         // Draw control
1641         //--------------------------------------------------------------------
1642         if (editMode) GuiPanel(boundsOpen);
1643 
1644         GuiDrawRectangle(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE + state*3)), guiAlpha));
1645         GuiDrawText(items[itemSelected], GetTextBounds(DEFAULT, bounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + state*3)), guiAlpha));
1646 
1647         if (editMode)
1648         {
1649             // Draw visible items
1650             for (int i = 0; i < itemCount; i++)
1651             {
1652                 // Update item rectangle y position for next item
1653                 itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_PADDING));
1654 
1655                 if (i == itemSelected)
1656                 {
1657                     GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_PRESSED)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_PRESSED)), guiAlpha));
1658                     GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_PRESSED)), guiAlpha));
1659                 }
1660                 else if (i == itemFocused)
1661                 {
1662                     GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_FOCUSED)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_FOCUSED)), guiAlpha));
1663                     GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_FOCUSED)), guiAlpha));
1664                 }
1665                 else GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_NORMAL)), guiAlpha));
1666             }
1667         }
1668 
1669         // Draw arrows (using icon if available)
1670         version(RAYGUI_NO_RICONS)
1671             GuiDrawText("v", Rectangle(bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10),
1672                         GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
1673         else
1674             GuiDrawText("#120#", Rectangle(bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10),
1675                         GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));   // RICON_ARROW_DOWN_FILL
1676         
1677         //--------------------------------------------------------------------
1678 
1679         *active = itemSelected;
1680         return pressed;
1681     }
1682 
1683     // Text Box control, updates input text
1684     // NOTE 2: Returns if KEY_ENTER pressed (useful for data validation)
1685     bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode)
1686     {
1687         GuiControlState state = guiState;
1688         bool pressed = false;
1689 
1690         Rectangle cursor = Rectangle(
1691             bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text) + 2,
1692             bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE),
1693             4,
1694             cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2
1695         );
1696 
1697         if (cursor.height > bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
1698 
1699         // Update control
1700         //--------------------------------------------------------------------
1701         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1702         {
1703             Vector2 mousePoint = GetMousePosition();
1704 
1705             if (editMode)
1706             {
1707                 state = GUI_STATE_PRESSED;
1708 
1709                 int key = GetCharPressed();      // Returns codepoint as Unicode
1710                 int keyCount = cast(int)strlen(text);
1711 
1712                 // Only allow keys in range [32..125]
1713                 if (keyCount < (textSize - 1))
1714                 {
1715                     float maxWidth = (bounds.width - (GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)*2));
1716 
1717                     if ((GetTextWidth(text) < (maxWidth - GuiGetStyle(DEFAULT, TEXT_SIZE))) && (key >= 32))
1718                     {
1719                         int byteSize = 0;
1720                         const(char)* textUTF8 = CodepointToUTF8(key, &byteSize);
1721 
1722                         for (int i = 0; i < byteSize; i++)
1723                         {
1724                             text[keyCount] = textUTF8[i];
1725                             keyCount++;
1726                         }
1727 
1728                         text[keyCount] = '\0';
1729                     }
1730                 }
1731 
1732                 // Delete text
1733                 if (keyCount > 0)
1734                 {
1735                     if (IsKeyPressed(KEY_BACKSPACE))
1736                     {
1737                         keyCount--;
1738                         text[keyCount] = '\0';
1739                         if (keyCount < 0) keyCount = 0;
1740                     }
1741                 }
1742 
1743                 if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true;
1744 
1745                 // Check text alignment to position cursor properly
1746                 int textAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT);
1747                 if (textAlignment == GUI_TEXT_ALIGN_CENTER) cursor.x = bounds.x + GetTextWidth(text)/2 + bounds.width/2 + 1;
1748                 else if (textAlignment == GUI_TEXT_ALIGN_RIGHT) cursor.x = bounds.x + bounds.width - GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING);
1749             }
1750             else
1751             {
1752                 if (CheckCollisionPointRec(mousePoint, bounds))
1753                 {
1754                     state = GUI_STATE_FOCUSED;
1755                     if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
1756                 }
1757             }
1758         }
1759         //--------------------------------------------------------------------
1760 
1761         // Draw control
1762         //--------------------------------------------------------------------
1763         if (state == GUI_STATE_PRESSED)
1764         {
1765             GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED)), guiAlpha));
1766         }
1767         else if (state == GUI_STATE_DISABLED)
1768         {
1769             GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED)), guiAlpha));
1770         }
1771         else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), BLANK);
1772 
1773         GuiDrawText(text, GetTextBounds(TEXTBOX, bounds), GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
1774 
1775         // Draw cursor
1776         if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
1777         //--------------------------------------------------------------------
1778 
1779         return pressed;
1780     }
1781 
1782     // Spinner control, returns selected value
1783     bool GuiSpinner(Rectangle bounds, const(char)* text, int* value, int minValue, int maxValue, bool editMode)
1784     {
1785         GuiControlState state = guiState;
1786 
1787         bool pressed = false;
1788         int tempValue = *value;
1789 
1790         Rectangle spinner = Rectangle(bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_PADDING), bounds.y,
1791                                       bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_PADDING)), bounds.height);
1792         Rectangle leftButtonBound = Rectangle(cast(float)bounds.x, cast(float)bounds.y, cast(float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), cast(float)bounds.height);
1793         Rectangle rightButtonBound = Rectangle(cast(float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), cast(float)bounds.y, cast(float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), cast(float)bounds.height);
1794 
1795         Rectangle textBounds;
1796         if (text != null)
1797         {
1798             textBounds.width = cast(float)GetTextWidth(text);
1799             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
1800             textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING);
1801             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
1802             if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING);
1803         }
1804 
1805         // Update control
1806         //--------------------------------------------------------------------
1807         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1808         {
1809             Vector2 mousePoint = GetMousePosition();
1810 
1811             // Check spinner state
1812             if (CheckCollisionPointRec(mousePoint, bounds))
1813             {
1814                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
1815                 else state = GUI_STATE_FOCUSED;
1816             }
1817         }
1818 
1819         if (!editMode)
1820         {
1821             if (tempValue < minValue) tempValue = minValue;
1822             if (tempValue > maxValue) tempValue = maxValue;
1823         }
1824         //--------------------------------------------------------------------
1825 
1826         // Draw control
1827         //--------------------------------------------------------------------
1828         // TODO: Set Spinner properties for ValueBox
1829         pressed = GuiValueBox(spinner, null, &tempValue, minValue, maxValue, editMode);
1830 
1831         // Draw value selector custom buttons
1832         // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
1833         int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
1834         int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
1835         GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(SPINNER, BORDER_WIDTH));
1836         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
1837 
1838         version(RAYGUI_NO_RICONS) {
1839             if (GuiButton(leftButtonBound, "<")) tempValue--;
1840             if (GuiButton(rightButtonBound, ">")) tempValue++;
1841         } else {
1842             if (GuiButton(leftButtonBound, GuiIconText(RICON_ARROW_LEFT_FILL, null))) tempValue--;
1843             if (GuiButton(rightButtonBound, GuiIconText(RICON_ARROW_RIGHT_FILL, null))) tempValue++;
1844         }
1845 
1846         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
1847         GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
1848 
1849         // Draw text label if provided
1850         GuiDrawText(text, textBounds, (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_RIGHT)? GUI_TEXT_ALIGN_LEFT : GUI_TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
1851         //--------------------------------------------------------------------
1852 
1853         *value = tempValue;
1854         return pressed;
1855     }
1856 
1857     // Value Box control, updates input text with numbers
1858     // NOTE: Requires variables: frameCounter
1859     bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, int maxValue, bool editMode)
1860     {
1861         GuiControlState state = guiState;
1862         bool pressed = false;
1863 
1864         char[VALUEBOX_MAX_CHARS + 1] textValue; memset(cast(char*)textValue, '\0', VALUEBOX_MAX_CHARS + 1);
1865         sprintf(cast(char*)textValue, "%i", *value);
1866 
1867         Rectangle textBounds;
1868         if (text != null)
1869         {
1870             textBounds.width = cast(float)GetTextWidth(text);
1871             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
1872             textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
1873             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
1874             if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING);
1875         }
1876 
1877         // Update control
1878         //--------------------------------------------------------------------
1879         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1880         {
1881             Vector2 mousePoint = GetMousePosition();
1882 
1883             bool valueHasChanged = false;
1884 
1885             if (editMode)
1886             {
1887                 state = GUI_STATE_PRESSED;
1888 
1889                 int keyCount = cast(int)strlen(cast(char*)textValue);
1890 
1891                 // Only allow keys in range [48..57]
1892                 if (keyCount < VALUEBOX_MAX_CHARS)
1893                 {
1894                     if (GetTextWidth(cast(char*)textValue) < bounds.width)
1895                     {
1896                         int key = GetCharPressed();
1897                         if ((key >= 48) && (key <= 57))
1898                         {
1899                             textValue[keyCount] = cast(char)key;
1900                             keyCount++;
1901                             valueHasChanged = true;
1902                         }
1903                     }
1904                 }
1905 
1906                 // Delete text
1907                 if (keyCount > 0)
1908                 {
1909                     if (IsKeyPressed(KEY_BACKSPACE))
1910                     {
1911                         keyCount--;
1912                         textValue[keyCount] = '\0';
1913                         if (keyCount < 0) keyCount = 0;
1914                         valueHasChanged = true;
1915                     }
1916                 }
1917 
1918                 if (valueHasChanged) *value = TextToInteger(cast(char*)textValue);
1919 
1920                 if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true;
1921             }
1922             else
1923             {
1924                 if (*value > maxValue) *value = maxValue;
1925                 else if (*value < minValue) *value = minValue;
1926 
1927                 if (CheckCollisionPointRec(mousePoint, bounds))
1928                 {
1929                     state = GUI_STATE_FOCUSED;
1930                     if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
1931                 }
1932             }
1933         }
1934         //--------------------------------------------------------------------
1935 
1936         // Draw control
1937         //--------------------------------------------------------------------
1938         Color baseColor = BLANK;
1939         if (state == GUI_STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED));
1940         else if (state == GUI_STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED));
1941 
1942         // WARNING: BLANK color does not work properly with Fade()
1943         GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), guiAlpha), baseColor);
1944         GuiDrawText(cast(char*)textValue, GetTextBounds(VALUEBOX, bounds), GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3))), guiAlpha));
1945 
1946         // Draw cursor
1947         if (editMode)
1948         {
1949             // NOTE: ValueBox internal text is always centered
1950             Rectangle cursor = Rectangle(bounds.x + GetTextWidth(cast(char*)textValue)/2 + bounds.width/2 + 2, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH));
1951             GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)), guiAlpha));
1952         }
1953 
1954         // Draw text label if provided
1955         GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_RIGHT)? GUI_TEXT_ALIGN_LEFT : GUI_TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
1956         //--------------------------------------------------------------------
1957 
1958         return pressed;
1959     }
1960 
1961     // Text Box control with multiple lines
1962     bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode)
1963     {
1964         GuiControlState state = guiState;
1965         bool pressed = false;
1966 
1967         Rectangle textAreaBounds = Rectangle(
1968             bounds.x + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
1969             bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
1970             bounds.width - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)),
1971             bounds.height - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING))
1972         );
1973 
1974         // Cursor position, [x, y] values should be updated
1975         Rectangle cursor = Rectangle(0, -1, 4, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE) + 2);
1976 
1977         float scaleFactor = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE)/cast(float)guiFont.baseSize;     // Character rectangle scaling factor
1978 
1979         // Update control
1980         //--------------------------------------------------------------------
1981         if ((state != GUI_STATE_DISABLED) && !guiLocked)
1982         {
1983             Vector2 mousePoint = GetMousePosition();
1984 
1985             if (editMode)
1986             {
1987                 state = GUI_STATE_PRESSED;
1988 
1989                 // We get an Unicode codepoint
1990                 int codepoint = GetCharPressed();
1991                 int textLength = cast(int)strlen(text);     // Length in bytes (UTF-8 string)
1992 
1993                 // Introduce characters
1994                 if (textLength < (textSize - 1))
1995                 {
1996                     if (IsKeyPressed(KEY_ENTER))
1997                     {
1998                         text[textLength] = '\n';
1999                         textLength++;
2000                     }
2001                     else if (codepoint >= 32)
2002                     {
2003                         // Supports Unicode inputs -> Encoded to UTF-8
2004                         int charUTF8Length = 0;
2005                         const(char)* charEncoded = CodepointToUTF8(codepoint, &charUTF8Length);
2006                         memcpy(text + textLength, charEncoded, charUTF8Length);
2007                         textLength += charUTF8Length;
2008                     }
2009                 }
2010 
2011                 // Delete characters
2012                 if (textLength > 0)
2013                 {
2014                     if (IsKeyPressed(KEY_BACKSPACE))
2015                     {
2016                         if (cast(ubyte)text[textLength - 1] < 127)
2017                         {
2018                             // Remove ASCII equivalent character (1 byte)
2019                             textLength--;
2020                             text[textLength] = '\0';
2021                         }
2022                         else
2023                         {
2024                             // Remove latest UTF-8 unicode character introduced (n bytes)
2025                             int charUTF8Length = 0;
2026                             while ((cast(ubyte)text[textLength - 1 - charUTF8Length] & 0b01000000) == 0) charUTF8Length++;
2027 
2028                             textLength -= (charUTF8Length + 1);
2029                             text[textLength] = '\0';
2030                         }
2031                     }
2032                 }
2033 
2034                 // Exit edit mode
2035                 if (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
2036             }
2037             else
2038             {
2039                 if (CheckCollisionPointRec(mousePoint, bounds))
2040                 {
2041                     state = GUI_STATE_FOCUSED;
2042                     if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
2043                 }
2044             }
2045         }
2046         //--------------------------------------------------------------------
2047 
2048         // Draw control
2049         //--------------------------------------------------------------------
2050         if (state == GUI_STATE_PRESSED)
2051         {
2052             GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED)), guiAlpha));
2053         }
2054         else if (state == GUI_STATE_DISABLED)
2055         {
2056             GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED)), guiAlpha));
2057         }
2058         else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), BLANK);
2059 
2060         int wrapMode = 1;      // 0-No wrap, 1-Char wrap, 2-Word wrap
2061         Vector2 cursorPos = Vector2(textAreaBounds.x, textAreaBounds.y);
2062 
2063         //int lastSpacePos = 0;
2064         //int lastSpaceWidth = 0;
2065         //int lastSpaceCursorPos = 0;
2066 
2067         for (int i = 0, codepointLength = 0; text[i] != '\0'; i += codepointLength)
2068         {
2069             int codepoint = GetCodepoint(text + i, &codepointLength);
2070             int index = GetGlyphIndex(guiFont, codepoint);      // If requested codepoint is not found, we get '?' (0x3f)
2071             Rectangle atlasRec = guiFont.recs[index];
2072             GlyphInfo glyphInfo = guiFont.glyphs[index];        // Glyph measures
2073 
2074             if ((codepointLength == 1) && (codepoint == '\n'))
2075             {
2076                 cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_PADDING));   // Line feed
2077                 cursorPos.x = textAreaBounds.x;                 // Carriage return
2078             }
2079             else
2080             {
2081                 if (wrapMode == 1)
2082                 {
2083                     int glyphWidth = 0;
2084                     if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
2085                     else glyphWidth += cast(int)(atlasRec.width + glyphInfo.offsetX);
2086 
2087                     // Jump line if the end of the text box area has been reached
2088                     if ((cursorPos.x + (glyphWidth*scaleFactor)) > (textAreaBounds.x + textAreaBounds.width))
2089                     {
2090                         cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_PADDING));   // Line feed
2091                         cursorPos.x = textAreaBounds.x;     // Carriage return
2092                     }
2093                 }
2094                 else if (wrapMode == 2)
2095                 {
2096                     /*
2097                     if ((codepointLength == 1) && (codepoint == ' '))
2098                     {
2099                         lastSpacePos = i;
2100                         lastSpaceWidth = 0;
2101                         lastSpaceCursorPos = cursorPos.x;
2102                     }
2103 
2104                     // Jump line if last word reaches end of text box area
2105                     if ((lastSpaceCursorPos + lastSpaceWidth) > (textAreaBounds.x + textAreaBounds.width))
2106                     {
2107                         cursorPos.y += 12;               // Line feed
2108                         cursorPos.x = textAreaBounds.x;  // Carriage return
2109                     }
2110                     */
2111                 }
2112 
2113                 // Draw current character glyph
2114                 DrawTextCodepoint(guiFont, codepoint, cursorPos, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
2115 
2116                 int glyphWidth = 0;
2117                 if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
2118                 else glyphWidth += cast(int)(atlasRec.width + glyphInfo.offsetX);
2119 
2120                 cursorPos.x += (glyphWidth*scaleFactor + cast(float)GuiGetStyle(DEFAULT, TEXT_SPACING));
2121                 //if (i > lastSpacePos) lastSpaceWidth += (atlasRec.width + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
2122             }
2123         }
2124 
2125         cursor.x = cursorPos.x;
2126         cursor.y = cursorPos.y;
2127 
2128         // Draw cursor position considering text glyphs
2129         if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
2130         //--------------------------------------------------------------------
2131 
2132         return pressed;
2133     }
2134 
2135     // Slider control with pro parameters
2136     // NOTE: Other GuiSlider*() controls use this one
2137     float GuiSliderPro(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue, int sliderWidth)
2138     {
2139         GuiControlState state = guiState;
2140 
2141         int sliderValue = cast(int)(((value - minValue)/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH)));
2142 
2143         Rectangle slider = Rectangle(bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING),
2144                             0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING));
2145 
2146         if (sliderWidth > 0)        // Slider
2147         {
2148             slider.x += (sliderValue - sliderWidth/2);
2149             slider.width = cast(float)sliderWidth;
2150         }
2151         else if (sliderWidth == 0)  // SliderBar
2152         {
2153             slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH);
2154             slider.width = cast(float)sliderValue;
2155         }
2156 
2157         // Update control
2158         //--------------------------------------------------------------------
2159         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2160         {
2161             Vector2 mousePoint = GetMousePosition();
2162 
2163             if (CheckCollisionPointRec(mousePoint, bounds))
2164             {
2165                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
2166                 {
2167                     state = GUI_STATE_PRESSED;
2168 
2169                     // Get equivalent value and slider position from mousePoint.x
2170                     value = ((maxValue - minValue)*(mousePoint.x - cast(float)(bounds.x + sliderWidth/2)))/cast(float)(bounds.width - sliderWidth) + minValue;
2171 
2172                     if (sliderWidth > 0) slider.x = mousePoint.x - slider.width/2;  // Slider
2173                     else if (sliderWidth == 0) slider.width = cast(float)sliderValue;          // SliderBar
2174                 }
2175                 else state = GUI_STATE_FOCUSED;
2176             }
2177 
2178             if (value > maxValue) value = maxValue;
2179             else if (value < minValue) value = minValue;
2180         }
2181 
2182         // Bar limits check
2183         if (sliderWidth > 0)        // Slider
2184         {
2185             if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH);
2186             else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH);
2187         }
2188         else if (sliderWidth == 0)  // SliderBar
2189         {
2190             if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH);
2191         }
2192         //--------------------------------------------------------------------
2193 
2194         // Draw control
2195         //--------------------------------------------------------------------
2196         GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(SLIDER, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(SLIDER, (state != GUI_STATE_DISABLED)?  BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
2197 
2198         // Draw slider internal bar (depends on state)
2199         if ((state == GUI_STATE_NORMAL) || (state == GUI_STATE_PRESSED)) GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED)), guiAlpha));
2200         else if (state == GUI_STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_FOCUSED)), guiAlpha));
2201 
2202         // Draw left/right text if provided
2203         if (textLeft != null)
2204         {
2205             Rectangle textBounds;
2206             textBounds.width = cast(float)GetTextWidth(textLeft);
2207             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
2208             textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING);
2209             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
2210 
2211             GuiDrawText(textLeft, textBounds, GUI_TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))), guiAlpha));
2212         }
2213 
2214         if (textRight != null)
2215         {
2216             Rectangle textBounds;
2217             textBounds.width = cast(float)GetTextWidth(textRight);
2218             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
2219             textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING);
2220             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
2221 
2222             GuiDrawText(textRight, textBounds, GUI_TEXT_ALIGN_LEFT, Fade(GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))), guiAlpha));
2223         }
2224         //--------------------------------------------------------------------
2225 
2226         return value;
2227     }
2228 
2229     // Slider control extended, returns selected value and has text
2230     float GuiSlider(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue)
2231     {
2232         return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH));
2233     }
2234 
2235     // Slider Bar control extended, returns selected value
2236     float GuiSliderBar(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue)
2237     {
2238         return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0);
2239     }
2240 
2241     // Progress Bar control extended, shows current progress value
2242     float GuiProgressBar(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue)
2243     {
2244         GuiControlState state = guiState;
2245 
2246         Rectangle progress = Rectangle(bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH),
2247                             bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0,
2248                             bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING));
2249 
2250         // Update control
2251         //--------------------------------------------------------------------
2252         if (state != GUI_STATE_DISABLED) progress.width = (cast(float)(value/(maxValue - minValue))*cast(float)(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)));
2253         //--------------------------------------------------------------------
2254 
2255         // Draw control
2256         //--------------------------------------------------------------------
2257         GuiDrawRectangle(bounds, GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(PROGRESSBAR, BORDER + (state*3))), guiAlpha), BLANK);
2258 
2259         // Draw slider internal progress bar (depends on state)
2260         if ((state == GUI_STATE_NORMAL) || (state == GUI_STATE_PRESSED)) GuiDrawRectangle(progress, 0, BLANK, Fade(GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)), guiAlpha));
2261         else if (state == GUI_STATE_FOCUSED) GuiDrawRectangle(progress, 0, BLANK, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT_COLOR_FOCUSED)), guiAlpha));
2262 
2263         // Draw left/right text if provided
2264         if (textLeft != null)
2265         {
2266             Rectangle textBounds;
2267             textBounds.width = cast(float)GetTextWidth(textLeft);
2268             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
2269             textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
2270             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
2271 
2272             GuiDrawText(textLeft, textBounds, GUI_TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))), guiAlpha));
2273         }
2274 
2275         if (textRight != null)
2276         {
2277             Rectangle textBounds;
2278             textBounds.width = cast(float)GetTextWidth(textRight);
2279             textBounds.height = cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE);
2280             textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
2281             textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
2282 
2283             GuiDrawText(textRight, textBounds, GUI_TEXT_ALIGN_LEFT, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))), guiAlpha));
2284         }
2285         //--------------------------------------------------------------------
2286 
2287         return value;
2288     }
2289 
2290     // Status Bar control
2291     void GuiStatusBar(Rectangle bounds, const(char)* text)
2292     {
2293         GuiControlState state = guiState;
2294 
2295         // Draw control
2296         //--------------------------------------------------------------------
2297         GuiDrawRectangle(bounds, GuiGetStyle(STATUSBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(STATUSBAR, (state != GUI_STATE_DISABLED)? BORDER_COLOR_NORMAL : BORDER_COLOR_DISABLED)), guiAlpha),
2298                         Fade(GetColor(GuiGetStyle(STATUSBAR, (state != GUI_STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
2299         GuiDrawText(text, GetTextBounds(STATUSBAR, bounds), GuiGetStyle(STATUSBAR, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(STATUSBAR, (state != GUI_STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED)), guiAlpha));
2300         //--------------------------------------------------------------------
2301     }
2302 
2303     // Dummy rectangle control, intended for placeholding
2304     void GuiDummyRec(Rectangle bounds, const(char)* text)
2305     {
2306         GuiControlState state = guiState;
2307 
2308         // Update control
2309         //--------------------------------------------------------------------
2310         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2311         {
2312             Vector2 mousePoint = GetMousePosition();
2313 
2314             // Check button state
2315             if (CheckCollisionPointRec(mousePoint, bounds))
2316             {
2317                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = GUI_STATE_PRESSED;
2318                 else state = GUI_STATE_FOCUSED;
2319             }
2320         }
2321         //--------------------------------------------------------------------
2322 
2323         // Draw control
2324         //--------------------------------------------------------------------
2325         GuiDrawRectangle(bounds, 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state != GUI_STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
2326         GuiDrawText(text, GetTextBounds(DEFAULT, bounds), GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(BUTTON, (state != GUI_STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED)), guiAlpha));
2327         //------------------------------------------------------------------
2328     }
2329 
2330     // Scroll Bar control
2331     int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
2332     {
2333         GuiControlState state = guiState;
2334 
2335         // Is the scrollbar horizontal or vertical?
2336         bool isVertical = (bounds.width > bounds.height)? false : true;
2337 
2338         // The size (width or height depending on scrollbar type) of the spinner buttons
2339         const(int) spinnerSize = GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)? (isVertical? cast(int)bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) : cast(int)bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH)) : 0;
2340 
2341         // Arrow buttons [<] [>] [∧] [∨]
2342         Rectangle arrowUpLeft;
2343         Rectangle arrowDownRight;
2344 
2345         // Actual area of the scrollbar excluding the arrow buttons
2346         Rectangle scrollbar;
2347 
2348         // Slider bar that moves     --[///]-----
2349         Rectangle slider;
2350 
2351         // Normalize value
2352         if (value > maxValue) value = maxValue;
2353         if (value < minValue) value = minValue;
2354 
2355         const(int) range = maxValue - minValue;
2356         int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
2357 
2358         // Calculate rectangles for all of the components
2359         arrowUpLeft = Rectangle(cast(float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)spinnerSize, cast(float)spinnerSize);
2360 
2361         if (isVertical)
2362         {
2363             arrowDownRight = Rectangle(cast(float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)spinnerSize, cast(float)spinnerSize);
2364             scrollbar = Rectangle(bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH));
2365             sliderSize = (sliderSize >= scrollbar.height)? (cast(int)scrollbar.height - 2) : sliderSize;     // Make sure the slider won't get outside of the scrollbar
2366             slider = Rectangle(cast(float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), cast(float)scrollbar.y + cast(int)((cast(float)(value - minValue)/range)*(scrollbar.height - sliderSize)), cast(float)bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)), cast(float)sliderSize);
2367         }
2368         else
2369         {
2370             arrowDownRight = Rectangle(cast(float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), cast(float)spinnerSize, cast(float)spinnerSize);
2371             scrollbar = Rectangle(arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)));
2372             sliderSize = (sliderSize >= scrollbar.width)? (cast(int)scrollbar.width - 2) : sliderSize;       // Make sure the slider won't get outside of the scrollbar
2373             slider = Rectangle(cast(float)scrollbar.x + cast(int)((cast(float)(value - minValue)/range)*(scrollbar.width - sliderSize)), cast(float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), cast(float)sliderSize, cast(float)bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)));
2374         }
2375 
2376         // Update control
2377         //--------------------------------------------------------------------
2378         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2379         {
2380             Vector2 mousePoint = GetMousePosition();
2381 
2382             if (CheckCollisionPointRec(mousePoint, bounds))
2383             {
2384                 state = GUI_STATE_FOCUSED;
2385 
2386                 // Handle mouse wheel
2387                 int wheel = cast(int)GetMouseWheelMove();
2388                 if (wheel != 0) value += wheel;
2389 
2390                 if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
2391                 {
2392                     if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
2393                     else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
2394 
2395                     state = GUI_STATE_PRESSED;
2396                 }
2397                 else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
2398                 {
2399                     if (!isVertical)
2400                     {
2401                         Rectangle scrollArea = Rectangle(arrowUpLeft.x + arrowUpLeft.width, arrowUpLeft.y, scrollbar.width, bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH));
2402                         if (CheckCollisionPointRec(mousePoint, scrollArea)) value = cast(int)((cast(float)(mousePoint.x - scrollArea.x - slider.width/2)*range)/(scrollArea.width - slider.width) + minValue);
2403                     }
2404                     else
2405                     {
2406                         Rectangle scrollArea = Rectangle(arrowUpLeft.x, arrowUpLeft.y+arrowUpLeft.height, bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH),  scrollbar.height);
2407                         if (CheckCollisionPointRec(mousePoint, scrollArea)) value = cast(int)((cast(float)(mousePoint.y - scrollArea.y - slider.height/2)*range)/(scrollArea.height - slider.height) + minValue);
2408                     }
2409                 }
2410             }
2411 
2412             // Normalize value
2413             if (value > maxValue) value = maxValue;
2414             if (value < minValue) value = minValue;
2415         }
2416         //--------------------------------------------------------------------
2417 
2418         // Draw control
2419         //--------------------------------------------------------------------
2420         GuiDrawRectangle(bounds, GuiGetStyle(SCROLLBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED)), guiAlpha));   // Draw the background
2421 
2422         GuiDrawRectangle(scrollbar, 0, BLANK, Fade(GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL)), guiAlpha));     // Draw the scrollbar active area background
2423         GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, BORDER + state*3)), guiAlpha));         // Draw the slider bar
2424 
2425         // Draw arrows (using icon if available)
2426         if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE))
2427         {
2428             version(RAYGUI_NO_RICONS) {
2429                 GuiDrawText(isVertical? "^" : "<", Rectangle(arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height),
2430                             GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
2431                 GuiDrawText(isVertical? "v" : ">", Rectangle(arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height),
2432                             GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
2433             } else {
2434                 GuiDrawText(isVertical? "#121#" : "#118#", Rectangle(arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height),
2435                             GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha));   // RICON_ARROW_UP_FILL / RICON_ARROW_LEFT_FILL
2436                 GuiDrawText(isVertical? "#120#" : "#119#", Rectangle(arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height),
2437                             GUI_TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha));   // RICON_ARROW_DOWN_FILL / RICON_ARROW_RIGHT_FILL
2438             }
2439         }
2440         //--------------------------------------------------------------------
2441 
2442         return value;
2443     }
2444 
2445     // List View control
2446     int GuiListView(Rectangle bounds, const(char)* text, int* scrollIndex, int active)
2447     {
2448         int itemCount = 0;
2449         const(char)** items = null;
2450 
2451         if (text != null) items = GuiTextSplit(text, &itemCount, null);
2452 
2453         return GuiListViewEx(bounds, items, itemCount, null, scrollIndex, active);
2454     }
2455 
2456     // List View control with extended parameters
2457     int GuiListViewEx(Rectangle bounds, const(char)** text, int count, int* focus, int* scrollIndex, int active)
2458     {
2459         GuiControlState state = guiState;
2460         int itemFocused = (focus == null)? -1 : *focus;
2461         int itemSelected = active;
2462 
2463         // Check if we need a scroll bar
2464         bool useScrollBar = false;
2465         if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING))*count > bounds.height) useScrollBar = true;
2466 
2467         // Define base item rectangle [0]
2468         Rectangle itemBounds;
2469         itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING);
2470         itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
2471         itemBounds.width = bounds.width - 2*GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) - GuiGetStyle(DEFAULT, BORDER_WIDTH);
2472         itemBounds.height = cast(float)GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT);
2473         if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH);
2474 
2475         // Get items on the list
2476         int visibleItems = cast(int)bounds.height/(GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
2477         if (visibleItems > count) visibleItems = count;
2478 
2479         int startIndex = (scrollIndex == null)? 0 : *scrollIndex;
2480         if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0;
2481         int endIndex = startIndex + visibleItems;
2482 
2483         // Update control
2484         //--------------------------------------------------------------------
2485         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2486         {
2487             Vector2 mousePoint = GetMousePosition();
2488 
2489             // Check mouse inside list view
2490             if (CheckCollisionPointRec(mousePoint, bounds))
2491             {
2492                 state = GUI_STATE_FOCUSED;
2493 
2494                 // Check focused and selected item
2495                 for (int i = 0; i < visibleItems; i++)
2496                 {
2497                     if (CheckCollisionPointRec(mousePoint, itemBounds))
2498                     {
2499                         itemFocused = startIndex + i;
2500                         if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
2501                         {
2502                             if (itemSelected == (startIndex + i)) itemSelected = -1;
2503                             else itemSelected = startIndex + i;
2504                         }
2505                         break;
2506                     }
2507 
2508                     // Update item rectangle y position for next item
2509                     itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
2510                 }
2511 
2512                 if (useScrollBar)
2513                 {
2514                     int wheelMove = cast(int)GetMouseWheelMove();
2515                     startIndex -= wheelMove;
2516 
2517                     if (startIndex < 0) startIndex = 0;
2518                     else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems;
2519 
2520                     endIndex = startIndex + visibleItems;
2521                     if (endIndex > count) endIndex = count;
2522                 }
2523             }
2524             else itemFocused = -1;
2525 
2526             // Reset item rectangle y to [0]
2527             itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
2528         }
2529         //--------------------------------------------------------------------
2530 
2531         // Draw control
2532         //--------------------------------------------------------------------
2533         GuiDrawRectangle(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), guiAlpha), GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));     // Draw background
2534 
2535         // Draw visible items
2536         for (int i = 0; ((i < visibleItems) && (text != null)); i++)
2537         {
2538             if (state == GUI_STATE_DISABLED)
2539             {
2540                 if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED)), guiAlpha));
2541 
2542                 GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED)), guiAlpha));
2543             }
2544             else
2545             {
2546                 if ((startIndex + i) == itemSelected)
2547                 {
2548                     // Draw item selected
2549                     GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED)), guiAlpha));
2550                     GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED)), guiAlpha));
2551                 }
2552                 else if ((startIndex + i) == itemFocused)
2553                 {
2554                     // Draw item focused
2555                     GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED)), guiAlpha));
2556                     GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED)), guiAlpha));
2557                 }
2558                 else
2559                 {
2560                     // Draw item normal
2561                     GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL)), guiAlpha));
2562                 }
2563             }
2564 
2565             // Update item rectangle y position for next item
2566             itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
2567         }
2568 
2569         if (useScrollBar)
2570         {
2571             Rectangle scrollBarBounds = Rectangle(
2572                 bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
2573                 bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), cast(float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
2574                 bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
2575             );
2576 
2577             // Calculate percentage of visible items and apply same percentage to scrollbar
2578             float percentVisible = cast(float)(endIndex - startIndex)/count;
2579             float sliderSize = bounds.height*percentVisible;
2580 
2581             int prevSliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);   // Save default slider size
2582             int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed
2583             GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, cast(int)sliderSize);            // Change slider size
2584             GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed
2585 
2586             startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems);
2587 
2588             GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default
2589             GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, prevSliderSize); // Reset slider size to default
2590         }
2591         //--------------------------------------------------------------------
2592 
2593         if (focus != null) *focus = itemFocused;
2594         if (scrollIndex != null) *scrollIndex = startIndex;
2595 
2596         return itemSelected;
2597     }
2598 
2599     // Color Panel control
2600     Color GuiColorPanel(Rectangle bounds, Color color)
2601     {
2602         const Color colWhite = Color(255, 255, 255, 255);
2603         const Color colBlack = Color(0, 0, 0, 255);
2604 
2605         GuiControlState state = guiState;
2606         Vector2 pickerSelector;
2607 
2608         Vector3 vcolor = Vector3(cast(float)color.r/255.0f, cast(float)color.g/255.0f, cast(float)color.b/255.0f);
2609         Vector3 hsv = ConvertRGBtoHSV(vcolor);
2610 
2611         pickerSelector.x = bounds.x + cast(float)hsv.y*bounds.width;            // HSV: Saturation
2612         pickerSelector.y = bounds.y + (1.0f - cast(float)hsv.z)*bounds.height;  // HSV: Value
2613 
2614         float hue = -1.0f;
2615         Vector3 maxHue = Vector3(hue >= 0.0f ? hue : hsv.x, 1.0f, 1.0f);
2616         Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
2617         Color maxHueCol = Color(cast(ubyte)(255.0f*rgbHue.x),
2618                                 cast(ubyte)(255.0f*rgbHue.y),
2619                                 cast(ubyte)(255.0f*rgbHue.z), 255);
2620 
2621         // Update control
2622         //--------------------------------------------------------------------
2623         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2624         {
2625             Vector2 mousePoint = GetMousePosition();
2626 
2627             if (CheckCollisionPointRec(mousePoint, bounds))
2628             {
2629                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
2630                 {
2631                     state = GUI_STATE_PRESSED;
2632                     pickerSelector = mousePoint;
2633 
2634                     // Calculate color from picker
2635                     Vector2 colorPick = Vector2(pickerSelector.x - bounds.x, pickerSelector.y - bounds.y);
2636 
2637                     colorPick.x /= cast(float)bounds.width;     // Get normalized value on x
2638                     colorPick.y /= cast(float)bounds.height;    // Get normalized value on y
2639 
2640                     hsv.y = colorPick.x;
2641                     hsv.z = 1.0f - colorPick.y;
2642 
2643                     Vector3 rgb = ConvertHSVtoRGB(hsv);
2644 
2645                     // NOTE: Vector3ToColor() only available on raylib 1.8.1
2646                     color = Color(cast(ubyte)(255.0f*rgb.x),
2647                                   cast(ubyte)(255.0f*rgb.y),
2648                                   cast(ubyte)(255.0f*rgb.z),
2649                                   cast(ubyte)(255.0f*cast(float)color.a/255.0f));
2650 
2651                 }
2652                 else state = GUI_STATE_FOCUSED;
2653             }
2654         }
2655         //--------------------------------------------------------------------
2656 
2657         // Draw control
2658         //--------------------------------------------------------------------
2659         if (state != GUI_STATE_DISABLED)
2660         {
2661             DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha));
2662             DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0));
2663 
2664             // Draw color picker: selector
2665             Rectangle selector = Rectangle(pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, cast(float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), cast(float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE));
2666             GuiDrawRectangle(selector, 0, BLANK, Fade(colWhite, guiAlpha));
2667         }
2668         else
2669         {
2670             DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha));
2671         }
2672 
2673         GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
2674         //--------------------------------------------------------------------
2675 
2676         return color;
2677     }
2678 
2679     // Color Bar Alpha control
2680     // NOTE: Returns alpha value normalized [0..1]
2681     float GuiColorBarAlpha(Rectangle bounds, float alpha)
2682     {
2683         GuiControlState state = guiState;
2684         Rectangle selector = Rectangle(cast(float)bounds.x + alpha*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, cast(float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), cast(float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), cast(float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2);
2685 
2686         // Update control
2687         //--------------------------------------------------------------------
2688         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2689         {
2690             Vector2 mousePoint = GetMousePosition();
2691 
2692             if (CheckCollisionPointRec(mousePoint, bounds) ||
2693                 CheckCollisionPointRec(mousePoint, selector))
2694             {
2695                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
2696                 {
2697                     state = GUI_STATE_PRESSED;
2698 
2699                     alpha = (mousePoint.x - bounds.x)/bounds.width;
2700                     if (alpha <= 0.0f) alpha = 0.0f;
2701                     if (alpha >= 1.0f) alpha = 1.0f;
2702                     //selector.x = bounds.x + (int)(((alpha - 0)/(100 - 0))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))) - selector.width/2;
2703                 }
2704                 else state = GUI_STATE_FOCUSED;
2705             }
2706         }
2707         //--------------------------------------------------------------------
2708 
2709         // Draw control
2710         //--------------------------------------------------------------------
2711 
2712         // Draw alpha bar: checked background
2713         if (state != GUI_STATE_DISABLED)
2714         {
2715             int checksX = cast(int)bounds.width/COLORBARALPHA_CHECKED_SIZE;
2716             int checksY = cast(int)bounds.height/COLORBARALPHA_CHECKED_SIZE;
2717 
2718             for (int x = 0; x < checksX; x++)
2719             {
2720                 for (int y = 0; y < checksY; y++)
2721                 {
2722                     Rectangle check = Rectangle(bounds.x + x*COLORBARALPHA_CHECKED_SIZE, bounds.y + y*COLORBARALPHA_CHECKED_SIZE, COLORBARALPHA_CHECKED_SIZE, COLORBARALPHA_CHECKED_SIZE);
2723                     GuiDrawRectangle(check, 0, BLANK, ((x + y)%2)? Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.4f), guiAlpha) : Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.4f), guiAlpha));
2724                 }
2725             }
2726 
2727             DrawRectangleGradientEx(bounds, Color(255, 255, 255, 0), Color(255, 255, 255, 0), Fade(Color(0, 0, 0, 255), guiAlpha), Fade(Color(0, 0, 0, 255 ), guiAlpha));
2728         }
2729         else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
2730 
2731         GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
2732 
2733         // Draw alpha bar: selector
2734         GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
2735         //--------------------------------------------------------------------
2736 
2737         return alpha;
2738     }
2739 
2740     // Color Bar Hue control
2741     // Returns hue value normalized [0..1]
2742     // NOTE: Other similar bars (for reference):
2743     //      Color GuiColorBarSat() [WHITE->color]
2744     //      Color GuiColorBarValue() [BLACK->color], HSV/HSL
2745     //      float GuiColorBarLuminance() [BLACK->WHITE]
2746     float GuiColorBarHue(Rectangle bounds, float hue)
2747     {
2748         GuiControlState state = guiState;
2749         Rectangle selector = Rectangle(cast(float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), cast(float)bounds.y + hue/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, cast(float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, cast(float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT));
2750 
2751         // Update control
2752         //--------------------------------------------------------------------
2753         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2754         {
2755             Vector2 mousePoint = GetMousePosition();
2756 
2757             if (CheckCollisionPointRec(mousePoint, bounds) ||
2758                 CheckCollisionPointRec(mousePoint, selector))
2759             {
2760                 if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
2761                 {
2762                     state = GUI_STATE_PRESSED;
2763 
2764                     hue = (mousePoint.y - bounds.y)*360/bounds.height;
2765                     if (hue <= 0.0f) hue = 0.0f;
2766                     if (hue >= 359.0f) hue = 359.0f;
2767 
2768                 }
2769                 else state = GUI_STATE_FOCUSED;
2770 
2771                 /*if (IsKeyDown(KEY_UP))
2772                 {
2773                     hue -= 2.0f;
2774                     if (hue <= 0.0f) hue = 0.0f;
2775                 }
2776                 else if (IsKeyDown(KEY_DOWN))
2777                 {
2778                     hue += 2.0f;
2779                     if (hue >= 360.0f) hue = 360.0f;
2780                 }*/
2781             }
2782         }
2783         //--------------------------------------------------------------------
2784 
2785         // Draw control
2786         //--------------------------------------------------------------------
2787         if (state != GUI_STATE_DISABLED)
2788         {
2789             // Draw hue bar:color bars
2790             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y), cast(int)bounds.width, cast(int)ceil(bounds.height/6),  Fade(Color(255, 0, 0, 255), guiAlpha), Fade(Color(255, 255, 0, 255), guiAlpha));
2791             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y + bounds.height/6), cast(int)bounds.width, cast(int)ceil(bounds.height/6), Fade(Color(255, 255, 0, 255), guiAlpha), Fade(Color(0, 255, 0, 255), guiAlpha));
2792             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y + 2*(bounds.height/6)), cast(int)bounds.width, cast(int)ceil(bounds.height/6), Fade(Color(0, 255, 0, 255), guiAlpha), Fade(Color(0, 255, 255, 255), guiAlpha));
2793             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y + 3*(bounds.height/6)), cast(int)bounds.width, cast(int)ceil(bounds.height/6), Fade(Color(0, 255, 255, 255), guiAlpha), Fade(Color(0, 0, 255, 255), guiAlpha));
2794             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y + 4*(bounds.height/6)), cast(int)bounds.width, cast(int)ceil(bounds.height/6), Fade(Color(0, 0, 255, 255), guiAlpha), Fade(Color(255, 0, 255, 255), guiAlpha));
2795             DrawRectangleGradientV(cast(int)bounds.x, cast(int)(bounds.y + 5*(bounds.height/6)), cast(int)bounds.width, cast(int)(bounds.height/6), Fade(Color(255, 0, 255, 255), guiAlpha), Fade(Color(255, 0, 0, 255), guiAlpha));
2796         }
2797         else DrawRectangleGradientV(cast(int)bounds.x, cast(int)bounds.y, cast(int)bounds.width, cast(int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
2798 
2799         GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
2800 
2801         // Draw hue bar: selector
2802         GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
2803         //--------------------------------------------------------------------
2804 
2805         return hue;
2806     }
2807 
2808     // Color Picker control
2809     // NOTE: It's divided in multiple controls:
2810     //      Color GuiColorPanel(Rectangle bounds, Color color)
2811     //      float GuiColorBarAlpha(Rectangle bounds, float alpha)
2812     //      float GuiColorBarHue(Rectangle bounds, float value)
2813     // NOTE: bounds define GuiColorPanel() size
2814     Color GuiColorPicker(Rectangle bounds, Color color)
2815     {
2816         color = GuiColorPanel(bounds, color);
2817 
2818         Rectangle boundsHue = Rectangle(cast(float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), cast(float)bounds.y, cast(float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), cast(float)bounds.height);
2819         //Rectangle boundsAlpha = Rectangle(bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK));
2820 
2821         Vector3 hsv = ConvertRGBtoHSV(Vector3(color.r/255.0f, color.g/255.0f, color.b/255.0f));
2822         hsv.x = GuiColorBarHue(boundsHue, hsv.x);
2823         //color.a = (ubyte)(GuiColorBarAlpha(boundsAlpha, cast(float)color.a/255.0f)*255.0f);
2824         Vector3 rgb = ConvertHSVtoRGB(hsv);
2825 
2826         color = Color(cast(ubyte)roundf(rgb.x*255.0f), cast(ubyte)roundf(rgb.y*255.0f), cast(ubyte)roundf(rgb.z*255.0f), color.a);
2827 
2828         return color;
2829     }
2830 
2831     // Message Box control
2832     int GuiMessageBox(Rectangle bounds, const(char)* title, const(char)* message, const(char)* buttons)
2833     {
2834         int clicked = -1;    // Returns clicked button from buttons list, 0 refers to closed window button
2835 
2836         int buttonCount = 0;
2837         const(char)** buttonsText = GuiTextSplit(buttons, &buttonCount, null);
2838         Rectangle buttonBounds;
2839         buttonBounds.x = bounds.x + MESSAGEBOX_BUTTON_PADDING;
2840         buttonBounds.y = bounds.y + bounds.height - MESSAGEBOX_BUTTON_HEIGHT - MESSAGEBOX_BUTTON_PADDING;
2841         buttonBounds.width = (bounds.width - MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
2842         buttonBounds.height = MESSAGEBOX_BUTTON_HEIGHT;
2843 
2844         Vector2 textSize = MeasureTextEx(guiFont, message, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), 1);
2845 
2846         Rectangle textBounds;
2847         textBounds.x = bounds.x + bounds.width/2 - textSize.x/2;
2848         textBounds.y = bounds.y + WINDOW_STATUSBAR_HEIGHT + (bounds.height - WINDOW_STATUSBAR_HEIGHT - MESSAGEBOX_BUTTON_HEIGHT - MESSAGEBOX_BUTTON_PADDING)/2 - textSize.y/2;
2849         textBounds.width = textSize.x;
2850         textBounds.height = textSize.y;
2851 
2852         // Draw control
2853         //--------------------------------------------------------------------
2854         if (GuiWindowBox(bounds, title)) clicked = 0;
2855 
2856         int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
2857         GuiSetStyle(LABEL, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
2858         GuiLabel(textBounds, message);
2859         GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
2860 
2861         prevTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
2862         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
2863 
2864         for (int i = 0; i < buttonCount; i++)
2865         {
2866             if (GuiButton(buttonBounds, buttonsText[i])) clicked = i + 1;
2867             buttonBounds.x += (buttonBounds.width + MESSAGEBOX_BUTTON_PADDING);
2868         }
2869 
2870         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevTextAlignment);
2871         //--------------------------------------------------------------------
2872 
2873         return clicked;
2874     }
2875 
2876     // Text Input Box control, ask for text
2877     int GuiTextInputBox(Rectangle bounds, const(char)* title, const(char)* message, const(char)* buttons, char* text)
2878     {
2879         // Used to enable text edit mode
2880         // WARNING: No more than one GuiTextInputBox() should be open at the same time
2881         bool textEditMode = false;
2882 
2883         int btnIndex = -1;
2884 
2885         int buttonCount = 0;
2886         const(char)** buttonsText = GuiTextSplit(buttons, &buttonCount, null);
2887         Rectangle buttonBounds;
2888         buttonBounds.x = bounds.x + TEXTINPUTBOX_BUTTON_PADDING;
2889         buttonBounds.y = bounds.y + bounds.height - TEXTINPUTBOX_BUTTON_HEIGHT - TEXTINPUTBOX_BUTTON_PADDING;
2890         buttonBounds.width = (bounds.width - TEXTINPUTBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
2891         buttonBounds.height = TEXTINPUTBOX_BUTTON_HEIGHT;
2892 
2893         int messageInputHeight = cast(int)bounds.height - WINDOW_STATUSBAR_HEIGHT - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - TEXTINPUTBOX_BUTTON_HEIGHT - 2*TEXTINPUTBOX_BUTTON_PADDING;
2894 
2895         Rectangle textBounds;
2896         if (message != null)
2897         {
2898             Vector2 textSize = MeasureTextEx(guiFont, message, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), 1);
2899 
2900             textBounds.x = bounds.x + bounds.width/2 - textSize.x/2;
2901             textBounds.y = bounds.y + WINDOW_STATUSBAR_HEIGHT + messageInputHeight/4 - textSize.y/2;
2902             textBounds.width = textSize.x;
2903             textBounds.height = textSize.y;
2904         }
2905 
2906         Rectangle textBoxBounds;
2907         textBoxBounds.x = bounds.x + TEXTINPUTBOX_BUTTON_PADDING;
2908         textBoxBounds.y = bounds.y + WINDOW_STATUSBAR_HEIGHT - TEXTINPUTBOX_HEIGHT/2;
2909         if (message == null) textBoxBounds.y += messageInputHeight/2;
2910         else textBoxBounds.y += (messageInputHeight/2 + messageInputHeight/4);
2911         textBoxBounds.width = bounds.width - TEXTINPUTBOX_BUTTON_PADDING*2;
2912         textBoxBounds.height = TEXTINPUTBOX_HEIGHT;
2913 
2914         // Draw control
2915         //--------------------------------------------------------------------
2916         if (GuiWindowBox(bounds, title)) btnIndex = 0;
2917 
2918         // Draw message if available
2919         if (message != null)
2920         {
2921             int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
2922             GuiSetStyle(LABEL, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
2923             GuiLabel(textBounds, message);
2924             GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
2925         }
2926 
2927         if (GuiTextBox(textBoxBounds, text, TEXTINPUTBOX_MAX_TEXT_LENGTH, textEditMode)) textEditMode = !textEditMode;
2928 
2929         int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
2930         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER);
2931 
2932         for (int i = 0; i < buttonCount; i++)
2933         {
2934             if (GuiButton(buttonBounds, buttonsText[i])) btnIndex = i + 1;
2935             buttonBounds.x += (buttonBounds.width + MESSAGEBOX_BUTTON_PADDING);
2936         }
2937 
2938         GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment);
2939         //--------------------------------------------------------------------
2940 
2941         return btnIndex;
2942     }
2943 
2944     // Grid control
2945     // NOTE: Returns grid mouse-hover selected cell
2946     // About drawing lines at subpixel spacing, simple put, not easy solution:
2947     // https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster
2948     Vector2 GuiGrid(Rectangle bounds, float spacing, int subdivs)
2949     {
2950         GuiControlState state = guiState;
2951         Vector2 mousePoint = GetMousePosition();
2952         Vector2 currentCell = Vector2(-1, -1);
2953 
2954         int linesV = (cast(int)(bounds.width/spacing))*subdivs + 1;
2955         int linesH = (cast(int)(bounds.height/spacing))*subdivs + 1;
2956 
2957         // Update control
2958         //--------------------------------------------------------------------
2959         if ((state != GUI_STATE_DISABLED) && !guiLocked)
2960         {
2961             if (CheckCollisionPointRec(mousePoint, bounds))
2962             {
2963                 currentCell.x = (mousePoint.x - bounds.x)/spacing;
2964                 currentCell.y = (mousePoint.y - bounds.y)/spacing;
2965             }
2966         }
2967         //--------------------------------------------------------------------
2968 
2969         // Draw control
2970         //--------------------------------------------------------------------
2971         switch (state)
2972         {
2973             case GUI_STATE_NORMAL:
2974             {
2975                 if (subdivs > 0)
2976                 {
2977                     // Draw vertical grid lines
2978                     for (int i = 0; i < linesV; i++)
2979                     {
2980                         Rectangle lineV = Rectangle(bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height);
2981                         GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
2982                     }
2983 
2984                     // Draw horizontal grid lines
2985                     for (int i = 0; i < linesH; i++)
2986                     {
2987                         Rectangle lineH = Rectangle(bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1);
2988                         GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), GRID_COLOR_ALPHA));
2989                     }
2990                 }
2991             } break;
2992             default: break;
2993         }
2994 
2995         return currentCell;
2996     }
2997 
2998     //----------------------------------------------------------------------------------
2999     // Styles loading functions
3000     //----------------------------------------------------------------------------------
3001 
3002     // Load raygui style file (.rgs)
3003     void GuiLoadStyle(const(char)* fileName)
3004     {
3005         bool tryBinary = false;
3006 
3007         // Try reading the files as text file first
3008         FILE *rgsFile = fopen(fileName, "rt");
3009 
3010         if (rgsFile != null)
3011         {
3012             char[256] buffer;
3013             fgets(cast(char*)buffer, 256, rgsFile);
3014 
3015             if (buffer[0] == '#')
3016             {
3017                 int controlId = 0;
3018                 int propertyId = 0;
3019                 uint propertyValue = 0;
3020 
3021                 while (!feof(rgsFile))
3022                 {
3023                     switch (buffer[0])
3024                     {
3025                         case 'p':
3026                         {
3027                             // Style property: p <control_id> <property_id> <property_value> <property_name>
3028 
3029                             sscanf(cast(char*)buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue);
3030 
3031                             GuiSetStyle(controlId, propertyId, cast(int)propertyValue);
3032 
3033                         } break;
3034                         case 'f':
3035                         {
3036                             // Style font: f <gen_font_size> <charmap_file> <font_file>
3037 
3038                             int fontSize = 0;
3039                             char[256] charmapFileName;
3040                             char[256] fontFileName;
3041                             sscanf(cast(char*)buffer, "f %d %s %[^\r\n]s", &fontSize, cast(char*)charmapFileName, cast(char*)fontFileName);
3042 
3043                             Font font;
3044 
3045                             if (charmapFileName[0] != '0')
3046                             {
3047                                 // Load characters from charmap file,
3048                                 // expected '\n' separated list of integer values
3049                                 char* charValues = LoadFileText(cast(char*)charmapFileName);
3050                                 if (charValues != null)
3051                                 {
3052                                     int glyphCount = 0;
3053                                     const(char)** chars = TextSplit(charValues, '\n', &glyphCount);
3054 
3055                                     int* values = cast(int*)RAYGUI_MALLOC(glyphCount*int.sizeof);
3056                                     for (int i = 0; i < glyphCount; i++) values[i] = TextToInteger(chars[i]);
3057 
3058                                     font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), cast(char*)fontFileName), fontSize, values, glyphCount);
3059 
3060                                     RAYGUI_FREE(values);
3061                                 }
3062                             }
3063                             else font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), cast(char*)fontFileName), fontSize, null, 0);
3064 
3065                             if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font);
3066 
3067                         } break;
3068                         default: break;
3069                     }
3070 
3071                     fgets(cast(char*)buffer, 256, rgsFile);
3072                 }
3073             }
3074             else tryBinary = true;
3075 
3076             fclose(rgsFile);
3077         }
3078 
3079         if (tryBinary)
3080         {
3081             rgsFile = fopen(fileName, "rb");
3082 
3083             if (rgsFile == null) return;
3084 
3085             char[5] signature = "";
3086             short _version = 0;
3087             short reserved = 0;
3088             int propertyCount = 0;
3089 
3090             fread(cast(char*)signature, 1, 4, rgsFile);
3091             fread(&_version, 1, short.sizeof, rgsFile);
3092             fread(&reserved, 1, short.sizeof, rgsFile);
3093             fread(&propertyCount, 1, int.sizeof, rgsFile);
3094 
3095             if ((signature[0] == 'r') &&
3096                 (signature[1] == 'G') &&
3097                 (signature[2] == 'S') &&
3098                 (signature[3] == ' '))
3099             {
3100                 short controlId = 0;
3101                 short propertyId = 0;
3102                 int propertyValue = 0;
3103 
3104                 for (int i = 0; i < propertyCount; i++)
3105                 {
3106                     fread(&controlId, 1, short.sizeof, rgsFile);
3107                     fread(&propertyId, 1, short.sizeof, rgsFile);
3108                     fread(&propertyValue, 1, int.sizeof, rgsFile);
3109 
3110                     if (controlId == 0) // DEFAULT control
3111                     {
3112                         // If a DEFAULT property is loaded, it is propagated to all controls
3113                         // NOTE: All DEFAULT properties should be defined first in the file
3114                         GuiSetStyle(0, cast(int)propertyId, propertyValue);
3115 
3116                         if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int n = 1; n < RAYGUI_MAX_CONTROLS; n++) GuiSetStyle(n, cast(int)propertyId, propertyValue);
3117                     }
3118                     else GuiSetStyle(cast(int)controlId, cast(int)propertyId, propertyValue);
3119                 }
3120 
3121                 // Font loading is highly dependant on raylib API to load font data and image
3122 
3123                 // Load custom font if available
3124                 int fontDataSize = 0;
3125                 fread(&fontDataSize, 1, int.sizeof, rgsFile);
3126 
3127                 if (fontDataSize > 0)
3128                 {
3129                     Font font;
3130                     int fontType = 0;   // 0-Normal, 1-SDF
3131                     Rectangle whiteRec;
3132 
3133                     fread(&font.baseSize, 1, int.sizeof, rgsFile);
3134                     fread(&font.glyphCount, 1, int.sizeof, rgsFile);
3135                     fread(&fontType, 1, int.sizeof, rgsFile);
3136 
3137                     // Load font white rectangle
3138                     fread(&whiteRec, 1, Rectangle.sizeof, rgsFile);
3139 
3140                     // Load font image parameters
3141                     int fontImageSize = 0;
3142                     fread(&fontImageSize, 1, int.sizeof, rgsFile);
3143 
3144                     if (fontImageSize > 0)
3145                     {
3146                         Image imFont;
3147                         imFont.mipmaps = 1;
3148                         fread(&imFont.width, 1, int.sizeof, rgsFile);
3149                         fread(&imFont.height, 1, int.sizeof, rgsFile);
3150                         fread(&imFont.format, 1, int.sizeof, rgsFile);
3151 
3152                         imFont.data = cast(ubyte*)RAYGUI_MALLOC(fontImageSize);
3153                         fread(imFont.data, 1, fontImageSize, rgsFile);
3154 
3155                         font.texture = LoadTextureFromImage(imFont);
3156 
3157                         RAYGUI_FREE(imFont.data);
3158                     }
3159 
3160                     // Load font recs data
3161                     font.recs = cast(Rectangle*)RAYGUI_CALLOC(font.glyphCount, Rectangle.sizeof);
3162                     for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], 1, Rectangle.sizeof, rgsFile);
3163 
3164                     // Load font chars info data
3165                     font.glyphs = cast(GlyphInfo*)RAYGUI_CALLOC(font.glyphCount, GlyphInfo.sizeof);
3166                     for (int i = 0; i < font.glyphCount; i++)
3167                     {
3168                         fread(&font.glyphs[i].value, 1, int.sizeof, rgsFile);
3169                         fread(&font.glyphs[i].offsetX, 1, int.sizeof, rgsFile);
3170                         fread(&font.glyphs[i].offsetY, 1, int.sizeof, rgsFile);
3171                         fread(&font.glyphs[i].advanceX, 1, int.sizeof, rgsFile);
3172                     }
3173 
3174                     GuiSetFont(font);
3175 
3176                     // Set font texture source rectangle to be used as white texture to draw shapes
3177                     // NOTE: This way, all gui can be draw using a single draw call
3178                     if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
3179                 }
3180             }
3181 
3182             fclose(rgsFile);
3183         }
3184     }
3185 
3186     // Load style default over global style
3187     void GuiLoadStyleDefault()
3188     {
3189         // We set this variable first to avoid cyclic function calls
3190         // when calling GuiSetStyle() and GuiGetStyle()
3191         guiStyleLoaded = true;
3192 
3193         // Initialize default LIGHT style property values
3194         GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff);
3195         GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff);
3196         GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff);
3197         GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff);
3198         GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff);
3199         GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff);
3200         GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff);
3201         GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff);
3202         GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff);
3203         GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff);
3204         GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff);
3205         GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff);
3206         GuiSetStyle(DEFAULT, BORDER_WIDTH, 1);                       // WARNING: Some controls use other values
3207         GuiSetStyle(DEFAULT, TEXT_PADDING, 0);                       // WARNING: Some controls use other values
3208         GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_CENTER); // WARNING: Some controls use other values
3209 
3210         // Initialize control-specific property values
3211         // NOTE: Those properties are in default list but require specific values by control type
3212         GuiSetStyle(LABEL, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_LEFT);
3213         GuiSetStyle(BUTTON, BORDER_WIDTH, 2);
3214         GuiSetStyle(SLIDER, TEXT_PADDING, 5);
3215         GuiSetStyle(CHECKBOX, TEXT_PADDING, 5);
3216         GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_RIGHT);
3217         GuiSetStyle(TEXTBOX, TEXT_PADDING, 5);
3218         GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_LEFT);
3219         GuiSetStyle(VALUEBOX, TEXT_PADDING, 4);
3220         GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_LEFT);
3221         GuiSetStyle(SPINNER, TEXT_PADDING, 4);
3222         GuiSetStyle(SPINNER, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_LEFT);
3223         GuiSetStyle(STATUSBAR, TEXT_PADDING, 6);
3224         GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, GUI_TEXT_ALIGN_LEFT);
3225 
3226         // Initialize extended property values
3227         // NOTE: By default, extended property values are initialized to 0
3228         GuiSetStyle(DEFAULT, TEXT_SIZE, 10);                // DEFAULT, shared by all controls
3229         GuiSetStyle(DEFAULT, TEXT_SPACING, 1);              // DEFAULT, shared by all controls
3230         GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff);       // DEFAULT specific property
3231         GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property
3232         GuiSetStyle(TOGGLE, GROUP_PADDING, 2);
3233         GuiSetStyle(SLIDER, SLIDER_WIDTH, 15);
3234         GuiSetStyle(SLIDER, SLIDER_PADDING, 1);
3235         GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1);
3236         GuiSetStyle(CHECKBOX, CHECK_PADDING, 1);
3237         GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 30);
3238         GuiSetStyle(COMBOBOX, COMBO_BUTTON_PADDING, 2);
3239         GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
3240         GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_PADDING, 2);
3241         GuiSetStyle(TEXTBOX, TEXT_LINES_PADDING, 5);
3242         GuiSetStyle(TEXTBOX, TEXT_INNER_PADDING, 4);
3243         GuiSetStyle(TEXTBOX, COLOR_SELECTED_FG, 0xf0fffeff);
3244         GuiSetStyle(TEXTBOX, COLOR_SELECTED_BG, 0x839affe0);
3245         GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 20);
3246         GuiSetStyle(SPINNER, SPIN_BUTTON_PADDING, 2);
3247         GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0);
3248         GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0);
3249         GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6);
3250         GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0);
3251         GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16);
3252         GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0);
3253         GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 10);
3254         GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 0x1e);
3255         GuiSetStyle(LISTVIEW, LIST_ITEMS_PADDING, 2);
3256         GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 10);
3257         GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE);
3258         GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 6);
3259         GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 0x14);
3260         GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 0xa);
3261         GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 6);
3262         GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2);
3263 
3264         guiFont = GetFontDefault();     // Initialize default font
3265     }
3266 
3267     // Get text with icon id prepended
3268     // NOTE: Useful to add icons by name id (enum) instead of
3269     // a number that can change between ricon versions
3270     const(char)* GuiIconText(int iconId, const(char)* text)
3271     {
3272         version(RAYGUI_NO_RICONS) return null;
3273         else {
3274             char[1024] buffer;
3275             memset(cast(char*)buffer, 0, 1024);
3276 
3277             sprintf(cast(char*)buffer, "#%03i#", iconId);
3278 
3279             if (text != null)
3280             {
3281                 for (int i = 5; i < 1024; i++)
3282                 {
3283                     buffer[i] = text[i - 5];
3284                     if (text[i - 5] == '\0') break;
3285                 }
3286             }
3287 
3288             const(char)* ret = cast(const(char)*)buffer;
3289             return ret;
3290         }
3291     }
3292 
3293 version(RAYGUI_NO_RICONS) {} else {
3294     // Get full icons data pointer
3295     uint* GuiGetIcons() { return cast(uint*)guiIcons; }
3296 
3297     // Load raygui icons file (.rgi)
3298     // NOTE: In case nameIds are required, they can be requested with loadIconsName,
3299     // they are returned as a guiIconsName[iconCount][RICON_MAX_NAME_LENGTH],
3300     // WARNING: guiIconsName[]][] memory should be manually freed!
3301     char** GuiLoadIcons(const(char)* fileName, bool loadIconsName)
3302     {
3303         // Style File Structure (.rgi)
3304         // ------------------------------------------------------
3305         // Offset  | Size    | Type       | Description
3306         // ------------------------------------------------------
3307         // 0       | 4       | char       | Signature: "rGI "
3308         // 4       | 2       | short      | Version: 100
3309         // 6       | 2       | short      | reserved
3310 
3311         // 8       | 2       | short      | Num icons (N)
3312         // 10      | 2       | short      | Icons size (Options: 16, 32, 64) (S)
3313 
3314         // Icons name id (32 bytes per name id)
3315         // foreach (icon)
3316         // {
3317         //   12+32*i  | 32   | char       | Icon NameId
3318         // }
3319 
3320         // Icons data: One bit per pixel, stored as uint array (depends on icon size)
3321         // S*S pixels/32bit per uint = K uint per icon
3322         // foreach (icon)
3323         // {
3324         //   ...   | K       | uint | Icon Data
3325         // }
3326 
3327         FILE *rgiFile = fopen(fileName, "rb");
3328 
3329         char** guiIconsName = null;
3330 
3331         if (rgiFile != null)
3332         {
3333             char[5] signature = "";
3334             short _version = 0;
3335             short reserved = 0;
3336             short iconCount = 0;
3337             short iconSize = 0;
3338 
3339             fread(cast(char*)signature, 1, 4, rgiFile);
3340             fread(&_version, 1, short.sizeof, rgiFile);
3341             fread(&reserved, 1, short.sizeof, rgiFile);
3342             fread(&iconCount, 1, short.sizeof, rgiFile);
3343             fread(&iconSize, 1, short.sizeof, rgiFile);
3344 
3345             if ((signature[0] == 'r') &&
3346                 (signature[1] == 'G') &&
3347                 (signature[2] == 'I') &&
3348                 (signature[3] == ' '))
3349             {
3350                 if (loadIconsName)
3351                 {
3352                     guiIconsName = cast(char**)RAYGUI_MALLOC(iconCount*(char**).sizeof);
3353                     for (int i = 0; i < iconCount; i++)
3354                     {
3355                         guiIconsName[i] = cast(char*)RAYGUI_MALLOC(RICON_MAX_NAME_LENGTH);
3356                         fread(guiIconsName[i], RICON_MAX_NAME_LENGTH, 1, rgiFile);
3357                     }
3358                 }
3359                 else fseek(rgiFile, iconCount*RICON_MAX_NAME_LENGTH, SEEK_CUR);
3360 
3361                 // Read icons data directly over guiIcons data array
3362                 fread(cast(uint*)guiIcons, iconCount*(iconSize*iconSize/32), uint.sizeof, rgiFile);
3363             }
3364 
3365             fclose(rgiFile);
3366         }
3367 
3368         return guiIconsName;
3369     }
3370 
3371     // Draw selected icon using rectangles pixel-by-pixel
3372     void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color)
3373     {
3374         bool BIT_CHECK(T,N)(T a, N b) { return (a & cast(T)(1<<(b))) != 0; }
3375 
3376         for (int i = 0, y = 0; i < RICON_SIZE*RICON_SIZE/32; i++)
3377         {
3378             for (int k = 0; k < 32; k++)
3379             {
3380                 if (BIT_CHECK(guiIcons[iconId*RICON_DATA_ELEMENTS + i], k))
3381                 {
3382                     DrawRectangle(posX + (k%RICON_SIZE)*pixelSize, posY + y*pixelSize, pixelSize, pixelSize, color);
3383                 }
3384 
3385                 if ((k == 15) || (k == 31)) y++;
3386             }
3387         }
3388     }
3389 
3390     // Get icon bit data
3391     // NOTE: Bit data array grouped as uint (ICON_SIZE*ICON_SIZE/32 elements)
3392     uint* GuiGetIconData(int iconId)
3393     {
3394         uint[RICON_DATA_ELEMENTS] iconData;
3395         memset(cast(uint*)iconData, 0, RICON_DATA_ELEMENTS*uint.sizeof);
3396 
3397         if (iconId < RICON_MAX_ICONS) memcpy(cast(uint*)iconData, &guiIcons[iconId*RICON_DATA_ELEMENTS], RICON_DATA_ELEMENTS*uint.sizeof);
3398 
3399         auto ret = cast(uint*)iconData;
3400         return ret;
3401     }
3402 
3403     // Set icon bit data
3404     // NOTE: Data must be provided as uint array (ICON_SIZE*ICON_SIZE/32 elements)
3405     void GuiSetIconData(int iconId, uint* data)
3406     {
3407         if (iconId < RICON_MAX_ICONS) memcpy(&guiIcons[iconId*RICON_DATA_ELEMENTS], data, RICON_DATA_ELEMENTS*uint.sizeof);
3408     }
3409 
3410     // Set icon pixel value
3411     void GuiSetIconPixel(int iconId, int x, int y)
3412     {
3413         void BIT_SET(T,N)(out T a, N b)   { (a) |= (1<<(b)); }
3414 
3415         // This logic works for any RICON_SIZE pixels icons,
3416         // For example, in case of 16x16 pixels, every 2 lines fit in one uint data element
3417         BIT_SET(guiIcons[iconId*RICON_DATA_ELEMENTS + y/(uint.sizeof*8/RICON_SIZE)], x + (y%(uint.sizeof*8/RICON_SIZE)*RICON_SIZE));
3418     }
3419 
3420     // Clear icon pixel value
3421     void GuiClearIconPixel(int iconId, int x, int y)
3422     {
3423         void BIT_CLEAR(T,N)(out T a, N b) { (a) &= ~((1)<<(b)); }
3424 
3425         // This logic works for any RICON_SIZE pixels icons,
3426         // For example, in case of 16x16 pixels, every 2 lines fit in one uint data element
3427         BIT_CLEAR(guiIcons[iconId*RICON_DATA_ELEMENTS + y/(uint.sizeof*8/RICON_SIZE)], x + (y%(uint.sizeof*8/RICON_SIZE)*RICON_SIZE));
3428     }
3429 
3430     // Check icon pixel value
3431     bool GuiCheckIconPixel(int iconId, int x, int y)
3432     {
3433         bool BIT_CHECK(T,N)(T a, N b) { return (a & cast(T)(1<<(b))) != 0; }
3434 
3435         return (BIT_CHECK(guiIcons[iconId*8 + y/2], x + (y%2*16)));
3436     }
3437 }
3438 
3439     //----------------------------------------------------------------------------------
3440     // Module specific Functions Definition
3441     //----------------------------------------------------------------------------------
3442     // Gui get text width using default font
3443     // NOTE: Icon is not considered here
3444     int GetTextWidth(const(char)* text)
3445     {
3446         Vector2 size;
3447 
3448         if ((text != null) && (text[0] != '\0'))
3449         {
3450             size = MeasureTextEx(guiFont, text, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), cast(float)GuiGetStyle(DEFAULT, TEXT_SPACING));
3451         }
3452 
3453         return cast(int)size.x;
3454     }
3455 
3456     // Get text bounds considering control bounds
3457     Rectangle GetTextBounds(int control, Rectangle bounds)
3458     {
3459         Rectangle textBounds = bounds;
3460 
3461         textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH);
3462         textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH);
3463         textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH);
3464         textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH);
3465 
3466         // Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT
3467         switch (control)
3468         {
3469             case COMBOBOX: bounds.width -= (GuiGetStyle(control, COMBO_BUTTON_WIDTH) + GuiGetStyle(control, COMBO_BUTTON_PADDING)); break;
3470             case VALUEBOX: break;   // NOTE: ValueBox text value always centered, text padding applies to label
3471             default:
3472             {
3473                 if (GuiGetStyle(control, TEXT_ALIGNMENT) == GUI_TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
3474                 else textBounds.x += GuiGetStyle(control, TEXT_PADDING);
3475             } break;
3476         }
3477 
3478         // TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
3479         // More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
3480 
3481         return textBounds;
3482     }
3483 
3484     // Get text icon if provided and move text cursor
3485     // NOTE: We support up to 999 values for iconId
3486     const(char)* GetTextIcon(const(char)* text, int* iconId)
3487     {
3488         version(RAYGUI_NO_RICONS) {} else {
3489             *iconId = -1;
3490             if (text[0] == '#')     // Maybe we have an icon!
3491             {
3492                 char[4] iconValue;  // Maximum length for icon value: 3 digits + '\0'
3493 
3494                 int pos = 1;
3495                 while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9'))
3496                 {
3497                     iconValue[pos - 1] = text[pos];
3498                     pos++;
3499                 }
3500 
3501                 if (text[pos] == '#')
3502                 {
3503                     *iconId = TextToInteger(cast(char*)iconValue);
3504 
3505                     // Move text pointer after icon
3506                     // WARNING: If only icon provided, it could point to EOL character: '\0'
3507                     if (*iconId >= 0) text += (pos + 1);
3508                 }
3509             }
3510         }
3511 
3512         return text;
3513     }
3514 
3515     // Gui draw text using default font
3516     void GuiDrawText(const(char)* text, Rectangle bounds, int alignment, Color tint)
3517     {
3518         int TEXT_VALIGN_PIXEL_OFFSET(T)(T h)  { return cast(int)(h%2);}     // Vertical alignment for pixel perfect
3519 
3520         if ((text != null) && (text[0] != '\0'))
3521         {
3522             int iconId = 0;
3523             text = GetTextIcon(text, &iconId);              // Check text for icon and move cursor
3524 
3525             // Get text position depending on alignment and iconId
3526             //---------------------------------------------------------------------------------
3527             Vector2 position = Vector2(bounds.x, bounds.y);
3528 
3529             // NOTE: We get text size after icon has been processed
3530             int textWidth = GetTextWidth(text);
3531             int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE);
3532 
3533             // If text requires an icon, add size to measure
3534             if (iconId >= 0)
3535             {
3536                 textWidth += RICON_SIZE;
3537 
3538                 // WARNING: If only icon provided, text could be pointing to EOF character: '\0'
3539                 if ((text != null) && (text[0] != '\0')) textWidth += RICON_TEXT_PADDING;
3540             }
3541 
3542             // Check guiTextAlign global variables
3543             switch (alignment)
3544             {
3545                 case GUI_TEXT_ALIGN_LEFT:
3546                 {
3547                     position.x = bounds.x;
3548                     position.y = bounds.y + bounds.height/2 - textHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
3549                 } break;
3550                 case GUI_TEXT_ALIGN_CENTER:
3551                 {
3552                     position.x = bounds.x + bounds.width/2 - textWidth/2;
3553                     position.y = bounds.y + bounds.height/2 - textHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
3554                 } break;
3555                 case GUI_TEXT_ALIGN_RIGHT:
3556                 {
3557                     position.x = bounds.x + bounds.width - textWidth;
3558                     position.y = bounds.y + bounds.height/2 - textHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
3559                 } break;
3560                 default: break;
3561             }
3562 
3563             // NOTE: Make sure we get pixel-perfect coordinates,
3564             // In case of decimals we got weird text positioning
3565             position.x = cast(float)(cast(int)position.x);
3566             position.y = cast(float)(cast(int)position.y);
3567             //---------------------------------------------------------------------------------
3568 
3569             // Draw text (with icon if available)
3570             //---------------------------------------------------------------------------------
3571             version(RAYGUI_NO_RICONS) {} else {
3572                 if (iconId >= 0)
3573                 {
3574                     // NOTE: We consider icon height, probably different than text size
3575                     GuiDrawIcon(iconId, cast(int)position.x, cast(int)(bounds.y + bounds.height/2 - RICON_SIZE/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height)), 1, tint);
3576                     position.x += (RICON_SIZE + RICON_TEXT_PADDING);
3577                 }
3578             }
3579             DrawTextEx(guiFont, text, position, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), cast(float)GuiGetStyle(DEFAULT, TEXT_SPACING), tint);
3580             //---------------------------------------------------------------------------------
3581         }
3582     }
3583 
3584     // Gui draw rectangle using default raygui plain style with borders
3585     void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color)
3586     {
3587         if (color.a > 0)
3588         {
3589             // Draw rectangle filled with color
3590             DrawRectangle(cast(int)rec.x, cast(int)rec.y, cast(int)rec.width, cast(int)rec.height, color);
3591         }
3592 
3593         if (borderWidth > 0)
3594         {
3595             // Draw rectangle border lines with color
3596             DrawRectangle(cast(int)rec.x, cast(int)rec.y, cast(int)rec.width, borderWidth, borderColor);
3597             DrawRectangle(cast(int)rec.x, cast(int)rec.y + borderWidth, borderWidth, cast(int)rec.height - 2*borderWidth, borderColor);
3598             DrawRectangle(cast(int)rec.x + cast(int)rec.width - borderWidth, cast(int)rec.y + borderWidth, borderWidth, cast(int)rec.height - 2*borderWidth, borderColor);
3599             DrawRectangle(cast(int)rec.x, cast(int)rec.y + cast(int)rec.height - borderWidth, cast(int)rec.width, borderWidth, borderColor);
3600         }
3601     }
3602 
3603     // Split controls text into multiple strings
3604     // Also check for multiple columns (required by GuiToggleGroup())
3605     const(char)** GuiTextSplit(const(char)* text, int* count, int* textRow)
3606     {
3607         // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
3608         // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
3609         // all used memory is static... it has some limitations:
3610         //      1. Maximum number of possible split strings is set by TEXTSPLIT_MAX_TEXT_ELEMENTS
3611         //      2. Maximum size of text to split is TEXTSPLIT_MAX_TEXT_LENGTH
3612         // NOTE: Those definitions could be externally provided if required
3613         const(char)*[TEXTSPLIT_MAX_TEXT_ELEMENTS] result;
3614         char[TEXTSPLIT_MAX_TEXT_LENGTH] buffer;
3615         memset(cast(char*)buffer, 0, TEXTSPLIT_MAX_TEXT_LENGTH);
3616 
3617         result[0] = cast(const(char)*)buffer;
3618         int counter = 1;
3619 
3620         if (textRow != null) textRow[0] = 0;
3621 
3622         // Count how many substrings we have on text and point to every one
3623         for (int i = 0; i < TEXTSPLIT_MAX_TEXT_LENGTH; i++)
3624         {
3625             buffer[i] = text[i];
3626             if (buffer[i] == '\0') break;
3627             else if ((buffer[i] == ';') || (buffer[i] == '\n'))
3628             {
3629                 result[counter] = cast(const(char)*)(cast(void*)buffer + i + 1);
3630 
3631                 if (textRow != null)
3632                 {
3633                     if (buffer[i] == '\n') textRow[counter] = textRow[counter - 1] + 1;
3634                     else textRow[counter] = textRow[counter - 1];
3635                 }
3636 
3637                 buffer[i] = '\0';   // Set an end of string at this point
3638 
3639                 counter++;
3640                 if (counter == TEXTSPLIT_MAX_TEXT_ELEMENTS) break;
3641             }
3642         }
3643 
3644         *count = counter;
3645 
3646         auto ret = cast(const(char)**) result;
3647         return ret;
3648     }
3649 
3650     // Convert color data from RGB to HSV
3651     // NOTE: Color data should be passed normalized
3652     Vector3 ConvertRGBtoHSV(Vector3 rgb)
3653     {
3654         Vector3 hsv;
3655         float min = 0.0f;
3656         float max = 0.0f;
3657         float delta = 0.0f;
3658 
3659         min = (rgb.x < rgb.y)? rgb.x : rgb.y;
3660         min = (min < rgb.z)? min  : rgb.z;
3661 
3662         max = (rgb.x > rgb.y)? rgb.x : rgb.y;
3663         max = (max > rgb.z)? max  : rgb.z;
3664 
3665         hsv.z = max;            // Value
3666         delta = max - min;
3667 
3668         if (delta < 0.00001f)
3669         {
3670             hsv.y = 0.0f;
3671             hsv.x = 0.0f;           // Undefined, maybe NAN?
3672             return hsv;
3673         }
3674 
3675         if (max > 0.0f)
3676         {
3677             // NOTE: If max is 0, this divide would cause a crash
3678             hsv.y = (delta/max);    // Saturation
3679         }
3680         else
3681         {
3682             // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
3683             hsv.y = 0.0f;
3684             hsv.x = 0.0f;           // Undefined, maybe NAN?
3685             return hsv;
3686         }
3687 
3688         // NOTE: Comparing float values could not work properly
3689         if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta;    // Between yellow & magenta
3690         else
3691         {
3692             if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta;  // Between cyan & yellow
3693             else hsv.x = 4.0f + (rgb.x - rgb.y)/delta;      // Between magenta & cyan
3694         }
3695 
3696         hsv.x *= 60.0f;     // Convert to degrees
3697 
3698         if (hsv.x < 0.0f) hsv.x += 360.0f;
3699 
3700         return hsv;
3701     }
3702 
3703     // Convert color data from HSV to RGB
3704     // NOTE: Color data should be passed normalized
3705     Vector3 ConvertHSVtoRGB(Vector3 hsv)
3706     {
3707         Vector3 rgb;
3708         float hh = 0.0f, p = 0.0f, q = 0.0f, t = 0.0f, ff = 0.0f;
3709         long i = 0;
3710 
3711         // NOTE: Comparing float values could not work properly
3712         if (hsv.y <= 0.0f)
3713         {
3714             rgb.x = hsv.z;
3715             rgb.y = hsv.z;
3716             rgb.z = hsv.z;
3717             return rgb;
3718         }
3719 
3720         hh = hsv.x;
3721         if (hh >= 360.0f) hh = 0.0f;
3722         hh /= 60.0f;
3723 
3724         i = cast(long)hh;
3725         ff = hh - i;
3726         p = hsv.z*(1.0f - hsv.y);
3727         q = hsv.z*(1.0f - (hsv.y*ff));
3728         t = hsv.z*(1.0f - (hsv.y*(1.0f - ff)));
3729 
3730         switch (i)
3731         {
3732             case 0:
3733             {
3734                 rgb.x = hsv.z;
3735                 rgb.y = t;
3736                 rgb.z = p;
3737             } break;
3738             case 1:
3739             {
3740                 rgb.x = q;
3741                 rgb.y = hsv.z;
3742                 rgb.z = p;
3743             } break;
3744             case 2:
3745             {
3746                 rgb.x = p;
3747                 rgb.y = hsv.z;
3748                 rgb.z = t;
3749             } break;
3750             case 3:
3751             {
3752                 rgb.x = p;
3753                 rgb.y = q;
3754                 rgb.z = hsv.z;
3755             } break;
3756             case 4:
3757             {
3758                 rgb.x = t;
3759                 rgb.y = p;
3760                 rgb.z = hsv.z;
3761             } break;
3762             case 5:
3763             default:
3764             {
3765                 rgb.x = hsv.z;
3766                 rgb.y = p;
3767                 rgb.z = q;
3768             } break;
3769         }
3770 
3771         return rgb;
3772     }