gimu

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2023 License: MIT Imports: 10 Imported by: 0

README

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/coalaura/gimu
Getting start

Let's create a simple demo.

package main

import (
  "fmt"
  "image"
  "runtime"

  "github.com/coalaura/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/coalaura/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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EditFilterAscii

func EditFilterAscii(r rune) bool

func EditFilterBinary

func EditFilterBinary(r rune) bool

func EditFilterDecimal

func EditFilterDecimal(r rune) bool

func EditFilterDefault

func EditFilterDefault(r rune) bool

func EditFilterFloat

func EditFilterFloat(r rune) bool

func EditFilterHex

func EditFilterHex(r rune) bool

func EditFilterOct

func EditFilterOct(r rune) bool

func ImgToRgba

func ImgToRgba(img image.Image) *image.RGBA

func LoadDefaultFont

func LoadDefaultFont() *nk.Font

func LoadFontFromFile

func LoadFontFromFile(filePath string, size float32, config *nk.FontConfig) *nk.Font

func SetFont

func SetFont(ctx *nk.Context, font *nk.Font)

Types

type BuilderFunc

type BuilderFunc func(w *Window)

type Canvas

type Canvas struct {
	// contains filtered or unexported fields
}

func (*Canvas) FillCircle

func (c *Canvas) FillCircle(rect nk.Rect, color color.RGBA)

func (*Canvas) FillPolygon

func (c *Canvas) FillPolygon(points []float32, color color.RGBA)

func (*Canvas) FillRect

func (c *Canvas) FillRect(rect nk.Rect, rounding float32, color color.RGBA)

func (*Canvas) FillTriangle

func (c *Canvas) FillTriangle(p1, p2, p3 image.Point, color color.RGBA)

type ChartSeries

type ChartSeries struct {
	ChartType   nk.ChartType
	Min, Max    float32
	Data        []float32
	Color       nk.Color
	ActiveColor nk.Color
}

type EditFilter

type EditFilter func(rune) bool

type Input

type Input struct {
	// contains filtered or unexported fields
}

func (*Input) IsMouseDown

func (i *Input) IsMouseDown(buttons nk.Buttons) bool

func (*Input) IsMouseHoveringRect

func (i *Input) IsMouseHoveringRect(rect nk.Rect) bool

func (*Input) IsMousePrevHoveringRect

func (i *Input) IsMousePrevHoveringRect(rect nk.Rect) bool

func (*Input) Mouse

func (i *Input) Mouse() *nk.Mouse

type ListViewItemBuilder

type ListViewItemBuilder func(w *Window, i int, item interface{})

type MasterWindow

type MasterWindow struct {
	// contains filtered or unexported fields
}

Master window

func NewMasterWindow

func NewMasterWindow(title string, width, height int, flags MasterWindowFlag) *MasterWindow

func (*MasterWindow) GetContext

func (w *MasterWindow) GetContext() *nk.Context

func (*MasterWindow) GetDefaultFont

func (w *MasterWindow) GetDefaultFont() *nk.Font

func (*MasterWindow) GetSize

func (w *MasterWindow) GetSize() (width, height int)

func (*MasterWindow) Main

func (w *MasterWindow) Main(builder BuilderFunc)

func (*MasterWindow) SetBgColor

func (w *MasterWindow) SetBgColor(color color.RGBA)

func (*MasterWindow) SetSize

func (w *MasterWindow) SetSize(width, height int)

func (*MasterWindow) SetTitle

func (w *MasterWindow) SetTitle(title string)

type MasterWindowFlag

type MasterWindowFlag int

Master window flag

const (
	// MasterWindowFlagNoResize - Create an not resizable window
	MasterWindowFlagDefault MasterWindowFlag = iota
	MasterWindowFlagNoResize
)

func (MasterWindowFlag) HasFlag

func (this MasterWindowFlag) HasFlag(flag MasterWindowFlag) bool

type Row

type Row struct {
	// contains filtered or unexported fields
}

func (*Row) Dynamic

func (r *Row) Dynamic(col int)

func (*Row) Ratio

func (r *Row) Ratio(ratio ...float32)

func (*Row) Space

func (r *Row) Space(spaceType nk.LayoutFormat, builder BuilderFunc)

func (*Row) Static

func (r *Row) Static(width ...int)

type RowLayoutFunc

type RowLayoutFunc func(r *Row)

Should only called in ListView to define the row layout.

type TextEdit

type TextEdit struct {
	// contains filtered or unexported fields
}

func NewTextEdit

func NewTextEdit() *TextEdit

func (*TextEdit) Edit

func (t *TextEdit) Edit(w *Window, flag nk.Flags, filter EditFilter)

func (*TextEdit) GetString

func (t *TextEdit) GetString() string

type Texture

type Texture struct {
	// contains filtered or unexported fields
}

func RgbaToTexture

func RgbaToTexture(rgba *image.RGBA) *Texture

type Window

type Window struct {
	// contains filtered or unexported fields
}

func (*Window) Button

func (w *Window) Button(content string) bool

func (*Window) ButtonColor

func (w *Window) ButtonColor(color nk.Color) bool

func (*Window) ButtonImage

func (w *Window) ButtonImage(img nk.Image) bool

func (*Window) ButtonImageLabel

func (w *Window) ButtonImageLabel(img nk.Image, label, align string) bool

func (*Window) ButtonSymbol

func (w *Window) ButtonSymbol(symbol nk.SymbolType) bool

func (*Window) ButtonSymbolLabel

func (w *Window) ButtonSymbolLabel(symbol nk.SymbolType, label, align string) bool

func (*Window) Chart

func (w *Window) Chart(chartType nk.ChartType, min, max float32, data []float32)

func (*Window) ChartColored

func (w *Window) ChartColored(chartType nk.ChartType, color, activeColor nk.Color, min, max float32, data []float32)

func (*Window) ChartMixed

func (w *Window) ChartMixed(series []ChartSeries)

func (*Window) Checkbox

func (w *Window) Checkbox(label string, active *bool)

func (*Window) ClosePopup

func (w *Window) ClosePopup()

func (*Window) ComboLabel

func (w *Window) ComboLabel(label string, dropDownWidth, dropDownHeight float32, itemBuilder BuilderFunc)

func (*Window) ComboSimple

func (w *Window) ComboSimple(labels []string, selected int, itemHeight int, dropDownWidth, dropDownHeight float32) int

func (*Window) Contextual

func (w *Window) Contextual(flag nk.Flags, width, height int, builder BuilderFunc)

func (*Window) ContextualLabel

func (w *Window) ContextualLabel(label, align string) bool

func (*Window) GetCanvas

func (w *Window) GetCanvas() *Canvas

func (*Window) GetInput

func (w *Window) GetInput() *Input

func (*Window) GetStyle

func (w *Window) GetStyle() *nk.Style

func (*Window) Group

func (w *Window) Group(title string, flag nk.Flags, builder BuilderFunc)

func (*Window) Image

func (w *Window) Image(texture *Texture)

func (*Window) L

func (w *Window) L(content string)

func (*Window) Label

func (w *Window) Label(content string, align string)

func (*Window) LabelColored

func (w *Window) LabelColored(content string, textColor color.RGBA, align string)

func (*Window) ListView

func (w *Window) ListView(view *nk.ListView, id string, flags nk.Flags, rowHeight int, items []interface{}, rowLayoutFunc RowLayoutFunc, builder ListViewItemBuilder)

func (*Window) MasterWindow

func (w *Window) MasterWindow() *MasterWindow

func (*Window) Menu

func (w *Window) Menu(label string, align string, width, height int, builder BuilderFunc)

func (*Window) MenuItemLabel

func (w *Window) MenuItemLabel(label, align string) bool

func (*Window) Menubar

func (w *Window) Menubar(builder BuilderFunc)

func (*Window) Popup

func (w *Window) Popup(title string, popupType nk.PopupType, flag nk.Flags, bounds nk.Rect, builder BuilderFunc) bool

func (*Window) Progress

func (w *Window) Progress(current *uint, max uint, modifiable bool)

func (*Window) PropertyFloat

func (w *Window) PropertyFloat(label string, min float32, val *float32, max float32, step float32, incPerPixel float32)

func (*Window) PropertyInt

func (w *Window) PropertyInt(label string, min int, val *int32, max int, step int, incPerPixel float32)

func (*Window) Push

func (w *Window) Push(rect nk.Rect)

func (*Window) Radio

func (w *Window) Radio(label string, active bool) bool

func (*Window) Row

func (w *Window) Row(height int) *Row

func (*Window) SelectableLabel

func (w *Window) SelectableLabel(label string, align string, selected *bool)

func (*Window) SelectableSymbolLabel

func (w *Window) SelectableSymbolLabel(symbol nk.SymbolType, label, align string, selected *bool)

func (*Window) SliderFloat

func (w *Window) SliderFloat(min float32, val *float32, max float32, step float32)

func (*Window) SliderInt

func (w *Window) SliderInt(min int32, val *int32, max int32, step int32)

func (*Window) Spacing

func (w *Window) Spacing(cols int)

func (*Window) Tooltip

func (w *Window) Tooltip(label string)

func (*Window) Tree

func (w *Window) Tree(treeType nk.TreeType, title string, initialState nk.CollapseStates, hash string, seed int32, builder BuilderFunc)

func (*Window) WidgetBounds

func (w *Window) WidgetBounds() nk.Rect

func (*Window) Window

func (w *Window) Window(title string, bounds nk.Rect, flags nk.Flags, builder BuilderFunc)

Directories

Path Synopsis
cmd
examples
Package nk provides Go bindings for nuklear.h — a small ANSI C gui library.
Package nk provides Go bindings for nuklear.h — a small ANSI C gui library.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL