mirror of
https://github.com/raysan5/raygui.git
synced 2025-12-25 10:22:33 -05:00
Changed GuiToggleGroup() how width parameter works
This commit is contained in:
@ -1137,8 +1137,8 @@ RAYGUIDEF int GuiToggleGroup(Rectangle bounds, const char **text, int count, int
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (i == active) GuiToggleButton((Rectangle){ bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]), bounds.y, bounds.width, bounds.height }, text[i], true);
|
||||
else if (GuiToggleButton((Rectangle){ bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]), bounds.y, bounds.width, bounds.height }, text[i], false) == true) active = i;
|
||||
if (i == active) GuiToggleButton((Rectangle){ bounds.x + i*(bounds.width/count + style[TOGGLEGROUP_PADDING]), bounds.y, bounds.width/count, bounds.height }, text[i], true);
|
||||
else if (GuiToggleButton((Rectangle){ bounds.x + i*(bounds.width/count + style[TOGGLEGROUP_PADDING]), bounds.y, bounds.width/count, bounds.height }, text[i], false) == true) active = i;
|
||||
}
|
||||
|
||||
return active;
|
||||
|
||||
7370
tools/rGuiLayout/external/tinyfiledialogs.c
vendored
Normal file
7370
tools/rGuiLayout/external/tinyfiledialogs.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
325
tools/rGuiLayout/external/tinyfiledialogs.h
vendored
Normal file
325
tools/rGuiLayout/external/tinyfiledialogs.h
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
/*_________
|
||||
/ \ tinyfiledialogs.h v3.3.1 [Feb 16, 2018] zlib licence
|
||||
|tiny file| Unique header file created [November 9, 2014]
|
||||
| dialogs | Copyright (c) 2014 - 2018 Guillaume Vareille http://ysengrin.com
|
||||
\____ ___/ http://tinyfiledialogs.sourceforge.net
|
||||
\| git clone http://git.code.sf.net/p/tinyfiledialogs/code tinyfd
|
||||
____________________________________________
|
||||
| |
|
||||
| email: tinyfiledialogs at ysengrin.com |
|
||||
|____________________________________________|
|
||||
________________________________________________________________________
|
||||
| |
|
||||
| the windows only wchar_t UTF-16 prototypes are at the end of this file |
|
||||
|________________________________________________________________________|
|
||||
|
||||
Please 1) let me know If you are using it on exotic hardware / OS / compiler
|
||||
2) leave a 1-word review on Sourceforge.
|
||||
3) upvote my stackoverflow answer/advert https://stackoverflow.com/a/47651444
|
||||
|
||||
tiny file dialogs (cross-platform C C++)
|
||||
InputBox PasswordBox MessageBox ColorPicker
|
||||
OpenFileDialog SaveFileDialog SelectFolderDialog
|
||||
Native dialog library for WINDOWS MAC OSX GTK+ QT CONSOLE & more
|
||||
SSH supported via automatic switch to console mode or X11 forwarding
|
||||
|
||||
a C file + a header (add them to your C or C++ project) with 8 functions:
|
||||
- beep
|
||||
- notify popup
|
||||
- message & question
|
||||
- input & password
|
||||
- save file
|
||||
- open file(s)
|
||||
- select folder
|
||||
- color picker
|
||||
|
||||
Complements OpenGL GLFW GLUT GLUI VTK SFML TGUI SDL Ogre Unity3d ION OpenCV
|
||||
CEGUI MathGL GLM CPW GLOW IMGUI MyGUI GLT NGL STB & GUI less programs
|
||||
|
||||
NO INIT
|
||||
NO MAIN LOOP
|
||||
NO LINKING
|
||||
NO INCLUDE
|
||||
|
||||
The dialogs can be forced into console mode
|
||||
|
||||
Windows (XP to 10) ASCII MBCS UTF-8 UTF-16
|
||||
- native code & vbs create the graphic dialogs
|
||||
- enhanced console mode can use dialog.exe from
|
||||
http://andrear.altervista.org/home/cdialog.php
|
||||
- basic console input
|
||||
|
||||
Unix (command line calls) ASCII UTF-8
|
||||
- applescript, kdialog, zenity
|
||||
- python (2 or 3) + tkinter + python-dbus (optional)
|
||||
- dialog (opens a console if needed)
|
||||
- basic console input
|
||||
The same executable can run across desktops & distributions
|
||||
|
||||
C89 & C++98 compliant: tested with C & C++ compilers
|
||||
VisualStudio MinGW-gcc GCC Clang TinyCC OpenWatcom-v2 BorlandC SunCC
|
||||
on Windows Mac Linux Bsd Solaris Minix Raspbian
|
||||
using Gnome Kde Enlightenment Mate Cinnamon Unity Lxde Lxqt Xfce
|
||||
WindowMaker IceWm Cde Jds OpenBox Awesome Jwm Xdm
|
||||
|
||||
Bindings for LUA and C# dll, Haskell
|
||||
Included in LWJGL(java), Rust, Allegrobasic
|
||||
|
||||
- License -
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef TINYFILEDIALOGS_H
|
||||
#define TINYFILEDIALOGS_H
|
||||
|
||||
/* #define TINYFD_NOLIB */
|
||||
/* On windows, define TINYFD_NOLIB here
|
||||
if you don't want to include the code creating the graphic dialogs.
|
||||
Then you won't need to link against Comdlg32.lib and Ole32.lib */
|
||||
|
||||
/* if tinydialogs.c is compiled as C++ code rather than C code,
|
||||
you may need to comment out:
|
||||
extern "C" {
|
||||
and the corresponding closing bracket near the end of this file:
|
||||
}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char tinyfd_version[8]; /* contains tinyfd current version number */
|
||||
extern int tinyfd_verbose; /* 0 (default) or 1 : on unix, prints the command line calls */
|
||||
extern char tinyfd_needs[]; /* info about requirements */
|
||||
|
||||
#ifdef _WIN32
|
||||
/* for UTF-16 use the functions at the end of this files */
|
||||
extern int tinyfd_winUtf8; /* 0 (default MBCS) or 1 (UTF-8)*/
|
||||
/* on windows string char can be 0:MBCS or 1:UTF-8
|
||||
unless your code is really prepared for UTF-8 on windows, leave this on MBSC.
|
||||
Or you can use the UTF-16 (wchar) prototypes at the end of ths file.*/
|
||||
#endif
|
||||
|
||||
extern int tinyfd_forceConsole; /* 0 (default) or 1 */
|
||||
/* for unix & windows: 0 (graphic mode) or 1 (console mode).
|
||||
0: try to use a graphic solution, if it fails then it uses console mode.
|
||||
1: forces all dialogs into console mode even when an X server is present,
|
||||
if the package dialog (and a console is present) or dialog.exe is installed.
|
||||
on windows it only make sense for console applications */
|
||||
|
||||
extern char tinyfd_response[1024];
|
||||
/* if you pass "tinyfd_query" as aTitle,
|
||||
the functions will not display the dialogs
|
||||
but will return 0 for console mode, 1 for graphic mode.
|
||||
tinyfd_response is then filled with the retain solution.
|
||||
possible values for tinyfd_response are (all lowercase)
|
||||
for graphic mode:
|
||||
windows_wchar windows
|
||||
applescript kdialog zenity zenity3 matedialog qarma
|
||||
python2-tkinter python3-tkinter python-dbus perl-dbus
|
||||
gxmessage gmessage xmessage xdialog gdialog
|
||||
for console mode:
|
||||
dialog whiptail basicinput */
|
||||
|
||||
void tinyfd_beep();
|
||||
|
||||
int tinyfd_notifyPopup(
|
||||
char const * const aTitle, /* NULL or "" */
|
||||
char const * const aMessage, /* NULL or "" may contain \n \t */
|
||||
char const * const aIconType); /* "info" "warning" "error" */
|
||||
/* return has only meaning for tinyfd_query */
|
||||
|
||||
int tinyfd_messageBox(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aMessage , /* NULL or "" may contain \n \t */
|
||||
char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */
|
||||
char const * const aIconType , /* "info" "warning" "error" "question" */
|
||||
int const aDefaultButton ) ;
|
||||
/* 0 for cancel/no , 1 for ok/yes , 2 for no in yesnocancel */
|
||||
|
||||
char const * tinyfd_inputBox(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aMessage , /* NULL or "" may NOT contain \n \t on windows */
|
||||
char const * const aDefaultInput ) ; /* "" , if NULL it's a passwordBox */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
char const * tinyfd_saveFileDialog(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aDefaultPathAndFile , /* NULL or "" */
|
||||
int const aNumOfFilterPatterns , /* 0 */
|
||||
char const * const * const aFilterPatterns , /* NULL | {"*.jpg","*.png"} */
|
||||
char const * const aSingleFilterDescription ) ; /* NULL | "text files" */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
char const * tinyfd_openFileDialog(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aDefaultPathAndFile , /* NULL or "" */
|
||||
int const aNumOfFilterPatterns , /* 0 */
|
||||
char const * const * const aFilterPatterns , /* NULL {"*.jpg","*.png"} */
|
||||
char const * const aSingleFilterDescription , /* NULL | "image files" */
|
||||
int const aAllowMultipleSelects ) ; /* 0 or 1 */
|
||||
/* in case of multiple files, the separator is | */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
char const * tinyfd_selectFolderDialog(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aDefaultPath ) ; /* NULL or "" */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
char const * tinyfd_colorChooser(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
char const * const aDefaultHexRGB , /* NULL or "#FF0000" */
|
||||
unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */
|
||||
unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */
|
||||
/* returns the hexcolor as a string "#FF0000" */
|
||||
/* aoResultRGB also contains the result */
|
||||
/* aDefaultRGB is used only if aDefaultHexRGB is NULL */
|
||||
/* aDefaultRGB and aoResultRGB can be the same array */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
|
||||
/************ NOT CROSS PLATFORM SECTION STARTS HERE ************************/
|
||||
#ifdef _WIN32
|
||||
#ifndef TINYFD_NOLIB
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
int tinyfd_notifyPopupW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aMessage, /* NULL or L"" may contain \n \t */
|
||||
wchar_t const * const aIconType); /* L"info" L"warning" L"error" */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
int tinyfd_messageBoxW(
|
||||
wchar_t const * const aTitle , /* NULL or L"" */
|
||||
wchar_t const * const aMessage, /* NULL or L"" may contain \n \t */
|
||||
wchar_t const * const aDialogType, /* L"ok" L"okcancel" L"yesno" */
|
||||
wchar_t const * const aIconType, /* L"info" L"warning" L"error" L"question" */
|
||||
int const aDefaultButton ); /* 0 for cancel/no , 1 for ok/yes */
|
||||
/* returns 0 for cancel/no , 1 for ok/yes */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
wchar_t const * tinyfd_inputBoxW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aMessage, /* NULL or L"" may NOT contain \n nor \t */
|
||||
wchar_t const * const aDefaultInput ); /* L"" , if NULL it's a passwordBox */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
wchar_t const * tinyfd_saveFileDialogW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aDefaultPathAndFile, /* NULL or L"" */
|
||||
int const aNumOfFilterPatterns, /* 0 */
|
||||
wchar_t const * const * const aFilterPatterns, /* NULL or {L"*.jpg",L"*.png"} */
|
||||
wchar_t const * const aSingleFilterDescription); /* NULL or L"image files" */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
wchar_t const * tinyfd_openFileDialogW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aDefaultPathAndFile, /* NULL or L"" */
|
||||
int const aNumOfFilterPatterns , /* 0 */
|
||||
wchar_t const * const * const aFilterPatterns, /* NULL {L"*.jpg",L"*.png"} */
|
||||
wchar_t const * const aSingleFilterDescription, /* NULL or L"image files" */
|
||||
int const aAllowMultipleSelects ) ; /* 0 or 1 */
|
||||
/* in case of multiple files, the separator is | */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
wchar_t const * tinyfd_selectFolderDialogW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aDefaultPath); /* NULL or L"" */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
/* windows only - utf-16 version */
|
||||
wchar_t const * tinyfd_colorChooserW(
|
||||
wchar_t const * const aTitle, /* NULL or L"" */
|
||||
wchar_t const * const aDefaultHexRGB, /* NULL or L"#FF0000" */
|
||||
unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */
|
||||
unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */
|
||||
/* returns the hexcolor as a string L"#FF0000" */
|
||||
/* aoResultRGB also contains the result */
|
||||
/* aDefaultRGB is used only if aDefaultHexRGB is NULL */
|
||||
/* aDefaultRGB and aoResultRGB can be the same array */
|
||||
/* returns NULL on cancel */
|
||||
|
||||
|
||||
#endif /*TINYFD_NOLIB*/
|
||||
#else /*_WIN32*/
|
||||
|
||||
/* unix zenity only */
|
||||
char const * tinyfd_arrayDialog(
|
||||
char const * const aTitle , /* NULL or "" */
|
||||
int const aNumOfColumns , /* 2 */
|
||||
char const * const * const aColumns, /* {"Column 1","Column 2"} */
|
||||
int const aNumOfRows, /* 2 */
|
||||
char const * const * const aCells);
|
||||
/* {"Row1 Col1","Row1 Col2","Row2 Col1","Row2 Col2"} */
|
||||
|
||||
#endif /*_WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TINYFILEDIALOGS_H */
|
||||
|
||||
/*
|
||||
- This is not for android nor ios.
|
||||
- The code is pure C, perfectly compatible with C++.
|
||||
- the windows only wchar_t (utf-16) prototypes are in the header file
|
||||
- windows is fully supported from XP to 10 (maybe even older versions)
|
||||
- C# & LUA via dll, see example files
|
||||
- OSX supported from 10.4 to latest (maybe even older versions)
|
||||
- Avoid using " and ' in titles and messages.
|
||||
- There's one file filter only, it may contain several patterns.
|
||||
- If no filter description is provided,
|
||||
the list of patterns will become the description.
|
||||
- char const * filterPatterns[3] = { "*.obj" , "*.stl" , "*.dxf" } ;
|
||||
- On windows char defaults to MBCS, set tinyfd_winUtf8=1 to use UTF-8
|
||||
- On windows link against Comdlg32.lib and Ole32.lib
|
||||
This linking is not compulsary for console mode (see above).
|
||||
- On unix: it tries command line calls, so no such need.
|
||||
- On unix you need one of the following:
|
||||
applescript, kdialog, zenity, matedialog, shellementary, qarma,
|
||||
python (2 or 3)/tkinter/python-dbus (optional), Xdialog
|
||||
or dialog (opens terminal if running without console) or xterm.
|
||||
- One of those is already included on most (if not all) desktops.
|
||||
- In the absence of those it will use gdialog, gxmessage or whiptail
|
||||
with a textinputbox.
|
||||
- If nothing is found, it switches to basic console input,
|
||||
it opens a console if needed (requires xterm + bash).
|
||||
- Use windows separators on windows and unix separators on unix.
|
||||
- String memory is preallocated statically for all the returned values.
|
||||
- File and path names are tested before return, they are valid.
|
||||
- If you pass only a path instead of path + filename,
|
||||
make sure it ends with a separator.
|
||||
- tinyfd_forceConsole=1; at run time, forces dialogs into console mode.
|
||||
- On windows, console mode only make sense for console applications.
|
||||
- On windows, Console mode is not implemented for wchar_T UTF-16.
|
||||
- Mutiple selects are not allowed in console mode.
|
||||
- The package dialog must be installed to run in enhanced console mode.
|
||||
It is already installed on most unix systems.
|
||||
- On osx, the package dialog can be installed via
|
||||
http://macappstore.org/dialog or http://macports.org
|
||||
- On windows, for enhanced console mode,
|
||||
dialog.exe should be copied somewhere on your executable path.
|
||||
It can be found at the bottom of the following page:
|
||||
http://andrear.altervista.org/home/cdialog.php
|
||||
- If dialog is missing, it will switch to basic console input.
|
||||
- You can query the type of dialog that will be use.
|
||||
- MinGW needs gcc >= v4.9 otherwise some headers are incomplete.
|
||||
- The Hello World (and a bit more) is on the sourceforge site:
|
||||
*/
|
||||
@ -15,6 +15,15 @@
|
||||
#define RAYGUI_STYLE_SAVE_LOAD
|
||||
#include "raygui.h"
|
||||
#include "easings.h"
|
||||
#include "external/tinyfiledialogs.h" // Open/Save file dialogs
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h>
|
||||
#define GetCurrentDir _getcwd
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define GetCurrentDir getcwd
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
@ -64,6 +73,7 @@ typedef struct {
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static char currentPath[256]; // Path to current working folder
|
||||
static int screenWidth = 1280;
|
||||
static int screenHeight = 720;
|
||||
|
||||
@ -81,10 +91,10 @@ const char *controlTypeNameShort[] = { "lbl", "btn", "ibtn", "tggl", "tgroup", "
|
||||
//----------------------------------------------------------------------------------
|
||||
// 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 SaveGuiLayout(const char *fileName); // Save gui layout project information
|
||||
static void LoadGuiLayout(const char *fileName); // Load gui layout project information
|
||||
static void GenerateGuiLayoutCode(const char *fileName); // Generate C code for gui layout
|
||||
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
|
||||
@ -107,6 +117,7 @@ int main()
|
||||
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;
|
||||
bool anchorMode = false;
|
||||
|
||||
@ -116,14 +127,14 @@ int main()
|
||||
(Rectangle){ 0, 0, 100, 30}, // BUTTON
|
||||
(Rectangle){ 0, 0, 100, 30}, // IMAGEBUTTON
|
||||
(Rectangle){ 0, 0, 100, 30}, // TOGGLE
|
||||
(Rectangle){ 0, 0, 80, 30}, // TOGGLEGROUP
|
||||
(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, 120, 30}, // SPINNER
|
||||
(Rectangle){ 0, 0, 120, 30}, // COMBOBOX
|
||||
(Rectangle){ 0, 0, 30, 30}, // CHECKBOX
|
||||
(Rectangle){ 0, 0, 80, 20}, // TEXTBOX
|
||||
(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, 250}, // LISTVIEW
|
||||
(Rectangle){ 0, 0, 120, 120} // COLORPICKER
|
||||
};
|
||||
@ -180,9 +191,15 @@ int main()
|
||||
GuiLoadStyleImage("default_light.png");
|
||||
Texture2D texture = LoadTexture("default_light.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
|
||||
|
||||
// TODO: Initialize layout controls to default values
|
||||
|
||||
|
||||
GuiSetStyleProperty(TOGGLEGROUP_PADDING, 5);
|
||||
|
||||
SetTargetFPS(120);
|
||||
//--------------------------------------------------------------------------------------
|
||||
@ -195,12 +212,6 @@ int main()
|
||||
mouseX = GetMouseX();
|
||||
mouseY = GetMouseY();
|
||||
|
||||
// Updates the defaultRec[selectedType] position
|
||||
|
||||
|
||||
defaultRec[selectedType].x = mouseX - defaultRec[selectedType].width/2;
|
||||
defaultRec[selectedType].y = mouseY - defaultRec[selectedType].height/2;
|
||||
|
||||
// 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;
|
||||
@ -334,7 +345,7 @@ int main()
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -345,7 +356,7 @@ int main()
|
||||
// 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++;
|
||||
}
|
||||
@ -360,7 +371,7 @@ int main()
|
||||
}
|
||||
|
||||
// Delete selected control and shift array position
|
||||
if (IsKeyDown(KEY_BACKSPACE))
|
||||
if (IsKeyDown(KEY_DELETE))
|
||||
{
|
||||
for (int i = selectedControl; i < controlsCounter; i++) layout[i] = layout[i + 1];
|
||||
|
||||
@ -387,11 +398,15 @@ int main()
|
||||
if (!CheckCollisionPointRec(GetMousePosition(), listViewControlsCounter)) controlCollision = false;
|
||||
// Updates the selectedType with the MouseWheel
|
||||
selectedType -= GetMouseWheelMove();
|
||||
if (selectedType < LABEL) selectedType = LABEL;
|
||||
else if (selectedType > COLORPICKER) selectedType = COLORPICKER;
|
||||
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;
|
||||
|
||||
// Enables or disables snapMode if not in textEditMode
|
||||
if (IsKeyPressed(KEY_S) && (!textEditMode)) snapMode = !snapMode;
|
||||
|
||||
@ -436,7 +451,7 @@ int main()
|
||||
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))
|
||||
@ -449,10 +464,18 @@ int main()
|
||||
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;
|
||||
if (textEditMode && IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
textEditMode = false;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
// Turns on textEditMode
|
||||
if (IsKeyPressed(KEY_T) && (selectedControl != -1) &&
|
||||
@ -474,9 +497,7 @@ int main()
|
||||
anchorPoint[anchorCounter].position = (Vector2){ mouseX, mouseY };
|
||||
anchorPoint[anchorCounter].bounds = (Rectangle){ anchorPoint[anchorCounter].position.x - 5, anchorPoint[anchorCounter].position.y - 5, 10, 10 };
|
||||
anchorCounter++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else anchorMode = false;
|
||||
|
||||
@ -486,6 +507,20 @@ int main()
|
||||
//layout[i].rec = (Rectangle){ anchorPoint[layout[i].anchorId].position.x + layout[i].ap.x - layout[i].rec.width/2, anchorPoint[layout[i].anchorId].position.y + layout[i].ap.y - layout[i].rec.height/2, layout[i].rec.width, layout[i].rec.height };
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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].rec.width <= 10) layout[selectedControl].rec.width = 10;
|
||||
|
||||
// Sets the minimum limit of the height
|
||||
if (layout[selectedControl].rec.height <= 10) layout[selectedControl].rec.height = 10;
|
||||
}
|
||||
|
||||
|
||||
// TODO: If mouse over anchor (define default bounds) and click, start anchor line
|
||||
// TODO: On mouse up over an existing control, anchor is created (draw line for reference)
|
||||
@ -499,9 +534,34 @@ int main()
|
||||
// Shows or hides the grid if not in textEditMode
|
||||
if (IsKeyPressed(KEY_G) && (!textEditMode)) showGrid = !showGrid;
|
||||
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_S)) SaveGuiLayout("test_layout.rlyt");
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_O)) LoadGuiLayout("test_layout.rlyt");
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_ENTER)) GenerateGuiLayoutCode("test_layout.c");
|
||||
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", false);
|
||||
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
|
||||
@ -558,6 +618,7 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draw the list of controls
|
||||
DrawRectangleRec(listViewControls, Fade(WHITE, 0.7f));
|
||||
selectedType = GuiListView(listViewControls, guiControls, 14, selectedType);
|
||||
@ -588,6 +649,15 @@ int main()
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
@ -655,55 +725,160 @@ static void DrawGrid2D(int divsX, int divsY)
|
||||
|
||||
// Save gui layout project information
|
||||
// NOTE: Exported as text file
|
||||
static void SaveGuiLayout(const char *fileName)
|
||||
static void SaveLayoutRGL(const char *fileName, bool binary)
|
||||
{
|
||||
FILE *flayout = fopen(fileName, "wt");
|
||||
|
||||
fprintf(flayout, "# Num Controls : %i\n\n", controlsCounter);
|
||||
|
||||
for (int i = 0; i < controlsCounter; i++)
|
||||
if (binary)
|
||||
{
|
||||
fprintf(flayout, "# Control %03i : %s\n", i, controlTypeName[layout[i].type]);
|
||||
fprintf(flayout, "type %i rec %i %i %i %i\n\n", layout[i].type, layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height);
|
||||
#define RGL_FILE_VERSION_BINARY 100
|
||||
|
||||
FILE *flayout = fopen(fileName, "wb");
|
||||
|
||||
if (flayout != 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, flayout);
|
||||
fwrite(&version, 1, sizeof(short), flayout);
|
||||
fwrite(&numControls, 1, sizeof(short), flayout);
|
||||
fwrite(&reserved, 1, sizeof(int), flayout);
|
||||
|
||||
for (int i = 0; i < controlsCounter; i++) fwrite(&layout[i], 1, sizeof(GuiControl), flayout);
|
||||
|
||||
fclose(flayout);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#define RGL_FILE_VERSION_TEXT "1.0"
|
||||
|
||||
FILE *flayout = fopen(fileName, "wt");
|
||||
|
||||
if (flayout != NULL)
|
||||
{
|
||||
// Write some description comments
|
||||
fprintf(flayout, "#\n# rglt file (v%s) - raygui layout text file generated using rGuiLayout\n#\n", RGL_FILE_VERSION_TEXT);
|
||||
fprintf(flayout, "# Total number of controls: %i\n#\n", controlsCounter);
|
||||
|
||||
|
||||
for (int i = 0; i < controlsCounter; i++)
|
||||
{
|
||||
|
||||
// fprintf(flayout, "Control %03i : %s\n", layout[i].id, controlTypeName[layout[i].type]);
|
||||
// fprintf(flayout, "Rec %i %i %i %i\n", layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height);
|
||||
// fprintf(flayout, "Text %s\n", layout[i].text);
|
||||
// fprintf(flayout, "Anchor Id %i\n\n", layout[i].anchorId);
|
||||
fprintf(flayout, "Control %03i : %s Rec %i %i %i %i Text %s Anchor Id %i\n\n", layout[i].id, controlTypeName[layout[i].type], layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height, layout[i].text, layout[i].anchorId);
|
||||
}
|
||||
|
||||
fclose(flayout);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(flayout);
|
||||
}
|
||||
|
||||
// Import gui layout project information
|
||||
// NOTE: Imported from text file
|
||||
static void LoadGuiLayout(const char *fileName)
|
||||
static void LoadLayoutRGL(const char *fileName)
|
||||
{
|
||||
char line[128];
|
||||
|
||||
char buffer[256];
|
||||
bool tryBinary = false;
|
||||
|
||||
FILE *flayout = fopen(fileName, "rt");
|
||||
|
||||
controlsCounter = 0;
|
||||
|
||||
while (!feof(flayout))
|
||||
if (flayout != NULL)
|
||||
{
|
||||
fgets(line, 128, flayout);
|
||||
fgets(buffer, 256, flayout);
|
||||
|
||||
switch (line[0])
|
||||
if (buffer[0] != 'R') // Text file!
|
||||
{
|
||||
case 'c':
|
||||
controlsCounter = 0;
|
||||
|
||||
while (!feof(flayout))
|
||||
{
|
||||
sscanf(line, "c type %i rec %i %i %i %i", &layout[controlsCounter].type,
|
||||
&layout[controlsCounter].rec.x,
|
||||
&layout[controlsCounter].rec.y,
|
||||
&layout[controlsCounter].rec.width,
|
||||
&layout[controlsCounter].rec.height);
|
||||
controlsCounter++;
|
||||
} break;
|
||||
default: break;
|
||||
if ((buffer[0] != '\n') && (buffer[0] != '#'))
|
||||
{
|
||||
sscanf(buffer, "Control %03i : %s Rec %i %i %i %i Text %s Anchor Id %i\n\n", layout[controlsCounter].id, controlTypeName[layout[controlsCounter].type], layout[controlsCounter].rec.x, layout[controlsCounter].rec.y, layout[controlsCounter].rec.width, layout[controlsCounter].rec.height, layout[controlsCounter].text, layout[controlsCounter].anchorId);
|
||||
controlsCounter++;
|
||||
}
|
||||
fgets(buffer, 256, flayout);
|
||||
}
|
||||
}
|
||||
else tryBinary = true;
|
||||
|
||||
fclose(flayout);
|
||||
}
|
||||
|
||||
if (tryBinary)
|
||||
{
|
||||
FILE *flayout = fopen(fileName, "rb");
|
||||
|
||||
if (flayout != NULL)
|
||||
{
|
||||
char signature[5] = "";
|
||||
short version = 0;
|
||||
int reserved = 0;
|
||||
|
||||
fread(signature, 1, 4, flayout);
|
||||
fread(&version, 1, sizeof(short), flayout);
|
||||
fread(&controlsCounter, 1, sizeof(short), flayout);
|
||||
fread(&reserved, 1, sizeof(int), flayout);
|
||||
|
||||
if ((signature[0] == 'R') &&
|
||||
(signature[1] == 'G') &&
|
||||
(signature[2] == 'L') &&
|
||||
(signature[3] == ' '))
|
||||
{
|
||||
while (!feof(flayout))
|
||||
{
|
||||
for (int i = 0; i < controlsCounter; i++) fread(&layout[i], 1, sizeof(GuiControl), flayout);
|
||||
}
|
||||
}
|
||||
else TraceLog(LOG_WARNING, "[raygui] Invalid layout file");
|
||||
|
||||
fclose(flayout);
|
||||
}
|
||||
}
|
||||
|
||||
// char line[128];
|
||||
|
||||
fclose(flayout);
|
||||
// FILE *flayout = fopen(fileName, "rt");
|
||||
|
||||
// controlsCounter = 0;
|
||||
|
||||
// while (!feof(flayout))
|
||||
// {
|
||||
// fgets(line, 128, flayout);
|
||||
|
||||
// switch (line[0])
|
||||
// {
|
||||
// case 'c':
|
||||
// {
|
||||
// sscanf(line, "c type %i rec %i %i %i %i", &layout[controlsCounter].type,
|
||||
// &layout[controlsCounter].rec.x,
|
||||
// &layout[controlsCounter].rec.y,
|
||||
// &layout[controlsCounter].rec.width,
|
||||
// &layout[controlsCounter].rec.height);
|
||||
// controlsCounter++;
|
||||
// } break;
|
||||
// default: break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// fclose(flayout);
|
||||
}
|
||||
|
||||
// Generate C code for gui layout
|
||||
static void GenerateGuiLayoutCode(const char *fileName)
|
||||
static void GenerateLayoutCode(const char *fileName)
|
||||
{
|
||||
FILE *ftool = fopen(fileName, "wt");
|
||||
|
||||
|
||||
13
tools/rGuiLayout/test_layout.rgl
Normal file
13
tools/rGuiLayout/test_layout.rgl
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
# rglt file (v1.0) - raygui layout text file generated using rGuiLayout
|
||||
#
|
||||
# Total number of controls: 4
|
||||
#
|
||||
Control 000 : BUTTON Rec 341 235 100 30 Text SAMPLE TEXT Anchor Id 0
|
||||
|
||||
Control 001 : BUTTON Rec 647 226 100 30 Text SAMPLE TEXT Anchor Id 0
|
||||
|
||||
Control 002 : BUTTON Rec 473 512 100 30 Text SAMPLE TEXT Anchor Id 0
|
||||
|
||||
Control 003 : BUTTON Rec 257 422 100 30 Text SAMPLE TEXT Anchor Id 0
|
||||
|
||||
Reference in New Issue
Block a user