/******************************************************************************************* * * raygui styler - raygui Style Editor * * Compile this program using: * gcc -c external/tinyfiledialogs.c -std=c99 -Wall * gcc -o $(NAME_PART).exe $(FILE_NAME) tinyfiledialogs.o -lraylib -lglfw3 -lopengl32 -lgdi32 -lcomdlg32 -lole32 -std=c99 -Wall * * * This example has been created using raylib v1.5 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2015 Sergio Martinez and Ramon Santamaria * ********************************************************************************************/ #include "raylib.h" #define RAYGUI_IMPLEMENTATION #include "../raygui.h" #include "external/tinyfiledialogs.h" #include "colorpicker.h" #include #include #include #define FONT_SIZE 10 #define COLOR_REC BEIGE #define NUM_COLOR_SAMPLES 10 #define ELEMENT_HEIGHT 38 #define STATUS_BAR_HEIGHT 25 #define NUM_ELEMENTS 13 // NOTE: Be extremely careful when defining: NUM_ELEMENTS, GuiElement, guiElementText, guiPropertyNum, guiPropertyType and guiPropertyPos // All those variables must be coherent, one small mistake breaks the program (and it could take ours to find the error!) typedef enum { GLOBAL, BACKGROUND, LABEL, BUTTON, TOGGLE, TOGGLEGROUP, SLIDER, SLIDERBAR, PROGRESSBAR, SPINNER, COMBOBOX, CHECKBOX, TEXTBOX } GuiElement; const char *guiElementText[NUM_ELEMENTS] = { "GLOBAL", "BACKGROUND", "LABEL", "BUTTON", "TOGGLE", "TOGGLEGROUP", "SLIDER", "SLIDERBAR", "PROGRESSBAR", "SPINNER", "COMBOBOX", "CHECKBOX", "TEXTBOX" }; int main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 1280; const int screenHeight = 720; const int guiPropertyNum[NUM_ELEMENTS] = { 5, 1, 3, 11, 14, 1, 7, 6, 4, 14, 18, 8, 6 }; // Defines if the property to change is a Color or a value to update it accordingly // NOTE: 0 - Color, 1 - value const unsigned char guiPropertyType[NUM_PROPERTIES] = { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1 }; int aux = 0; int guiPropertyPos[NUM_ELEMENTS]; for (int i = 0; i < NUM_ELEMENTS; i++) { guiPropertyPos[i] = aux; aux += guiPropertyNum[i]; } //SetConfigFlags(FLAG_FULLSCREEN_MODE); InitWindow(screenWidth, screenHeight, "raygui styler"); int count = 0; char **droppedFiles; Rectangle guiElementRec[NUM_ELEMENTS]; for (int i = 0; i < NUM_ELEMENTS; i++) guiElementRec[i] = (Rectangle){ 0, 0 + i*ELEMENT_HEIGHT, 140, ELEMENT_HEIGHT }; int guiElementSelected = -1; int guiElementHover = -1; // Generate properties rectangles depending on guiPropertyNum[] and guiPropertyPos[] //------------------------------------------------------------ Rectangle propertyRec[NUM_PROPERTIES]; for (int j = 0; j < NUM_ELEMENTS; j++) { for (int i = 0; i < guiPropertyNum[j]; i++) { if ((j + guiPropertyNum[j]) > 18) propertyRec[guiPropertyPos[j] + i] = (Rectangle){ guiElementRec[0].width, guiElementRec[18 - guiPropertyNum[j]].y + i*ELEMENT_HEIGHT, 260, ELEMENT_HEIGHT }; else propertyRec[guiPropertyPos[j] + i] = (Rectangle){ guiElementRec[0].width, guiElementRec[j].y + i*ELEMENT_HEIGHT, 260, ELEMENT_HEIGHT }; } } int guiPropertySelected = -1; int guiPropertyHover = -1; //------------------------------------------------------------ // GUI //----------------------------------------------------------- int guiPosX = 455; int guiPosY = 35; int guiHeight = 30; int guiWidth = 150; int deltaX = 153; int deltaY = 60; int selectPosX = 401; //int selectPosY = 0; int selectWidth = screenWidth - 723; //int selectHeight = screenHeight; //------------------------------------------------------------ // Cursor texture generation //----------------------------------------------------------- int sizeCursor = 16; // size must be POT unsigned char *cursorData = (unsigned char *)malloc(sizeCursor*sizeCursor*2*sizeof(unsigned char)); for(int w = 0; w < sizeCursor; w++) { for (int h = 0; h < sizeCursor; h++) { cursorData[w*sizeCursor*2 + 2*h] = 0; if((sizeCursor%2) == 0) { if(((w == (sizeCursor/2 - 1)) || (w == sizeCursor/2)) && ((h == (sizeCursor/2 - 1)) || (h == sizeCursor/2))) { cursorData[w*sizeCursor*2 + 2*h + 1] = 0; } else if((w == (sizeCursor/2 - 1)) || (w == sizeCursor/2)) cursorData[w*sizeCursor*2 + 2*h + 1] = 255; else if((h == (sizeCursor/2 - 1)) || (h == sizeCursor/2)) cursorData[w*sizeCursor*2 + 2*h + 1] = 255; else cursorData[w*sizeCursor*2 + 2*h + 1] = 0; } } } Texture2D cursorTexture = LoadTextureEx(cursorData, sizeCursor, sizeCursor, UNCOMPRESSED_GRAY_ALPHA); free(cursorData); //----------------------------------------------------------- // Color picker //----------------------------------------------------------- Vector2 colorPickerPos = { (float)screenWidth - 287, 20.0f }; Image colorPickerImage; colorPickerImage.data = pickerData; colorPickerImage.width = 256; colorPickerImage.height = 256; colorPickerImage.mipmaps = 1; colorPickerImage.format = UNCOMPRESSED_R8G8B8; Texture2D colorPickerTexture = LoadTextureFromImage(colorPickerImage); Vector2 cursorPickerPos = {colorPickerPos.x +(colorPickerTexture.width/2) - cursorTexture.width/2, colorPickerPos.y + (colorPickerTexture.height/2) - cursorTexture.height/2}; Color *colorPickerPixel = GetImageData(colorPickerImage); Rectangle colorPickerBounds = (Rectangle){ (int)colorPickerPos.x, (int)colorPickerPos.y, colorPickerTexture.width, colorPickerTexture.height }; Vector2 colorPosition; Color colorPickerValue; Color colorSample[NUM_COLOR_SAMPLES]; for (int i = 0; i < NUM_COLOR_SAMPLES; i++) colorSample[i] = RAYWHITE; int sampleDelta = 18; int rgbWidthLabel = 30; int rgbHeightLabel = 20; int rgbDelta = 6; int redValue = 0; int greenValue = 0; int blueValue = 0; int alphaValue = 255; // -- Color samples Rectangle colorSelectedBoundsRec = {colorPickerPos.x, colorPickerPos.y + colorPickerTexture.height + 2*rgbDelta, 2*rgbWidthLabel, 2*rgbWidthLabel}; bool colorSelectedHover = false; Rectangle sampleBoundsRec[NUM_COLOR_SAMPLES]; int sampleHover = -1; int sampleSelected = 0; for (int i = 0; i < NUM_COLOR_SAMPLES/2; i++) sampleBoundsRec[i] = (Rectangle) {colorPickerPos.x + 2*rgbWidthLabel + i*rgbWidthLabel + 3*rgbDelta + i*rgbDelta, colorPickerPos.y + colorPickerTexture.height + 2*rgbDelta, rgbWidthLabel, rgbWidthLabel - 2}; for (int i = NUM_COLOR_SAMPLES/2; i < NUM_COLOR_SAMPLES; i++) sampleBoundsRec[i] = (Rectangle) {colorPickerPos.x + 2*rgbWidthLabel + (i-5)*rgbWidthLabel + 3*rgbDelta + (i-5)*rgbDelta, colorPickerPos.y + colorPickerTexture.height + 2*rgbDelta + rgbWidthLabel + 2, rgbWidthLabel, rgbWidthLabel - 2}; //------------------------------------------------------------ // Value size selection //----------------------------------------------------------- int sizeValueSelected = 10; //----------------------------------------------------------- Color bgColor = RAYWHITE; bool toggleActive = false; int toggleNum = 3; char *toggleGuiText[3] = { "toggle", "group", "selection" }; float sliderValue = 50; float sliderBarValue = 50; float progressValue = 0; int spinnerValue = 20; int comboNum = 5; char *comboText[5] = { "this", "is", "a" ,"combo", "box" }; int comboActive = 0; char *guiText = (char *)malloc(20); for (int i = 0; i < 20; i++) guiText[i] = '\0'; bool saveStyle = false; bool loadStyle = false; bool isModified = false; const char *fileName; // Checked texture generation //----------------------------------------------------------- int size = 8; Color *pixels = (Color *)malloc(size*size*sizeof(Color)); for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { if (((x/(size/2) + y/(size/2)))%2 == 0) pixels[y*size + x] = RAYWHITE; else pixels[y*size + x] = Fade(LIGHTGRAY, 0.5f); } } Texture2D checkerTexture = LoadTextureEx(pixels, size, size, UNCOMPRESSED_R8G8B8A8); free(pixels); //----------------------------------------------------------- SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- if (IsFileDropped()) { guiPropertySelected = -1; droppedFiles = GetDroppedFiles(&count); fileName = droppedFiles[0]; loadStyle = true; printf("Droped file detected: %s\n", droppedFiles[0]); } if (guiElementSelected == PROGRESSBAR) { if (progressValue > 1.0f) progressValue = 0; progressValue += 0.005f; } for (int i = 0; i < NUM_ELEMENTS; i++) { if (CheckCollisionPointRec(GetMousePosition(), guiElementRec[i])) { guiElementSelected = i; guiElementHover = i; guiPropertySelected = -1; guiPropertyHover = -1; } } if (!CheckCollisionPointRec(GetMousePosition(), guiElementRec[guiElementHover])) guiElementHover = -1; // Check for selected property for (int i = guiPropertyPos[guiElementSelected]; i < guiPropertyPos[guiElementSelected] + guiPropertyNum[guiElementSelected]; i++) { if (CheckCollisionPointRec(GetMousePosition(), propertyRec[i])) { guiPropertyHover = i; // Show current value in color picker or spinner if (guiPropertySelected == -1) { if (guiPropertyType[guiPropertyHover] == 0) // Color type { // Update color picker color value colorPickerValue = GetColor(GetStyleProperty(guiPropertyHover)); redValue = colorPickerValue.r; greenValue = colorPickerValue.g; blueValue = colorPickerValue.b; cursorPickerPos = (Vector2){screenWidth, screenHeight}; } // Value Type else if (guiPropertyType[guiPropertyHover] == 1) sizeValueSelected = GetStyleProperty(guiPropertyHover); } // TODO: REVIEW: Can make the application crash... /* if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { if (guiPropertySelected == i) guiPropertySelected = -1; else { guiPropertySelected = i; if (guiPropertyType[guiPropertyHover] == 0) { colorPickerValue = GetColor(GetStyleProperty(guiPropertySelected)); redValue = colorPickerValue.r; greenValue = colorPickerValue.g; blueValue = colorPickerValue.b; } else sizeValueSelected = GetStyleProperty(guiPropertySelected); } } */ break; } else guiPropertyHover = -1; } // Update style size value if ((guiPropertySelected >= 0) && (guiPropertyType[guiPropertySelected] == 1)) { if (GetStyleProperty(guiPropertySelected) != sizeValueSelected) { isModified = true; SetStyleProperty(guiPropertySelected, sizeValueSelected); } } // Color picker logic if (CheckCollisionPointRec(GetMousePosition(), colorPickerBounds)) { if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { if (!IsCursorHidden()) HideCursor(); cursorPickerPos = (Vector2){ GetMousePosition().x - cursorTexture.width/2, GetMousePosition().y - cursorTexture.height/2}; colorPosition = (Vector2){ GetMousePosition().x - colorPickerPos.x, GetMousePosition().y - colorPickerPos.y}; colorPickerValue = colorPickerPixel[(int)colorPosition.x + (int)colorPosition.y*colorPickerTexture.width]; redValue = colorPickerValue.r; greenValue = colorPickerValue.g; blueValue = colorPickerValue.b; alphaValue = colorPickerValue.a; } if (IsMouseButtonUp(MOUSE_LEFT_BUTTON)) if(IsCursorHidden()) ShowCursor(); } else { if (IsCursorHidden()) ShowCursor(); colorPickerValue.r = redValue; colorPickerValue.g = greenValue; colorPickerValue.b = blueValue; colorPickerValue.a = alphaValue; if ((guiPropertySelected >= 0) && (guiPropertyType[guiPropertySelected] == 0)) { if (GetStyleProperty(guiPropertySelected) != GetHexValue(colorPickerValue)) { SetStyleProperty(guiPropertySelected, GetHexValue(colorPickerValue)); isModified = true; } } } // Color samples if (CheckCollisionPointRec(GetMousePosition(), colorSelectedBoundsRec)) { colorSelectedHover = true; if(IsMouseButtonDown (MOUSE_RIGHT_BUTTON)) colorSample[sampleSelected] = colorPickerValue; } else colorSelectedHover = false; for (int i = 0; i < NUM_COLOR_SAMPLES; i++) { if (CheckCollisionPointRec(GetMousePosition(), sampleBoundsRec[i])) { sampleHover = i; if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { sampleSelected = i; } if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) { sampleSelected = i; colorPickerValue = colorSample[sampleSelected]; redValue = colorPickerValue.r; greenValue = colorPickerValue.g; blueValue = colorPickerValue.b; alphaValue = colorPickerValue.a; } } } // Update style color value --> PROGRAM CRASH!!! /* if (guiPropertySelected == BACKGROUND_COLOR) bgColor = colorPickerValue; else if ((guiPropertySelected != BACKGROUND_COLOR) && (guiPropertyType[guiPropertySelected] == 0)) { bgColor = GetColor(GetStyleProperty(BACKGROUND_COLOR)); SetStyleProperty(guiPropertySelected, GetHexValue(colorPickerValue)); } */ if (saveStyle) { SaveGuiStyle(fileName); saveStyle = false; fileName = ""; isModified = false; } if (loadStyle) { LoadGuiStyle(fileName); loadStyle = false; fileName = ""; isModified = false; ClearDroppedFiles(); } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); // Show selected properties if (guiPropertySelected >= 0) DrawText(FormatText("SELECTED PROPERTY: <%s>", guiPropertyName[guiPropertySelected]), 5, screenHeight - STATUS_BAR_HEIGHT + 8, FONT_SIZE , BLACK); else DrawText("SELECTED PROPERTY: