Cross-platform GUI for go is never this easy and clean.

gimu

Strongly suggest NOT to use this project anymore, the auto-generated cgo wrapper of Nuklear has a random crash issue which is hard to fix (because cgo doesn't provide detail information about where the crash exactly happened).

Please consider to use giu instead. It's very stable and actively developed.

Cross-platform GUI for go based on nuklear.

Package nk provides Go bindings for nuklear.h — a small ANSI C gui library. See github.com/Immediate-Mode-UI/Nuklear.

All the binding code has automatically been generated with rules defined in nk.yml.

This package provides a go-style idiomatic wrapper for nuklear.

Screenshots

Simple demo screen shots

Chart demo screen shots

Overview

Supported platforms are:

  • Windows 32-bit
  • Windows 64-bit
  • OS X
  • Linux

The desktop support is achieved using GLFW and there are backends written in Go for OpenGL 3.2.

Installation

Just go get it and everythings ready to work.

go get -u github.com/AllenDang/gimu

Getting start

Let's create a simple demo.

package main

import (
  "fmt"
  "image"
  "runtime"

  "github.com/AllenDang/gimu"
)

func builder(w *gimu.Window) {
  // Create a new window inside master window
  width, height := w.MasterWindow().GetSize()
  bounds := nk.NkRect(0, 0, float32(width), float32(height))

  w.Window("Simple Demo", bounds, nk.WindowNoScrollbar, func(w *gimu.Window) {
    // Define the row with 25px height, and contains one widget for each row.
    w.Row(25).Dynamic(1)
    // Let's create a label first, note the second parameter "LC" means the text alignment is left-center.
    w.Label("I'm a label", "LC")
    // Create a button.
    clicked := w.Button("Click Me")
    if clicked {
      fmt.Println("The button is clicked")
    }
  })
}

func main() {
  runtime.LockOSThread()

  // Create master window
  wnd := gimu.NewMasterWindow("Simple Demo", 200, 100, gimu.MasterWindowFlagDefault)

  wnd.Main(builder)
}

Save and run.

Deploy

gimu provides a tool to pack compiled executable for several platform to enable app icon and etc.

go get -u github.com/AllenDang/gimu/cmd/gmdeploy

Run gmdeploy in your project folder.

gmdeploy -icon AppIcon.icns .

Then you can find bundled executable in [PROJECTDIR]/build/[OS]/

Note:

Currently only MacOS is supported. Windows and linux is WIP.

Layout system

Layouting in general describes placing widget inside a window with position and size. While in this particular implementation there are two different APIs for layouting

All layouting methods in this library are based around the concept of a row.

A row has a height the window content grows by and a number of columns and each layouting method specifies how each widget is placed inside the row.

After a row has been allocated by calling a layouting functions and then filled with widgets will advance an internal pointer over the allocated row.

To actually define a layout you just call the appropriate layouting function and each subsequent widget call will place the widget as specified. Important here is that if you define more widgets then columns defined inside the layout functions it will allocate the next row without you having to make another layouting call.

Static layout

Define a row with 25px height with two widgets.

w.Row(25).Static(50, 50)

Use the magic number 0 to define a widget will auto expand if there is enough space.

w.Row(25).Static(0, 50)
w.Label("I'm a auto growth label", "LC")
w.Button("I'm a button with fixed width")

Dynamic layout

It provides each widgets with same horizontal space inside the row and dynamically grows if the owning window grows in width.

Define a row with two widgets each of them will have same width.

w.Row(25).Dynamic(2)

Flexible Layout

Finally the most flexible API directly allows you to place widgets inside the window. The space layout API is an immediate mode API which does not support row auto repeat and directly sets position and size of a widget. Position and size hereby can be either specified as ratio of allocated space or allocated space local position and pixel size. Since this API is quite powerful there are a number of utility functions to get the available space and convert between local allocated space and screen space.

w.Row(500).Space(nk.Static, func(w *gimu.Window) {
  w.Push(nk.NkRect(0, 0, 150, 150))
    w.Group("Group Left", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })

  w.Push(nk.NkRect(160, 0, 150, 240))
    w.Group("Group Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })

  w.Push(nk.NkRect(160, 250, 150, 250))
  w.Group("Group Bottom", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })

  w.Push(nk.NkRect(320, 0, 150, 150))
  w.Group("Group Right Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })

  w.Push(nk.NkRect(320, 160, 150, 150))
  w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })

  w.Push(nk.NkRect(320, 320, 150, 150))
  w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) {
  })
})

Widgets usage

Most of the widget's usage are very straight forward.

Common widgets

Label

The second parameter of label indicates the text alignment.

w.Label("Label caption", "LC")

"LC" means horizontally left and vertically center.

"LT" means horizontally left and vertically top.

The alignment char layout is listed below, you could use any combinations of those.

T

L-C-R

B

Selectable Label

Label can be toggled by mouse click.

var selected bool
w.SelectableLabel("Selectable 1", "LC", &selected1)

Button

Button function will return a bool to indicate whether it was clicked.

clicked := w.Button("Click Me")
if clicked {
  // Do something here
}

Progressbar

Progress could be readonly or modifiable.

progress := 0
// Modifiable
w.Progress(&progress, 100, true)
// Readonly
w.Progress(&progress, 100, false)

To read current progress or update progress bar, just set the progress variable.

Slider

Slider behaves like progress bar but step control.

var slider int
w.SliderInt(0, &slider, 100, 1)

Property widgets

It contains a label and a adjustable control to modify int or float variable.

var propertyInt int
var propertyFloat float32
w.PropertyInt("Age", 1, &propertyInt, 100, 10, 1)
w.PropertyFloat("Height", 1, &propertyFloat, 10, 0.2, 1)

Checkbox

var checked bool
w.Checkbox("Check me", &checked)

Radio

option := 1
if op1 := w.Radio("Option 1", option == 1); op1 {
  option = 1
}
if op2 := w.Radio("Option 2", option == 2); op2 {
  option = 2
}
if op3 := w.Radio("Option 3", option == 3); op3 {
  option = 3
}

Textedit

Textedit is special because it will retain the input string, so you will have to explicitly create it and call the Edit() function in BuilderFunc.

textedit := gimu.NewTextEdit()

func builder(w *gimu.Window) {
  textedit.Edit(w, gimu.EditField, gimu.EditFilterDefault)
}

ListView

ListView is designed to display very huge amount of data and only render visible items.

var (
  listview *nk.ListView
  listitem []interface{}
)

func builder(w *gimu.Window) {
  width, height := w.MasterWindow().GetSize()
  bounds := nk.NkRect(0, 0, float32(width), float32(height))
  w.Window("", bounds, 0, func(w *gimu.Window) {
    w.Row(int(height - 18)).Dynamic(1)
    w.ListView(listview, "huge list", nk.WindowBorder, 25,
      listitem,
      func(r *gimu.Row) {
        r.Dynamic(1)
      },
      func(w *gimu.Window, i int, item interface{}) {
        if s, ok := item.(string); ok {
          w.Label(s, "LC")
        }
      })
  })
}

func main() {
  // Init the listview widget
  listview = &nk.ListView{}

  // Create list items
  listitem = make([]interface{}, 12345)
  for i := range listitem {
    listitem[i] = fmt.Sprintf("Label item %d", i)
  }

  runtime.LockOSThread()

  wnd := gimu.NewMasterWindow("Huge list", 800, 600, gimu.MasterWindowFlagNoResize)
  wnd.Main(builder)
}

Popups

Tooltip

Note: Tooltip has to be placed above the widget which wants a tooltip when mouse hovering.

w.Tooltip("This is a tooltip")
w.Button("Hover me to see tooltip")

Popup Window

func msgbox(w *gimu.Window) {
  opened := w.Popup(
    "Message", 
    gimu.PopupStatic, 
    nk.WindowTitle|nk.WindowNoScrollbar|nk.WindowClosable, 
    nk.NkRect(30, 10, 300, 100), 
    func(w *gimu.Window) {
      w.Row(25).Dynamic(1)
      w.Label("Here is a pop up window", "LC")
      if w.Button("Close") {
        showPopup = false
        w.ClosePopup()
      }
    })
  if !opened {
    showPopup = false
  }
}

Menu

Window Menu

Note: window menu bar has to be the first widget in the builder method.

// Menu
w.Menubar(func(w *gimu.Window) {
  w.Row(25).Static(60, 60)
  // Menu 1
  w.Menu("Menu1", "CC", 200, 100, func(w *gimu.Window) {
    w.Row(25).Dynamic(1)
    w.MenuItemLabel("Menu item 1", "LC")
    w.MenuItemLabel("Menu item 2", "LC")
    w.Button("Button inside menu")
  })
  // Menu 2
  w.Menu("Menu2", "CC", 100, 100, func(w *gimu.Window) {
    w.Row(25).Dynamic(1)
    w.MenuItemLabel("Menu item 1", "LC")
    w.SliderInt(0, &slider, 100, 1)
    w.MenuItemLabel("Menu item 2", "LC")
  })
})

Contextual Menu

Note: Contextual menu has to be placed above the widget which wants a tooltip when right click.

You could put any kind of widgets inside the contextual menu.

w.Contextual(0, 100, 300, func(w *gimu.Window) {
  w.Row(25).Dynamic(1)
  w.ContextualLabel("Context menu 1", "LC")
  w.ContextualLabel("Context menu 1", "LC")
  w.SliderInt(0, &slider, 100, 1)
})
w.Button("Right click me")

License

All the code except when stated otherwise is licensed under the MIT license. Nuklear (ANSI C version) is in public domain, authored from 2015-2016 by Micha Mettke.

Similar Resources

Tiny cross-platform webview library for C/C++/Golang. Uses WebKit (Gtk/Cocoa) and Edge (Windows)

webview A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs. Also, there are Rust bindings, Python bindings, Ni

Dec 28, 2022

Go cross-platform library for displaying dialogs and input boxes

dlgs dlgs is a cross-platform library for displaying dialogs and input boxes. Installation go get -u github.com/gen2brain/dlgs Documentation Document

Dec 24, 2022

Tiny cross-platform webview library for C/C++/Golang. Uses WebKit (Gtk/Cocoa) and Edge (Windows)

webview A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs. Also, there are Rust bindings, Python bindings, Ni

Jan 1, 2023

An experimental Go cross platform UI library.

GXUI - A Go cross platform UI library. Notice: Unfortunately due to a shortage of hours in a day, GXUI is no longer maintained. If you're looking for

Jan 6, 2023

Build cross-platform modern desktop apps in Go + HTML5

Build cross-platform modern desktop apps in Go + HTML5

Lorca A very small library to build modern HTML5 desktop apps in Go. It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome in

Jan 6, 2023

Cross-platform Go library to place an icon in the host operating system's taskbar.

trayhost Package trayhost is a cross-platform Go library to place an icon in the host operating system's taskbar. Platform Support macOS - Fully imple

Nov 6, 2022

A cross-platform app-development module for Go.

A cross-platform app-development module for Go.

The cross-platform Go module for building apps (pronounced klo-va-seed). Usecases As a lightweight alternative to Electron Write your frontend and nat

Dec 1, 2022

pure go, cross-platform, MIT-licensed ui toolkit for developers

pure go, cross-platform, MIT-licensed ui toolkit for developers

duit - developer ui toolkit WARNING: this library is work in progress. backwards incompatible changes will be made. details duit is a pure go (*), cro

Dec 24, 2022

Windows API and GUI in idiomatic Go.

Windows API and GUI in idiomatic Go.

Windigo Win32 API and GUI in idiomatic Go. Overview The UI library is divided in the following packages: Package Description ui High-level UI wrappers

Dec 27, 2022
Comments
  • Need to add go.mod to gimu/nk package

    Need to add go.mod to gimu/nk package

    error msg:

    Build github.com/AllenDang/gimu: cannot load github.com/AllenDang/gimu/nk: cannot find module providing package github.com/AllenDang/gimu/nk
    

    sys env:

    os: win7 x64
    go version: go1.13.1 windows/386
    gcc:  7.3.0 (i6860-posix-dwarf-rev0, Build by MinGW-W64 project)
    
  • README.md Example compile Error

    README.md Example compile Error

    The simple demo example in the https://github.com/AllenDang/gimu/blob/master/README.md has the following compile error

    # command-line-arguments
    ./main.go:14:25: cannot use width (type int32) as type int in argument to image.Rect
    ./main.go:14:25: cannot use height (type int32) as type int in argument to image.Rect
    ./main.go:16:10: cannot use bounds (type image.Rectangle) as type nk.Rect in argument to w.Window
    

    Changing

    bounds := image.Rect(0, 0, width, height)
    

    to

    bounds := nk.NkRecti(0, 0, width, height)
    

    Seems to solve the issue, but is this the right fix ?

    Awesome Library BTW

  • MasterWindow.Run wait for events?

    MasterWindow.Run wait for events?

    Hi, It looks like it runs at 30 fps regardless of what's going on, but if it used WaitEvents it could allow saving CPU cycles and battery. PostEmptyEvent could be used to break out of the WaitEvents for exit or updates. This makes UI updates somewhat more difficult, requiring an explicit update call to invalidate the current display and force update, but this is fairly common in GUIs. Or at least it seems like a tradeoff the application might want to make.

Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs)
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs)

gowd Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs) How to use this library: Download and install nwjs Install this library g

Dec 11, 2022
Cross platform GUI in Go based on Material Design
Cross platform GUI in Go based on Material Design

About Fyne is an easy to use UI toolkit and app API written in Go. It is designed to build applications that run on desktop and mobile devices with a

Jan 3, 2023
RobotGo, Go Native cross-platform GUI automation @vcaesar

Robotgo Golang Desktop Automation. Control the mouse, keyboard, bitmap, read the screen, Window Handle and global event listener. RobotGo supports Mac

Jan 7, 2023
Cross platform rapid GUI framework for golang based on Dear ImGui.
Cross platform rapid GUI framework for golang based on Dear ImGui.

giu Cross platform rapid GUI framework for golang based on Dear ImGui and the great golang binding imgui-go. Any contribution (features, widgets, tuto

Dec 28, 2022
Cross-Platform GUI Framework for Go

⚠️ I'm currently working on this project as part of my master's thesis at the Berlin University of Applied Sciences and Technology. It is under active

Oct 31, 2022
Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase
Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase. Inspired by Flutter, React. S

Apr 18, 2022
UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase
 UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

Apr 18, 2022
Cross-platform Go/Golang GUI library.

中文 | English GoVCL Cross-platform Golang GUI library, The core binding is liblcl, a common cross-platform GUI library created by Lazarus. GoVCL is a n

Dec 30, 2022
Easy Go GUI wrapper for interactive manipulation of visual algorithms/backend code.
Easy Go GUI wrapper for interactive manipulation of visual algorithms/backend code.

RenderView ================ Install: go get github.com/TheGrum/renderview Needs either Shiny (limited functionality), Gio, go-gtk, or gotk3. The latt

Aug 4, 2022
Platform-native GUI library for Go.

ui: platform-native GUI library for Go This is a library that aims to provide simple GUI software development in Go. It is based on my libui, a simple

Jan 9, 2023