giu GUI Framework

repository·master·Indexed 25 days ago

https://github.com/allendang/giu

A rapid cross-platform immediate-mode GUI framework for Go, built on top of Dear ImGui and GLFW. It allows developers to define UIs declaratively using widgets like Buttons, Checkboxes, and CodeEditors, and provides a Canvas API for low-level drawing of shapes and textures. Supports deployment and cross-compilation for MacOS, Windows, and Linux.

Tokens
33.6K
Snippets
45
Records
254
Agent score
83%

What's inside giu

  1. Install giu

    master

    To use giu, you must have a C/C++ compiler installed and your environment must support OpenGL 3.3. Follow the specific instructions for your operating system:

    MacOS

    1. Install Xcode command line tools: xcode-select --install
    2. Get the package: go get github.com/AllenDang/giu

    Windows

    1. Install mingw.
    2. Add the mingw64\bin folder to your system PATH.
    3. Get the package: go get github.com/AllenDang/giu

    Linux

    Install the required development libraries based on your distribution, then use go build.

  2. Deploy giu applications

    master

    Use specific build flags to optimize your binaries for different platforms:

    MacOS

    go build -ldflags "-s -w" .

    Windows

    To build a Windows GUI application (hiding the console window) with static linking:

    go build -ldflags "-s -w -H=windowsgui -extldflags=-static" .

    Cross-compiling for Windows from MacOS/Linux

    Requires mingw-w64 (version v12.0.0 or later). You must also prepare a .rc resource file to embed the application icon.

    # Example for Windows deployment from Mac/Linux
    cat > YourExeName.rc << EOL
    id ICON "./res/app_win.ico"
    GLFW_ICON ICON "./res/app_win.ico"
    EOL
    
    x86_64-w64-mingw32-windres YourExeName.rc -O coff -o YourExeName.syso
    
    GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ HOST=x86_64-w64-mingw32 go build -ldflags "-s -w -H=windowsgui -extldflags=-static" -p 4 -v -o YourExeName.exe
    
    rm YourExeName.syso
    rm YourExeName.rc
  3. Apply custom CSS styling to a GIU app

    master

    GIU supports custom styling via a CSSWidget. To style your application, follow these steps:

    1. Load your stylesheet (e.g., using go:embed).
    2. Register the stylesheet with the application using giu.ParseCSSStyleSheet(...).
    3. Apply styles to specific widgets using giu.CSS("tag name") within your UI code.

    Note: The special tag main is automatically applied to the entire application; you do not need to call giu.CSS("main") to style the global app context.

  4. Understand giu layout and sizing

    master

    Layout Direction

    • By default, widgets placed inside a container's Layout are arranged vertically.
    • Use g.Row(...) to place widgets horizontally.
    • Use g.Column(...) to place widgets vertically inside a Row.

    Sizing

    • Widgets with a Size() method can be sized explicitly.
    • Use giu.Auto to make a widget fill the remaining available width or height in its container.
    • Passing a negative value to Size() also allows a widget to fill remaining space.
  5. Initialize a new application with NewMasterWindow

    master

    Use NewMasterWindow to create the primary application window and initialize the GLFW backend, ImGui context, and other necessary subsystems (like implot and imnodes). This should be called within your main function.

    Available MasterWindowFlags:

    • MasterWindowFlagsNotResizable: Fixed window size.
    • MasterWindowFlagsMaximized: Starts maximized.
    • MasterWindowFlagsFloating: Always-on-top.
    • MasterWindowFlagsFrameless: No window decorations.
    • MasterWindowFlagsTransparent: Transparent window.
    • MasterWindowFlagsHidden: Hidden window (useful for multi-window setups).
  6. Initialize message boxes with PrepareMsgbox

    master

    To use message boxes in your application, you must call giu.PrepareMsgbox() within your layout. It should be invoked at the same layout level where you intend to call giu.Msgbox.

    Warning: Do not call PrepareMsgbox() more than once per frame, as this can cause unexpected merging of message box layouts.

  7. Apply styles using Push/Pop pattern

    master

    You can apply styles manually using Push... functions and must call the corresponding Pop... functions to avoid panics. This is useful inside giu.Custom widgets.

    Style Variables (PushStyle...):

    • PushWindowPadding(width, height float32)
    • PushFramePadding(width, height float32)
    • PushItemSpacing(width, height float32)
    • PushButtonTextAlign(width, height float32)
    • PushSelectableTextAlign(width, height float32)
    • PushItemWidth(width float32)
    • PopStyle() or PopStyleV(count int) to revert style variables.

    Colors (PushStyleColor...):

    • PushStyleColor(id StyleColorID, col color.Color)
    • PushColorText(col color.Color)
    • PushColorTextDisabled(col color.Color)
    • PushColorWindowBg(col color.Color)
    • PushColorFrameBg(col color.Color)
    • PushColorButton(col color.Color)
    • PushColorButtonHovered(col color.Color)
    • PushColorButtonActive(col color.Color)
    • PopStyleColor() or PopStyleColorV(count int) to revert colors.

    Text Wrapping:

    • PushTextWrapPos()
    • PopTextWrapPos()

    Example:

    	giu.Custom(func() {
    		imgui.PushStyleVarFlot(giu.StyleVarFrameRounding, 2)
    	}),
    	/*your widgets here*/
    	giu.Custom(func() {
    		imgui.PopStyleVar()
    	}),
    giu.Custom(func() {
    		imgui.PushStyleVarFlot(giu.StyleVarFrameRounding, 2)
    	}),
    	/*your widgets here*/
    	giu.Custom(func() {
    		imgui.PopStyleVar()
    	}),
  8. Apply styles to widgets using To() and Build()

    master

    The most common way to use a StyleSetter is to define a set of styles and then apply them to a specific group of widgets using .To(widgets...) and .Build().

    When you call .Build(), the StyleSetter automatically calls Push(), builds the specified widgets, and then calls Pop() to clean up the style stack.

  9. Apply a CSS stylesheet to the entire application

    master
    To apply styles globally to your application, use ParseCSSStyleSheet with your CSS data. You can also use the special main tag within your CSS to target the whole application. This function parses the data and sets it as the current stylesheet in the giu.Context.
  10. Apply styles using StyleSetter

    master

    The recommended way to apply styles to a group of widgets is using the giu.Style() builder. This allows you to chain style changes and apply them to a block of widgets without manually managing push/pop calls.

    Example usage:

    	giu.Style().
    		SetStyle(giu.StyleVarWindowPadding, imgui.Vec2{10, 10}).
    		SetStyleFloat(giu.StyleVarGrabRounding, 5).
    		SetColor(giu.StyleColorButton, colornames.Red).
    		To(/* your widgets here */)
    giu.Style().
    	SetStyle(giu.StyleVarWindowPadding, imgui.Vec2{10, 10}).
    	SetStyleFloat(giu.StyleVarGrabRounding, 5).
    	SetColor(giu.StyleColorButton, colornames.Red).
    	To(/*your widgets here*/)
  11. CSS Limitations in GIU

    master

    When using the CSS system in GIU, be aware of the following:

    • Comments: Be careful with CSS comments as they may not be parsed correctly. It is recommended to comment out entire tags if necessary rather than using inline comments.
    • Complexity: Only simple rules (e.g., ruleName { ... }) are supported. More complex CSS selectors and rules are not implemented.
  12. Create a Hello World application with giu

    master

    A giu application typically follows this structure:

    1. Define callback functions for user interactions (e.g., OnClick).
    2. Define a loop function that describes the UI structure using declarative widgets.
    3. Create a MasterWindow using g.NewMasterWindow and call .Run(loop) to start the application.

    Note: giu uses an immediate mode GUI pattern. The loop function is called repeatedly (e.g., 30-60 times per second) to redraw the UI based on the current state.

    package main
    
    import (
            "fmt"
    
            g "github.com/AllenDang/giu"
    )
    
    func onClickMe() {
            fmt.Println("Hello world!")
    }
    
    func onImSoCute() {
            fmt.Println("Im sooooooo cute!!")
    }
    
    func loop() {
            g.SingleWindow().Layout(
                    g.Label("Hello world from giu"),
                    g.Row(
                            g.Button("Click Me").OnClick(onClickMe),
                            g.Button("I'm so cute").OnClick(onImSoCute),
                    ),
            )
    }
    
    func main() {
            wnd := g.NewMasterWindow("Hello world", 400, 200, g.MasterWindowFlagsNotResizable)
            wnd.Run(loop)
    }