diff --git a/dub.json b/dub.json index f5a92b9..536c1dc 100644 --- a/dub.json +++ b/dub.json @@ -3,25 +3,33 @@ "description": "D binding for Raylib", "license": "Zlib", "authors": [ - "ONROUNDIT" + "ONROUNDIT", + "Steven Schveighoffer", + "Liam McGillivray" ], - "configurations" : [ - { - "name": "library" - }, - { - "name": "unittest", - "versions" : ["raylib_test"], - "libs" : ["raylib"], - "lflags-posix": ["-L."], - "lflags-osx": ["-rpath", "@executable_path/"], - "lflags-linux" : ["-rpath=$$ORIGIN"] - } - ], + "configurations" : [ + { + "name": "library" + }, + { + "name": "unittest", + "versions" : ["raylib_test"], + "libs" : ["raylib"], + "lflags-posix": ["-L."], + "lflags-osx": ["-rpath", "@executable_path/"], + "lflags-linux" : ["-rpath=$$ORIGIN"] + } + ], "copyright": "Copyright (c) Ramon Santamaria (@raysan5), Petro Romanovych (@onroundit), Jan Hoenig (@m3m0ry), Steven Schveighoffer (@schveiguy), Liam McGillivray (@LiamM32)", "excludedSourceFiles": ["source/rlgl.d", "source/raymath.d", "source/easings.d", "source/raymathext.d", "source/raylib_types.d"], "targetType": "sourceLibrary", - "subPackages" : [ - "install" - ] + "libs": ["raylib"], + "subPackages": [ + { + "name": "raygui", + "targetType": "sourceLibrary", + "dependencies": {"raylib-d": {"path": "."}}, + "sourceFiles": ["source/raygui.d"] + } + ] } diff --git a/example/dub.json b/example/dub.json index ce626b7..c593fcf 100644 --- a/example/dub.json +++ b/example/dub.json @@ -6,10 +6,8 @@ "dependencies": { "raylib-d": {"path": "../"} }, - "libs": [ - "raylib" - ], - "description": "A minimal D application.", + "description": "'Hello World' example", "license": "Zlib", - "name": "example" + "name": "example", + "mainSourceFile": "source/app.d" } diff --git a/rayguiexample/dub.json b/rayguiexample/dub.json index dc83e2b..f9184fe 100644 --- a/rayguiexample/dub.json +++ b/rayguiexample/dub.json @@ -5,12 +5,14 @@ "dependencies" : { "raylib-d" : { "path" : "../" + }, + "raylib-d:raygui" : { + "path" : "../" } }, "description": "D port of raygui example controls_test_suite", "license": "zlib", "name": "rayguiexample", - "libs": ["raylib"], "lflags-posix": ["-L."], "lflags-osx": ["-rpath", "@executable_path/"], "buildOptions": ["betterC"] diff --git a/rayguiexample/source/app.d b/rayguiexample/source/app.d index 128d58d..0cdeae7 100644 --- a/rayguiexample/source/app.d +++ b/rayguiexample/source/app.d @@ -15,7 +15,6 @@ extern(C): __gshared: * - GuiComboBox() * - GuiListView() * - GuiToggleGroup() -* - GuiTextBoxMulti() * - GuiColorPicker() * - GuiSlider() * - GuiSliderBar() @@ -23,13 +22,9 @@ extern(C): __gshared: * - GuiColorBarAlpha() * - GuiScrollPanel() * -* * DEPENDENCIES: -* raylib 4.0 - Windowing/input management and drawing. -* raygui 3.2 - Immediate-mode GUI controls. -* -* COMPILATION (Windows - MinGW): -* gcc -o $(NAME_PART).exe $(FILE_NAME) -I../../src -lraylib -lopengl32 -lgdi32 -std=c99 +* Raylib-D +* raylib 4.5 * * LICENSE: zlib/libpng * @@ -40,8 +35,6 @@ extern(C): __gshared: import raylib; version = RAYGUI_IMPLEMENTATION; -//#define RAYGUI_CUSTOM_ICONS // It requires providing gui_icons.h in the same directory -//#include "gui_icons.h" // External icons data provided, it can be generated with rGuiIcons tool import raygui; public import core.stdc.string; // Required for: strcpy() @@ -124,9 +117,9 @@ int main() { //---------------------------------------------------------------------------------- exitWindow = WindowShouldClose(); - if (IsKeyPressed(KeyboardKey.KEY_ESCAPE)) showMessageBox = !showMessageBox; + if (IsKeyPressed(KeyboardKey.ESCAPE)) showMessageBox = !showMessageBox; - if (IsKeyDown(KeyboardKey.KEY_LEFT_CONTROL) && IsKeyPressed(KeyboardKey.KEY_S)) showTextInputBox = true; + if (IsKeyDown(KeyboardKey.LEFT_CONTROL) && IsKeyPressed(KeyboardKey.KEY_S)) showTextInputBox = true; if (IsFileDropped()) { @@ -146,9 +139,8 @@ int main() { // raygui: controls drawing //---------------------------------------------------------------------------------- + // Check all possible events that require GuiLock if (dropDown000EditMode || dropDown001EditMode) GuiLock(); - else if (!dropDown000EditMode && !dropDown001EditMode) GuiUnlock(); - //GuiDisable(); // First GUI column //GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); @@ -177,6 +169,7 @@ int main() { comboBoxActive = GuiComboBox(Rectangle( 25, 470, 125, 30 ), "ONE;TWO;THREE;FOUR", comboBoxActive); // NOTE: GuiDropdownBox must draw after any other control that can be covered on unfolding + GuiUnlock; GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); if (GuiDropdownBox(Rectangle( 25, 65, 125, 30 ), "#01#ONE;#02#TWO;#03#THREE;#04#FOUR", &dropdownBox001Active, dropDown001EditMode)) dropDown001EditMode = !dropDown001EditMode; @@ -190,7 +183,7 @@ int main() { toggleGroupActive = GuiToggleGroup(Rectangle( 165, 400, 140, 25 ), "#1#ONE\n#3#TWO\n#8#THREE\n#23#", toggleGroupActive); // Third GUI column - if (GuiTextBoxMulti(Rectangle( 320, 25, 225, 140 ), multiTextBoxText.ptr, 256, multiTextBoxEditMode)) multiTextBoxEditMode = !multiTextBoxEditMode; + GuiPanel(Rectangle( 320, 25, 225, 140 ), "Panel Info"); colorPickerValue = GuiColorPicker(Rectangle( 320, 185, 196, 192 ), null, colorPickerValue); sliderValue = cast(int)GuiSlider(Rectangle( 355, 400, 165, 20 ), "TEST", TextFormat("%2.2f", cast(float)sliderValue), sliderValue, -50, 100); @@ -198,11 +191,11 @@ int main() { progressValue = GuiProgressBar(Rectangle( 320, 460, 200, 20 ), null, null, progressValue, 0, 1); // NOTE: View rectangle could be used to perform some scissor test - Rectangle view = GuiScrollPanel(Rectangle( 560, 25, 100, 160 ), null, Rectangle( 560, 25, 200, 400 ), &viewScroll); + Rectangle view = GuiScrollPanel(Rectangle( 560, 25, 102, 354 ), null, Rectangle( 560, 25, 200, 400 ), &viewScroll); GuiPanel(Rectangle( 560, 25 + 180, 100, 160 ), "Panel Info"); - GuiGrid(Rectangle( 560, 25 + 180 + 180, 100, 120 ), null, 20, 2); + GuiGrid(Rectangle( 560, 25 + 195 + 180, 100, 120 ), null, 20, 2); GuiStatusBar(Rectangle( 0, cast(float)GetScreenHeight() - 20, cast(float)GetScreenWidth(), 20 ), "This is a status bar"); diff --git a/source/raygui.d b/source/raygui.d index 784aa42..ffaa648 100644 --- a/source/raygui.d +++ b/source/raygui.d @@ -1,14 +1,11 @@ module raygui; -enum enumMixin(Enum) = { - assert(__ctfe); - string result; - foreach(m; __traits(allMembers, Enum)) +template enumAlias(alias Enum) { + static foreach(m; __traits(allMembers, Enum)) static if (!__traits(isDeprecated, __traits(getMember, Enum, m))) { - result ~= "alias " ~ m ~ " = " ~ Enum.stringof ~ "." ~ m ~ ";"; + mixin("alias "~m~" = __traits(getMember, Enum, m);"); } - return result; -}(); +}; @nogc nothrow extern(C) __gshared: private template HasVersion(string versionId) { @@ -17,7 +14,7 @@ private template HasVersion(string versionId) { import core.stdc.config: c_long, c_ulong; /******************************************************************************************* * -* raygui v3.5-dev - A simple and easy-to-use immediate-mode gui library +* raygui v3.5 - A simple and easy-to-use immediate-mode gui library * * DESCRIPTION: * @@ -106,27 +103,6 @@ import core.stdc.config: c_long, c_ulong; * * TOOL: rGuiIcons is a visual tool to customize raygui icons and create new ones. * -* -* CONFIGURATION: -* -* #define RAYGUI_IMPLEMENTATION -* Generates the implementation of the library into the included file. -* If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. -* -* #define RAYGUI_STANDALONE -* Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined -* internally in the library and input management and drawing functions must be provided by -* the user (check library implementation for further details). -* -* #define RAYGUI_NO_ICONS -* Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB) -* -* #define RAYGUI_CUSTOM_ICONS -* Includes custom ricons.h header defining a set of custom icons, -* this file can be generated using rGuiIcons tool -* -* * VERSIONS HISTORY: * 3.5 (xx-xxx-2022) ADDED: Multiple new icons, useful for code editing tools * ADDED: GuiTabBar(), based on GuiToggle() @@ -217,7 +193,9 @@ import core.stdc.config: c_long, c_ulong; * **********************************************************************************************/ -enum RAYGUI_VERSION = "3.2"; +enum RAYGUI_VERSION_MAJOR = 3; +enum RAYGUI_VERSION_MINOR = 5; +enum RAYGUI_VERSION = "3.5"; import raylib; @@ -237,7 +215,8 @@ alias RAYGUI_FREE=free; // Simple log system to avoid printf() calls if required // NOTE: Avoiding those calls, also avoids const strings memory usage -alias RAYGUI_LOG=printf; +// D Note: Don't use this. Use `writeln` +deprecated alias RAYGUI_LOG=printf; // Style property struct GuiStyleProp { @@ -254,7 +233,7 @@ enum _GuiState { STATE_DISABLED, }alias _GuiState GuiState; -mixin(enumMixin!GuiState); +mixin enumAlias!GuiState; // Gui control text alignment enum _GuiTextAlignment { @@ -263,7 +242,7 @@ enum _GuiTextAlignment { TEXT_ALIGN_RIGHT, }alias _GuiTextAlignment GuiTextAlignment; -mixin(enumMixin!GuiTextAlignment); +mixin enumAlias!GuiTextAlignment; // Gui controls enum _GuiControl { @@ -287,7 +266,7 @@ enum _GuiControl { STATUSBAR }alias _GuiControl GuiControl; -mixin(enumMixin!GuiControl); +mixin enumAlias!GuiControl; // Gui base properties for every control // NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties) @@ -310,7 +289,7 @@ enum _GuiControlProperty { RESERVED }alias _GuiControlProperty GuiControlProperty; -mixin(enumMixin!GuiControlProperty); +mixin enumAlias!GuiControlProperty; // Gui extended properties depend on control // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default 8 properties) @@ -325,7 +304,7 @@ enum _GuiDefaultProperty { BACKGROUND_COLOR, // Background color }alias _GuiDefaultProperty GuiDefaultProperty; -mixin(enumMixin!GuiDefaultProperty); +mixin enumAlias!GuiDefaultProperty; // Label //typedef enum { } GuiLabelProperty; @@ -338,7 +317,7 @@ enum _GuiToggleProperty { GROUP_PADDING = 16, // ToggleGroup separation between toggles }alias _GuiToggleProperty GuiToggleProperty; -mixin(enumMixin!GuiToggleProperty); +mixin enumAlias!GuiToggleProperty; // Slider/SliderBar enum _GuiSliderProperty { @@ -346,14 +325,14 @@ enum _GuiSliderProperty { SLIDER_PADDING // Slider/SliderBar internal bar padding }alias _GuiSliderProperty GuiSliderProperty; -mixin(enumMixin!GuiSliderProperty); +mixin enumAlias!GuiSliderProperty; // ProgressBar enum _GuiProgressBarProperty { PROGRESS_PADDING = 16, // ProgressBar internal padding }alias _GuiProgressBarProperty GuiProgressBarProperty; -mixin(enumMixin!GuiProgressBarProperty); +mixin enumAlias!GuiProgressBarProperty; // ScrollBar enum _GuiScrollBarProperty { @@ -365,14 +344,14 @@ enum _GuiScrollBarProperty { SCROLL_SPEED, }alias _GuiScrollBarProperty GuiScrollBarProperty; -mixin(enumMixin!GuiScrollBarProperty); +mixin enumAlias!GuiScrollBarProperty; // CheckBox enum _GuiCheckBoxProperty { CHECK_PADDING = 16 // CheckBox internal check padding }alias _GuiCheckBoxProperty GuiCheckBoxProperty; -mixin(enumMixin!GuiCheckBoxProperty); +mixin enumAlias!GuiCheckBoxProperty; // ComboBox enum _GuiComboBoxProperty { @@ -380,7 +359,7 @@ enum _GuiComboBoxProperty { COMBO_BUTTON_SPACING // ComboBox button separation }alias _GuiComboBoxProperty GuiComboBoxProperty; -mixin(enumMixin!GuiComboBoxProperty); +mixin enumAlias!GuiComboBoxProperty; // DropdownBox enum _GuiDropdownBoxProperty { @@ -388,15 +367,18 @@ enum _GuiDropdownBoxProperty { DROPDOWN_ITEMS_SPACING // DropdownBox items separation }alias _GuiDropdownBoxProperty GuiDropdownBoxProperty; -mixin(enumMixin!GuiDropdownBoxProperty); +mixin enumAlias!GuiDropdownBoxProperty; // TextBox/TextBoxMulti/ValueBox/Spinner enum _GuiTextBoxProperty { TEXT_INNER_PADDING = 16, // TextBox/TextBoxMulti/ValueBox/Spinner inner text padding TEXT_LINES_SPACING, // TextBoxMulti lines separation + TEXT_ALIGNMENT_VERTICAL, // TextBoxMulti vertical alignment: 0-CENTERED, 1-UP, 2-DOWN + TEXT_MULTILINE, // TextBox supports multiple lines + TEXT_WRAP_MODE, // TextBox wrap mode for multiline: 0-NO_WRAP, 1-CHAR_WRAP, 2-WORD_WRAP }alias _GuiTextBoxProperty GuiTextBoxProperty; -mixin(enumMixin!GuiTextBoxProperty); +mixin enumAlias!GuiTextBoxProperty; // Spinner enum _GuiSpinnerProperty { @@ -404,7 +386,7 @@ enum _GuiSpinnerProperty { SPIN_BUTTON_SPACING, // Spinner buttons separation }alias _GuiSpinnerProperty GuiSpinnerProperty; -mixin(enumMixin!GuiSpinnerProperty); +mixin enumAlias!GuiSpinnerProperty; // ListView enum _GuiListViewProperty { @@ -414,7 +396,7 @@ enum _GuiListViewProperty { SCROLLBAR_SIDE, // ListView scrollbar side (0-left, 1-right) }alias _GuiListViewProperty GuiListViewProperty; -mixin(enumMixin!GuiListViewProperty); +mixin enumAlias!GuiListViewProperty; // ColorPicker enum _GuiColorPickerProperty { @@ -425,7 +407,7 @@ enum _GuiColorPickerProperty { HUEBAR_SELECTOR_OVERFLOW // ColorPicker right hue bar selector overflow }alias _GuiColorPickerProperty GuiColorPickerProperty; -mixin(enumMixin!GuiColorPickerProperty); +mixin enumAlias!GuiColorPickerProperty; enum SCROLLBAR_LEFT_SIDE = 0; enum SCROLLBAR_RIGHT_SIDE = 1; @@ -435,81 +417,7 @@ enum SCROLLBAR_RIGHT_SIDE = 1; //---------------------------------------------------------------------------------- // ... -//---------------------------------------------------------------------------------- -// Module Functions Declaration -//---------------------------------------------------------------------------------- -/+ -// Global gui state control functions - void GuiEnable(); // Enable gui controls (global state) - void GuiDisable(); // Disable gui controls (global state) - void GuiLock(); // Lock gui controls (global state) - void GuiUnlock(); // Unlock gui controls (global state) - bool GuiIsLocked(); // Check if gui is locked (global state) - void GuiFade(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f - void GuiSetState(int state); // Set gui state (global state) - int GuiGetState(); // Get gui state (global state) - -// Font set/get functions - void GuiSetFont(Font font); // Set gui custom font (global state) - Font GuiGetFont(); // Get gui custom font (global state) - -// Style set/get functions - void GuiSetStyle(int control, int property, int value); // Set one style property - int GuiGetStyle(int control, int property); // Get one style property - -// Container/separator controls, useful for controls organization - bool GuiWindowBox(Rectangle bounds, const(char)* title); // Window Box control, shows a window that can be closed - void GuiGroupBox(Rectangle bounds, const(char)* text); // Group Box control with text name - void GuiLine(Rectangle bounds, const(char)* text); // Line separator control, could contain text - void GuiPanel(Rectangle bounds, const(char)* text); // Panel control, useful to group controls - int GuiTabBar(Rectangle bounds, const(char)** text, int count, int* active); // Tab Bar control, returns TAB to be closed or -1 - Rectangle GuiScrollPanel(Rectangle bounds, const(char)* text, Rectangle content, Vector2* scroll); // Scroll Panel control - -// Basic controls set - void GuiLabel(Rectangle bounds, const(char)* text); // Label control, shows text - bool GuiButton(Rectangle bounds, const(char)* text); // Button control, returns true when clicked - bool GuiLabelButton(Rectangle bounds, const(char)* text); // Label button control, show true when clicked - bool GuiToggle(Rectangle bounds, const(char)* text, bool active); // Toggle Button control, returns true when active - int GuiToggleGroup(Rectangle bounds, const(char)* text, int active); // Toggle Group control, returns active toggle index - bool GuiCheckBox(Rectangle bounds, const(char)* text, bool checked); // Check Box control, returns true when active - int GuiComboBox(Rectangle bounds, const(char)* text, int active); // Combo Box control, returns selected item index - bool GuiDropdownBox(Rectangle bounds, const(char)* text, int* active, bool editMode); // Dropdown Box control, returns selected item - bool GuiSpinner(Rectangle bounds, const(char)* text, int* value, int minValue, int maxValue, bool editMode); // Spinner control, returns selected value - bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers - bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode); // Text Box control, updates input text - bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode); // Text Box control with multiple lines - float GuiSlider(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue); // Slider control, returns selected value - float GuiSliderBar(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue); // Slider Bar control, returns selected value - float GuiProgressBar(Rectangle bounds, const(char)* textLeft, const(char)* textRight, float value, float minValue, float maxValue); // Progress Bar control, shows current progress value - void GuiStatusBar(Rectangle bounds, const(char)* text); // Status Bar control, shows info text - void GuiDummyRec(Rectangle bounds, const(char)* text); // Dummy control for placeholders - Vector2 GuiGrid(Rectangle bounds, const(char)* text, float spacing, int subdivs); // Grid control, returns mouse cell position - -// Advance controls set - int GuiListView(Rectangle bounds, const(char)* text, int* scrollIndex, int active); // List View control, returns selected list item index - int GuiListViewEx(Rectangle bounds, const(char)** text, int count, int* focus, int* scrollIndex, int active); // List View with extended parameters - int GuiMessageBox(Rectangle bounds, const(char)* title, const(char)* message, const(char)* buttons); // Message Box control, displays a message - int GuiTextInputBox(Rectangle bounds, const(char)* title, const(char)* message, const(char)* buttons, char* text, int textMaxSize, int* secretViewActive); // Text Input Box control, ask for text, supports secret - Color GuiColorPicker(Rectangle bounds, const(char)* text, Color color); // Color Picker control (multiple color controls) - Color GuiColorPanel(Rectangle bounds, const(char)* text, Color color); // Color Panel control - float GuiColorBarAlpha(Rectangle bounds, const(char)* text, float alpha); // Color Bar Alpha control - float GuiColorBarHue(Rectangle bounds, const(char)* text, float value); // Color Bar Hue control - -// Styles loading functions - void GuiLoadStyle(const(char)* fileName); // Load style file over global style variable (.rgs) - void GuiLoadStyleDefault(); // Load style default over global style - -// Icons functionality - const(char)* GuiIconText(int iconId, const(char)* text); // Get text with icon id prepended (if supported) - - -static if (!HasVersion!"RAYGUI_NO_ICONS") { - uint* GuiGetIcons(); // Get raygui icons data pointer - char** GuiLoadIcons(const(char)* fileName, bool loadIconsName); // Load raygui icons file (.rgi) into internal icons data - void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); - +/ - -// NOTE: because D doesn't work like C, we can't define custom icons this way. +// D NOTE: because D doesn't work like C, we can't define custom icons this way. // If we want custom icons we can do it a different way (if needed). But for // now, just error. version(RAYGUI_CUSTOM_ICONS) { @@ -738,8 +646,10 @@ enum _GuiIconName { ICON_BURGER_MENU = 214, ICON_CASE_SENSITIVE = 215, ICON_REG_EXP = 216, - ICON_217 = 217, - ICON_218 = 218, +deprecated("Use `ICON_FOLDER`") ICON_217 = 217, + ICON_FOLDER = 217, +deprecated("Use `ICON_FILE`") ICON_218 = 218, + ICON_FILE = 218, ICON_219 = 219, ICON_220 = 220, ICON_221 = 221, @@ -780,7 +690,7 @@ enum _GuiIconName { }alias _GuiIconName GuiIconName; } -mixin(enumMixin!GuiIconName); +mixin enumAlias!GuiIconName; /*********************************************************************************** @@ -800,7 +710,7 @@ enum RAYGUI_ICON_MAX_NAME_LENGTH = 32; // Maximum length of icon nam // Those arrays are stored as unsigned int data arrays, so, // every array element defines 32 pixels (bits) of information // One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels) -// NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) +// NOTE: Number of elements depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) enum RAYGUI_ICON_DATA_ELEMENTS = (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32); //---------------------------------------------------------------------------------- @@ -1032,8 +942,8 @@ private uint[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] guiIcons = [ 0x00000000, 0x00000000, 0x1ff81ff8, 0x1ff80000, 0x00001ff8, 0x1ff81ff8, 0x00000000, 0x00000000, // ICON_BURGER_MENU 0x00000000, 0x00000000, 0x00880070, 0x0c880088, 0x1e8810f8, 0x3e881288, 0x00000000, 0x00000000, // ICON_CASE_SENSITIVE 0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_217 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_218 + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_219 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221 @@ -1088,18 +998,25 @@ enum RAYGUI_MAX_PROPS_EXTENDED = 8; // Maximum number of extended pr // Gui control property style color element enum _GuiPropertyElement { BORDER = 0, BASE, TEXT, OTHER }alias _GuiPropertyElement GuiPropertyElement; -mixin(enumMixin!GuiPropertyElement); +mixin enumAlias!GuiPropertyElement; //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- private GuiState guiState = GuiState.STATE_NORMAL; // Gui global state, if !STATE_NORMAL, forces defined state -private Font guiFont; // Gui current font (WARNING: highly coupled to raylib) -private bool guiLocked = false; // Gui lock state (no inputs processed) -private float guiAlpha = 1.0f; // Gui element transpacency on drawing +private Font guiFont; // Gui current font (WARNING: highly coupled to raylib) +private bool guiLocked = false; // Gui lock state (no inputs processed) +private float guiAlpha = 1.0f; // Gui element transpacency on drawing + +private uint guiIconScale = 1; // Gui icon default scale (if icons enabled) + +private bool guiTooltip = false; // Tooltip enabled/disabled +private char* guiTooltipPtr = null; // Tooltip string pointer (string provided by user) -private uint guiIconScale = 1; // Gui icon default scale (if icons enabled) +private int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() +private int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down +private int autoCursorDelayCounter = 0; // Delay frame coutner for automatic cursor movement //---------------------------------------------------------------------------------- // Style data array for all gui style properties (allocated on data segment by default) @@ -1344,44 +1261,47 @@ enum RAYGUI_TABBAR_ITEM_WIDTH = 160; int closing = -1; Rectangle tabBounds = { bounds.x, bounds.y, RAYGUI_TABBAR_ITEM_WIDTH, bounds.height }; - Vector2 mousePoint = GetMousePosition(); + //Vector2 mousePoint = GetMousePosition(); if (*active < 0) *active = 0; else if (*active > count - 1) *active = count - 1; + int offsetX = (*active + 2)*RAYGUI_TABBAR_ITEM_WIDTH - GetScreenWidth(); + if (offsetX < 0) offsetX = 0; + // Draw control //-------------------------------------------------------------------- for (int i = 0; i < count; i++) { - tabBounds.x = bounds.x + (RAYGUI_TABBAR_ITEM_WIDTH + 4)*i; - - int textAlignment = GuiGetStyle(TOGGLE, TEXT_ALIGNMENT); - int textPadding = GuiGetStyle(TOGGLE, TEXT_PADDING); - GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(TOGGLE, TEXT_PADDING, 8); - if (i == *active) GuiToggle(tabBounds, GuiIconText(12, text[i]), true); - else if (GuiToggle(tabBounds, GuiIconText(12, text[i]), false) == true) *active = i; - GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); - GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); - - // Draw tab close button - // NOTE: Only draw close button for curren tab: if (CheckCollisionPointRec(mousePoint, tabBounds)) - int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); - int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); - GuiSetStyle(BUTTON, BORDER_WIDTH, 1); - GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + tabBounds.x = bounds.x + (RAYGUI_TABBAR_ITEM_WIDTH + 4)*i - offsetX; + + if (tabBounds.x < GetScreenWidth()) { + int textAlignment = GuiGetStyle(TOGGLE, TEXT_ALIGNMENT); + int textPadding = GuiGetStyle(TOGGLE, TEXT_PADDING); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(TOGGLE, TEXT_PADDING, 8); + if (i == *active) GuiToggle(tabBounds, GuiIconText(12, text[i]), true); + else if (GuiToggle(tabBounds, GuiIconText(12, text[i]), false) == true) *active = i; + GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); + + // Draw tab close button + // NOTE: Only draw close button for current tab: if (CheckCollisionPointRec(mousePoint, tabBounds)) + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); version (RAYGUI_NO_ICONS) { - if (GuiButton(closeButtonRec, "x")) closing = i; + if (GuiButton(Rectangle(tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14), "x")) closing = i; } else { - if (GuiButton(Rectangle( tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 ), GuiIconText(ICON_CROSS_SMALL, null))) closing = i; + if (GuiButton(Rectangle(tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14), GuiIconText(ICON_CROSS_SMALL, null))) closing = i; } - GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); - GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + } } GuiDrawRectangle(Rectangle( bounds.x, bounds.y + bounds.height - 1, bounds.width, 1 ), 0, Colors.BLANK, GetColor(GuiGetStyle(TOGGLE, BORDER_COLOR_NORMAL))); - //GuiLine(Rectangle( bounds.x, bounds.y + bounds.height - 1, bounds.width, 1 ), NULL); - //-------------------------------------------------------------------- return closing; // Return closing tab requested } @@ -1440,26 +1360,26 @@ Rectangle GuiScrollPanel(Rectangle bounds, const(char)* text, Rectangle content, // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; version (SUPPORT_SCROLLBAR_KEY_INPUT) { if (hasHorizontalScrollBar) { - if (IsKeyDown(KeyboardKey.KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KeyboardKey.KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KeyboardKey.RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KeyboardKey.LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } if (hasVerticalScrollBar) { - if (IsKeyDown(KeyboardKey.KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KeyboardKey.KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KeyboardKey.DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KeyboardKey.UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } } float wheelMove = GetMouseWheelMove(); // Horizontal scroll (Shift + Mouse wheel) - if (hasHorizontalScrollBar && (IsKeyDown(KeyboardKey.KEY_LEFT_CONTROL) || IsKeyDown(KeyboardKey.KEY_RIGHT_SHIFT))) scrollPos.x += wheelMove*20; + if (hasHorizontalScrollBar && (IsKeyDown(KeyboardKey.LEFT_CONTROL) || IsKeyDown(KeyboardKey.RIGHT_SHIFT))) scrollPos.x += wheelMove*20; else scrollPos.y += wheelMove*20; // Vertical scroll } } @@ -1546,10 +1466,10 @@ bool GuiButton(Rectangle bounds, const(char)* text) { // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (IsMouseButtonReleased(MouseButton.LEFT)) pressed = true; } } //-------------------------------------------------------------------- @@ -1558,6 +1478,8 @@ bool GuiButton(Rectangle bounds, const(char)* text) { //-------------------------------------------------------------------- GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(BUTTON, BASE + (state*3))), guiAlpha)); GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))), guiAlpha)); + + if (state == STATE_FOCUSED) GuiTooltip(bounds); //------------------------------------------------------------------ return pressed; @@ -1581,10 +1503,10 @@ bool GuiLabelButton(Rectangle bounds, const(char)* text) { // Check checkbox state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (IsMouseButtonReleased(MouseButton.LEFT)) pressed = true; } } //-------------------------------------------------------------------- @@ -1610,8 +1532,8 @@ bool GuiToggle(Rectangle bounds, const(char)* text, bool active) { // Check toggle button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; + else if (IsMouseButtonReleased(MouseButton.LEFT)) { state = STATE_NORMAL; active = !active; @@ -1633,6 +1555,8 @@ bool GuiToggle(Rectangle bounds, const(char)* text, bool active) { GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(TOGGLE, BASE + state*3)), guiAlpha)); GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + state*3)), guiAlpha)); } + + if (state == STATE_FOCUSED) GuiTooltip(bounds); //-------------------------------------------------------------------- return active; @@ -1702,10 +1626,10 @@ bool GuiCheckBox(Rectangle bounds, const(char)* text, bool checked) { // Check checkbox state if (CheckCollisionPointRec(mousePoint, totalBounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) checked = !checked; + if (IsMouseButtonReleased(MouseButton.LEFT)) checked = !checked; } } //-------------------------------------------------------------------- @@ -1754,13 +1678,13 @@ int GuiComboBox(Rectangle bounds, const(char)* text, int active) { if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MouseButton.LEFT)) { active += 1; if (active >= itemCount) active = 0; } - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -1819,11 +1743,11 @@ bool GuiDropdownBox(Rectangle bounds, const(char)* text, int* active, bool editM // Check if mouse has been pressed or released outside limits if (!CheckCollisionPointRec(mousePoint, boundsOpen)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (IsMouseButtonPressed(MouseButton.LEFT) || IsMouseButtonReleased(MouseButton.LEFT)) pressed = true; } // Check if already selected item has been pressed again - if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true; + if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MouseButton.LEFT)) pressed = true; // Check focused and selected item for (int i = 0; i < itemCount; i++) @@ -1834,7 +1758,7 @@ bool GuiDropdownBox(Rectangle bounds, const(char)* text, int* active, bool editM if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = i; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonReleased(MouseButton.LEFT)) { itemSelected = i; pressed = true; // Item selected, change to editMode = false @@ -1849,7 +1773,7 @@ bool GuiDropdownBox(Rectangle bounds, const(char)* text, int* active, bool editM { if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MouseButton.LEFT)) { pressed = true; state = STATE_PRESSED; @@ -1905,23 +1829,47 @@ version (RAYGUI_NO_ICONS) { // Text Box control, updates input text // NOTE 2: Returns if KEY_ENTER pressed (useful for data validation) -bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode) { +bool GuiTextBox(Rectangle bounds, char* text, int bufferSize, bool editMode) { + const uint AUTO_CURSOR_COOLDOWN = 40; + const uint AUTO_CURSOR_DELAY = 3; + GuiState state = guiState; Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); bool pressed = false; - int textWidth = GetTextWidth(text); + int textWidth = GetTextWidth(text) - GetTextWidth(text + textBoxCursorIndex); + int textIndexOffset = 0; + int alignmentVertical = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL); + int multiline = GuiGetStyle(TEXTBOX, TEXT_MULTILINE); + // Cursor rectangle + // NOTE: Position X value should be updated Rectangle cursor = { - bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + textWidth + 2, + bounds.x + GuiGetStyle(DEFAULT, TEXT_SPACING) + textWidth + 2, bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE), - 4, + 2, cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2 }; + final switch (alignmentVertical) + { + case 0: cursor.y = textBounds.y + textBounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE); break; // Centered + case 1: cursor.y = textBounds.y - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; break; // Up + case 3: cursor.y = textBounds.y + textBounds.height; break; + } + if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2; if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH); + // Auto-cursor movement logic + // NOTE: Cursor moves automatically when key down after some time + if (IsKeyDown(KeyboardKey.KEY_LEFT) || IsKeyDown(KeyboardKey.KEY_RIGHT) || IsKeyDown(KeyboardKey.KEY_UP) || IsKeyDown(KeyboardKey.KEY_DOWN) || IsKeyDown(KeyboardKey.KEY_BACKSPACE)) autoCursorCooldownCounter++; + else + { + autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter + autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter + } + // Update control //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) @@ -1932,46 +1880,112 @@ bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode) { { state = STATE_PRESSED; - int key = GetCharPressed(); // Returns codepoint as Unicode - int keyCount = cast(int)strlen(text); - int byteSize = 0; - const(char)* textUTF8 = CodepointToUTF8(key, &byteSize); + // If text does not fit in the textbox and current cursor position is out of bounds, + // we add an index offset to text for drawing only what requires depending on cursor + while (textWidth >= textBounds.width) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textIndexOffset, &nextCodepointSize); + + textIndexOffset += nextCodepointSize; + + textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex); + } + + uint textLength = cast(uint)text.strlen; // Get current text length + int codepoint = GetCharPressed(); // Get Unicode codepoint + if (multiline && IsKeyPressed(KeyboardKey.KEY_ENTER)) codepoint = cast(int)'\n'; - // Only allow keys in range [32..125] - if ((keyCount + byteSize) < textSize) + // Encode codepoint as UTF-8 + int codepointSize = 0; + const char* charEncoded = CodepointToUTF8(codepoint, &codepointSize); + + // Add codepoint to text, at current cursor position + // NOTE: Make sure we do not overflow buffer size + if (((multiline && (codepoint == cast(int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < bufferSize)) { - //float maxWidth = (bounds.width - (GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)*2)); + // Move forward data from cursor position + for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize]; + + // Add new codepoint in current cursor position + for (int i = 0; i < codepointSize; i++) text[textBoxCursorIndex + i] = charEncoded[i]; + + textBoxCursorIndex += codepointSize; + textLength += codepointSize; - if (key >= 32) + // Make sure text last character is EOL + text[textLength] = '\0'; + } + + // Delete codepoint from text, at current cursor position + if ((textLength > 0) && (IsKeyPressed(KeyboardKey.KEY_BACKSPACE) || (IsKeyDown(KeyboardKey.KEY_BACKSPACE) && (autoCursorCooldownCounter >= AUTO_CURSOR_COOLDOWN)))) + { + autoCursorDelayCounter++; + + if (IsKeyPressed(KeyboardKey.KEY_BACKSPACE) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames { - for (int i = 0; i < byteSize; i++) - { - text[keyCount] = textUTF8[i]; - keyCount++; - } + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - text[keyCount] = '\0'; + // Move backward text from cursor position + for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize]; + + textBoxCursorIndex -= codepointSize; + textLength -= codepointSize; + + // Make sure text last character is EOL + text[textLength] = '\0'; } } - // Delete text - if (keyCount > 0) + // Move cursor position with keys + //if (IsKeyDown(KEY_LEFT) && autoCursorMode) + if (IsKeyPressed(KeyboardKey.KEY_LEFT) || (IsKeyDown(KeyboardKey.KEY_LEFT) && (autoCursorCooldownCounter > AUTO_CURSOR_COOLDOWN))) { - if (IsKeyPressed(KeyboardKey.KEY_BACKSPACE)) + autoCursorDelayCounter++; + + if (IsKeyPressed(KeyboardKey.KEY_LEFT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames { - while ((keyCount > 0) && ((text[--keyCount] & 0xc0) == 0x80)){} - text[keyCount] = '\0'; + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + + if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize; } } + else if (IsKeyPressed(KeyboardKey.KEY_RIGHT) || (IsKeyDown(KeyboardKey.KEY_RIGHT) && (autoCursorCooldownCounter > AUTO_CURSOR_COOLDOWN))) + { + autoCursorDelayCounter++; + if (IsKeyPressed(KeyboardKey.KEY_RIGHT) || (autoCursorDelayCounter%AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); - if (IsKeyPressed(KeyboardKey.KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true; + if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize; + } + } + + // Recalculate cursor position.y depending on textBoxCursorIndex + cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + + // Finish text editing on ENTER (if not multiline mode) or mouse click outside bounds + if ((!multiline && IsKeyPressed(KeyboardKey.KEY_ENTER)) || + (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + { + pressed = true; // Exiting edit mode + textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + } } else { if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true; + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + pressed = true; // Entering edit mode + textBoxCursorIndex = cast(int)strlen(text); // GLOBAL: Place cursor index to the end of current text + } } } } @@ -1989,6 +2003,11 @@ bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode) { } else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Colors.BLANK); + // Draw text considering index offset if required + // NOTE: Text index offset depends on cursor position + GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha)); + + // Draw cursor if (editMode) { // In case we edit and text does not fit in the textbox, @@ -2001,14 +2020,14 @@ bool GuiTextBox(Rectangle bounds, char* text, int textSize, bool editMode) { textWidth = GetTextWidth(text); cursor.x = textBounds.x + textWidth + 2; } + //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0)) + GuiDrawRectangle(cursor, 0, Colors.BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha)); } + else if (state == STATE_FOCUSED) GuiTooltip(bounds); + //-------------------------------------------------------------------- GuiDrawText(text, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha)); - // Draw cursor - if (editMode) GuiDrawRectangle(cursor, 0, Colors.BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha)); - //-------------------------------------------------------------------- - return pressed; } @@ -2043,7 +2062,7 @@ bool GuiSpinner(Rectangle bounds, const(char)* text, int* value, int minValue, i // Check spinner state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -2141,7 +2160,7 @@ bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, // Delete text if (keyCount > 0) { - if (IsKeyPressed(KeyboardKey.KEY_BACKSPACE)) + if (IsKeyPressed(KeyboardKey.BACKSPACE)) { keyCount--; textValue[keyCount] = '\0'; @@ -2155,7 +2174,7 @@ bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, //if (*value > maxValue) *value = maxValue; //else if (*value < minValue) *value = minValue; - if (IsKeyPressed(KeyboardKey.KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true; + if (IsKeyPressed(KeyboardKey.ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MouseButton.LEFT))) pressed = true; } else { @@ -2165,7 +2184,7 @@ bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true; + if (IsMouseButtonPressed(MouseButton.LEFT)) pressed = true; } } } @@ -2185,7 +2204,7 @@ bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = { bounds.x + GetTextWidth(textValue.ptr)/2 + bounds.width/2 + 2, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; + Rectangle cursor = { bounds.x + GetTextWidth(textValue.ptr)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; GuiDrawRectangle(cursor, 0, Colors.BLANK, Fade(GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)), guiAlpha)); } @@ -2197,7 +2216,9 @@ bool GuiValueBox(Rectangle bounds, const(char)* text, int* value, int minValue, } // Text Box control with multiple lines -bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode) { +// D Note: Deprecated (removed in upstream raygui) because cursor placement is not working correctly +// This was never included in a release of raygui, but is kept here because it was available for a long time. +deprecated bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode) { GuiState state = guiState; bool pressed = false; @@ -2232,7 +2253,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode) // Introduce characters if ((textLength + byteSize) < textSize) { - if (IsKeyPressed(KeyboardKey.KEY_ENTER)) + if (IsKeyPressed(KeyboardKey.ENTER)) { text[textLength] = '\n'; textLength++; @@ -2250,7 +2271,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode) // Delete characters if (textLength > 0) { - if (IsKeyPressed(KeyboardKey.KEY_BACKSPACE)) + if (IsKeyPressed(KeyboardKey.BACKSPACE)) { if (cast(ubyte)text[textLength - 1] < 127) { @@ -2271,14 +2292,14 @@ bool GuiTextBoxMulti(Rectangle bounds, char* text, int textSize, bool editMode) } // Exit edit mode - if (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true; + if (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MouseButton.LEFT)) pressed = true; } else { if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true; + if (IsMouseButtonPressed(MouseButton.LEFT)) pressed = true; } } } @@ -2400,7 +2421,7 @@ float GuiSliderPro(Rectangle bounds, const(char)* textLeft, const(char)* textRig if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonDown(MouseButton.LEFT)) { state = STATE_PRESSED; @@ -2549,7 +2570,7 @@ void GuiDummyRec(Rectangle bounds, const(char)* text) { // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (IsMouseButtonDown(MouseButton.LEFT)) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -2615,7 +2636,7 @@ int GuiListViewEx(Rectangle bounds, const(char)** text, int count, int* focus, i if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = startIndex + i; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MouseButton.LEFT)) { if (itemSelected == (startIndex + i)) itemSelected = -1; else itemSelected = startIndex + i; @@ -2744,7 +2765,7 @@ Color GuiColorPanel(Rectangle bounds, const(char)* text, Color color) if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonDown(MouseButton.LEFT)) { state = STATE_PRESSED; pickerSelector = mousePoint; @@ -2813,7 +2834,7 @@ float GuiColorBarAlpha(Rectangle bounds, const(char)* text, float alpha) { if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonDown(MouseButton.LEFT)) { state = STATE_PRESSED; @@ -2877,7 +2898,7 @@ float GuiColorBarHue(Rectangle bounds, const(char)* text, float hue) { if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonDown(MouseButton.LEFT)) { state = STATE_PRESSED; @@ -2888,12 +2909,12 @@ float GuiColorBarHue(Rectangle bounds, const(char)* text, float hue) { } else state = STATE_FOCUSED; - /*if (IsKeyDown(KeyboardKey.KEY_UP)) + /*if (IsKeyDown(KeyboardKey.UP)) { hue -= 2.0f; if (hue <= 0.0f) hue = 0.0f; } - else if (IsKeyDown(KeyboardKey.KEY_DOWN)) + else if (IsKeyDown(KeyboardKey.DOWN)) { hue += 2.0f; if (hue >= 360.0f) hue = 360.0f; @@ -3107,9 +3128,9 @@ Vector2 GuiGrid(Rectangle bounds, const(char)* text, float spacing, int subdivs) { if (CheckCollisionPointRec(mousePoint, bounds)) { - // NOTE: Cell values must be rounded to int - currentCell.x = cast(int)((mousePoint.x - bounds.x)/spacing); - currentCell.y = cast(int)((mousePoint.y - bounds.y)/spacing); + // NOTE: Cell values must be the upper left of the cell the mouse is in + currentCell.x = floor((mousePoint.x - bounds.x)/spacing); + currentCell.y = floor((mousePoint.y - bounds.y)/spacing); } } //-------------------------------------------------------------------- @@ -3146,6 +3167,20 @@ Vector2 GuiGrid(Rectangle bounds, const(char)* text, float spacing, int subdivs) return currentCell; } +//---------------------------------------------------------------------------------- +// Tooltip management functions +// NOTE: Tooltips requires some global variables: tooltipPtr +//---------------------------------------------------------------------------------- +// Enable gui tooltips (global state) +void GuiEnableTooltip() { guiTooltip = true; } + +// Disable gui tooltips (global state) +void GuiDisableTooltip() { guiTooltip = false; } + +// Set tooltip string +void GuiSetTooltip(const(char)* tooltip) { guiTooltipPtr = cast(char*) tooltip; } + + //---------------------------------------------------------------------------------- // Styles loading functions //---------------------------------------------------------------------------------- @@ -3263,9 +3298,9 @@ void GuiLoadStyle(const(char)* fileName) { for (int i = 0; i < propertyCount; i++) { - fread(&controlId, 1, short.sizeof, rgsFile); - fread(&propertyId, 1, short.sizeof, rgsFile); - fread(&propertyValue, 1, uint.sizeof, rgsFile); + fread(&controlId, short.sizeof, 1, rgsFile); + fread(&propertyId, short.sizeof, 1, rgsFile); + fread(&propertyValue, uint.sizeof, 1, rgsFile); if (controlId == 0) // DEFAULT control { @@ -3290,35 +3325,35 @@ static if (!HasVersion!"RAYGUI_STANDALONE") { int fontType = 0; // 0-Normal, 1-SDF Rectangle whiteRec; // = { 0 }; - fread(&font.baseSize, 1, int.sizeof, rgsFile); - fread(&font.glyphCount, 1, int.sizeof, rgsFile); - fread(&fontType, 1, int.sizeof, rgsFile); + fread(&font.baseSize, int.sizeof, 1, rgsFile); + fread(&font.glyphCount, int.sizeof, 1, rgsFile); + fread(&fontType, int.sizeof, 1, rgsFile); // Load font white rectangle - fread(&whiteRec, 1, Rectangle.sizeof, rgsFile); + fread(&whiteRec, Rectangle.sizeof, 1, rgsFile); // Load font image parameters int fontImageUncompSize = 0; int fontImageCompSize = 0; - fread(&fontImageUncompSize, 1, int.sizeof, rgsFile); - fread(&fontImageCompSize, 1, int.sizeof, rgsFile); + fread(&fontImageUncompSize, int.sizeof, 1, rgsFile); + fread(&fontImageCompSize, int.sizeof, 1, rgsFile); Image imFont; // = { 0 }; imFont.mipmaps = 1; - fread(&imFont.width, 1, int.sizeof, rgsFile); - fread(&imFont.height, 1, int.sizeof, rgsFile); - fread(&imFont.format, 1, int.sizeof, rgsFile); + fread(&imFont.width, int.sizeof, 1, rgsFile); + fread(&imFont.height, int.sizeof, 1, rgsFile); + fread(&imFont.format, int.sizeof, 1, rgsFile); if (fontImageCompSize < fontImageUncompSize) { // Compressed font atlas image data (DEFLATE), it requires DecompressData() int dataUncompSize = 0; ubyte* compData = cast(ubyte*)RAYGUI_MALLOC(fontImageCompSize); - fread(compData, 1, fontImageCompSize, rgsFile); + fread(compData, fontImageCompSize, 1, rgsFile); imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize); // Security check, dataUncompSize must match the provided fontImageUncompSize - if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted"); + if (dataUncompSize != fontImageUncompSize) printf("WARNING: Uncompressed font atlas image data could be corrupted"); RAYGUI_FREE(compData); } @@ -3326,7 +3361,7 @@ static if (!HasVersion!"RAYGUI_STANDALONE") { { // Font atlas image data is not compressed imFont.data = cast(ubyte*)RAYGUI_MALLOC(fontImageUncompSize); - fread(imFont.data, 1, fontImageUncompSize, rgsFile); + fread(imFont.data, fontImageUncompSize, 1, rgsFile); } if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); @@ -3337,16 +3372,16 @@ static if (!HasVersion!"RAYGUI_STANDALONE") { // Load font recs data font.recs = cast(Rectangle*)RAYGUI_CALLOC(font.glyphCount, Rectangle.sizeof); - for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], 1, Rectangle.sizeof, rgsFile); + for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], Rectangle.sizeof, 1, rgsFile); // Load font chars info data font.glyphs = cast(GlyphInfo*)RAYGUI_CALLOC(font.glyphCount, GlyphInfo.sizeof); for (int i = 0; i < font.glyphCount; i++) { - fread(&font.glyphs[i].value, 1, int.sizeof, rgsFile); - fread(&font.glyphs[i].offsetX, 1, int.sizeof, rgsFile); - fread(&font.glyphs[i].offsetY, 1, int.sizeof, rgsFile); - fread(&font.glyphs[i].advanceX, 1, int.sizeof, rgsFile); + fread(&font.glyphs[i].value, int.sizeof, 1, rgsFile); + fread(&font.glyphs[i].offsetX, int.sizeof, 1, rgsFile); + fread(&font.glyphs[i].offsetY, int.sizeof, 1, rgsFile); + fread(&font.glyphs[i].advanceX, int.sizeof, 1, rgsFile); } GuiSetFont(font); @@ -3394,9 +3429,9 @@ void GuiLoadStyleDefault() { GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT); GuiSetStyle(TEXTBOX, TEXT_PADDING, 4); GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(VALUEBOX, TEXT_PADDING, 4); + GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(SPINNER, TEXT_PADDING, 4); + GuiSetStyle(SPINNER, TEXT_PADDING, 0); GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); @@ -3551,7 +3586,7 @@ char** GuiLoadIcons(const(char)* fileName, bool loadIconsName) { else fseek(rgiFile, iconCount*RAYGUI_ICON_MAX_NAME_LENGTH, SEEK_CUR); // Read icons data directly over internal icons array - fread(guiIconsPtr, iconCount*(iconSize*iconSize/32), uint.sizeof, rgiFile); + fread(guiIconsPtr, uint.sizeof, iconCount*(iconSize*iconSize/32), rgiFile); } fclose(rgiFile); @@ -3581,6 +3616,11 @@ void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color) { } } // !RAYGUI_NO_ICONS +void GuiSetIconScale(int scale) +{ + if (scale >= 1) guiIconScale = scale; +} + //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -3650,14 +3690,13 @@ private Rectangle GetTextBounds(int control, Rectangle bounds) { Rectangle textBounds = bounds; textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH); - textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH); + textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH) + GuiGetStyle(control, TEXT_PADDING); textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); - textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH); + textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - GuiGetStyle(control, TEXT_PADDING); // Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT switch (control) { - case COMBOBOX: bounds.width -= (GuiGetStyle(control, COMBO_BUTTON_WIDTH) + GuiGetStyle(control, COMBO_BUTTON_SPACING)); break; case VALUEBOX: break; // NOTE: ValueBox text value always centered, text padding applies to label default: { @@ -3705,12 +3744,13 @@ static if (!HasVersion!"RAYGUI_NO_ICONS") { } // Get text divided into lines (by line-breaks '\n') -char** GetTextLines(char* text, int* count) { -enum RAYGUI_MAX_TEXT_LINES = 128; - - static char*[RAYGUI_MAX_TEXT_LINES] lines = null; +const(char)** GetTextLines(const(char)* text, int* count) { + enum RAYGUI_MAX_TEXT_LINES = 128; + + static const(char)*[RAYGUI_MAX_TEXT_LINES] lines = null; memset(lines.ptr, 0, (char*).sizeof); + for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = null; // Init null pointers to substrings int textLen = cast(int)strlen(text); lines[0] = text; @@ -3744,14 +3784,16 @@ private void GuiDrawText(const(char)* text, Rectangle bounds, int alignment, Col enum ICON_TEXT_PADDING = 4; } + int alignmentVertical = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT_VERTICAL); + // We process the text lines one by one if ((text != null) && (text[0] != '\0')) { // Get text lines ('\n' delimiter) to process lines individually - // NOTE: We can't use GuiTextSplit() because it can be already use before calling + // NOTE: We can't use GuiTextSplit() because it can already be used before calling // GuiDrawText() and static buffer would be overriden :( int lineCount = 0; - char** lines = GetTextLines(cast(char*)text, &lineCount); + const(char)** lines = GetTextLines(cast(const(char)*)text, &lineCount); Rectangle textBounds = GetTextBounds(LABEL, bounds); float totalHeight = lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2; @@ -3783,20 +3825,28 @@ private void GuiDrawText(const(char)* text, Rectangle bounds, int alignment, Col switch (alignment) { case TEXT_ALIGN_LEFT: - { position.x = bounds.x; - position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height); - } break; + break; case TEXT_ALIGN_CENTER: - { position.x = bounds.x + bounds.width/2 - textSizeX/2; - position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height); - } break; + break; case TEXT_ALIGN_RIGHT: - { position.x = bounds.x + bounds.width - textSizeX; + break; + default: break; + } + + switch (alignmentVertical) + { + case 0: + position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height); + break; // Centred + case TEXT_ALIGN_CENTER: position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height); - } break; + break; // Up + case TEXT_ALIGN_RIGHT: + position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height); + break; // Down default: break; } @@ -3840,8 +3890,7 @@ static if (!HasVersion!"RAYGUI_NO_ICONS") { { if ((codepoint != ' ') && (codepoint != '\t')) { - // TODO: Draw only required text glyphs fitting the bounds.width, '...' can be appended at the end of the text - if (textOffsetX < bounds.width) + if (textOffsetX < bounds.width - guiFont.recs[index].width) { DrawTextCodepoint(guiFont, codepoint, Vector2( position.x + textOffsetX, position.y + textOffsetY ), cast(float)GuiGetStyle(DEFAULT, TEXT_SIZE), tint); } @@ -3876,6 +3925,26 @@ private void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, } } +private void GuiTooltip(Rectangle controlRec) +{ + if (!guiLocked && guiTooltip && (guiTooltipPtr != null)) + { + Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, GuiGetStyle(DEFAULT, TEXT_SIZE), GuiGetStyle(DEFAULT, TEXT_SPACING)); + + if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); + + GuiPanel(Rectangle(controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f), null); + + int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); + int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_PADDING, 0); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(Rectangle(controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f), guiTooltipPtr); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); + GuiSetStyle(LABEL, TEXT_PADDING, textPadding); + } +} + // Split controls text into multiple strings // Also check for multiple columns (required by GuiToggleGroup()) private const(char)** GuiTextSplit(const(char)* text, char delimiter, int* count, int* textRow) { @@ -4081,7 +4150,7 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) if (value > maxValue) value = maxValue; if (value < minValue) value = minValue; - const(int) range = maxValue - minValue; + const(int) valueRange = maxValue - minValue; int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); // Calculate rectangles for all of the components @@ -4092,17 +4161,21 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) if (isVertical) { - 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 ); + 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 ); 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) ); - sliderSize = (sliderSize >= scrollbar.height)? (cast(int)scrollbar.height - 2) : sliderSize; // Make sure the slider won't get outside of the scrollbar - 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 ); + + // Make sure the slider won't get outside of the scrollbar + sliderSize = (sliderSize >= scrollbar.height)? (cast(int)scrollbar.height - 2) : sliderSize; + slider = Rectangle( cast(float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), scrollbar.y + cast(int)((cast(float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)), cast(float)bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)), cast(float)sliderSize ); } - else + else // horizontal { 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 ); 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)) ); + + // Make sure the slider won't get outside of the scrollbar sliderSize = (sliderSize >= scrollbar.width)? (cast(int)scrollbar.width - 2) : sliderSize; // Make sure the slider won't get outside of the scrollbar - 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)) ); + slider = Rectangle( cast(float)scrollbar.x + cast(int)((cast(float)(value - minValue)/valueRange)*(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)) ); } // Update control @@ -4119,25 +4192,23 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) int wheel = cast(int)GetMouseWheelMove(); if (wheel != 0) value += wheel; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MouseButton.LEFT)) { - if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (!CheckCollisionPointRec(mousePoint, slider)) + { + // If click on scrollbar position but not on slider, place slider directly on that position + if (isVertical) value = cast(int)(((mousePoint.y - scrollbar.y - slider.height/2.0f)*valueRange)/(scrollbar.height - slider.height) + minValue); + else value = cast(int)(((mousePoint.x - scrollbar.x - slider.width/2.0f)*valueRange)/(scrollbar.width - slider.width) + minValue); + } state = STATE_PRESSED; } - else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + else if (IsMouseButtonDown(MouseButton.LEFT)) { - if (!isVertical) - { - Rectangle scrollArea = { arrowUpLeft.x + arrowUpLeft.width, arrowUpLeft.y, scrollbar.width, bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) }; - if (CheckCollisionPointRec(mousePoint, scrollArea)) value = cast(int)((cast(float)(mousePoint.x - scrollArea.x - slider.width/2)*range)/(scrollArea.width - slider.width) + minValue); - } - else - { - Rectangle scrollArea = { arrowUpLeft.x, arrowUpLeft.y+arrowUpLeft.height, bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), scrollbar.height }; - if (CheckCollisionPointRec(mousePoint, scrollArea)) value = cast(int)((cast(float)(mousePoint.y - scrollArea.y - slider.height/2)*range)/(scrollArea.height - slider.height) + minValue); - } + if (isVertical) value += cast(int)(GetMouseDelta.y/scrollbar.height - slider.height)*valueRange; + else value += cast(int)(GetMouseDelta.x/(scrollbar.width - slider.width)*valueRange); } } diff --git a/source/raylib/package.d b/source/raylib/package.d index ddeb78f..9905bd1 100644 --- a/source/raylib/package.d +++ b/source/raylib/package.d @@ -75,6 +75,8 @@ * 3. This notice may not be removed or altered from any source distribution. * **********************************************************************************************/ +// This version of Raylib has been altered from the original. + module raylib; public @@ -88,6 +90,8 @@ public import raylib.binding; } +//import raylibd_templates; + import core.stdc.config; import core.stdc.stdarg; @@ -270,15 +274,6 @@ struct Camera3D alias Camera = Camera3D; // Camera type fallback, defaults to Camera3D -// Camera2D, defines position/orientation in 2d space -struct Camera2D -{ - Vector2 offset; // Camera offset (displacement from target) - Vector2 target; // Camera target (rotation and zoom origin) - float rotation; // Camera rotation in degrees - float zoom; // Camera zoom (scaling), should be 1.0f by default -} - // Mesh, vertex data and vao/vbo struct Mesh { @@ -498,21 +493,37 @@ struct AutomationEventList enum ConfigFlags { FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU + VSYNC_HINT = 0x00000040, FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen + FULLSCREEN_MODE = 0x00000002, FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window + WINDOW_RESIZABLE = 0x00000004, FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) + WINDOW_UNDECORATED = 0x00000008, FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window + WINDOW_HIDDEN = 0x00000080, FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) + WINDOW_MINIMIZED = 0x00000200, FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) + WINDOW_MAXIMIZED = 0x00000400, FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused + WINDOW_UNFOCUSED = 0x00000800, FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top + WINDOW_TOPMOST = 0x00001000, FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized + WINDOW_ALWAYS_RUN = 0x00000100, FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer + WINDOW_TRANSPARENT = 0x00000010, FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI + WINDOW_HIGHDPI = 0x00002000, FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + WINDOW_MOUSE_PASSTHROUGH = 0x00004000, FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode + BORDERLESS_WINDOWED_MODE = 0x00008000, FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X - FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) + MSAA_4X_HINT = 0x00000020, + FLAG_INTERLACED_HINT = 0x00010000, // Set to try enabling interlaced video format (for V3D) + INTERLACED_HINT = 0x00010000 } // Trace log level @@ -520,13 +531,21 @@ enum ConfigFlags enum TraceLogLevel { LOG_ALL = 0, // Display all logs + ALL = 0, LOG_TRACE = 1, // Trace logging, intended for internal use only + TRACE = 1, LOG_DEBUG = 2, // Debug logging, used for internal debugging, it should be disabled on release builds + DEBUG = 2, LOG_INFO = 3, // Info logging, used for program execution info + INFO = 3, LOG_WARNING = 4, // Warning logging, used on recoverable failures + WARNING = 4, LOG_ERROR = 5, // Error logging, used on unrecoverable failures + ERROR = 5, LOG_FATAL = 6, // Fatal logging, used to abort program: exit(EXIT_FAILURE) - LOG_NONE = 7 // Disable logging + FATAL = 6, + LOG_NONE = 7, // Disable logging + NONE = 7 } // Keyboard keys (US keyboard layout) @@ -535,202 +554,370 @@ enum TraceLogLevel enum KeyboardKey { KEY_NULL = 0, // Key: NULL, used for no key pressed + NULL = 0, // Alphanumeric keys KEY_APOSTROPHE = 39, // Key: ' + APOSTROPHE = 39, KEY_COMMA = 44, // Key: , + COMMA = 44, KEY_MINUS = 45, // Key: - + MINUS = 45, KEY_PERIOD = 46, // Key: . + PERIOD = 46, KEY_SLASH = 47, // Key: / + SLASH = 47, KEY_ZERO = 48, // Key: 0 + ZERO = 48, KEY_ONE = 49, // Key: 1 + ONE = 49, KEY_TWO = 50, // Key: 2 + TWO = 50, KEY_THREE = 51, // Key: 3 + THREE = 51, KEY_FOUR = 52, // Key: 4 + FOUR = 52, KEY_FIVE = 53, // Key: 5 + FIVE = 53, KEY_SIX = 54, // Key: 6 + SIX = 54, KEY_SEVEN = 55, // Key: 7 + SEVEN = 55, KEY_EIGHT = 56, // Key: 8 + EIGHT = 56, KEY_NINE = 57, // Key: 9 + NINE = 57, KEY_SEMICOLON = 59, // Key: ; + SEMICOLON = 59, KEY_EQUAL = 61, // Key: = + EQUAL = 61, KEY_A = 65, // Key: A | a + A = 65, KEY_B = 66, // Key: B | b + B = 66, KEY_C = 67, // Key: C | c + C = 67, KEY_D = 68, // Key: D | d + D = 68, KEY_E = 69, // Key: E | e + E = 69, KEY_F = 70, // Key: F | f + F = 70, KEY_G = 71, // Key: G | g + G = 71, KEY_H = 72, // Key: H | h + H = 72, KEY_I = 73, // Key: I | i + I = 73, KEY_J = 74, // Key: J | j + J = 74, KEY_K = 75, // Key: K | k + K = 75, KEY_L = 76, // Key: L | l + L = 76, KEY_M = 77, // Key: M | m + M = 77, KEY_N = 78, // Key: N | n + N = 78, KEY_O = 79, // Key: O | o + O = 79, KEY_P = 80, // Key: P | p + P = 80, KEY_Q = 81, // Key: Q | q + Q = 81, KEY_R = 82, // Key: R | r + R = 82, KEY_S = 83, // Key: S | s + S = 83, KEY_T = 84, // Key: T | t + T = 84, KEY_U = 85, // Key: U | u + U = 85, KEY_V = 86, // Key: V | v + V = 86, KEY_W = 87, // Key: W | w + W = 87, KEY_X = 88, // Key: X | x + X = 88, KEY_Y = 89, // Key: Y | y + Y = 89, KEY_Z = 90, // Key: Z | z + Z = 90, KEY_LEFT_BRACKET = 91, // Key: [ + LEFT_BRACKET = 91, KEY_BACKSLASH = 92, // Key: '\' + BACKSLASH = 92, KEY_RIGHT_BRACKET = 93, // Key: ] + RIGHT_BRACKET = 93, KEY_GRAVE = 96, // Key: ` + GRAVE = 96, // Function keys KEY_SPACE = 32, // Key: Space + SPACE = 32, KEY_ESCAPE = 256, // Key: Esc + ESCAPE = 256, KEY_ENTER = 257, // Key: Enter + ENTER = 257, KEY_TAB = 258, // Key: Tab + TAB = 258, KEY_BACKSPACE = 259, // Key: Backspace + BACKSPACE = 259, KEY_INSERT = 260, // Key: Ins + INSERT = 260, KEY_DELETE = 261, // Key: Del + DELETE = 261, KEY_RIGHT = 262, // Key: Cursor right + RIGHT = 262, KEY_LEFT = 263, // Key: Cursor left + LEFT = 263, KEY_DOWN = 264, // Key: Cursor down + DOWN = 264, KEY_UP = 265, // Key: Cursor up + UP = 265, KEY_PAGE_UP = 266, // Key: Page up + PAGE_UP = 266, KEY_PAGE_DOWN = 267, // Key: Page down + PAGE_DOWN = 267, KEY_HOME = 268, // Key: Home + HOME = 268, KEY_END = 269, // Key: End + END = 269, KEY_CAPS_LOCK = 280, // Key: Caps lock + CAPS_LOCK = 280, KEY_SCROLL_LOCK = 281, // Key: Scroll down + SCROLL_LOCK = 281, KEY_NUM_LOCK = 282, // Key: Num lock + NUM_LOCK = 282, KEY_PRINT_SCREEN = 283, // Key: Print screen + PRINT_SCREEN = 283, KEY_PAUSE = 284, // Key: Pause + PAUSE = 284, KEY_F1 = 290, // Key: F1 + F1 = 290, KEY_F2 = 291, // Key: F2 + F2 = 291, KEY_F3 = 292, // Key: F3 + F3 = 292, KEY_F4 = 293, // Key: F4 + F4 = 293, KEY_F5 = 294, // Key: F5 + F5 = 294, KEY_F6 = 295, // Key: F6 + F6 = 295, KEY_F7 = 296, // Key: F7 + F7 = 296, KEY_F8 = 297, // Key: F8 + F8 = 297, KEY_F9 = 298, // Key: F9 + F9 = 298, KEY_F10 = 299, // Key: F10 + F10 = 299, KEY_F11 = 300, // Key: F11 + F11 = 300, KEY_F12 = 301, // Key: F12 + F12 = 301, KEY_LEFT_SHIFT = 340, // Key: Shift left + LEFT_SHIFT = 340, KEY_LEFT_CONTROL = 341, // Key: Control left + LEFT_CONTROL = 341, KEY_LEFT_ALT = 342, // Key: Alt left + LEFT_ALT = 342, KEY_LEFT_SUPER = 343, // Key: Super left + LEFT_SUPER = 343, KEY_RIGHT_SHIFT = 344, // Key: Shift right + RIGHT_SHIFT = 344, KEY_RIGHT_CONTROL = 345, // Key: Control right + RIGHT_CONTROL = 345, KEY_RIGHT_ALT = 346, // Key: Alt right + RIGHT_ALT = 346, KEY_RIGHT_SUPER = 347, // Key: Super right + RIGHT_SUPER = 347, KEY_KB_MENU = 348, // Key: KB menu + KB_MENU = 348, // Keypad keys KEY_KP_0 = 320, // Key: Keypad 0 + KP_0 = 320, KEY_KP_1 = 321, // Key: Keypad 1 + KP_1 = 321, KEY_KP_2 = 322, // Key: Keypad 2 + KP_2 = 322, KEY_KP_3 = 323, // Key: Keypad 3 + KP_3 = 323, KEY_KP_4 = 324, // Key: Keypad 4 + KP_4 = 324, KEY_KP_5 = 325, // Key: Keypad 5 + KP_5 = 325, KEY_KP_6 = 326, // Key: Keypad 6 + KP_6 = 326, KEY_KP_7 = 327, // Key: Keypad 7 + KP_7 = 327, KEY_KP_8 = 328, // Key: Keypad 8 + KP_8 = 328, KEY_KP_9 = 329, // Key: Keypad 9 + KP_9 = 329, KEY_KP_DECIMAL = 330, // Key: Keypad . + KP_DECIMAL = 330, KEY_KP_DIVIDE = 331, // Key: Keypad / + KP_DIVIDE = 331, KEY_KP_MULTIPLY = 332, // Key: Keypad * + KP_MULTIPLY = 332, KEY_KP_SUBTRACT = 333, // Key: Keypad - + KP_SUBTRACT = 333, KEY_KP_ADD = 334, // Key: Keypad + + KP_ADD = 334, KEY_KP_ENTER = 335, // Key: Keypad Enter + KP_ENTER = 335, KEY_KP_EQUAL = 336, // Key: Keypad = + KP_EQUAL = 336, // Android key buttons KEY_BACK = 4, // Key: Android back button + BACK = 4, KEY_MENU = 82, // Key: Android menu button + MENU = 82, KEY_VOLUME_UP = 24, // Key: Android volume up button - KEY_VOLUME_DOWN = 25 // Key: Android volume down button + VOLUME_UP = 24, + KEY_VOLUME_DOWN = 25, // Key: Android volume down button + VOLUME_DOWN = 25, } // Add backwards compatibility support for deprecated names -enum MOUSE_LEFT_BUTTON = MouseButton.MOUSE_BUTTON_LEFT; -enum MOUSE_RIGHT_BUTTON = MouseButton.MOUSE_BUTTON_RIGHT; -enum MOUSE_MIDDLE_BUTTON = MouseButton.MOUSE_BUTTON_MIDDLE; +deprecated enum MOUSE_LEFT_BUTTON = MouseButton.MOUSE_BUTTON_LEFT; +deprecated enum MOUSE_RIGHT_BUTTON = MouseButton.MOUSE_BUTTON_RIGHT; +deprecated enum MOUSE_MIDDLE_BUTTON = MouseButton.MOUSE_BUTTON_MIDDLE; // Mouse buttons enum MouseButton { MOUSE_BUTTON_LEFT = 0, // Mouse button left + LEFT = 0, MOUSE_BUTTON_RIGHT = 1, // Mouse button right + RIGHT = 1, MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) + MIDDLE = 2, MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) + SIDE = 3, MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device) - MOUSE_BUTTON_BACK = 6 // Mouse button back (advanced mouse device) + FORWARD = 5, + MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) + BACK = 6 } // Mouse cursor enum MouseCursor { MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape + DEFAULT = 0, MOUSE_CURSOR_ARROW = 1, // Arrow shape + ARROW = 1, MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape + IBEAM = 2, MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape + CROSSHAIR = 3, MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor + POINTING_HAND = 4, MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape + RESIZE_EW = 5, MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape + RESIZE_NS = 6, MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape + RESIZE_NWSE = 7, MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape + RESIZE_NESW = 8, MOUSE_CURSOR_RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape - MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape + RESIZE_ALL = 9, + MOUSE_CURSOR_NOT_ALLOWED = 10, // The operation-not-allowed shape + NOT_ALLOWED = 10 } // Gamepad buttons enum GamepadButton { GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking + UNKNOWN = 0, GAMEPAD_BUTTON_LEFT_FACE_UP = 1, // Gamepad left DPAD up button + DPAD_UP = 1, GAMEPAD_BUTTON_LEFT_FACE_RIGHT = 2, // Gamepad left DPAD right button + DPAD_RIGHT = 2, GAMEPAD_BUTTON_LEFT_FACE_DOWN = 3, // Gamepad left DPAD down button + DPAD_DOWN = 3, GAMEPAD_BUTTON_LEFT_FACE_LEFT = 4, // Gamepad left DPAD left button + DPAD_LEFT = 4, GAMEPAD_BUTTON_RIGHT_FACE_UP = 5, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + FACE_UP = 5, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT = 6, // Gamepad right button right (i.e. PS3: Square, Xbox: X) + FACE_RIGHT = 6, GAMEPAD_BUTTON_RIGHT_FACE_DOWN = 7, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) + FACE_DOWN = 7, GAMEPAD_BUTTON_RIGHT_FACE_LEFT = 8, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) - GAMEPAD_BUTTON_LEFT_TRIGGER_1 = 9, // Gamepad top/back trigger left (first), it could be a trailing button - GAMEPAD_BUTTON_LEFT_TRIGGER_2 = 10, // Gamepad top/back trigger left (second), it could be a trailing button - GAMEPAD_BUTTON_RIGHT_TRIGGER_1 = 11, // Gamepad top/back trigger right (one), it could be a trailing button - GAMEPAD_BUTTON_RIGHT_TRIGGER_2 = 12, // Gamepad top/back trigger right (second), it could be a trailing button + FACE_LEFT = 8, + GAMEPAD_BUTTON_LEFT_TRIGGER_1 = 9, // Gamepad top/back shoulder/trigger left (first), it could be a trailing button + LEFT_SHOULDER = 9, + SHOULDER_LEFT = 9, + GAMEPAD_BUTTON_LEFT_TRIGGER_2 = 10, // Gamepad top/back shoulder/trigger left (second), it could be a trailing button + LEFT_TRIGGER = 10, + TRIGGER_LEFT = 10, + GAMEPAD_BUTTON_RIGHT_TRIGGER_1 = 11, // Gamepad top/back shoulder/trigger right (one), it could be a trailing button + RIGHT_SHOULDER = 11, + SHOULDER_RIGHT = 11, + GAMEPAD_BUTTON_RIGHT_TRIGGER_2 = 12, // Gamepad top/back shoulder/trigger right (second), it could be a trailing button + RIGHT_TRIGGER = 12, + TRIGGER_RIGHT = 12, GAMEPAD_BUTTON_MIDDLE_LEFT = 13, // Gamepad center buttons, left one (i.e. PS3: Select) + MIDDLE_LEFT = 13, GAMEPAD_BUTTON_MIDDLE = 14, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + MIDDLE_MIDDLE = 14, GAMEPAD_BUTTON_MIDDLE_RIGHT = 15, // Gamepad center buttons, right one (i.e. PS3: Start) + MIDDLE_RIGHT = 15, GAMEPAD_BUTTON_LEFT_THUMB = 16, // Gamepad joystick pressed button left - GAMEPAD_BUTTON_RIGHT_THUMB = 17 // Gamepad joystick pressed button right + LEFT_STICK = 16, + GAMEPAD_BUTTON_RIGHT_THUMB = 17, // Gamepad joystick pressed button right + RIGHT_STICK = 17, } // Gamepad axis enum GamepadAxis { GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis + LEFT_X = 0, GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis + LEFT_Y = 1, GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis + RIGHT_X = 2, GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis + RIGHT_Y = 3, GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] - GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] + LEFT_TRIGGER = 4, + TRIGGER_LEFT = 4, + GAMEPAD_AXIS_RIGHT_TRIGGER = 5, // Gamepad back trigger right, pressure level: [1..-1] + RIGHT_TRIGGER = 5, + TRIGGER_RIGHT = 5, } // Material map index enum MaterialMapIndex { MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) + ALBEDO = 0, MATERIAL_MAP_METALNESS = 1, // Metalness material (same as: MATERIAL_MAP_SPECULAR) + METALNESS = 1, MATERIAL_MAP_NORMAL = 2, // Normal material + NORMAL = 2, MATERIAL_MAP_ROUGHNESS = 3, // Roughness material + ROUGHNESS = 3, MATERIAL_MAP_OCCLUSION = 4, // Ambient occlusion material + OCCLUSION = 4, MATERIAL_MAP_EMISSION = 5, // Emission material + EMISSION = 5, MATERIAL_MAP_HEIGHT = 6, // Heightmap material + HEIGHT = 6, MATERIAL_MAP_CUBEMAP = 7, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + CUBEMAP = 7, MATERIAL_MAP_IRRADIANCE = 8, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + IRRADIANCE = 8, MATERIAL_MAP_PREFILTER = 9, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - MATERIAL_MAP_BRDF = 10 // Brdf material + PREFILTER = 9, + MATERIAL_MAP_BRDF = 10, // Brdf material + BRDF = 10 } enum MATERIAL_MAP_DIFFUSE = MaterialMapIndex.MATERIAL_MAP_ALBEDO; @@ -739,32 +926,58 @@ enum MATERIAL_MAP_SPECULAR = MaterialMapIndex.MATERIAL_MAP_METALNESS; // Shader location index enum ShaderLocationIndex { - SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + VERTEX_POSITION = 0, SHADER_LOC_VERTEX_TEXCOORD01 = 1, // Shader location: vertex attribute: texcoord01 + VERTEX_TEXCOORD01 = 1, SHADER_LOC_VERTEX_TEXCOORD02 = 2, // Shader location: vertex attribute: texcoord02 + VERTEX_TEXCOORD02 = 2, SHADER_LOC_VERTEX_NORMAL = 3, // Shader location: vertex attribute: normal + VERTEX_NORMAL = 3, SHADER_LOC_VERTEX_TANGENT = 4, // Shader location: vertex attribute: tangent + VERTEX_TANGENT = 4, SHADER_LOC_VERTEX_COLOR = 5, // Shader location: vertex attribute: color + VERTEX_COLOR = 5, SHADER_LOC_MATRIX_MVP = 6, // Shader location: matrix uniform: model-view-projection + MATRIX_MVP = 6, SHADER_LOC_MATRIX_VIEW = 7, // Shader location: matrix uniform: view (camera transform) + MATRIX_VIEW = 7, SHADER_LOC_MATRIX_PROJECTION = 8, // Shader location: matrix uniform: projection + MATRIX_PROJECTION = 8, SHADER_LOC_MATRIX_MODEL = 9, // Shader location: matrix uniform: model (transform) + MATRIX_MODEL = 9, SHADER_LOC_MATRIX_NORMAL = 10, // Shader location: matrix uniform: normal + MATRIX_NORMAL = 10, SHADER_LOC_VECTOR_VIEW = 11, // Shader location: vector uniform: view + VECTOR_VIEW = 11, SHADER_LOC_COLOR_DIFFUSE = 12, // Shader location: vector uniform: diffuse color + COLOR_DIFFUSE = 12, SHADER_LOC_COLOR_SPECULAR = 13, // Shader location: vector uniform: specular color + COLOR_SPECULAR = 13, SHADER_LOC_COLOR_AMBIENT = 14, // Shader location: vector uniform: ambient color + COLOR_AMBIENT = 14, SHADER_LOC_MAP_ALBEDO = 15, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + MAP_ALBEDO = 15, SHADER_LOC_MAP_METALNESS = 16, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + MAP_METALNESS = 16, SHADER_LOC_MAP_NORMAL = 17, // Shader location: sampler2d texture: normal + MAP_NORMAL = 17, SHADER_LOC_MAP_ROUGHNESS = 18, // Shader location: sampler2d texture: roughness + MAP_ROUGHNESS = 18, SHADER_LOC_MAP_OCCLUSION = 19, // Shader location: sampler2d texture: occlusion + MAP_OCCLUSION = 19, SHADER_LOC_MAP_EMISSION = 20, // Shader location: sampler2d texture: emission + MAP_EMISSION = 20, SHADER_LOC_MAP_HEIGHT = 21, // Shader location: sampler2d texture: height + MAP_HEIGHT = 21, SHADER_LOC_MAP_CUBEMAP = 22, // Shader location: samplerCube texture: cubemap + MAP_CUBEMAP = 22, SHADER_LOC_MAP_IRRADIANCE = 23, // Shader location: samplerCube texture: irradiance + MAP_IRRADIANCE = 23, SHADER_LOC_MAP_PREFILTER = 24, // Shader location: samplerCube texture: prefilter - SHADER_LOC_MAP_BRDF = 25 // Shader location: sampler2d texture: brdf + MAP_PREFILTER = 24, + SHADER_LOC_MAP_BRDF = 25, // Shader location: sampler2d texture: brdf + MAP_BRDF = 25 } enum SHADER_LOC_MAP_DIFFUSE = ShaderLocationIndex.SHADER_LOC_MAP_ALBEDO; @@ -774,23 +987,36 @@ enum SHADER_LOC_MAP_SPECULAR = ShaderLocationIndex.SHADER_LOC_MAP_METALNESS; enum ShaderUniformDataType { SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + FLOAT = 0, SHADER_UNIFORM_VEC2 = 1, // Shader uniform type: vec2 (2 float) + VEC2 = 1, SHADER_UNIFORM_VEC3 = 2, // Shader uniform type: vec3 (3 float) + VEC3 = 2, SHADER_UNIFORM_VEC4 = 3, // Shader uniform type: vec4 (4 float) + VEC4 = 3, SHADER_UNIFORM_INT = 4, // Shader uniform type: int + INT = 4, SHADER_UNIFORM_IVEC2 = 5, // Shader uniform type: ivec2 (2 int) + IVEC2 = 5, SHADER_UNIFORM_IVEC3 = 6, // Shader uniform type: ivec3 (3 int) + IVEC3 = 6, SHADER_UNIFORM_IVEC4 = 7, // Shader uniform type: ivec4 (4 int) - SHADER_UNIFORM_SAMPLER2D = 8 // Shader uniform type: sampler2d + IVEC4 = 7, + SHADER_UNIFORM_SAMPLER2D = 8, // Shader uniform type: sampler2d + SAMPLER2D = 8 } // Shader attribute data types enum ShaderAttributeDataType { SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + FLOAT = 0, SHADER_ATTRIB_VEC2 = 1, // Shader attribute type: vec2 (2 float) + VEC2 = 1, SHADER_ATTRIB_VEC3 = 2, // Shader attribute type: vec3 (3 float) - SHADER_ATTRIB_VEC4 = 3 // Shader attribute type: vec4 (4 float) + VEC3 = 2, + SHADER_ATTRIB_VEC4 = 3, // Shader attribute type: vec4 (4 float) + VEC4 = 3 } // Pixel formats @@ -798,29 +1024,53 @@ enum ShaderAttributeDataType enum PixelFormat { PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + UNCOMPRESSED_GRAYSCALE = 1, PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA = 2, // 8*2 bpp (2 channels) + UNCOMPRESSED_GRAY_ALPHA = 2, PIXELFORMAT_UNCOMPRESSED_R5G6B5 = 3, // 16 bpp + UNCOMPRESSED_R5G6B5 = 3, PIXELFORMAT_UNCOMPRESSED_R8G8B8 = 4, // 24 bpp + UNCOMPRESSED_R8G8B8 = 4, PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 = 5, // 16 bpp (1 bit alpha) + UNCOMPRESSED_R5G5B5A1 = 5, PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 = 6, // 16 bpp (4 bit alpha) + UNCOMPRESSED_R4G4B4A4 = 6, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 = 7, // 32 bpp + UNCOMPRESSED_R8G8B8A8 = 7, PIXELFORMAT_UNCOMPRESSED_R32 = 8, // 32 bpp (1 channel - float) + UNCOMPRESSED_R32 = 8, PIXELFORMAT_UNCOMPRESSED_R32G32B32 = 9, // 32*3 bpp (3 channels - float) + UNCOMPRESSED_R32G32B32 = 9, PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 = 10, // 32*4 bpp (4 channels - float) + UNCOMPRESSED_R32G32B32A32 = 10, PIXELFORMAT_UNCOMPRESSED_R16 = 11, // 16 bpp (1 channel - half float) + UNCOMPRESSED_R16 = 11, PIXELFORMAT_UNCOMPRESSED_R16G16B16 = 12, // 16*3 bpp (3 channels - half float) + UNCOMPRESSED_R16G16B16 = 12, PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 = 13, // 16*4 bpp (4 channels - half float) + UNCOMPRESSED_R16G16B16A16 = 13, PIXELFORMAT_COMPRESSED_DXT1_RGB = 14, // 4 bpp (no alpha) + COMPRESSED_DXT1_RGB = 14, PIXELFORMAT_COMPRESSED_DXT1_RGBA = 15, // 4 bpp (1 bit alpha) + COMPRESSED_DXT1_RGBA = 15, PIXELFORMAT_COMPRESSED_DXT3_RGBA = 16, // 8 bpp + COMPRESSED_DXT3_RGBA = 16, PIXELFORMAT_COMPRESSED_DXT5_RGBA = 17, // 8 bpp + COMPRESSED_DXT5_RGBA = 17, PIXELFORMAT_COMPRESSED_ETC1_RGB = 18, // 4 bpp + COMPRESSED_ETC1_RGB = 18, PIXELFORMAT_COMPRESSED_ETC2_RGB = 19, // 4 bpp + COMPRESSED_ETC2_RGB = 19, PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA = 20, // 8 bpp + COMPRESSED_ETC2_EAC_RGBA = 20, PIXELFORMAT_COMPRESSED_PVRT_RGB = 21, // 4 bpp + COMPRESSED_PVRT_RGB = 21, PIXELFORMAT_COMPRESSED_PVRT_RGBA = 22, // 4 bpp + COMPRESSED_PVRT_RGBA = 22, PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA = 23, // 8 bpp - PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24 // 2 bpp + COMPRESSED_ASTC_4x4_RGBA = 23, + PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24, // 2 bpp + COMPRESSED_ASTC_8x8_RGBA = 24 } // Texture parameters: filter mode @@ -829,52 +1079,79 @@ enum PixelFormat enum TextureFilter { TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + POINT = 0, TEXTURE_FILTER_BILINEAR = 1, // Linear filtering + BILINEAR = 1, TEXTURE_FILTER_TRILINEAR = 2, // Trilinear filtering (linear with mipmaps) + TRILINEAR = 2, TEXTURE_FILTER_ANISOTROPIC_4X = 3, // Anisotropic filtering 4x + ANISOTROPIC_4X = 3, TEXTURE_FILTER_ANISOTROPIC_8X = 4, // Anisotropic filtering 8x - TEXTURE_FILTER_ANISOTROPIC_16X = 5 // Anisotropic filtering 16x + ANISOTROPIC_8X = 4, + TEXTURE_FILTER_ANISOTROPIC_16X = 5, // Anisotropic filtering 16x + ANISOTROPIC_16X = 5 } // Texture parameters: wrap mode enum TextureWrap { TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode + REPEAT = 0, TEXTURE_WRAP_CLAMP = 1, // Clamps texture to edge pixel in tiled mode + CLAMP = 1, TEXTURE_WRAP_MIRROR_REPEAT = 2, // Mirrors and repeats the texture in tiled mode - TEXTURE_WRAP_MIRROR_CLAMP = 3 // Mirrors and clamps to border the texture in tiled mode + MIRROR_REPEAT = 2, + TEXTURE_WRAP_MIRROR_CLAMP = 3, // Mirrors and clamps to border the texture in tiled mode + MIRROR_CLAMP = 3 } // Cubemap layouts enum CubemapLayout { CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type + AUTO_DETECT = 0, CUBEMAP_LAYOUT_LINE_VERTICAL = 1, // Layout is defined by a vertical line with faces + LINE_VERTICAL = 1, CUBEMAP_LAYOUT_LINE_HORIZONTAL = 2, // Layout is defined by a horizontal line with faces + LINE_HORIZONTAL = 2, CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR = 3, // Layout is defined by a 3x4 cross with cubemap faces + CROSS_THREE_BY_FOUR = 3, CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE = 4, // Layout is defined by a 4x3 cross with cubemap faces - CUBEMAP_LAYOUT_PANORAMA = 5 // Layout is defined by a panorama image (equirrectangular map) + CROSS_FOUR_BY_THREE = 4, + CUBEMAP_LAYOUT_PANORAMA = 5, // Layout is defined by a panorama image (equirrectangular map) + PANORAMA = 5 } // Font type, defines generation method enum FontType { - FONT_DEFAULT = 0, // Default font generation, anti-aliased + FONT_DEFAULT = 0, // Default font generation, anti-aliased + DEFAULT = 0, FONT_BITMAP = 1, // Bitmap font generation, no anti-aliasing - FONT_SDF = 2 // SDF font generation, requires external shader + BITMAP = 1, + FONT_SDF = 2, // SDF font generation, requires external shader + SDF = 2 } // Color blending modes (pre-defined) enum BlendMode { - BLEND_ALPHA = 0, // Blend textures considering alpha (default) - BLEND_ADDITIVE = 1, // Blend textures adding colors - BLEND_MULTIPLIED = 2, // Blend textures multiplying colors - BLEND_ADD_COLORS = 3, // Blend textures adding colors (alternative) - BLEND_SUBTRACT_COLORS = 4, // Blend textures subtracting colors (alternative) - BLEND_ALPHA_PREMULTIPLY = 5, // Blend premultiplied textures considering alpha - BLEND_CUSTOM = 6, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) - BLEND_CUSTOM_SEPARATE = 7 // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) + BLENDMODE_BLEND_ALPHA = 0, // Blend textures considering alpha (default) + BLEND_ALPHA = 0, + BLENDMODE_BLEND_ADDITIVE = 1, // Blend textures adding colors + BLEND_ADDITIVE = 1, + BLENDMODE_BLEND_MULTIPLIED = 2, // Blend textures multiplying colors + BLEND_MULTIPLIED = 2, + BLENDMODE_BLEND_ADD_COLORS = 3, // Blend textures adding colors (alternative) + BLEND_ADD_COLORS = 3, + BLENDMODE_BLEND_SUBTRACT_COLORS = 4, // Blend textures subtracting colors (alternative) + BLEND_SUBTRACT_COLORS = 4, + BLENDMODE_BLEND_ALPHA_PREMULTIPLY = 5, // Blend premultiplied textures considering alpha + BLEND_ALPHA_PREMULTIPLY = 5, + BLENDMODE_BLEND_CUSTOM = 6, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + BLEND_CUSTOM = 6, + BLENDMODE_BLEND_CUSTOM_SEPARATE = 7, // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) + BLEND_CUSTOM_SEPARATE = 7 } // Gesture @@ -882,41 +1159,62 @@ enum BlendMode enum Gesture { GESTURE_NONE = 0, // No gesture + NONE = 0, GESTURE_TAP = 1, // Tap gesture + TAP = 1, GESTURE_DOUBLETAP = 2, // Double tap gesture + DOUBLETAP = 2, GESTURE_HOLD = 4, // Hold gesture + HOLD = 4, GESTURE_DRAG = 8, // Drag gesture + DRAG = 8, GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture + SWIPE_RIGHT = 16, GESTURE_SWIPE_LEFT = 32, // Swipe left gesture + SWIPE_LEFT = 32, GESTURE_SWIPE_UP = 64, // Swipe up gesture + SWIPE_UP = 64, GESTURE_SWIPE_DOWN = 128, // Swipe down gesture + SWIPE_DOWN = 128, GESTURE_PINCH_IN = 256, // Pinch in gesture - GESTURE_PINCH_OUT = 512 // Pinch out gesture + PINCH_IN = 256, + GESTURE_PINCH_OUT = 512, // Pinch out gesture + PINCH_OUT = 512 } // Camera system modes enum CameraMode { CAMERA_CUSTOM = 0, // Custom camera + CUSTOM = 0, CAMERA_FREE = 1, // Free camera + FREE = 1, CAMERA_ORBITAL = 2, // Orbital camera + ORBITAL = 2, CAMERA_FIRST_PERSON = 3, // First person camera - CAMERA_THIRD_PERSON = 4 // Third person camera + FIRST_PERSON = 3, + CAMERA_THIRD_PERSON = 4, // Third person camera + THIRD_PERSON = 4 } // Camera projection enum CameraProjection { CAMERA_PERSPECTIVE = 0, // Perspective projection - CAMERA_ORTHOGRAPHIC = 1 // Orthographic projection + PERSPECTIVE = 0, + CAMERA_ORTHOGRAPHIC = 1, // Orthographic projection + ORTHOGRAPHIC = 1 } // N-patch layout enum NPatchLayout { - NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles + NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles + NINE_PATCH = 0, NPATCH_THREE_PATCH_VERTICAL = 1, // Npatch layout: 1x3 tiles - NPATCH_THREE_PATCH_HORIZONTAL = 2 // Npatch layout: 3x1 tiles + THREE_PATCH_VERTICAL = 1, + NPATCH_THREE_PATCH_HORIZONTAL = 2, // Npatch layout: 3x1 tiles + THREE_PATCH_HORIZONTAL = 2 } // Callbacks to hook some internal functions @@ -1643,4 +1941,5 @@ void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as s void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline -// RAYLIB_H +// To generate overloads using `string` arguments instead of `const(char)*`: +//mixin GenerateOverloadsWithStrings!"raylib"; \ No newline at end of file diff --git a/source/raylib/raylib_types.d b/source/raylib/raylib_types.d index d1f4199..9b945e4 100644 --- a/source/raylib/raylib_types.d +++ b/source/raylib/raylib_types.d @@ -2,6 +2,12 @@ module raylib.raylib_types; import raylib; +debug import std.stdio; + +version (enhancedD) const ED = true; +else const ED = false; + +@safe: // Vector2 type struct Vector2 @@ -54,6 +60,17 @@ struct Matrix float m15 = 0.0f; } +// Camera2D, defines position/orientation in 2d space +struct Camera2D +{ + + Vector2 offset; // Camera offset (displacement from target) + Vector2 target; // Camera target (rotation and zoom origin) + float rotation; // Camera rotation in degrees + // Warning: In Raylib, & previous versions of Raylib-D, `zoom` is initially `0.0f`. + float zoom = 1f; // Camera zoom (scaling), should be 1.0f by default +} + // Rectangle type struct Rectangle { @@ -64,6 +81,11 @@ struct Rectangle alias w = width; alias h = height; + float top() {return y;} + float bottom() {return y + height;} + float left() {return x;} + float right() {return x + width;} + Vector2 origin() { // Rectangle function exclusive to raylib-d return Vector2(x, y); } @@ -102,6 +124,8 @@ struct Rectangle result.opOpAssign!op(offset); return result; } + + Vector2 opCast(T)() if (is(T==Vector2)) => origin(); } enum Colors diff --git a/source/templates.d b/source/templates.d new file mode 100644 index 0000000..40f2278 --- /dev/null +++ b/source/templates.d @@ -0,0 +1,63 @@ +module raylibd_templates; + +import std.traits; +import std.conv; + +string EnumPrefixes(T)(string oldName, string prefix) { + string result = "enum " ~ oldName ~ " {\n"; + static foreach(member; __traits(allMembers, T)) { + result ~= " " ~ prefix ~ member ~ " = " ~ __traits(getMember, T, member).to!int.to!string ~ ",\n"; + } + return result ~ "}\n"; +} + +string EnumPrefixes(T)(string prefix) { + string result; + static foreach(member; __traits(allMembers, T)) { + result ~= "enum " ~ T.stringof ~ " " ~ prefix ~ member ~ " = " ~ T.stringof ~ "." ~ member ~ ";\n"; + } + return result; +} + +template OverloadWithString(Args) { + static if (is(Args == function)) { + // Extract function name + alias Func FunctionType; + enum funcName = __traits(identifier, FunctionType); + + // Extract function parameters + alias Params = ParameterTypeTuple!FunctionType; + + // Convert const(char)* to string + alias ConvertedParams = staticMap!(ToConstCharPointer, Params); + + // Generate overloaded function signature with string arguments + string generateOverload(alias name, alias params)() { + bool hasCString; + + string result = "void " ~ name ~ "("; + foreach (param; params) { + if (param.stringof == "const(char)*") { + result ~= "string " ~ __traits(identifier, param) ~ ", "; + hasCString = true; + } else result ~= param.stringof ~ " " ~ __traits(identifier, param) ~ ", "; + } + if (!hasCString) return ""; + result ~= ") {" ~ name ~ "("; + foreach (param; params) { + result ~= "toStringz(" ~ __traits(identifier, param) ~ "), "; + } + result ~= "); }"; + return result; + } + + // Generate and mixin the overloaded function definition + mixin(generateOverload!(funcName, ConvertedParams)); + } +} + +template GenerateOverloadsWithStrings(string moduleName) { + static foreach (f; __traits(allMembers, mixin(moduleName))) { + mixin("OverloadWithString!" ~ f ~ "();"); + } +}