mirror of
https://github.com/raysan5/raygui.git
synced 2025-12-25 10:22:33 -05:00
1312 lines
64 KiB
C
1312 lines
64 KiB
C
/*******************************************************************************************
|
|
*
|
|
* raylib GUI layout editor
|
|
*
|
|
* This example has been created using raylib 1.6 (www.raylib.com)
|
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
|
*
|
|
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
|
*
|
|
********************************************************************************************/
|
|
|
|
#include "raylib.h"
|
|
|
|
#define RAYGUI_IMPLEMENTATION
|
|
#define RAYGUI_STYLE_SAVE_LOAD
|
|
#include "raygui.h"
|
|
#include "easings.h"
|
|
#include "external/tinyfiledialogs.h" // Open/Save file dialogs
|
|
|
|
#include <stdlib.h>
|
|
|
|
#if defined(_WIN32)
|
|
#include <direct.h>
|
|
#define GetCurrentDir _getcwd
|
|
#else
|
|
#include <unistd.h>
|
|
#define GetCurrentDir getcwd
|
|
#endif
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Defines and Macros
|
|
//----------------------------------------------------------------------------------
|
|
#define MAX_GUI_CONTROLS 64 // Maximum number of gui controls
|
|
#define MAX_ANCHOR_POINTS 8 // Maximum number of anchor points
|
|
|
|
#define GRID_LINE_SPACING 10 // Grid line spacing in pixels
|
|
#define GRID_ALPHA 0.1f // Grid lines alpha amount
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Types and Structures Definition
|
|
//----------------------------------------------------------------------------------
|
|
typedef enum {
|
|
LABEL = 0,
|
|
BUTTON,
|
|
IMAGEBUTTON,
|
|
TOGGLE,
|
|
TOGGLEGROUP,
|
|
SLIDER,
|
|
SLIDERBAR,
|
|
PROGRESSBAR,
|
|
SPINNER,
|
|
COMBOBOX,
|
|
CHECKBOX,
|
|
TEXTBOX,
|
|
GROUPBOX,
|
|
WINDOWBOX,
|
|
LISTVIEW,
|
|
COLORPICKER
|
|
} GuiControlType;
|
|
|
|
// Anchor point type
|
|
typedef struct {
|
|
int id;
|
|
int x;
|
|
int y;
|
|
float radius;
|
|
bool enabled;
|
|
} AnchorPoint;
|
|
|
|
// Gui control type
|
|
typedef struct {
|
|
int id;
|
|
int type;
|
|
Rectangle rec;
|
|
unsigned char *text;
|
|
AnchorPoint *ap;
|
|
} GuiControl;
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Global Variables Definition
|
|
//----------------------------------------------------------------------------------
|
|
static char currentPath[256]; // Path to current working folder
|
|
static int screenWidth = 800;
|
|
static int screenHeight = 600;
|
|
|
|
static GuiControl layout[MAX_GUI_CONTROLS] = { 0 };
|
|
static AnchorPoint anchors[MAX_ANCHOR_POINTS];
|
|
static int controlsCounter = 0;
|
|
static int anchorCounter = 1; // NOTE: anchorCounter starts at 1 because the global anchor is 0
|
|
|
|
const char *controlTypeName[] = { "LABEL", "BUTTON", "IMAGEBUTTON", "TOGGLE", "TOGGLEGROUP", "SLIDER", "SLIDERBAR", "PROGRESSBAR", "SPINNER", "COMBOBOX", "CHECKBOX", "TEXTBOX", "GROUPBOX", "WINDOWBOX", "LISTVIEW", "COLORPICKER" };
|
|
const char *controlTypeNameLow[] = { "Label", "Button", "ImageButton", "Toggle", "ToggleGroup", "Slider", "SliderBar", "ProgressBar", "Spinner", "ComboBox", "CheckBox", "TextBox", "GroupBox", "WindowBox", "ListView", "ColorPicker" };
|
|
const char *controlTypeNameShort[] = { "lbl", "btn", "ibtn", "tggl", "tgroup", "sldr", "sldrb", "prgssb", "spnr", "combox", "chkbox", "txtbox", "grpbox", "wdwbox", "lstvw", "clrpckr" };
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Module specific Functions Declaration
|
|
//----------------------------------------------------------------------------------
|
|
static void DrawGrid2D(int divsX, int divsY); // Draw 2d grid with horizontal and vertical lines depending on the screen size
|
|
static void SaveLayoutRGL(const char *fileName, bool binary); // Save gui layout project information
|
|
static void LoadLayoutRGL(const char *fileName); // Load gui layout project information
|
|
static void GenerateLayoutCode(const char *fileName); // Generate C code for gui layout
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Main Entry point
|
|
//----------------------------------------------------------------------------------
|
|
int main()
|
|
{
|
|
// Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
|
InitWindow(screenWidth, screenHeight, "rGuiLayout - raygui layout editor");
|
|
|
|
// Initialize layout data
|
|
for (int i = 0; i < MAX_GUI_CONTROLS; i++)
|
|
{
|
|
layout[i].id = 0;
|
|
layout[i].type = 0;
|
|
layout[i].rec = (Rectangle){ 0, 0, 0, 0 };
|
|
layout[i].text = (unsigned char *)malloc(32);// strcpy(layout[i].text, "SAMPLE TEXT\0");
|
|
layout[i].ap = NULL;
|
|
}
|
|
|
|
int selectedControl = -1;
|
|
int selectedType = BUTTON;
|
|
int selectedTypeDraw = LABEL;
|
|
|
|
int mouseX, mouseY;
|
|
bool snapMode = false;
|
|
bool showGrid = true;
|
|
bool controlCollision = false; // Checks if the mouse is colliding with a control or list
|
|
bool controlDrag = false; // Allows the control to be moved with the mouse without detecting collision every frame
|
|
|
|
bool textEditMode = false;
|
|
int framesCounter = 0;
|
|
int saveControlSelected = -1;
|
|
char previewText[8] = "TEXTBOX";
|
|
bool anchorMode = false;
|
|
bool anchorLinkMode = false;
|
|
int selectedAnchor = -1;
|
|
int linkedAnchor = -1;
|
|
|
|
bool lockMode = false;
|
|
bool helpMode = false;
|
|
|
|
// Used to draw the preview of selectedControl
|
|
Rectangle defaultRec[16] = {
|
|
(Rectangle){ 0, 0, 80, 20}, // LABEL
|
|
(Rectangle){ 0, 0, 100, 30}, // BUTTON
|
|
(Rectangle){ 0, 0, 120, 40}, // IMAGEBUTTON
|
|
(Rectangle){ 0, 0, 100, 30}, // TOGGLE
|
|
(Rectangle){ 0, 0, 240, 30}, // TOGGLEGROUP
|
|
(Rectangle){ 0, 0, 200, 20}, // SLIDER
|
|
(Rectangle){ 0, 0, 200, 20}, // SLIDERBAR
|
|
(Rectangle){ 0, 0, 200, 20}, // PROGRESSBAR
|
|
(Rectangle){ 0, 0, 150, 30}, // SPINNER
|
|
(Rectangle){ 0, 0, 150, 30}, // COMBOBOX
|
|
(Rectangle){ 0, 0, 20, 20}, // CHECKBOX
|
|
(Rectangle){ 0, 0, 120, 30}, // TEXTBOX
|
|
(Rectangle){ 0, 0, 120, 40}, // GROUPBOX
|
|
(Rectangle){ 0, 0, 120, 48}, // WINDOWBOX
|
|
(Rectangle){ 0, 0, 120, 250}, // LISTVIEW
|
|
(Rectangle){ 0, 0, 120, 120} // COLORPICKER
|
|
};
|
|
|
|
// List view required variables
|
|
Rectangle listViewControls = { -200, 0, 140, 500 };
|
|
int counterListViewControls = 0;
|
|
int startPosXListViewControls = -200;
|
|
int deltaPosXListViewControls = 0;
|
|
Rectangle listViewControlsCounter = { GetScreenWidth() + 140, 0, 140, 500 };
|
|
int counterListViewControlsCounter = 0;
|
|
int startPosXListViewControlsCounter = GetScreenWidth() + 140;
|
|
int deltaPosXListViewControlsCounter = 0;
|
|
|
|
const char *list[3] = { "ONE", "TWO", "THREE" };
|
|
|
|
const char *guiControls[16] = {
|
|
"LABEL",
|
|
"BUTTON",
|
|
"IMAGEBUTTON",
|
|
"TOGGLE",
|
|
"TOGGLEGROUP",
|
|
"SLIDER",
|
|
"SLIDERBAR",
|
|
"PROGRESSBAR",
|
|
"SPINNER",
|
|
"COMBOBOX",
|
|
"CHECKBOX",
|
|
"TEXTBOX",
|
|
"GROUPBOX",
|
|
"WINDOWBOX",
|
|
"LISTVIEW",
|
|
"COLORPICKER"
|
|
};
|
|
|
|
const char *guiControlsCounter[16] = {
|
|
"Control 000",
|
|
"Control 001",
|
|
"Control 002",
|
|
"Control 003",
|
|
"Control 004",
|
|
"Control 005",
|
|
"Control 006",
|
|
"Control 007",
|
|
"Control 008",
|
|
"Control 009",
|
|
"Control 010",
|
|
"Control 011",
|
|
"Control 012",
|
|
"Control 013",
|
|
"Control 014",
|
|
"Control 015",
|
|
};
|
|
|
|
Texture2D texture = LoadTexture("icons.png");
|
|
|
|
// Get current directory
|
|
// NOTE: Current working directory could not match current executable directory
|
|
GetCurrentDir(currentPath, sizeof(currentPath));
|
|
currentPath[strlen(currentPath)] = '\\';
|
|
currentPath[strlen(currentPath) + 1] = '\0'; // Not really required
|
|
|
|
// Initialize anchor points to default values
|
|
for (int i = 0; i < MAX_ANCHOR_POINTS; i++)
|
|
{
|
|
anchors[i].id = i;
|
|
anchors[i].x = 0;
|
|
anchors[i].y = 0;
|
|
anchors[i].radius = 20;
|
|
anchors[i].enabled = false;
|
|
}
|
|
|
|
anchors[0].enabled = true; // Enable anchors parent (0, 0)
|
|
|
|
//GuiSetStyleProperty(TOGGLEGROUP_PADDING, 5);
|
|
|
|
SetTargetFPS(120);
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
// Main game loop
|
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
|
{
|
|
// Update
|
|
//----------------------------------------------------------------------------------
|
|
mouseX = GetMouseX();
|
|
mouseY = GetMouseY();
|
|
|
|
// Enables or disables snapMode if not in textEditMode
|
|
if (IsKeyPressed(KEY_S) && (!textEditMode)) snapMode = !snapMode;
|
|
|
|
// Checks if the defaultRec[selectedType] is colliding with the list of the controls
|
|
if (CheckCollisionPointRec(GetMousePosition(), listViewControls)) controlCollision = true;
|
|
else if (CheckCollisionPointRec(GetMousePosition(), listViewControlsCounter)) controlCollision = true;
|
|
|
|
// Toggle on the controlListView
|
|
/*if (IsKeyPressed(KEY_TAB))
|
|
{
|
|
startPosXListViewControls = listViewControls.x;
|
|
deltaPosXListViewControls = 0 - startPosXListViewControls;
|
|
counterListViewControls = 0;
|
|
}
|
|
|
|
if (IsKeyDown(KEY_TAB))
|
|
{
|
|
counterListViewControls++;
|
|
if (counterListViewControls >= 60) counterListViewControls = 60;
|
|
listViewControls.x = (int)EaseCubicInOut(counterListViewControls, startPosXListViewControls, deltaPosXListViewControls, 60);
|
|
}
|
|
else if (IsKeyReleased(KEY_TAB))
|
|
{
|
|
startPosXListViewControls = listViewControls.x;
|
|
deltaPosXListViewControls = -200 - startPosXListViewControls;
|
|
counterListViewControls = 0;
|
|
}
|
|
else
|
|
{
|
|
counterListViewControls++;
|
|
if (counterListViewControls >= 60) counterListViewControls = 60;
|
|
listViewControls.x = (int)EaseCubicInOut(counterListViewControls, startPosXListViewControls, deltaPosXListViewControls, 60);
|
|
}
|
|
|
|
// Toggle on the controlListViewCounter
|
|
if (IsKeyPressed(KEY_W))
|
|
{
|
|
startPosXListViewControlsCounter = listViewControlsCounter.x;
|
|
deltaPosXListViewControlsCounter = GetScreenWidth() -listViewControlsCounter.width - startPosXListViewControlsCounter;
|
|
counterListViewControlsCounter = 0;
|
|
}
|
|
|
|
if (IsKeyDown(KEY_W))
|
|
{
|
|
counterListViewControlsCounter++;
|
|
if (counterListViewControlsCounter >= 60) counterListViewControlsCounter = 60;
|
|
listViewControlsCounter.x = (int)EaseCubicInOut(counterListViewControlsCounter, startPosXListViewControlsCounter, deltaPosXListViewControlsCounter, 60);
|
|
}
|
|
else if (IsKeyReleased(KEY_W))
|
|
{
|
|
startPosXListViewControlsCounter = listViewControlsCounter.x;
|
|
deltaPosXListViewControlsCounter = GetScreenWidth() + 140 - startPosXListViewControlsCounter;
|
|
counterListViewControlsCounter = 0;
|
|
}
|
|
else
|
|
{
|
|
counterListViewControlsCounter++;
|
|
if (counterListViewControlsCounter >= 60) counterListViewControlsCounter = 60;
|
|
listViewControlsCounter.x = (int)EaseCubicInOut(counterListViewControlsCounter, startPosXListViewControlsCounter, deltaPosXListViewControlsCounter, 60);
|
|
}
|
|
*/
|
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && (selectedControl == -1) && !controlCollision && !anchorMode)
|
|
{
|
|
// Add new control (button)
|
|
layout[controlsCounter].id = controlsCounter;
|
|
layout[controlsCounter].type = selectedType;
|
|
layout[controlsCounter].rec = (Rectangle){ mouseX - defaultRec[selectedType].width/2, mouseY - defaultRec[selectedType].height/2, defaultRec[selectedType].width, defaultRec[selectedType].height };
|
|
strcpy(layout[controlsCounter].text, "SAMPLE TEXT\0");
|
|
layout[controlsCounter].ap = &anchors[0]; // Default anchor point (0, 0)
|
|
|
|
controlsCounter++;
|
|
}
|
|
|
|
// Check selected control (on mouse hover)
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
if (controlDrag || lockMode) break;
|
|
if ((layout[i].type == WINDOWBOX) && (CheckCollisionPointRec(GetMousePosition(), (Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, 24 })))
|
|
{
|
|
selectedControl = i;
|
|
break;
|
|
}
|
|
else if (CheckCollisionPointRec(GetMousePosition(), (Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }) && layout[i].type != WINDOWBOX)
|
|
{
|
|
selectedControl = i;
|
|
break;
|
|
}
|
|
else selectedControl = -1;
|
|
}
|
|
|
|
if (selectedControl != -1 && !textEditMode && !anchorMode)
|
|
{
|
|
// Disables the defaultRec[selectedType]
|
|
controlCollision = true;
|
|
|
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
|
{
|
|
controlDrag = true;
|
|
}
|
|
else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
|
{
|
|
controlDrag = false;
|
|
selectedControl = -1;
|
|
}
|
|
|
|
if (controlDrag && !lockMode)
|
|
{
|
|
layout[selectedControl].rec.x = mouseX - layout[selectedControl].rec.width/2 - layout[selectedControl].ap->x;
|
|
layout[selectedControl].rec.y = mouseY - layout[selectedControl].rec.height/2 - layout[selectedControl].ap->y;
|
|
|
|
// Snap to grid position and size
|
|
if (snapMode)
|
|
{
|
|
// Snap rectangle position to closer snap point
|
|
int offsetX = layout[selectedControl].rec.x%GRID_LINE_SPACING;
|
|
int offsetY = layout[selectedControl].rec.y%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) layout[selectedControl].rec.x += (GRID_LINE_SPACING - offsetX);
|
|
else layout[selectedControl].rec.x -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) layout[selectedControl].rec.y += (GRID_LINE_SPACING - offsetY);
|
|
else layout[selectedControl].rec.y -= offsetY;
|
|
|
|
// Snap rectangle size to closer snap point sizes
|
|
offsetX = layout[selectedControl].rec.width%GRID_LINE_SPACING;
|
|
offsetY = layout[selectedControl].rec.height%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) layout[selectedControl].rec.width += (GRID_LINE_SPACING - offsetX);
|
|
else layout[selectedControl].rec.width -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) layout[selectedControl].rec.height += (GRID_LINE_SPACING - offsetY);
|
|
else layout[selectedControl].rec.height -= offsetY;
|
|
}
|
|
}
|
|
|
|
if (snapMode)
|
|
{
|
|
if (IsKeyDown(KEY_LEFT_ALT))
|
|
{
|
|
// Control modifier of position
|
|
if (IsKeyPressed(KEY_RIGHT)) layout[selectedControl].rec.x += GRID_LINE_SPACING;
|
|
else if (IsKeyPressed(KEY_LEFT)) layout[selectedControl].rec.x -= GRID_LINE_SPACING;
|
|
|
|
if (IsKeyPressed(KEY_UP)) layout[selectedControl].rec.y -= GRID_LINE_SPACING;
|
|
else if (IsKeyPressed(KEY_DOWN)) layout[selectedControl].rec.y += GRID_LINE_SPACING;
|
|
}
|
|
else
|
|
{
|
|
// Control modifier of width and height
|
|
if (IsKeyPressed(KEY_RIGHT)) layout[selectedControl].rec.width += GRID_LINE_SPACING;
|
|
else if (IsKeyPressed(KEY_LEFT)) layout[selectedControl].rec.width -= GRID_LINE_SPACING;
|
|
|
|
if (IsKeyPressed(KEY_UP)) layout[selectedControl].rec.height -= GRID_LINE_SPACING;
|
|
else if (IsKeyPressed(KEY_DOWN)) layout[selectedControl].rec.height += GRID_LINE_SPACING;
|
|
}
|
|
|
|
|
|
int offsetX = layout[selectedControl].rec.width%GRID_LINE_SPACING;
|
|
int offsetY = layout[selectedControl].rec.height%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) layout[selectedControl].rec.width += (GRID_LINE_SPACING - offsetX);
|
|
else layout[selectedControl].rec.width -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) layout[selectedControl].rec.height += (GRID_LINE_SPACING - offsetY);
|
|
else layout[selectedControl].rec.height -= offsetY;
|
|
}
|
|
|
|
else
|
|
{
|
|
if (IsKeyDown(KEY_LEFT_CONTROL))
|
|
{
|
|
// Control modifier for a more precise sizing
|
|
if (IsKeyPressed(KEY_RIGHT)) layout[selectedControl].rec.width++;
|
|
else if (IsKeyPressed(KEY_LEFT)) layout[selectedControl].rec.width--;
|
|
|
|
if (IsKeyPressed(KEY_UP)) layout[selectedControl].rec.height--;
|
|
else if (IsKeyPressed(KEY_DOWN)) layout[selectedControl].rec.height++;
|
|
}
|
|
else if (IsKeyDown(KEY_LEFT_ALT))
|
|
{
|
|
// Control modifier of position
|
|
if (IsKeyPressed(KEY_RIGHT)) layout[selectedControl].rec.x ++;
|
|
else if (IsKeyPressed(KEY_LEFT)) layout[selectedControl].rec.x --;
|
|
|
|
if (IsKeyPressed(KEY_UP)) layout[selectedControl].rec.y --;
|
|
else if (IsKeyPressed(KEY_DOWN)) layout[selectedControl].rec.y ++;
|
|
}
|
|
else
|
|
{
|
|
if (IsKeyDown(KEY_RIGHT)) layout[selectedControl].rec.width++;
|
|
else if (IsKeyDown(KEY_LEFT)) layout[selectedControl].rec.width--;
|
|
|
|
if (IsKeyDown(KEY_UP)) layout[selectedControl].rec.height--;
|
|
else if (IsKeyDown(KEY_DOWN)) layout[selectedControl].rec.height++;
|
|
}
|
|
}
|
|
|
|
// Delete selected control and shift array position
|
|
if (IsKeyPressed(KEY_DELETE))
|
|
{
|
|
for (int i = selectedControl; i < controlsCounter; i++) layout[i] = layout[i + 1];
|
|
|
|
controlsCounter--;
|
|
selectedControl = -1;
|
|
}
|
|
|
|
// Unlinks the control selected from its current anchor
|
|
if(IsKeyPressed(KEY_R))
|
|
{
|
|
layout[selectedControl].rec.x += layout[selectedControl].ap->x;
|
|
layout[selectedControl].rec.y += layout[selectedControl].ap->y;
|
|
layout[selectedControl].ap = &anchors[0];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check mouse hover a list view
|
|
if (!CheckCollisionPointRec(GetMousePosition(), listViewControls)) controlCollision = false;
|
|
if (!CheckCollisionPointRec(GetMousePosition(), listViewControlsCounter)) controlCollision = false;
|
|
|
|
// Updates the selectedType with the MouseWheel
|
|
selectedType -= GetMouseWheelMove();
|
|
|
|
if (selectedType < LABEL) selectedType = COLORPICKER;
|
|
else if (selectedType > COLORPICKER) selectedType = LABEL;
|
|
|
|
selectedTypeDraw = selectedType;
|
|
}
|
|
|
|
// Updates the defaultRec[selectedType] position
|
|
defaultRec[selectedType].x = mouseX - defaultRec[selectedType].width/2;
|
|
defaultRec[selectedType].y = mouseY - defaultRec[selectedType].height/2;
|
|
|
|
// Mouse snap
|
|
// NOTE: Snap point changes when GRID_LINE_SPACING/2 has been surpassed in X and Y
|
|
if ((snapMode) && (selectedControl == -1))
|
|
{
|
|
int offsetX = mouseX%GRID_LINE_SPACING;
|
|
int offsetY = mouseY%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) mouseX += (GRID_LINE_SPACING - offsetX);
|
|
else mouseX -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) mouseY += (GRID_LINE_SPACING - offsetY);
|
|
else mouseY -= offsetY;
|
|
|
|
// SnapMode of the DrawingControls
|
|
// Snap rectangle position to closer snap point
|
|
offsetX = defaultRec[selectedType].x%GRID_LINE_SPACING;
|
|
offsetY = defaultRec[selectedType].y%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) defaultRec[selectedType].x += (GRID_LINE_SPACING - offsetX);
|
|
else defaultRec[selectedType].x -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) defaultRec[selectedType].y += (GRID_LINE_SPACING - offsetY);
|
|
else defaultRec[selectedType].y -= offsetY;
|
|
// Snap rectangle size to closer snap point sizes
|
|
offsetX = defaultRec[selectedType].width%GRID_LINE_SPACING;
|
|
offsetY = defaultRec[selectedType].height%GRID_LINE_SPACING;
|
|
|
|
if (offsetX >= GRID_LINE_SPACING/2) defaultRec[selectedType].width += (GRID_LINE_SPACING - offsetX);
|
|
else defaultRec[selectedType].width -= offsetX;
|
|
|
|
if (offsetY >= GRID_LINE_SPACING/2) defaultRec[selectedType].height += (GRID_LINE_SPACING - offsetY);
|
|
else defaultRec[selectedType].height -= offsetY;
|
|
}
|
|
|
|
// Check if control has text to edit
|
|
if (textEditMode)
|
|
{
|
|
// Locks the selectedControl for text editing
|
|
selectedControl = saveControlSelected;
|
|
int key = GetKeyPressed();
|
|
int keyCount = strlen(layout[selectedControl].text); // Keeps track of text length
|
|
|
|
// Replaces characters with pressed keys or '\0' in case of backspace
|
|
// NOTE: Only allow keys in range [32..125]
|
|
if ((key >= 32) && (key <= 125) && (keyCount < 32))
|
|
{
|
|
layout[selectedControl].text[keyCount] = (char)key;
|
|
}
|
|
|
|
if (IsKeyPressed(KEY_BACKSPACE_TEXT))
|
|
{
|
|
layout[selectedControl].text[keyCount - 1] = '\0';
|
|
if (keyCount < 0) keyCount = 0;
|
|
}
|
|
|
|
// Used to show the cursor('_') in textEditMode
|
|
if (keyCount < 32) framesCounter++;
|
|
else if (keyCount == 32) framesCounter = 21;
|
|
}
|
|
|
|
// Turns off textEditMode
|
|
if (textEditMode && IsKeyPressed(KEY_ENTER))
|
|
{
|
|
textEditMode = false;
|
|
framesCounter = 0;
|
|
}
|
|
|
|
// Turns on textEditMode
|
|
if (IsKeyPressed(KEY_T) && (selectedControl != -1) && (!anchorMode) &&
|
|
((layout[selectedControl].type == LABEL) || (layout[selectedControl].type == BUTTON) || (layout[selectedControl].type == TOGGLE) || (layout[selectedControl].type == IMAGEBUTTON) || (layout[selectedControl].type == GROUPBOX) || (layout[selectedControl].type == WINDOWBOX)))
|
|
{
|
|
textEditMode = true;
|
|
saveControlSelected = selectedControl;
|
|
}
|
|
|
|
if (IsKeyPressed(KEY_H)) helpMode = !helpMode;
|
|
|
|
// Selected control lock logic
|
|
if (lockMode)
|
|
{
|
|
selectedControl = saveControlSelected;
|
|
}
|
|
|
|
if (IsKeyPressed(KEY_SPACE) && !textEditMode && (selectedControl != -1) && !lockMode && !anchorMode)
|
|
{
|
|
lockMode = true;
|
|
saveControlSelected = selectedControl;
|
|
}
|
|
else if (IsKeyPressed(KEY_SPACE) && (selectedControl != -1))
|
|
{
|
|
lockMode = false;
|
|
}
|
|
|
|
// Checks if mouse is over an anchor
|
|
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
|
|
{
|
|
if (anchorLinkMode || controlDrag) break;
|
|
|
|
if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){ anchors[i].x, anchors[i].y }, anchors[i].radius))
|
|
{
|
|
selectedAnchor = i;
|
|
anchorMode = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
selectedAnchor = -1;
|
|
if (!IsKeyDown(KEY_A)) anchorMode = false;
|
|
}
|
|
}
|
|
|
|
// Create and edit anchor points
|
|
if (anchorMode)
|
|
{
|
|
// On mouse click anchor is created
|
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && !controlCollision && selectedAnchor == -1 && selectedControl == -1)
|
|
{
|
|
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
|
|
{
|
|
if (!anchors[i].enabled)
|
|
{
|
|
anchors[i].x = mouseX;
|
|
anchors[i].y = mouseY;
|
|
anchors[i].enabled = true;
|
|
anchorMode = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (selectedAnchor > 0)
|
|
{
|
|
// Unlinks and deletes the selected anchor point
|
|
if (IsKeyPressed(KEY_DELETE))
|
|
{
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
if (layout[i].ap->id == selectedAnchor)
|
|
{
|
|
layout[i].rec.x += layout[i].ap->x;
|
|
layout[i].rec.y += layout[i].ap->y;
|
|
layout[i].ap = &anchors[0];
|
|
}
|
|
}
|
|
anchors[selectedAnchor].x = 0;
|
|
anchors[selectedAnchor].y = 0;
|
|
anchors[selectedAnchor].enabled = false;
|
|
anchorMode = false;
|
|
}
|
|
|
|
// Allows to drag an anchor without losing collision
|
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) controlDrag = true;
|
|
|
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
|
{
|
|
controlDrag = false;
|
|
selectedAnchor = -1;
|
|
anchorMode = false;
|
|
}
|
|
|
|
// Moves the anchor to the mouse position
|
|
if (controlDrag)
|
|
{
|
|
anchors[selectedAnchor].x = mouseX;
|
|
anchors[selectedAnchor].y = mouseY;
|
|
}
|
|
|
|
// Enables the linking between anchor and control
|
|
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON))
|
|
{
|
|
linkedAnchor = selectedAnchor;
|
|
anchorLinkMode = true;
|
|
}
|
|
|
|
// Links the selected control to the current anchor
|
|
if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))
|
|
{
|
|
if (selectedControl != -1 && !lockMode /*&& (layout[selectedControl].ap != &anchors[linkedAnchor])*/)
|
|
{
|
|
layout[selectedControl].rec.x += layout[selectedControl].ap->x;
|
|
layout[selectedControl].rec.y += layout[selectedControl].ap->y;
|
|
layout[selectedControl].ap = &anchors[linkedAnchor];
|
|
layout[selectedControl].rec.x -= anchors[linkedAnchor].x;
|
|
layout[selectedControl].rec.y -= anchors[linkedAnchor].y;
|
|
}
|
|
|
|
anchorLinkMode = false;
|
|
anchorMode = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Enable anchor mode editing
|
|
if (IsKeyDown(KEY_A) && !textEditMode && (layout[selectedControl].type != TEXTBOX)) anchorMode = true;
|
|
|
|
// Checks the minimum size of the rec
|
|
if (selectedControl != -1)
|
|
{
|
|
// Sets the minimum limit of the width
|
|
if (layout[selectedControl].type == LABEL || layout[selectedControl].type == BUTTON || layout[selectedControl].type == TOGGLE || layout[selectedControl].type == TEXTBOX)
|
|
{
|
|
if (layout[selectedControl].rec.width < MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE])) layout[selectedControl].rec.width = MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE]);
|
|
}
|
|
else if (layout[selectedControl].type == IMAGEBUTTON)
|
|
{
|
|
if (layout[selectedControl].rec.width < MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE]) + texture.width/3) layout[selectedControl].rec.width = MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE]) + texture.width/3 + 5;
|
|
}
|
|
else if (layout[selectedControl].type == WINDOWBOX || layout[selectedControl].type == GROUPBOX)
|
|
{
|
|
if (layout[selectedControl].rec.width < MeasureText(layout[selectedControl].text, style[DEFAULT_TEXT_SIZE]) + 31) layout[selectedControl].rec.width = MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE]) + 31;
|
|
}
|
|
else if (layout[selectedControl].rec.width <= 20) layout[selectedControl].rec.width = 20;
|
|
|
|
|
|
|
|
// Sets the minimum limit of the height
|
|
if (layout[selectedControl].type == IMAGEBUTTON)
|
|
{
|
|
if (layout[selectedControl].rec.height <= texture.height/6 + 5) layout[selectedControl].rec.height = texture.height/6 + 5;
|
|
}
|
|
else if (layout[selectedControl].type == WINDOWBOX)
|
|
{
|
|
if (layout[selectedControl].rec.height < 48) layout[selectedControl].rec.height = 48;
|
|
}
|
|
else if (layout[selectedControl].rec.height <= 20) layout[selectedControl].rec.height = 20;
|
|
}
|
|
|
|
|
|
|
|
// TODO: Draw global app screen limits (black rectangle with black default anchor)
|
|
|
|
// Shows or hides the grid if not in textEditMode
|
|
if (IsKeyPressed(KEY_G) && (!textEditMode)) showGrid = !showGrid;
|
|
|
|
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_S))
|
|
{
|
|
char currrentPathFile[256];
|
|
|
|
// Add sample file name to currentPath
|
|
strcpy(currrentPathFile, currentPath);
|
|
//strcat(currrentPathFile, defaultName);
|
|
|
|
// Save file dialog
|
|
const char *filters[] = { "*.rgl" };
|
|
const char *fileName = tinyfd_saveFileDialog("Save raygui layout text file", currrentPathFile, 1, filters, "raygui Layout Files (*.rgl)");
|
|
|
|
if (fileName != NULL)
|
|
{
|
|
// Save layout file (text or binary)
|
|
SaveLayoutRGL("test_layout.rgl", true);
|
|
fileName = "";
|
|
}
|
|
}
|
|
|
|
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_O))
|
|
{
|
|
// Open file dialog
|
|
const char *filters[] = { "*.rgl" };
|
|
const char *fileName = tinyfd_openFileDialog("Load raygui layout file", currentPath, 1, filters, "raygui Layout Files (*.rgl)", 0);
|
|
|
|
if (fileName != NULL) LoadLayoutRGL(fileName);
|
|
}
|
|
|
|
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_ENTER)) GenerateLayoutCode("test_layout.c");
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Draw
|
|
//----------------------------------------------------------------------------------
|
|
BeginDrawing();
|
|
|
|
ClearBackground(RAYWHITE);
|
|
|
|
if (showGrid) DrawGrid2D(GetScreenWidth()/13, GetScreenHeight()/13);
|
|
|
|
// Draws the defaultRec[selectedType] of the control selected
|
|
if (selectedControl == -1 && !anchorMode)
|
|
{
|
|
switch (selectedTypeDraw)
|
|
{
|
|
case LABEL: GuiLabel(defaultRec[selectedTypeDraw], "TEXT SAMPLE"); break;
|
|
case BUTTON: GuiButton(defaultRec[selectedTypeDraw], "BUTTON"); break;
|
|
case IMAGEBUTTON: GuiImageButtonEx(defaultRec[selectedTypeDraw], texture , (Rectangle){ 0, 0, texture.width/3, texture.height/6 }, "IMAGE BUTTON"); break;
|
|
case TOGGLE: GuiToggleButton(defaultRec[selectedTypeDraw], "TOGGLE", false); break;
|
|
case TOGGLEGROUP: GuiToggleGroup(defaultRec[selectedTypeDraw], list, 3, 1); break;
|
|
case SLIDER: GuiSlider(defaultRec[selectedTypeDraw], 40, 0, 100); break;
|
|
case SLIDERBAR: GuiSliderBar(defaultRec[selectedTypeDraw], 40, 0, 100); break;
|
|
case PROGRESSBAR: GuiProgressBar(defaultRec[selectedTypeDraw], 40, 0, 100); break;
|
|
case SPINNER: GuiSpinner(defaultRec[selectedTypeDraw], 40, 0, 100); break;
|
|
case COMBOBOX: GuiComboBox(defaultRec[selectedTypeDraw], list, 3, 1); break;
|
|
case CHECKBOX: GuiCheckBox(defaultRec[selectedTypeDraw], false); break;
|
|
case TEXTBOX: GuiTextBox(defaultRec[selectedTypeDraw], previewText, 7); break;
|
|
case GROUPBOX: GuiGroupBox(defaultRec[selectedTypeDraw], "GROUP BOX"); break;
|
|
case WINDOWBOX: GuiWindowBox(defaultRec[selectedTypeDraw], "WINDOW BOX"); break;
|
|
case LISTVIEW: GuiListView(defaultRec[selectedTypeDraw], guiControls, 14, 1); break;
|
|
case COLORPICKER: GuiColorPicker(defaultRec[selectedTypeDraw], RED); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
// Draws the Controls when placed on the grid.
|
|
switch (layout[i].type)
|
|
{
|
|
case LABEL: GuiLabel((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
|
|
case BUTTON: GuiButton((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
|
|
case IMAGEBUTTON: GuiImageButtonEx((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, texture, (Rectangle){ 0, 0, texture.width/3, texture.height/6 }, layout[i].text); break;
|
|
case TOGGLE: GuiToggleButton((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text, false); break;
|
|
case TOGGLEGROUP: GuiToggleGroup((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, list, 3, 1); break;
|
|
case SLIDER: GuiSlider((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
|
|
case SLIDERBAR: GuiSliderBar((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
|
|
case PROGRESSBAR: GuiProgressBar((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
|
|
case SPINNER: GuiSpinner((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
|
|
case COMBOBOX: GuiComboBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, list, 3, 1); break;
|
|
case CHECKBOX: GuiCheckBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, false); break;
|
|
case TEXTBOX: GuiTextBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text, 32); break;
|
|
case GROUPBOX: GuiGroupBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
|
|
case WINDOWBOX: GuiWindowBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
|
|
case LISTVIEW: GuiListView((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, guiControls, 14, 1); break;
|
|
case COLORPICKER: GuiColorPicker((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, RED); break;
|
|
default: break;
|
|
}
|
|
|
|
if ((layout[i].ap->id == selectedAnchor) && (layout[i].ap->id > 0)) DrawLine(layout[i].ap->x, layout[i].ap->y, layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, RED);
|
|
// Draw Control anchor information
|
|
// DrawText(FormatText("Id: %i | X: %i | Y: %i | Enabled: %i", layout[0].ap->id, layout[0].ap->x, layout[0].ap->y, layout[0].ap->enabled), 100, 100, style[DEFAULT_TEXT_SIZE], RED);
|
|
}
|
|
|
|
// Draw the list of controls
|
|
/*DrawRectangleRec(listViewControls, Fade(WHITE, 0.7f));
|
|
selectedType = GuiListView(listViewControls, guiControls, 14, selectedType);
|
|
|
|
// Draw the list of controlsCounter
|
|
DrawRectangleRec(listViewControlsCounter, Fade(WHITE, 0.7f));
|
|
GuiListView(listViewControlsCounter, guiControlsCounter, controlsCounter, selectedControl);
|
|
*/
|
|
|
|
// Draw the anchorPoints
|
|
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
|
|
{
|
|
if (anchors[i].id == selectedAnchor) DrawCircle(anchors[i].x, anchors[i].y, anchors[i].radius, Fade(RED, 0.5f));
|
|
else DrawCircleLines(anchors[i].x, anchors[i].y, anchors[i].radius, Fade(RED, 0.5f));
|
|
DrawRectangle(anchors[i].x - anchors[i].radius - 5, anchors[i].y, anchors[i].radius*2 + 10, 1, RED);
|
|
DrawRectangle(anchors[i].x, anchors[i].y - anchors[i].radius - 5, 1, anchors[i].radius*2 + 10, RED);
|
|
}
|
|
|
|
if ((selectedControl != -1) && (selectedControl < controlsCounter))
|
|
{
|
|
|
|
DrawRectangleRec((Rectangle){ layout[selectedControl].ap->x + layout[selectedControl].rec.x, layout[selectedControl].ap->y + layout[selectedControl].rec.y, layout[selectedControl].rec.width, layout[selectedControl].rec.height }, Fade(RED, 0.5f));
|
|
if (layout[selectedControl].ap->id > 0) DrawLine(layout[selectedControl].ap->x, layout[selectedControl].ap->y, layout[selectedControl].ap->x + layout[selectedControl].rec.x, layout[selectedControl].ap->y + layout[selectedControl].rec.y, RED);
|
|
}
|
|
|
|
if ((selectedControl == -1) && (selectedAnchor == -1))
|
|
{
|
|
if (anchorMode)
|
|
{
|
|
DrawCircleLines(mouseX, mouseY, anchors[0].radius, Fade(RED, 0.5f));
|
|
DrawRectangle(mouseX - anchors[0].radius - 5, mouseY, anchors[0].radius*2 + 10, 1, RED);
|
|
DrawRectangle(mouseX, mouseY - anchors[0].radius - 5, 1, anchors[0].radius*2 + 10, RED);
|
|
}
|
|
else
|
|
{
|
|
DrawRectangle(mouseX - 8, mouseY, 17, 1, RED);
|
|
DrawRectangle(mouseX, mouseY - 8, 1, 17, RED);
|
|
}
|
|
}
|
|
|
|
// Draws the cursor of textEditMode
|
|
if (textEditMode)
|
|
{
|
|
if (((framesCounter/20)%2) == 0)
|
|
{
|
|
if (layout[selectedControl].type == LABEL) DrawText("|", layout[selectedControl].rec.x + MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE]) + 2, layout[selectedControl].rec.y - 1, style[DEFAULT_TEXT_SIZE] + 2, BLACK);
|
|
else if (layout[selectedControl].type == IMAGEBUTTON) DrawText("|", layout[selectedControl].rec.x + layout[selectedControl].rec.width/2 + MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE])/2 + texture.width/6, layout[selectedControl].rec.y + layout[selectedControl].rec.height/2 - 6, style[DEFAULT_TEXT_SIZE] + 2, BLACK);
|
|
else if (layout[selectedControl].type == GROUPBOX) DrawText("|", layout[selectedControl].rec.x + 15 + MeasureText(layout[selectedControl].text, style[DEFAULT_TEXT_SIZE]), layout[selectedControl].rec.y - style[DEFAULT_TEXT_SIZE]/2, style[DEFAULT_TEXT_SIZE] + 2, BLACK);
|
|
else if (layout[selectedControl].type == WINDOWBOX) DrawText("|", layout[selectedControl].rec.x + 10 + MeasureText(layout[selectedControl].text, style[DEFAULT_TEXT_SIZE]), layout[selectedControl].rec.y + style[DEFAULT_TEXT_SIZE]/2, style[DEFAULT_TEXT_SIZE] + 2, BLACK);
|
|
else DrawText("|", layout[selectedControl].rec.x + layout[selectedControl].rec.width/2 + MeasureText(layout[selectedControl].text , style[DEFAULT_TEXT_SIZE])/2 + 2, layout[selectedControl].rec.y + layout[selectedControl].rec.height/2 - 6, style[DEFAULT_TEXT_SIZE] + 2, BLACK);
|
|
}
|
|
}
|
|
|
|
if (anchorLinkMode) DrawLine(anchors[linkedAnchor].x, anchors[linkedAnchor].y, mouseX, mouseY, BLACK);
|
|
|
|
if (helpMode)
|
|
{
|
|
DrawRectangleRec((Rectangle){ 20, 20, 260, 270 }, GetColor(style[DEFAULT_BACKGROUND_COLOR]));
|
|
GuiGroupBox((Rectangle){ 20, 20, 260, 270 }, "Shortcuts");
|
|
GuiLabel((Rectangle){ 30, 30, 0, 0 }, "G - Show/hide grid");
|
|
GuiLabel((Rectangle){ 30, 50, 0, 0 }, "S - Toggle snap");
|
|
GuiLabel((Rectangle){ 30, 70, 0, 0 }, "A - Anchor mode");
|
|
GuiLabel((Rectangle){ 30, 90, 0, 0 }, "Space - Lock/unlock control");
|
|
GuiLabel((Rectangle){ 30, 110, 0, 0 }, "T - Enter text mode(if possible)");
|
|
GuiLabel((Rectangle){ 30, 130, 0, 0 }, "Enter - Exit text mode");
|
|
GuiLabel((Rectangle){ 30, 150, 0, 0 }, "Delete - Delete a control");
|
|
GuiLabel((Rectangle){ 30, 170, 0, 0 }, "Arrows - Modify width/height");
|
|
GuiLabel((Rectangle){ 30, 190, 0, 0 }, "L. Ctrl + Arrows - Modify width/height(smooth)");
|
|
GuiLabel((Rectangle){ 30, 210, 0, 0 }, "L. Alt + Arrows - Modify position");
|
|
GuiLabel((Rectangle){ 30, 230, 0, 0 }, "L. Ctrl + Enter - Export layout to code");
|
|
GuiLabel((Rectangle){ 30, 250, 0, 0 }, "L. Ctrl + S - Save layout(.rgl)");
|
|
GuiLabel((Rectangle){ 30, 270, 0, 0 }, "L. Ctrl + O - Open layout(.rgl)");
|
|
}
|
|
// Debug information
|
|
/*DrawText(FormatText("Controls count: %i", controlsCounter), 10, screenHeight - 20, 20, BLUE);
|
|
DrawText(FormatText("Selected type: %s", controlTypeName[selectedType]), 300, screenHeight - 20, 20, BLUE);
|
|
if (snapMode) DrawText("SNAP ON", 700, screenHeight - 20, 20, RED);
|
|
if (selectedControl != -1) DrawText(FormatText("rec: (%i, %i, %i, %i)",
|
|
layout[selectedControl].rec.x, layout[selectedControl].rec.y,
|
|
layout[selectedControl].rec.width, layout[selectedControl].rec.height),
|
|
10, screenHeight - 40, 10, DARKGREEN);
|
|
DrawText(FormatText("mouse: (%i, %i)", mouseX, mouseY), 700, screenHeight - 40, 10, RED);
|
|
*/
|
|
// Draw status bar bottom with debug information
|
|
GuiStatusBar((Rectangle){ 0, GetScreenHeight() - 24, 125, 24}, FormatText("Controls count: %i", controlsCounter), 20);
|
|
GuiStatusBar((Rectangle){ 124, GetScreenHeight() - 24, 126, 24}, FormatText("Mouse: (%i, %i)", mouseX, mouseY), 15);
|
|
if (snapMode) GuiStatusBar((Rectangle){ 249, GetScreenHeight() - 24, 81, 24}, "SNAP ON", 10);
|
|
else GuiStatusBar((Rectangle){ 249, GetScreenHeight() - 24, 81, 24}, "SNAP OFF", 10);
|
|
GuiStatusBar((Rectangle){ 329, GetScreenHeight() - 24, 80, 24}, "H - Help", 10);
|
|
GuiStatusBar((Rectangle){ 400, GetScreenHeight() - 24, GetScreenWidth() - 400, 24}, FormatText("Selected Control: %s (%i, %i, %i, %i)", controlTypeName[selectedType], layout[selectedControl].rec.x, layout[selectedControl].rec.y, layout[selectedControl].rec.width, layout[selectedControl].rec.height), 15);
|
|
|
|
EndDrawing();
|
|
//----------------------------------------------------------------------------------
|
|
}
|
|
|
|
// De-Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
UnloadTexture(texture);
|
|
CloseWindow(); // Close window and OpenGL context
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Module specific Functions Definition
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Draw 2d grid
|
|
static void DrawGrid2D(int divsX, int divsY)
|
|
{
|
|
int offset = 0;
|
|
|
|
// Draw vertical grid lines
|
|
for (int i = 0; i < divsX; i++)
|
|
{
|
|
for (int k = 0; k < 5; k++)
|
|
{
|
|
DrawRectangle(-(divsX/2*GRID_LINE_SPACING*5) + offset - 1, -1, 1, GetScreenHeight(), ((k == 0) ? Fade(BLACK, GRID_ALPHA*2) : Fade(GRAY, GRID_ALPHA)));
|
|
offset += GRID_LINE_SPACING;
|
|
}
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
// Draw horizontal grid lines
|
|
for (int i = 0; i < divsY; i++)
|
|
{
|
|
for (int k = 0; k < 5; k++)
|
|
{
|
|
DrawRectangle(-1, -(divsY/2*GRID_LINE_SPACING*5) + offset - 1, GetScreenWidth(), 1, ((k == 0) ? Fade(BLACK, GRID_ALPHA*2) : Fade(GRAY, GRID_ALPHA)));
|
|
offset += GRID_LINE_SPACING;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save gui layout project information
|
|
// NOTE: Exported as text file
|
|
static void SaveLayoutRGL(const char *fileName, bool binary)
|
|
{
|
|
if (binary)
|
|
{
|
|
#define RGL_FILE_VERSION_BINARY 100
|
|
|
|
FILE *rglFile = fopen(fileName, "wb");
|
|
|
|
if (rglFile != NULL)
|
|
{
|
|
|
|
// Write some header info (12 bytes)
|
|
// id: "RGL " - 4 bytes
|
|
// version: 100 - 2 bytes
|
|
// NUM_CONTROLS - 2 bytes
|
|
// reserved - 4 bytes
|
|
|
|
char signature[5] = "RGL ";
|
|
short version = RGL_FILE_VERSION_BINARY;
|
|
short numControls = controlsCounter;
|
|
int reserved = 0;
|
|
|
|
fwrite(signature, 1, 4, rglFile);
|
|
fwrite(&version, 1, sizeof(short), rglFile);
|
|
fwrite(&numControls, 1, sizeof(short), rglFile);
|
|
fwrite(&reserved, 1, sizeof(int), rglFile);
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
// Export data in independent way
|
|
fwrite(&layout[i].id, 1, sizeof(int), rglFile);
|
|
fwrite(&layout[i].type, 1, sizeof(int), rglFile);
|
|
fwrite(&layout[i].rec, 1, sizeof(Rectangle), rglFile);
|
|
fwrite(layout[i].text, 1, 32, rglFile);
|
|
|
|
// TODO: Export anchors data
|
|
}
|
|
|
|
fclose(rglFile);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#define RGL_FILE_VERSION_TEXT "1.0"
|
|
|
|
FILE *rglFile = fopen(fileName, "wt");
|
|
|
|
if (rglFile != NULL)
|
|
{
|
|
// Write some description comments
|
|
fprintf(rglFile, "#\n# rgl text file (v%s) - raygui layout text file generated using rGuiLayout\n#\n", RGL_FILE_VERSION_TEXT);
|
|
fprintf(rglFile, "# Total number of controls: %i\n", controlsCounter);
|
|
fprintf(rglFile, "# Control info: c <id> <type> <rectangle> <text> <anchor_id> <anchor_pos>\n#\n");
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
fprintf(rglFile, "c %03i %i %i %i %i %i %i %i %i %s\n", layout[i].id, layout[i].type, layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height, layout[i].ap->id, layout[i].ap->x, layout[i].ap->y, layout[i].text);
|
|
}
|
|
|
|
fclose(rglFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Import gui layout project information
|
|
// NOTE: Imported from text file
|
|
static void LoadLayoutRGL(const char *fileName)
|
|
{
|
|
char buffer[256];
|
|
bool tryBinary = false;
|
|
|
|
int anchorId = 0; // TODO: Review!!!
|
|
int anchorX = 0;
|
|
int anchorY = 0;
|
|
|
|
FILE *rglFile = fopen(fileName, "rt");
|
|
|
|
if (rglFile != NULL)
|
|
{
|
|
fgets(buffer, 256, rglFile);
|
|
|
|
if (buffer[0] != 'R') // Text file!
|
|
{
|
|
controlsCounter = 0;
|
|
|
|
while (!feof(rglFile))
|
|
{
|
|
if ((buffer[0] != '\n') && (buffer[0] != '#'))
|
|
{
|
|
sscanf(buffer, "c %d %i %i %i %i %i %d %d %d %[^\n]s", &layout[controlsCounter].id, &layout[controlsCounter].type, &layout[controlsCounter].rec.x, &layout[controlsCounter].rec.y, &layout[controlsCounter].rec.width, &layout[controlsCounter].rec.height, &anchorId, &anchorX, &anchorY, layout[controlsCounter].text);
|
|
printf("c %d %i %i %i %i %i %s %i %i %i\n", layout[controlsCounter].id, layout[controlsCounter].type, layout[controlsCounter].rec.x, layout[controlsCounter].rec.y, layout[controlsCounter].rec.width, layout[controlsCounter].rec.height, layout[controlsCounter].text, anchorId, anchorX, anchorY);
|
|
|
|
controlsCounter++;
|
|
}
|
|
fgets(buffer, 256, rglFile);
|
|
}
|
|
}
|
|
else tryBinary = true;
|
|
|
|
fclose(rglFile);
|
|
}
|
|
|
|
if (tryBinary)
|
|
{
|
|
FILE *rglFile = fopen(fileName, "rb");
|
|
|
|
if (rglFile != NULL)
|
|
{
|
|
char signature[5] = "";
|
|
short version = 0;
|
|
int reserved = 0;
|
|
int counter = 0;
|
|
|
|
fread(signature, 1, 4, rglFile);
|
|
fread(&version, 1, sizeof(short), rglFile);
|
|
fread(&controlsCounter, 1, sizeof(short), rglFile);
|
|
fread(&reserved, 1, sizeof(int), rglFile);
|
|
|
|
printf("[READ] Controls counter: %i\n", controlsCounter);
|
|
|
|
if ((signature[0] == 'R') &&
|
|
(signature[1] == 'G') &&
|
|
(signature[2] == 'L') &&
|
|
(signature[3] == ' '))
|
|
{
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
// Import data in independent way
|
|
fread(&layout[i].id, 1, sizeof(int), rglFile);
|
|
fread(&layout[i].type, 1, sizeof(int), rglFile);
|
|
fread(&layout[i].rec, 1, sizeof(Rectangle), rglFile);
|
|
fread(layout[i].text, 1, 32, rglFile);
|
|
/*
|
|
// Import anchor id and position
|
|
// fread(&layout[i].ap->id, 1, sizeof(int), rglFile);
|
|
// fread(&layout[i].ap->x, 1, sizeof(int), rglFile);
|
|
// fread(&layout[i].ap->y, 1, sizeof(int), rglFile);
|
|
*/
|
|
|
|
printf("[READ] Controls info: id-%i type-%i rec-%i,%i,%i,%i text-%s\n", layout[i].id, layout[i].type, layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height, layout[i].text);
|
|
}
|
|
}
|
|
else TraceLog(LOG_WARNING, "[raygui] Invalid layout file");
|
|
|
|
fclose(rglFile);
|
|
}
|
|
}
|
|
|
|
printf("[READ] Layout data loaded successfully!\n");
|
|
}
|
|
|
|
// Generate C code for gui layout
|
|
static void GenerateLayoutCode(const char *fileName)
|
|
{
|
|
#define RGL_TOOL_NAME "rGuiLayout"
|
|
#define RGL_TOOL_DESCRIPTION "tool_name"
|
|
#define RGL_TOOL_AUTHOR "tool_name"
|
|
#define RGL_TOOL_YEAR "2018"
|
|
|
|
FILE *ftool = fopen(fileName, "wt");
|
|
|
|
fprintf(ftool, "/*******************************************************************************************\n");
|
|
fprintf(ftool, "*\n");
|
|
fprintf(ftool, "* %s - %s\n", RGL_TOOL_NAME, RGL_TOOL_DESCRIPTION);
|
|
fprintf(ftool, "*\n");
|
|
fprintf(ftool, "* LICENSE: zlib/libpng\n");
|
|
fprintf(ftool, "*\n");
|
|
fprintf(ftool, "* Copyright (c) %s %s\n", RGL_TOOL_YEAR, RGL_TOOL_AUTHOR);
|
|
fprintf(ftool, "*\n");
|
|
fprintf(ftool, "**********************************************************************************************/\n\n");
|
|
fprintf(ftool, "#include \"raylib.h\"\n\n");
|
|
fprintf(ftool, "#define RAYGUI_IMPLEMENTATION\n");
|
|
fprintf(ftool, "#include \"raygui.h\"\n\n");
|
|
fprintf(ftool, "//----------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, "// Controls Functions Declaration\n");
|
|
fprintf(ftool, "//----------------------------------------------------------------------------------\n");
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
if (layout[i].type == BUTTON) fprintf(ftool, "static void Button%03i();\n", i);
|
|
if (layout[i].type == IMAGEBUTTON) fprintf(ftool, "static void ImageButton%03i();\n", i);
|
|
}
|
|
|
|
fprintf(ftool, "\n");
|
|
fprintf(ftool, "//------------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, "// Program main entry point\n");
|
|
fprintf(ftool, "//------------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, "int main()\n");
|
|
fprintf(ftool, "{\n");
|
|
fprintf(ftool, " // Initialization\n");
|
|
fprintf(ftool, " //---------------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, " int screenWidth = %i;\n", screenWidth);
|
|
fprintf(ftool, " int screenHeight = %i;\n\n", screenHeight);
|
|
fprintf(ftool, " InitWindow(screenWidth, screenHeight, \"rFXGen\");\n\n");
|
|
|
|
fprintf(ftool, " // Needed variables\n");
|
|
fprintf(ftool, " // Anchor points\n");
|
|
fprintf(ftool, " Vector2 %s%02i = { 0, 0 };\n", "anchor", 0);
|
|
|
|
for(int i = 1; i < MAX_ANCHOR_POINTS; i++)
|
|
{
|
|
if (anchors[i].x != 0 && anchors[i].y != 0)
|
|
{
|
|
for (int j = 0; j < controlsCounter; j++)
|
|
{
|
|
if(layout[j].ap->id == anchors[i].id)
|
|
{
|
|
fprintf(ftool, " Vector2 %s%02i = { %i, %i };\n", "anchor", i, anchors[i].x, anchors[i].y);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
// Define texture for IMAGEBUTTON
|
|
fprintf(ftool, " Texture2D texture = LoadTexture(\"icons.png\");\n\n");
|
|
// Define controls variables
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
switch (layout[i].type)
|
|
{
|
|
// Bools
|
|
case TOGGLE:
|
|
case CHECKBOX:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " bool %s%03i = false;\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
break;
|
|
|
|
case COMBOBOX:
|
|
case LISTVIEW:
|
|
case TOGGLEGROUP:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " int %sCount%03i = 3;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " int %sActive%03i = 0;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " const char *%sList%03i[3] = { \"ONE\", \"TWO\", \"THREE\" };\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
break;
|
|
|
|
// Floats
|
|
case SLIDER:
|
|
case SLIDERBAR:
|
|
case PROGRESSBAR:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " float %sValue%03i = 50.0f;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " float %sMinValue%03i = 0.0f;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " float %sMaxValue%03i = 100.0f;\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
break;
|
|
|
|
// Ints
|
|
case SPINNER:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " int %sValue%03i = 0;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " int %sMinValue%03i = 0;\n", controlTypeNameShort[layout[i].type], i);
|
|
fprintf(ftool, " int %sMaxValue%03i = 100;\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
break;
|
|
|
|
// Colors
|
|
case COLORPICKER:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " Color %sColor%03i;\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
break;
|
|
|
|
case TEXTBOX:
|
|
{
|
|
fprintf(ftool, " // %s%03i variables\n", controlTypeName[layout[i].type], i);
|
|
fprintf(ftool, " char %s%03i[32] = \"%s\";\n", controlTypeNameShort[layout[i].type], i, layout[i].text);
|
|
fprintf(ftool, " int %sSize%03i = 32;\n", controlTypeNameShort[layout[i].type], i);
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
fprintf(ftool, "\n");
|
|
|
|
// Define controls rectangles
|
|
fprintf(ftool, " // Define controls rectangles\n");
|
|
fprintf(ftool, " Rectangle layoutRecs[%i] = {\n", controlsCounter);
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
fprintf(ftool, " (Rectangle){ %s%02i%s + %i, %s%02i%s + %i, %i, %i }", "anchor", layout[i].ap->id, ".x", layout[i].rec.x, "anchor", layout[i].ap->id, ".y", layout[i].rec.y, layout[i].rec.width, layout[i].rec.height);
|
|
|
|
if (i == controlsCounter - 1) fprintf(ftool, "\t\t// %s %03i\n };\n\n", controlTypeName[layout[i].type], i);
|
|
else fprintf(ftool, ",\t\t// %s %03i\n", controlTypeName[layout[i].type], i);
|
|
}
|
|
|
|
fprintf(ftool, " SetTargetFPS(60);\n");
|
|
fprintf(ftool, " //--------------------------------------------------------------------------------------\n\n");
|
|
fprintf(ftool, " // Main game loop\n");
|
|
fprintf(ftool, " while (!WindowShouldClose()) // Detect window close button or ESC key\n");
|
|
fprintf(ftool, " {\n");
|
|
fprintf(ftool, " // Update\n");
|
|
fprintf(ftool, " //----------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, " // TODO: Implement required update logic\n");
|
|
fprintf(ftool, " //----------------------------------------------------------------------------------\n\n");
|
|
fprintf(ftool, " // Draw\n");
|
|
fprintf(ftool, " //----------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, " BeginDrawing();\n\n");
|
|
fprintf(ftool, " ClearBackground(GuiBackgroundColor());\n\n");
|
|
|
|
fprintf(ftool, "\t\t\t// Draw all controls\n");
|
|
|
|
// Draw all controls
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
switch (layout[i].type)
|
|
{
|
|
case LABEL: fprintf(ftool, "\t\t\tGuiLabel(layoutRecs[%i], \"%s\");\n\n", i, layout[i].text); break;
|
|
case BUTTON: fprintf(ftool, "\t\t\tif (GuiButton(layoutRecs[%i], \"%s\")) Button%03i(); \n\n", i, layout[i].text, i); break;
|
|
case IMAGEBUTTON: fprintf(ftool, "\t\t\tif (GuiImageButtonEx(layoutRecs[%i], texture, (Rectangle){ 0, 0, texture.width/3, texture.height/6 }, \"%s\")) ImageButton%03i(); \n\n", i, layout[i].text, i); break;
|
|
case TOGGLE: fprintf(ftool, "\t\t\t%s%03i = GuiToggleButton(layoutRecs[%i], \"%s\", %s%03i); \n\n", controlTypeNameShort[layout[i].type], i, i, layout[i].text, controlTypeNameShort[layout[i].type], i); break;
|
|
case TOGGLEGROUP: fprintf(ftool, "\t\t\t%sActive%03i = GuiToggleGroup(layoutRecs[%i], %sList%03i, %sCount%03i, %sActive%03i); \n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case SLIDER: fprintf(ftool, "\t\t\t%sValue%03i = GuiSlider(layoutRecs[%i], %sValue%03i, %sMinValue%03i, %sMaxValue%03i);\n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case SLIDERBAR: fprintf(ftool, "\t\t\t%sValue%03i = GuiSliderBar(layoutRecs[%i], %sValue%03i, %sMinValue%03i, %sMaxValue%03i);\n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case PROGRESSBAR: fprintf(ftool, "\t\t\t%sValue%03i = GuiProgressBar(layoutRecs[%i], %sValue%03i, %sMinValue%03i, %sMaxValue%03i);\n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case SPINNER: fprintf(ftool, "\t\t\t%sValue%03i = GuiSpinner(layoutRecs[%i], %sValue%03i, %sMinValue%03i, %sMaxValue%03i);\n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case COMBOBOX: fprintf(ftool, "\t\t\t%sActive%03i = GuiComboBox(layoutRecs[%i], %sList%03i, %sCount%03i, %sActive%03i); \n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case CHECKBOX: fprintf(ftool, "\t\t\t%s%03i = GuiCheckBox(layoutRecs[%i], %s%03i); \n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i); break;
|
|
case LISTVIEW: fprintf(ftool, "\t\t\t%sActive%03i = GuiListView(layoutRecs[%i], %sList%03i, %sCount%03i, %sActive%03i); \n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case TEXTBOX: fprintf(ftool, "\t\t\tGuiTextBox(layoutRecs[%i], %s%03i, %sSize%03i);\n\n", i, controlTypeNameShort[layout[i].type], i, controlTypeNameShort[layout[i].type], i); break;
|
|
case GROUPBOX: fprintf(ftool, "\t\t\tGuiGroupBox(layoutRecs[%i], \"%s\");\n\n", i, layout[i].text); break;
|
|
case WINDOWBOX: fprintf(ftool, "\t\t\tGuiWindowBox(layoutRecs[%i], \"%s\");\n\n", i, layout[i].text); break;
|
|
case COLORPICKER: fprintf(ftool, "\t\t\t%sColor%03i = GuiColorPicker(layoutRecs[%i], %sColor%03i);\n\n", controlTypeNameShort[layout[i].type], i, i, controlTypeNameShort[layout[i].type], i); break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
fprintf(ftool, " EndDrawing();\n");
|
|
fprintf(ftool, " //----------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, " }\n\n");
|
|
fprintf(ftool, " // De-Initialization\n");
|
|
fprintf(ftool, " //--------------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, " UnloadTexture(texture);\n");
|
|
fprintf(ftool, " CloseWindow(); // Close window and OpenGL context\n");
|
|
fprintf(ftool, " //--------------------------------------------------------------------------------------\n\n");
|
|
fprintf(ftool, " return 0;\n");
|
|
fprintf(ftool, "}\n\n");
|
|
|
|
fprintf(ftool, "//------------------------------------------------------------------------------------\n");
|
|
fprintf(ftool, "// Controls Functions Definitions (local)\n");
|
|
fprintf(ftool, "//------------------------------------------------------------------------------------\n");
|
|
|
|
for (int i = 0; i < controlsCounter; i++)
|
|
{
|
|
if (layout[i].type == BUTTON)
|
|
fprintf(ftool, "static void Button%03i()\n{\n // TODO: Implement control logic\n}\n\n", i);
|
|
|
|
if (layout[i].type == IMAGEBUTTON)
|
|
fprintf(ftool, "static void ImageButton%03i()\n{\n // TODO: Implement control logic\n}\n\n", i);
|
|
}
|
|
|
|
fclose(ftool);
|
|
}
|