From d62f9c0b75be069cb225578988461955a2fca99d Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 15 Jan 2017 22:40:02 +0100 Subject: [PATCH] Upload rGuiLayout tool -IN PROGRESS- Working on a tool to visually define raygui-based layouts and export C code base implementation prepared for completion --- tools/rGuiLayout/SOON.txt | 0 tools/rGuiLayout/rguilayout.c | 464 ++++++++++++++++++++++++++++++ tools/rGuiLayout/test_layout.c | 96 +++++++ tools/rGuiLayout/test_layout.png | Bin 0 -> 21602 bytes tools/rGuiLayout/test_layout.rlyt | 38 +++ 5 files changed, 598 insertions(+) delete mode 100644 tools/rGuiLayout/SOON.txt create mode 100644 tools/rGuiLayout/rguilayout.c create mode 100644 tools/rGuiLayout/test_layout.c create mode 100644 tools/rGuiLayout/test_layout.png create mode 100644 tools/rGuiLayout/test_layout.rlyt diff --git a/tools/rGuiLayout/SOON.txt b/tools/rGuiLayout/SOON.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tools/rGuiLayout/rguilayout.c b/tools/rGuiLayout/rguilayout.c new file mode 100644 index 0000000..425d284 --- /dev/null +++ b/tools/rGuiLayout/rguilayout.c @@ -0,0 +1,464 @@ +/******************************************************************************************* +* +* 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 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define MAX_GUI_CONTROLS 128 // Maximum number of gui controls + +#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, + TOGGLE, + TOGGLEGROUP, + SLIDER, + SLIDERBAR, + PROGRESSBAR, + SPINNER, + COMBOBOX, + CHECKBOX, + TEXTBOX +} GuiControlType; + +// Gui control type +typedef struct { + int id; + GuiControlType type; + Rectangle rec; +} GuiControl; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static int screenWidth = 800; +static int screenHeight = 450; + +static GuiControl layout[MAX_GUI_CONTROLS]; +static int controlsCounter = 0; + +//Rectangle defaultControlWidth[] = { }; + +const char *controlTypeName[] = { "LABEL", "BUTTON", "TOGGLE", "TOGGLEGROUP", "SLIDER", "SLIDERBAR", "PROGRESSBAR", "SPINNER", "COMBOBOX", "CHECKBOX", "TEXTBOX" }; +const char *controlTypeNameLow[] = { "Label", "Button", "Toggle", "ToggleGroup", "Slider", "SliderBar", "ProgressBar", "Spinner", "ComboBox", "CheckBox", "TextBox" }; +const char *controlTypeNameShort[] = { "lbl", "btn", "tggl", "tgroup", "sldr", "sldrb", "prgssb", "spnr", "combox", "chkbox", "txtbox" }; + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static void DrawGrid2D(int divsX, int divsY); // Draw 2d grid with a specific number of divisions for horizontal and vertical lines +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 + +//---------------------------------------------------------------------------------- +// Main Entry point +//---------------------------------------------------------------------------------- +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "raylib tool - raygui layout editor"); + + int controlSelected = -1; + + char *list[3] = { "ONE", "TWO", "THREE" }; + + bool snapMode = false; + int selectedType = BUTTON; + int mouseX, mouseY; + + SetTargetFPS(120); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + mouseX = GetMouseX(); + mouseY = GetMouseY(); + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && (controlSelected == -1)) + { + // Add new control (button) + layout[controlsCounter].id = controlsCounter; + layout[controlsCounter].type = selectedType; + layout[controlsCounter].rec = (Rectangle){ mouseX, mouseY, 100, 30 }; + + controlsCounter++; + } + + for (int i = 0; i < controlsCounter; i++) + { + if (CheckCollisionPointRec(GetMousePosition(), layout[i].rec)) + { + controlSelected = i; + break; + } + else controlSelected = -1; + } + + if (controlSelected != -1) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + layout[controlSelected].rec.x = mouseX - layout[controlSelected].rec.width/2; + layout[controlSelected].rec.y = mouseY - layout[controlSelected].rec.height/2; + + // Snap to grid position and size + if (snapMode) + { + // Snap rectangle position to closer snap point + int offsetX = layout[controlSelected].rec.x%GRID_LINE_SPACING; + int offsetY = layout[controlSelected].rec.y%GRID_LINE_SPACING; + + if (offsetX >= GRID_LINE_SPACING/2) layout[controlSelected].rec.x += (GRID_LINE_SPACING - offsetX); + else layout[controlSelected].rec.x -= offsetX; + + if (offsetY >= GRID_LINE_SPACING/2) layout[controlSelected].rec.y += (GRID_LINE_SPACING - offsetY); + else layout[controlSelected].rec.y -= offsetY; + + // Snap rectangle size to closer snap point sizes + offsetX = layout[controlSelected].rec.width%GRID_LINE_SPACING; + offsetY = layout[controlSelected].rec.height%GRID_LINE_SPACING; + + if (offsetX >= GRID_LINE_SPACING/2) layout[controlSelected].rec.width += (GRID_LINE_SPACING - offsetX); + else layout[controlSelected].rec.width -= offsetX; + + if (offsetY >= GRID_LINE_SPACING/2) layout[controlSelected].rec.height += (GRID_LINE_SPACING - offsetY); + else layout[controlSelected].rec.height -= offsetY; + } + } + + if (snapMode) + { + if (IsKeyPressed(KEY_RIGHT)) layout[controlSelected].rec.width += GRID_LINE_SPACING; + else if (IsKeyPressed(KEY_LEFT)) layout[controlSelected].rec.width -= GRID_LINE_SPACING; + + if (IsKeyPressed(KEY_UP)) layout[controlSelected].rec.height -= GRID_LINE_SPACING; + else if (IsKeyPressed(KEY_DOWN)) layout[controlSelected].rec.height += GRID_LINE_SPACING; + } + else + { + if (IsKeyDown(KEY_LEFT_CONTROL)) + { + // Control modifier for a more precise sizing + if (IsKeyPressed(KEY_RIGHT)) layout[controlSelected].rec.width++; + else if (IsKeyPressed(KEY_LEFT)) layout[controlSelected].rec.width--; + + if (IsKeyPressed(KEY_UP)) layout[controlSelected].rec.height--; + else if (IsKeyPressed(KEY_DOWN)) layout[controlSelected].rec.height++; + } + else + { + if (IsKeyDown(KEY_RIGHT)) layout[controlSelected].rec.width++; + else if (IsKeyDown(KEY_LEFT)) layout[controlSelected].rec.width--; + + if (IsKeyDown(KEY_UP)) layout[controlSelected].rec.height--; + else if (IsKeyDown(KEY_DOWN)) layout[controlSelected].rec.height++; + } + } + + // Delete selected control and shift array position + if (IsKeyDown(KEY_BACKSPACE)) + { + for (int i = controlSelected; i < controlsCounter; i++) layout[i] = layout[i + 1]; + + controlsCounter--; + controlSelected = -1; + } + } + else + { + if (IsKeyPressed(KEY_LEFT)) + { + selectedType--; + if (selectedType < LABEL) selectedType = LABEL; + } + else if (IsKeyPressed(KEY_RIGHT)) + { + selectedType++; + if (selectedType > TEXTBOX) selectedType = TEXTBOX; + } + } + + if (IsKeyPressed(KEY_S)) snapMode = !snapMode; + + // Mouse snap + // NOTE: Snap point changes when GRID_LINE_SPACING/2 has been surpassed in X and Y + if ((snapMode) && (controlSelected == -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; + } + + 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"); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawGrid2D(40, 20); + + if (controlSelected == -1) + { + DrawLine(mouseX - 8, mouseY, mouseX + 8, mouseY, RED); + DrawLine(mouseX, mouseY - 8, mouseX, mouseY + 8, RED); + } + + for (int i = 0; i < controlsCounter; i++) + { + switch (layout[i].type) + { + case LABEL: GuiLabel(layout[i].rec, "TEXT SAMPLE"); break; + case BUTTON: GuiButton(layout[i].rec, "BUTTON"); break; + case TOGGLE: GuiToggleButton(layout[i].rec, "TOGGLE", false); break; + case TOGGLEGROUP: GuiToggleGroup(layout[i].rec, 3, list, 1); break; + case SLIDER: GuiSlider(layout[i].rec, 40, 0, 100); break; + case SLIDERBAR: GuiSliderBar(layout[i].rec, 40, 0, 100); break; + case PROGRESSBAR: GuiProgressBar(layout[i].rec, 40); break; + case SPINNER: GuiSpinner(layout[i].rec, 40, 0, 100); break; + case COMBOBOX: GuiComboBox(layout[i].rec, 3, list, 1); break; + case CHECKBOX: GuiCheckBox(layout[i].rec, "CHECKBOX", false); break; + case TEXTBOX: GuiTextBox(layout[i].rec, "test text"); break; + default: break; + } + } + + if ((controlSelected != -1) && (controlSelected < controlsCounter)) DrawRectangleRec(layout[controlSelected].rec, Fade(RED, 0.5f)); + + // 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 (controlSelected != -1) DrawText(FormatText("rec: (%i, %i, %i, %i)", + layout[controlSelected].rec.x, layout[controlSelected].rec.y, + layout[controlSelected].rec.width, layout[controlSelected].rec.height), + 10, screenHeight - 40, 10, DARKGREEN); + DrawText(FormatText("mouse: (%i, %i)", mouseX, mouseY), 700, screenHeight - 40, 10, RED); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Draw 2d grid +static void DrawGrid2D(int divsX, int divsY) +{ + int spacing = 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) + spacing - 1, -1, 1, 4000, ((k == 0) ? Fade(BLACK, GRID_ALPHA*2) : Fade(GRAY, GRID_ALPHA))); + spacing += GRID_LINE_SPACING; + } + } + + spacing = 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) + spacing - 1, 4000, 1, ((k == 0) ? Fade(BLACK, GRID_ALPHA*2) : Fade(GRAY, GRID_ALPHA))); + spacing += GRID_LINE_SPACING; + } + } +} + +// Save gui layout project information +// NOTE: Exported as text file +static void SaveGuiLayout(const char *fileName) +{ + FILE *flayout = fopen(fileName, "wt"); + + fprintf(flayout, "# Num Controls : %i\n\n", controlsCounter); + + for (int i = 0; i < controlsCounter; i++) + { + 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); + } + + fclose(flayout); +} + +// Import gui layout project information +// NOTE: Imported from text file +static void LoadGuiLayout(const char *fileName) +{ + char line[128]; + + 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) +{ + FILE *ftool = fopen(fileName, "wt"); + + fprintf(ftool, "/*******************************************************************************************\n"); + fprintf(ftool, "*\n"); + fprintf(ftool, "* $(tool_name) - $(tool_description)\n"); + fprintf(ftool, "*\n"); + fprintf(ftool, "* LICENSE: zlib/libpng\n"); + fprintf(ftool, "*\n"); + fprintf(ftool, "* Copyright (c) $(year) $(author)\n"); + 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); + + 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"); + + // Define controls rectangles + fprintf(ftool, " Rectangle layoutRecs[%i] = {\n", controlsCounter); + + for (int i = 0; i < controlsCounter; i++) + { + fprintf(ftool, " (Rectangle){ %i, %i, %i, %i }", layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height); + + if (i == controlsCounter - 1) fprintf(ftool, " // %s %03i\n };\n\n", controlTypeName[layout[i].type], i); + else fprintf(ftool, ", // %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(GuiBackground());\n\n"); + + // Draw all controls + for (int i = 0; i < controlsCounter; i++) + { + switch (layout[i].type) + { + case LABEL: fprintf(ftool, " GuiLabel(layoutRecs[%i], \"TEXT SAMPLE\");\n\n", i); break; + case BUTTON: fprintf(ftool, " if (GuiButton(layoutRecs[%i], \"BUTTON\")) Button%03i(); \n\n", i, i); break; + /* + case TOGGLE: GuiToggleButton(layout[i].rec, \"TOGGLE\", false); break; + case TOGGLEGROUP: GuiToggleGroup(layout[i].rec, 3, list, 1); break; + case SLIDER: GuiSlider(layout[i].rec, 40, 0, 100); break; + case SLIDERBAR: GuiSliderBar(layout[i].rec, 40, 0, 100); break; + case PROGRESSBAR: GuiProgressBar(layout[i].rec, 40); break; + case SPINNER: GuiSpinner(layout[i].rec, 40, 0, 100); break; + case COMBOBOX: GuiComboBox(layout[i].rec, 3, list, 1); break; + case CHECKBOX: GuiCheckBox(layout[i].rec, \"CHECKBOX\", false); break; + case TEXTBOX: GuiTextBox(layout[i].rec, \"test text\"); break; + */ + default: break; + } + } + + fprintf(ftool, " EndDrawing();\n"); + fprintf(ftool, " //----------------------------------------------------------------------------------\n"); + fprintf(ftool, " }\n\n"); + fprintf(ftool, " // De-Initialization\n"); + fprintf(ftool, " //--------------------------------------------------------------------------------------\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); + + fclose(ftool); +} \ No newline at end of file diff --git a/tools/rGuiLayout/test_layout.c b/tools/rGuiLayout/test_layout.c new file mode 100644 index 0000000..bbb244a --- /dev/null +++ b/tools/rGuiLayout/test_layout.c @@ -0,0 +1,96 @@ +/******************************************************************************************* +* +* $(tool_name) - $(tool_description) +* +* LICENSE: zlib/libpng +* +* Copyright (c) $(year) $(author) +* +**********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" + +//---------------------------------------------------------------------------------- +// Controls Functions Declaration +//---------------------------------------------------------------------------------- +static void Button000(); +static void Button001(); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main() +{ + // Initialization + //--------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "rFXGen"); + + Rectangle layoutRecs[12] = { + (Rectangle){ 100, 50, 100, 30 }, // BUTTON 000 + (Rectangle){ 100, 100, 150, 30 }, // BUTTON 001 + (Rectangle){ 100, 150, 100, 30 }, // LABEL 002 + (Rectangle){ 100, 190, 100, 30 }, // TOGGLE 003 + (Rectangle){ 100, 240, 90, 30 }, // TOGGLEGROUP 004 + (Rectangle){ 100, 290, 300, 20 }, // SLIDER 005 + (Rectangle){ 100, 330, 250, 20 }, // PROGRESSBAR 006 + (Rectangle){ 350, 50, 150, 30 }, // SPINNER 007 + (Rectangle){ 350, 100, 120, 30 }, // COMBOBOX 008 + (Rectangle){ 420, 160, 20, 20 }, // CHECKBOX 009 + (Rectangle){ 420, 210, 20, 20 }, // CHECKBOX 010 + (Rectangle){ 450, 250, 150, 30 } // TEXTBOX 011 + }; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Implement required update logic + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(GuiBackground()); + + if (GuiButton(layoutRecs[0], "BUTTON")) Button000(); + + if (GuiButton(layoutRecs[1], "BUTTON")) Button001(); + + GuiLabel(layoutRecs[2], "TEXT SAMPLE"); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Controls Functions Definitions (local) +//------------------------------------------------------------------------------------ +static void Button000() +{ + // TODO: Implement control logic +} + +static void Button001() +{ + // TODO: Implement control logic +} + diff --git a/tools/rGuiLayout/test_layout.png b/tools/rGuiLayout/test_layout.png new file mode 100644 index 0000000000000000000000000000000000000000..90bd03b6304db5a0ecb3093713984e5e635ad6ae GIT binary patch literal 21602 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 E0S~y?3jhEB literal 0 HcmV?d00001 diff --git a/tools/rGuiLayout/test_layout.rlyt b/tools/rGuiLayout/test_layout.rlyt new file mode 100644 index 0000000..460039e --- /dev/null +++ b/tools/rGuiLayout/test_layout.rlyt @@ -0,0 +1,38 @@ +# Num Controls : 12 + +# Control 000 : BUTTON +type 1 rec 100 50 100 30 + +# Control 001 : BUTTON +type 1 rec 100 100 150 30 + +# Control 002 : LABEL +type 0 rec 100 150 100 30 + +# Control 003 : TOGGLE +type 2 rec 100 190 100 30 + +# Control 004 : TOGGLEGROUP +type 3 rec 100 240 90 30 + +# Control 005 : SLIDER +type 4 rec 100 290 300 20 + +# Control 006 : PROGRESSBAR +type 6 rec 100 330 250 20 + +# Control 007 : SPINNER +type 7 rec 350 50 150 30 + +# Control 008 : COMBOBOX +type 8 rec 350 100 120 30 + +# Control 009 : CHECKBOX +type 9 rec 420 160 20 20 + +# Control 010 : CHECKBOX +type 9 rec 420 210 20 20 + +# Control 011 : TEXTBOX +type 10 rec 450 250 150 30 +