greenfork / nimraylib_now

The Ultimate Raylib gaming library wrapper for Nim
MIT License
151 stars 17 forks source link

Any raygui samples? #88

Open ahungry opened 1 year ago

ahungry commented 1 year ago

I see the paint program has a Save button, which produces a file on save, and supposedly the library here has support for raygui - I'm new to raylib, raygui, and nim, so hoping to find a good reference to do something simple with the 3.

I found https://github.com/raysan5/raygui/blob/master/examples/custom_file_dialog/custom_file_dialog.c, but when I try guessing at names for the translations based on how raylib did it, I'm hitting some snags (initGuiFileDialog() doesn't exist, at least not when I just import nimraylib_now).

Any help would be greatly appreciated!

greenfork commented 1 year ago

I have spent time with it and failed to port this example. The problem is that they use a gui_file_dialog.h module together with the example. And because of the complexity of C file includes it doesn't work when we want to include just a little module in C that uses raygui library.

For reference some files:

custom_file_dialog.nim ```nim #/ ****************************************************************************************** #/ #/ raygui - custom file dialog to load image #/ #/ DEPENDENCIES: #/ raylib 4.0 - Windowing/input management and drawing. #/ raygui 3.0 - 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-2021 Ramon Santamaria (@raysan5) #/ #/ ******************************************************************************************** import ../../../src/nimraylib_now/raylib import ../../../src/nimraylib_now/raygui as gui import ./gui_file_dialog from strutils import format #/ ------------------------------------------------------------------------------------ #/ Program main entry point #/ ------------------------------------------------------------------------------------ #/ Initialization #/ --------------------------------------------------------------------------------------- var screenWidth = 800 var screenHeight = 560 initWindow(screenWidth.cint, screenHeight.cint, "raygui - custom modal dialog") setExitKey(0) #/ Custom file dialog var fileDialogState: GuiFileDialogState = initGuiFileDialog(420, 310, getWorkingDirectory(), false) var exitWindow: bool = false var fileNameToLoad: string var texture: Texture setTargetFPS(60) #/ -------------------------------------------------------------------------------------- #/ Main game loop while not exitWindow: #/ Detect window close button or ESC key #/ Update #/ ---------------------------------------------------------------------------------- exitWindow = windowShouldClose() if fileDialogState.selectFilePressed: var fileNameText: string = "" for ch in fileDialogState.fileNameText: if ch == '\0': break fileNameText.add(ch) #/ Load image file (if supported extension) if isFileExtension(fileNameText.cstring, ".png"): fileNameToLoad = format("$1/$2", fileDialogState.dirPathText, fileDialogState.fileNameText) unloadTexture(texture) texture = loadTexture(fileNameToLoad) fileDialogState.selectFilePressed = false beginDrawing() clearBackground(getColor(cuint(getStyle(Control.Default.cint, DefaultProperty.BackgroundColor.cint)))) drawTexture(texture, getScreenWidth() div 2 - texture.width div 2, getScreenHeight() div 2 - texture.height div 2 - 5, White) drawRectangleLines(getScreenWidth() div 2 - texture.width div 2, getScreenHeight() div 2 - texture.height div 2 - 5, texture.width, texture.height, Black) drawText(fileNameToLoad, 208, getScreenHeight() - 20, 10, Gray) #/ raygui: controls drawing #/ ---------------------------------------------------------------------------------- if fileDialogState.fileDialogActive: gui.lock() if gui.button(Rectangle(x: 20.0, y: 20.0, width: 140.0, height: 30.0), "Open Image"): # if gui.button((20.0, 20, 140, 30), gui.iconText(ricon_File_Open, "Open Image")): fileDialogState.fileDialogActive = true gui.unlock() #/ GUI: Dialog Window #/ -------------------------------------------------------------------------------- guiFileDialog(addr(fileDialogState)) #/ -------------------------------------------------------------------------------- #/ ---------------------------------------------------------------------------------- endDrawing() #/ ---------------------------------------------------------------------------------- #/ De-Initialization #/ -------------------------------------------------------------------------------------- #/ Unload texture unloadTexture(texture) #/ Close window and OpenGL context #/ -------------------------------------------------------------------------------------- closeWindow() ```
gui_file_dialog.nim ```nim from ../../../src/nimraylib_now import Vector2 from os import parentDir, `/` const guiFileDialogHeader = currentSourcePath().parentDir()/"gui_file_dialog.h" {.passC: "-DGUI_FILE_DIALOG_IMPLEMENTATION".} type GuiFileDialogState* {.bycopy.} = object position*: Vector2 size*: Vector2 fileDialogActive*: bool dirPathEditMode*: bool dirPathText*: array[256, char] filesListScrollIndex*: cint filesListEditMode*: bool filesListActive*: cint fileNameEditMode*: bool fileNameText*: array[256, char] selectFilePressed*: bool cancelFilePressed*: bool fileTypeActive*: cint itemFocused*: cint ## Custom state variables (depend on development software) ## NOTE: This variables should be added manually if required dirFiles*: cstringArray dirFilesCount*: cint filterExt*: array[256, char] dirPathTextCopy*: array[256, char] fileNameTextCopy*: array[256, char] prevFilesListActive*: cint proc initGuiFileDialog*(width: cint, height: cint, initPath: cstring, active: bool): GuiFileDialogState {.importc: "InitGuiFileDialog", header: guiFileDialogHeader.} proc guiFileDialog*(state: ptr GuiFileDialogState) {.importc: "GuiFileDialog", header: guiFileDialogHeader.} ```

Now the challenge is to correctly include raygui.h into gui_file_dialog.h so that it works with all the imports. I don't believe it is possible. We kind of have to include that header file into the main compilation target. But we can't do it on-demand since it may require additional #define directives to work properly. I will surrender here.