diff --git a/examples/gui/controls_test_suite/controls_test_suite.go b/examples/gui/controls_test_suite/controls_test_suite.go new file mode 100644 index 0000000..f891939 --- /dev/null +++ b/examples/gui/controls_test_suite/controls_test_suite.go @@ -0,0 +1,280 @@ +package main + +import ( + "fmt" + + gui "github.com/gen2brain/raylib-go/raygui" + rl "github.com/gen2brain/raylib-go/raylib" +) + +/******************************************************************************************* +* +* raygui - controls test suite +* +* TEST CONTROLS: +* - gui.DropdownBox() +* - gui.CheckBox() +* - gui.Spinner() +* - gui.ValueBox() +* - gui.TextBox() +* - gui.Button() +* - gui.ComboBox() +* - gui.ListView() +* - gui.ToggleGroup() +* - gui.TextBoxMulti() +* - gui.ColorPicker() +* - gui.Slider() +* - gui.SliderBar() +* - gui.ProgressBar() +* - gui.ColorBarAlpha() +* - gui.ScrollPanel() +* +* +* DEPENDENCIES: +* raylib 4.0 - Windowing/input management and drawing. +* raygui 3.2 - Immediate-mode GUI controls. +* +* COMPILATION (Windows - MinGW): +* gcc -o $(NAME_PART).exe $(FILE_NAME) -I../../src -lraylib -lopengl32 -lgdi32 -std=c99 +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2016-2022 Ramon Santamaria (@raysan5) +* +**********************************************************************************************/ + +//#define RAYGUI_CUSTOM_ICONS // It requires providing gui_icons.h in the same directory +//#include "gui_icons.h" // External icons data provided, it can be generated with rGuiIcons tool + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +func main() { + // Initialization + //--------------------------------------------------------------------------------------- + const ( + screenWidth = 690 + screenHeight = 560 + ) + + rl.InitWindow(screenWidth, screenHeight, "raygui - controls test suite") + rl.SetExitKey(0) + + // GUI controls initialization + //---------------------------------------------------------------------------------- + var ( + dropdownBox000Active int32 = 0 + dropDown000EditMode bool = false + + dropdownBox001Active int32 = 0 + dropDown001EditMode bool = false + + spinner001Value int32 = 0 + spinnerEditMode bool = false + + valueBox002Value int32 = 0 + valueBoxEditMode bool = false + + textBoxText = "Text box" + textBoxEditMode bool = false + + listViewScrollIndex int32 = 0 + listViewActive int32 = -1 + + //TODO listViewExScrollIndex int32 = 0 + //TODO listViewExActive int32 = 2 + //TODO listViewExFocus int32 = -1 + //TODO listViewExList = [8]string{"This", "is", "a", "list view", "with", "disable", "elements", "amazing!"} + + // TODO multiTextBoxText = "Multi text box" + // TODO multiTextBoxEditMode bool = false + colorPickerValue = rl.Red + + sliderValue float32 = 50 + sliderBarValue float32 = 60 + progressValue float32 = 0.4 + + forceSquaredChecked bool = false + + alphaValue float32 = 0.5 + + comboBoxActive int32 = 1 + + toggleGroupActive int32 = 0 + + //TODO viewScroll = rl.Vector2{0, 0} + + //---------------------------------------------------------------------------------- + + // Custom GUI font loading + //Font font = LoadFontEx("fonts/rainyhearts16.ttf", 12, 0, 0); + //GuiSetFont(font); + + exitWindow bool = false + showMessageBox bool = false + + // TODO textInput string + showTextInputBox bool = false + + // TODO textInputFileName string + ) + + rl.SetTargetFPS(60) + //-------------------------------------------------------------------------------------- + + // Main game loop + for !exitWindow { // Detect window close button or ESC key + // Update + //---------------------------------------------------------------------------------- + exitWindow = rl.WindowShouldClose() + + if rl.IsKeyPressed(rl.KeyEscape) { + showMessageBox = !showMessageBox + } + + if rl.IsKeyDown(rl.KeyLeftControl) && rl.IsKeyPressed(rl.KeyS) { + showTextInputBox = true + } + + if rl.IsFileDropped() { + // TODO var droppedFiles gui.FilePathList = rl.LoadDroppedFiles() + // TODO if (droppedFiles.count > 0) && rl.IsFileExtension(droppedFiles.paths[0], ".rgs") { + // TODO gui.LoadStyle(droppedFiles.paths[0]) + // TODO } + // TODO rl.UnloadDroppedFiles(droppedFiles) // Clear internal buffers + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.BeginDrawing() + + rl.ClearBackground(rl.GetColor(uint(gui.GetStyle(gui.DEFAULT, gui.BACKGROUND_COLOR)))) + + // raygui: controls drawing + //---------------------------------------------------------------------------------- + if dropDown000EditMode || dropDown001EditMode { + gui.Lock() + } else if !dropDown000EditMode && !dropDown001EditMode { + gui.Unlock() + } + //GuiDisable(); + + // First GUI column + //GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + forceSquaredChecked = gui.CheckBox(rl.Rectangle{25, 108, 15, 15}, "FORCE CHECK!", forceSquaredChecked) + + gui.SetStyle(gui.TEXTBOX, gui.TEXT_ALIGNMENT, gui.TEXT_ALIGN_CENTER) + //GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + if gui.Spinner(rl.Rectangle{25, 135, 125, 30}, "", &spinner001Value, 0, 100, spinnerEditMode) { + spinnerEditMode = !spinnerEditMode + } + if gui.ValueBox(rl.Rectangle{25, 175, 125, 30}, "", &valueBox002Value, 0, 100, valueBoxEditMode) { + valueBoxEditMode = !valueBoxEditMode + } + gui.SetStyle(gui.TEXTBOX, gui.TEXT_ALIGNMENT, gui.TEXT_ALIGN_LEFT) + if gui.TextBox(rl.Rectangle{25, 215, 125, 30}, textBoxText, 64, textBoxEditMode) { + textBoxEditMode = !textBoxEditMode + } + + gui.SetStyle(gui.BUTTON, gui.TEXT_ALIGNMENT, gui.TEXT_ALIGN_CENTER) + + // TODO if gui.Button(rl.Rectangle{25, 255, 125, 30}, gui.IconText(gui.ICON_FILE_SAVE, "Save File")) { + // TODO showTextInputBox = true + // TODO } + + gui.GroupBox(rl.Rectangle{25, 310, 125, 150}, "STATES") + //GuiLock(); + gui.SetState(gui.STATE_NORMAL) + if gui.Button(rl.Rectangle{30, 320, 115, 30}, "NORMAL") { + } + gui.SetState(gui.STATE_FOCUSED) + if gui.Button(rl.Rectangle{30, 355, 115, 30}, "FOCUSED") { + } + gui.SetState(gui.STATE_PRESSED) + if gui.Button(rl.Rectangle{30, 390, 115, 30}, "#15#PRESSED") { + } + gui.SetState(gui.STATE_DISABLED) + if gui.Button(rl.Rectangle{30, 425, 115, 30}, "DISABLED") { + } + gui.SetState(gui.STATE_NORMAL) + //GuiUnlock(); + + comboBoxActive = gui.ComboBox(rl.Rectangle{25, 470, 125, 30}, "ONE;TWO;THREE;FOUR", comboBoxActive) + + // NOTE: gui.DropdownBox must draw after any other control that can be covered on unfolding + gui.SetStyle(gui.DROPDOWNBOX, gui.TEXT_ALIGNMENT, gui.TEXT_ALIGN_LEFT) + if gui.DropdownBox(rl.Rectangle{25, 65, 125, 30}, "#01#ONE;#02#TWO;#03#THREE;#04#FOUR", &dropdownBox001Active, dropDown001EditMode) { + dropDown001EditMode = !dropDown001EditMode + } + + gui.SetStyle(gui.DROPDOWNBOX, gui.TEXT_ALIGNMENT, gui.TEXT_ALIGN_CENTER) + if gui.DropdownBox(rl.Rectangle{25, 25, 125, 30}, "ONE;TWO;THREE", &dropdownBox000Active, dropDown000EditMode) { + dropDown000EditMode = !dropDown000EditMode + } + + // Second GUI column + listViewActive = gui.ListView(rl.Rectangle{165, 25, 140, 140}, "Charmander;Bulbasaur;#18#Squirtel;Pikachu;Eevee;Pidgey", &listViewScrollIndex, listViewActive) + //TODO listViewExActive = gui.ListViewEx(rl.Rectangle{165, 180, 140, 200}, listViewExList, 8, &listViewExFocus, &listViewExScrollIndex, listViewExActive) + + toggleGroupActive = gui.ToggleGroup(rl.Rectangle{165, 400, 140, 25}, "#1#ONE\n#3#TWO\n#8#THREE\n#23#", toggleGroupActive) + + // Third GUI column + // TODO if gui.TextBoxMulti(rl.Rectangle{320, 25, 225, 140}, multiTextBoxText, 256, multiTextBoxEditMode) { + // TODO multiTextBoxEditMode = !multiTextBoxEditMode + // TODO } + colorPickerValue = gui.ColorPicker(rl.Rectangle{320, 185, 196, 192}, "", colorPickerValue) + + sliderValue = gui.Slider(rl.Rectangle{355, 400, 165, 20}, "TEST", + fmt.Sprintf("%2.2f", sliderValue), sliderValue, -50, 100) + sliderBarValue = gui.SliderBar(rl.Rectangle{320, 430, 200, 20}, "", + fmt.Sprint("%d", sliderBarValue), sliderBarValue, 0, 100) + progressValue = gui.ProgressBar(rl.Rectangle{320, 460, 200, 20}, "", "", progressValue, 0, 1) + + // NOTE: View rectangle could be used to perform some scissor test + //var view rl.Rectangle = gui.ScrollPanel(rl.Rectangle{560, 25, 100, 160}, "", rl.Rectangle{560, 25, 200, 400}, &viewScroll) + + gui.Panel(rl.Rectangle{560, 25 + 180, 100, 160}, "Panel Info") + + gui.Grid(rl.Rectangle{560, 25 + 180 + 180, 100, 120}, "", 20, 2) + + gui.StatusBar(rl.Rectangle{0, float32(rl.GetScreenHeight()) - 20, float32(rl.GetScreenWidth()), 20}, "This is a status bar") + + alphaValue = gui.ColorBarAlpha(rl.Rectangle{320, 490, 200, 30}, "", alphaValue) + + if showMessageBox { + rl.DrawRectangle(0, 0, int32(rl.GetScreenWidth()), int32(rl.GetScreenHeight()), rl.Fade(rl.RayWhite, 0.8)) + // TODO var result int32 = gui.MessageBox(rl.Rectangle{float32(rl.GetScreenWidth())/2 - 125, float32(rl.GetScreenHeight())/2 - 50, 250, 100}, gui.IconText(gui.ICON_EXIT, "Close Window"), "Do you really want to exit?", "Yes;No") + + // TODO if (result == 0) || (result == 2) { + // TODO showMessageBox = false + // TODO } else if result == 1 { + // TODO exitWindow = true + // TODO } + } + + if showTextInputBox { + rl.DrawRectangle(0, 0, int32(rl.GetScreenWidth()), int32(rl.GetScreenHeight()), rl.Fade(rl.RayWhite, 0.8)) + //TODO var result int = gui.TextInputBox(rl.Rectangle{float32(rl.GetScreenWidth())/2 - 120, float32(rl.GetScreenHeight())/2 - 60, 240, 140}, "Save", gui.IconText(gui.ICON_FILE_SAVE, "Save file as..."), "Ok;Cancel", textInput, 255, "") + // TODO if result == 1 { + // TODO // TODO: Validate textInput value and save + // TODO // strcpy(textInputFileName, textInput) + // TODO textInputFileName = textInput + // TODO } + // TODO if (result == 0) || (result == 1) || (result == 2) { + // TODO showTextInputBox = false + // TODO //strcpy(textInput, "\0"); + // TODO textInput = "" + // TODO } + } + //---------------------------------------------------------------------------------- + + rl.EndDrawing() + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + rl.CloseWindow() // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +} diff --git a/examples/gui/controls_test_suite/example b/examples/gui/controls_test_suite/example new file mode 100755 index 0000000..37537d6 Binary files /dev/null and b/examples/gui/controls_test_suite/example differ diff --git a/examples/gui/controls_test_suite/go.mod b/examples/gui/controls_test_suite/go.mod new file mode 100644 index 0000000..f8e917a --- /dev/null +++ b/examples/gui/controls_test_suite/go.mod @@ -0,0 +1,11 @@ +module example + +go 1.19 + +require ( + github.com/gen2brain/raylib-go/raygui v0.0.0-20221122151443-e8a384ed1346 + github.com/gen2brain/raylib-go/raylib v0.0.0-20221122155035-fe6d2c0ed32a +) + +replace github.com/gen2brain/raylib-go/raylib => ../../../raylib +replace github.com/gen2brain/raylib-go/raygui => ../../../raygui3_5 diff --git a/raygui3_5/raygui.go b/raygui3_5/raygui.go index 0675487..0055f60 100644 --- a/raygui3_5/raygui.go +++ b/raygui3_5/raygui.go @@ -992,6 +992,69 @@ func ColorBarHue(bounds rl.Rectangle, text string, value float32) float32 { return float32(C.GuiColorBarHue(cbounds, ctext, cvalue)) } +// Dropdown Box control +// NOTE: Returns mouse click +func DropdownBox(bounds rl.Rectangle, text string, active *int32, editMode bool) bool { + var cbounds C.struct_Rectangle + cbounds.x = C.float(bounds.X) + cbounds.y = C.float(bounds.Y) + cbounds.width = C.float(bounds.Width) + cbounds.height = C.float(bounds.Height) + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + + var cactive C.int + cactive = C.int(*active) + defer func() { + *active = int32(cactive) + }() + + ceditMode := C.bool(editMode) + + return bool(C.GuiDropdownBox(cbounds, ctext, &cactive, ceditMode)) +} + +// Value Box control, updates input text with numbers +// NOTE: Requires static variables: frameCounter +func ValueBox(bounds rl.Rectangle, text string, value *int32, minValue, maxValue int, editMode bool) bool { + var cbounds C.struct_Rectangle + cbounds.x = C.float(bounds.X) + cbounds.y = C.float(bounds.Y) + cbounds.width = C.float(bounds.Width) + cbounds.height = C.float(bounds.Height) + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + + var cvalue C.int + cvalue = C.int(*value) + defer func() { + *value = int32(cvalue) + }() + + cminValue := C.int(minValue) + cmaxValue := C.int(maxValue) + ceditMode := C.bool(editMode) + + return bool(C.GuiValueBox(cbounds, ctext, &cvalue, cminValue, cmaxValue, ceditMode)) +} + +// Text Box control, updates input text +// NOTE 2: Returns if KEY_ENTER pressed (useful for data validation) +func TextBox(bounds rl.Rectangle , text string, textSize int, editMode bool) bool { + var cbounds C.struct_Rectangle + cbounds.x = C.float(bounds.X) + cbounds.y = C.float(bounds.Y) + cbounds.width = C.float(bounds.Width) + cbounds.height = C.float(bounds.Height) + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + + ctextSize := C.int(textSize) + ceditMode := C.bool(editMode) + + return bool(C.GuiTextBox(cbounds, ctext, ctextSize, ceditMode)) +} + // GuiLoadStyle - transpiled function from C4GO/tests/raylib/raygui.h:560 // Styles loading functions // Load style file over global style variable (.rgs) @@ -1008,16 +1071,15 @@ func LoadStyleDefault() { C.GuiLoadStyleDefault() } -// TODO // GuiIconText - transpiled function from C4GO/tests/raylib/raygui.h:564 // Icons functionality // Get text with icon id prepended (if supported) -// func IconText(iconId int32, text string) []byte { -// ciconId := C.int(iconId) -// ctext := C.CString(text) -// defer C.free(unsafe.Pointer(ctext)) -// return C.GuiIconText(ciconId, ctext) -// } +func IconText(iconId int32, text string) string { + ciconId := C.int(iconId) + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + return C.GoString(C.GuiIconText(ciconId, ctext)) +} // TODO // GuiGetIcons - transpiled function from C4GO/tests/raylib/raygui.h:567 @@ -1032,15 +1094,9 @@ func LoadStyleDefault() { // List View with extended parameters // Warning (*ast.FunctionDecl): {prefix: n:GuiListViewEx,t1:int (Rectangle, const char **, int, int *, int *, int),t2:}. C4GO/tests/raylib/raygui.h:551 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiListViewEx`. cannot parse C type: `const char **` -// Warning (*ast.FunctionDecl): {prefix: n:GuiValueBox,t1:_Bool (Rectangle, const char *, int *, int, int, _Bool),t2:}. C4GO/tests/raylib/raygui.h:539 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiValueBox`. cannot parse C type: `int *` - -// Warning (*ast.FunctionDecl): {prefix: n:GuiTextBox,t1:_Bool (Rectangle, char *, int, _Bool),t2:}. C4GO/tests/raylib/raygui.h:540 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiTextBox`. cannot parse C type: `_Bool` // Warning (*ast.FunctionDecl): {prefix: n:GuiTextBoxMulti,t1:_Bool (Rectangle, char *, int, _Bool),t2:}. C4GO/tests/raylib/raygui.h:541 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiTextBoxMulti`. cannot parse C type: `_Bool` -// Dropdown Box control, returns selected item -// Warning (*ast.FunctionDecl): {prefix: n:GuiDropdownBox,t1:_Bool (Rectangle, const char *, int *, _Bool),t2:}. C4GO/tests/raylib/raygui.h:537 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiDropdownBox`. cannot parse C type: `int *` - // Check Box control, returns true when active // Warning (*ast.FunctionDecl): {prefix: n:GuiCheckBox,t1:_Bool (Rectangle, const char *, _Bool),t2:}. C4GO/tests/raylib/raygui.h:535 :cannot transpileFunctionDecl. cannot bindingFunctionDecl func `GuiCheckBox`. cannot parse C type: `_Bool`