README

Mostly-immediate-mode GUI library for Go. Source port to go of an early version of nuklear.

⚠️ Subject to backwards incompatible changes. ⚠️

Documentation

See godoc, _examples/overview/main.go for a single window example, _examples/demo/demo.go for a multi-window example, and gdlv for a more complex application built using nucular.

Screenshots

Overview Gdlv

Expand ▾ Collapse ▴

Documentation

Overview

Nucular is an immediate mode GUI library for Go, its implementation is a partial source port of Nuklear [0] by Micha Mettke. For a brief introduction to Immediate Mode GUI see [1]

Opening a Window

A window can be opened with the following three lines of code:

wnd := nucular.NewMasterWindow(updatefn, 0)
wnd.SetStyle(nucular.StyleFromTheme(nucular.DarkTheme), nil, 1.0)
wnd.Main()

The first line creates the MasterWindow object and sets its flags (usually 0 is fine) and updatefn as the update function. Updatefn will be responsible for drawing the contents of the window and handling the GUI logic (see the "Window Update and layout" section).

The second line configures the theme, the font (passing nil will use the default font face) and the default scaling factor (see the "Scaling" section).

The third line opens the window and starts its event loop, updatefn will be called whenever the window needs to be redrawn, this is usually only in response to mouse and keyboard events, if you want the window to be redrawn you can also manually call wnd.Changed().

Window Update and layout

The update function is responsible for drawing the contents of the window as well as handling user events, this is usually done by calling methods of nucular.Window.

For example, drawing a simple text button is done with this code:

if w.ButtonText("button caption", 0) {
	// code here only runs once every time the button is clicked
}

Widgets are laid out left to right and top to bottom, each row has a layout that can be configured calling the Layout* methods of nucular.Window. There are three main row layout modes:

- Static: in this mode the columns of the row have a fixed, user defined, width. This row layout can be selected calling Static or StaticScaled

- Dynamic: in this mode the columns of the row have a width proportional to the total width of the window. This row layout can be selected calling Dynamic, DynamicScaled or Ratio

- Space: in this mode widgets are positioned and sized arbitrarily. This row layout can be selected calling LayoutSpaceBegin or LayoutSpaceBeginRatio, once this row layout is selected widgets can be positioned using LayoutSpacePush or LayoutSpacePushRatio

Scaling

When calling SetStyle you can specify a scaling factor, this will be used to scale the sizes in the style argument and also all the size arguments for the Layout* functions.

Links

[0] https://github.com/vurtun/nuklear/
[1] https://mollyrocket.com/861

Index

Constants

This section is empty.

Variables

View Source
var InvalidLayoutErr = errors.New("invalid layout")
View Source
var UnknownCommandErr = errors.New("unknown command")
View Source
var UsingSubErr = errors.New("parent window used while populating a sub window")
View Source
var WrongLayoutErr = errors.New("Command not available with current layout")

Functions

func ChangeFontWidthCache

func ChangeFontWidthCache(size int)

func FilterDecimal

func FilterDecimal(c rune) bool

func FilterDefault

func FilterDefault(c rune) bool

func FilterFloat

func FilterFloat(c rune) bool

func FontHeight

func FontHeight(f font.Face) int

func FontWidth

func FontWidth(f font.Face, str string) int

func GroupListStart

func GroupListStart(w *Window, num int, name string, flags WindowFlags) (GroupList, *Window)

GroupListStart starts a scrollable list of <num> rows of <height> height

Types

type DockSplit

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

func (*DockSplit) Open

func (ds *DockSplit) Open(title string, flags WindowFlags, rect rect.Rect, scale bool, updateFn UpdateFn)

func (*DockSplit) Split

func (ds *DockSplit) Split(horiz bool, size int) (left, right *DockSplit)

type EditEvents

type EditEvents int
const (
	EditActive EditEvents = 1 << iota
	EditInactive
	EditActivated
	EditDeactivated
	EditCommitted
)

type EditFlags

type EditFlags int
const (
	EditDefault  EditFlags = 0
	EditReadOnly EditFlags = 1 << iota
	EditAutoSelect
	EditSigEnter
	EditNoCursor
	EditSelectable
	EditClipboard
	EditCtrlEnterNewline
	EditNoHorizontalScroll
	EditAlwaysInsertMode
	EditMultiline
	EditNeverInsertMode
	EditFocusFollowsMouse
	EditNoContextMenu

	EditSimple = EditAlwaysInsertMode
	EditField  = EditSelectable | EditClipboard | EditSigEnter
	EditBox    = EditSelectable | EditMultiline | EditClipboard
)

type FilterFunc

type FilterFunc func(c rune) bool

type FittingWidthFn

type FittingWidthFn func(width int)

type GroupList

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

func (*GroupList) Center

func (gl *GroupList) Center()

func (*GroupList) Index

func (gl *GroupList) Index() int

func (*GroupList) Next

func (gl *GroupList) Next() bool

func (*GroupList) SkipToVisible

func (gl *GroupList) SkipToVisible(lineheight int)

func (*GroupList) SkipToVisibleScaled

func (gl *GroupList) SkipToVisibleScaled(lineheight int)

type Heading

type Heading int
const (
	Up Heading = iota
	Right
	Down
	Left
)

type Input

type Input struct {
	Keyboard KeyboardInput
	Mouse    MouseInput
}

type KeyboardInput

type KeyboardInput struct {
	Keys []key.Event
	Text string
}

func (*KeyboardInput) Pressed

func (i *KeyboardInput) Pressed(key key.Code) bool

type MasterWindow

type MasterWindow interface {
	Main()
	Changed()
	Close()
	Closed() bool
	ActivateEditor(ed *TextEditor)

	Style() *nstyle.Style
	SetStyle(*nstyle.Style)

	GetPerf() bool
	SetPerf(bool)

	Input() *Input

	PopupOpen(title string, flags WindowFlags, rect rect.Rect, scale bool, updateFn UpdateFn)

	Walk(WindowWalkFn)
	ResetWindows() *DockSplit

	Lock()
	Unlock()
	// contains filtered or unexported methods
}

func NewMasterWindow

func NewMasterWindow(flags WindowFlags, title string, updatefn UpdateFn) MasterWindow

func NewMasterWindowSize

func NewMasterWindowSize(flags WindowFlags, title string, sz image.Point, updatefn UpdateFn) MasterWindow

Creates new master window

type MouseInput

type MouseInput struct {
	Buttons     [4]mouseButton
	Pos         image.Point
	Prev        image.Point
	Delta       image.Point
	ScrollDelta int
	// contains filtered or unexported fields
}

func (*MouseInput) AnyClickInRect

func (i *MouseInput) AnyClickInRect(b rect.Rect) bool

func (*MouseInput) Clicked

func (i *MouseInput) Clicked(id mouse.Button, rect rect.Rect) bool

func (*MouseInput) Down

func (i *MouseInput) Down(id mouse.Button) bool

func (*MouseInput) HasClickInRect

func (i *MouseInput) HasClickInRect(id mouse.Button, b rect.Rect) bool

func (*MouseInput) HoveringRect

func (i *MouseInput) HoveringRect(rect rect.Rect) bool

func (*MouseInput) IsClickDownInRect

func (i *MouseInput) IsClickDownInRect(id mouse.Button, b rect.Rect, down bool) bool

func (*MouseInput) IsClickInRect

func (i *MouseInput) IsClickInRect(id mouse.Button, b rect.Rect) bool

func (*MouseInput) Pressed

func (i *MouseInput) Pressed(id mouse.Button) bool

func (*MouseInput) PrevHoveringRect

func (i *MouseInput) PrevHoveringRect(rect rect.Rect) bool

func (*MouseInput) Released

func (i *MouseInput) Released(id mouse.Button) bool

type ScalableSplit

type ScalableSplit struct {
	Size    int
	MinSize int
	Spacing int
	// contains filtered or unexported fields
}

func (*ScalableSplit) Horizontal

func (s *ScalableSplit) Horizontal(w *Window, bounds rect.Rect) (bounds0, bounds1 rect.Rect)

func (*ScalableSplit) Vertical

func (s *ScalableSplit) Vertical(w *Window, bounds rect.Rect) (bounds0, bounds1 rect.Rect)

type TestWindow

type TestWindow struct {
	Img *image.RGBA
	// contains filtered or unexported fields
}

func NewTestWindow

func NewTestWindow(flags WindowFlags, size image.Point, updatefn UpdateFn) *TestWindow

func (*TestWindow) ActivateEditor

func (w *TestWindow) ActivateEditor(ed *TextEditor)

func (*TestWindow) Changed

func (w *TestWindow) Changed()

func (*TestWindow) Click

func (w *TestWindow) Click(button mouse.Button, p image.Point)

Click simulates a click at point p. The update function will be run as many times as needed, the window will be drawn every time.

func (*TestWindow) Close

func (w *TestWindow) Close()

func (*TestWindow) Closed

func (w *TestWindow) Closed() bool

func (*TestWindow) GetPerf

func (w *TestWindow) GetPerf() bool

func (*TestWindow) Input

func (w *TestWindow) Input() *Input

func (*TestWindow) Lock

func (w *TestWindow) Lock()

func (*TestWindow) Main

func (w *TestWindow) Main()

func (*TestWindow) PopupOpen

func (w *TestWindow) PopupOpen(title string, flags WindowFlags, rect rect.Rect, scale bool, updateFn UpdateFn)

func (*TestWindow) ResetWindows

func (w *TestWindow) ResetWindows() *DockSplit

func (*TestWindow) SetPerf

func (w *TestWindow) SetPerf(p bool)

func (*TestWindow) SetStyle

func (w *TestWindow) SetStyle(style *nstyle.Style)

func (*TestWindow) Style

func (w *TestWindow) Style() *nstyle.Style

func (*TestWindow) Type

func (w *TestWindow) Type(text string)

Type simulates typing. The update function will be run as many times as needed, the window will be drawn every time.

func (*TestWindow) TypeKey

func (w *TestWindow) TypeKey(e key.Event)

func (*TestWindow) Unlock

func (w *TestWindow) Unlock()

func (*TestWindow) Update

func (w *TestWindow) Update()

Update runs the update function.

func (*TestWindow) Walk

func (w *TestWindow) Walk(fn WindowWalkFn)

type TextEditType

type TextEditType int
const (
	TextEditSingleLine TextEditType = iota
	TextEditMultiLine
)

type TextEditor

type TextEditor struct {
	Cursor       int
	Buffer       []rune
	Filter       FilterFunc
	Flags        EditFlags
	CursorFollow bool
	Redraw       bool

	Maxlen int

	Initialized            bool
	Active                 bool
	InsertMode             bool
	Scrollbar              image.Point
	SelectStart, SelectEnd int
	HasPreferredX          bool
	SingleLine             bool
	PreferredX             int
	Undo                   textUndoState
	// contains filtered or unexported fields
}

TextEditor stores the state of a text editor. To add a text editor to a window create a TextEditor object with &TextEditor{}, store it somewhere then in the update function call the Edit method passing the window to it.

func (*TextEditor) Cut

func (edit *TextEditor) Cut() int

func (*TextEditor) Delete

func (edit *TextEditor) Delete(where int, len int)

Deletes a chunk of text in the editor.

func (*TextEditor) DeleteSelection

func (edit *TextEditor) DeleteSelection()

Deletes selection.

func (*TextEditor) DoRedo

func (edit *TextEditor) DoRedo()

func (*TextEditor) DoUndo

func (edit *TextEditor) DoUndo()

func (*TextEditor) Edit

func (edit *TextEditor) Edit(win *Window) EditEvents

Adds text editor edit to win. Initial contents of the text editor will be set to text. If alwaysSet is specified the contents of the editor will be reset to text.

func (*TextEditor) Paste

func (edit *TextEditor) Paste(ctext string)

Paste from clipboard

func (*TextEditor) SelectAll

func (edit *TextEditor) SelectAll()

func (*TextEditor) Text

func (edit *TextEditor) Text(text []rune)

type TreeType

type TreeType int
const (
	TreeNode TreeType = iota
	TreeTab
)

type UpdateFn

type UpdateFn func(*Window)

type Window

type Window struct {
	LastWidgetBounds rect.Rect
	Data             interface{}

	Bounds    rect.Rect
	Scrollbar image.Point
	// contains filtered or unexported fields
}

func (*Window) At

func (win *Window) At() image.Point

func (*Window) Button

func (win *Window) Button(lbl label.Label, repeat bool) bool

Button adds a button

func (*Window) ButtonText

func (win *Window) ButtonText(text string) bool

func (*Window) CheckboxText

func (win *Window) CheckboxText(text string, active *bool) bool

CheckboxText adds a checkbox button to win. Active will contain the checkbox value. Returns true when value changes.

func (*Window) Close

func (win *Window) Close()

Programmatically closes this window

func (*Window) Cmds

func (win *Window) Cmds() *command.Buffer

func (*Window) Combo

func (win *Window) Combo(lbl label.Label, height int, updateFn UpdateFn) *Window

Adds a drop-down list to win.

func (*Window) ComboSimple

func (win *Window) ComboSimple(items []string, selected int, item_height int) int

Adds a drop-down list to win. The contents are specified by items, with selected being the index of the selected item.

func (*Window) Commands

func (win *Window) Commands() *command.Buffer

func (*Window) ContextualOpen

func (win *Window) ContextualOpen(flags WindowFlags, size image.Point, trigger_bounds rect.Rect, updateFn UpdateFn) *Window

Opens a contextual menu with maximum size equal to 'size'. Specify size == image.Point{} if you want a menu big enough to fit its larges MenuItem

func (*Window) Custom

func (win *Window) Custom(state nstyle.WidgetStates) (bounds rect.Rect, out *command.Buffer)

Custom adds a custom widget.

func (*Window) CustomState

func (win *Window) CustomState() nstyle.WidgetStates

CustomState returns the widget state of a custom widget.

func (*Window) GroupBegin

func (win *Window) GroupBegin(title string, flags WindowFlags) *Window

Creates a group of widgets. Group are useful for creating lists as well as splitting a main window into tiled subwindows. Items that you want to add to the group should be added to the returned window.

func (*Window) GroupEnd

func (win *Window) GroupEnd()

Signals that you are done adding widgets to a group.

func (*Window) Image

func (win *Window) Image(img *image.RGBA)

Image draws an image.

func (*Window) Input

func (win *Window) Input() *Input

func (*Window) Invisible

func (win *Window) Invisible() (above, below bool)

Will return (false, false) if the last widget is visible, (true, false) if it is above the visible area, (false, true) if it is below the visible area

func (*Window) KeyboardOnHover

func (win *Window) KeyboardOnHover(bounds rect.Rect) KeyboardInput

func (*Window) Label

func (win *Window) Label(str string, alignment label.Align)

Label draws a text label.

func (*Window) LabelColored

func (win *Window) LabelColored(str string, alignment label.Align, color color.RGBA)

LabelColored draws a text label with the specified background color.

func (*Window) LabelWrap

func (win *Window) LabelWrap(str string)

LabelWrap draws a text label, autowrapping its contents.

func (*Window) LabelWrapColored

func (win *Window) LabelWrapColored(str string, color color.RGBA)

LabelWrapColored draws a text label with the specified background color autowrappping the text.

func (*Window) LayoutAvailableHeight

func (win *Window) LayoutAvailableHeight() int

Returns remaining available height of win in scaled units.

func (*Window) LayoutAvailableWidth

func (win *Window) LayoutAvailableWidth() int

func (*Window) LayoutFitWidth

func (win *Window) LayoutFitWidth(id int, minwidth int)

LayoutFitWidth adds a new column to a static layout. The width of the column will be large enough to fit the largest widget exactly. The largest widget will only be calculated once per id, if the dataset changes the id should change.

func (*Window) LayoutReserveRow

func (win *Window) LayoutReserveRow(height int, num int)

Reserves space for num rows of the specified height at the bottom of the panel. If a row of height == 0 is inserted it will take reserved space into account.

func (*Window) LayoutReserveRowScaled

func (win *Window) LayoutReserveRowScaled(height int, num int)

Like LayoutReserveRow but with a scaled height.

func (*Window) LayoutResetStatic

func (win *Window) LayoutResetStatic(width ...int)

Reset static row

func (*Window) LayoutResetStaticScaled

func (win *Window) LayoutResetStaticScaled(width ...int)

func (*Window) LayoutSetWidth

func (win *Window) LayoutSetWidth(width int)

LayoutSetWidth adds a new column with the specified width to a static layout.

func (*Window) LayoutSetWidthScaled

func (win *Window) LayoutSetWidthScaled(width int)

LayoutSetWidthScaled adds a new column width the specified scaled width to a static layout.

func (*Window) LayoutSpacePush

func (win *Window) LayoutSpacePush(rect rect.Rect)

Sets position and size of the next widgets in a Space row layout

func (*Window) LayoutSpacePushRatio

func (win *Window) LayoutSpacePushRatio(x, y, w, h float64)

Sets position and size of the next widgets in a Space row layout

func (*Window) LayoutSpacePushScaled

func (win *Window) LayoutSpacePushScaled(rect rect.Rect)

Like LayoutSpacePush but with scaled units

func (*Window) Master

func (w *Window) Master() MasterWindow

func (*Window) Menu

func (win *Window) Menu(lbl label.Label, width int, updateFn UpdateFn) *Window

Adds a menu to win with a text label. If width == 0 the width will be automatically adjusted to fit the largest MenuItem

func (*Window) MenuItem

func (win *Window) MenuItem(lbl label.Label) bool

MenuItem adds a menu item

func (*Window) MenubarBegin

func (win *Window) MenubarBegin()

MenubarBegin adds a menubar to the current window. A menubar is an area displayed at the top of the window that is unaffected by scrolling. Remember to call MenubarEnd when you are done adding elements to the menubar.

func (*Window) MenubarEnd

func (win *Window) MenubarEnd()

MenubarEnd signals that all widgets have been added to the menubar.

func (*Window) OptionText

func (win *Window) OptionText(text string, is_active bool) bool

OptionText adds a radio button to win. If is_active is true the radio button will be drawn selected. Returns true when the button is clicked once. You are responsible for ensuring that only one radio button is selected at once.

func (*Window) Progress

func (win *Window) Progress(cur *int, maxval int, is_modifiable bool) bool

Adds a progress bar to win. if is_modifiable is true the progress bar will be user modifiable through click-and-drag. Returns true when the progress bar values is modified.

func (*Window) PropertyFloat

func (win *Window) PropertyFloat(name string, min float64, val *float64, max, step, inc_per_pixel float64, prec int) (changed bool)

Adds a property widget to win for floating point properties. A property widget will display a text label, a small text editor for the property value and one up and one down button. The value can be modified by editing the text value, by clicking the up/down buttons (which will increase/decrease the value by step) or by clicking and dragging over the label. Returns true when the property's value is changed

func (*Window) PropertyInt

func (win *Window) PropertyInt(name string, min int, val *int, max, step, inc_per_pixel int) (changed bool)

Same as PropertyFloat but with integer values.

func (*Window) Row

func (win *Window) Row(height int) *rowConstructor

Changes row layout and starts a new row. Use the returned value to configure the new row layout:

win.Row(10).Static(100, 120, 100)

If height == 0 all the row is stretched to fill all the remaining space.

func (*Window) RowScaled

func (win *Window) RowScaled(height int) *rowConstructor

Same as Row but with scaled units.

func (*Window) SelectableLabel

func (win *Window) SelectableLabel(str string, align label.Align, value *bool) bool

SelectableLabel adds a selectable label. Value is a pointer to a flag that will be changed to reflect the selected state of this label. Returns true when the label is clicked.

func (*Window) SliderFloat

func (win *Window) SliderFloat(min_value float64, value *float64, max_value float64, value_step float64) bool

Adds a slider with a floating point value to win. Returns true when the slider's value is changed.

func (*Window) SliderInt

func (win *Window) SliderInt(min int, val *int, max int, step int) bool

Adds a slider with an integer value to win. Returns true when the slider's value changes.

func (*Window) Spacing

func (win *Window) Spacing(cols int)

Spacing adds empty space

func (*Window) Tooltip

func (win *Window) Tooltip(text string)

Shows a tooltip window containing the specified text.

func (*Window) TooltipOpen

func (win *Window) TooltipOpen(width int, scale bool, updateFn UpdateFn)

Displays a tooltip window.

func (*Window) TreeClose

func (win *Window) TreeClose(path ...string)

Closes the collapsable section specified by path

func (*Window) TreeIsOpen

func (win *Window) TreeIsOpen(name string) bool

Returns true if the specified node is open

func (*Window) TreeOpen

func (win *Window) TreeOpen(path ...string)

Opens the collapsable section specified by path

func (*Window) TreePop

func (win *Window) TreePop()

TreePop signals that the program is done adding elements to the current collapsable section.

func (*Window) TreePush

func (win *Window) TreePush(type_ TreeType, title string, initialOpen bool) bool

func (*Window) TreePushCustom

func (win *Window) TreePushCustom(type_ TreeType, name string, initial_open bool) (bounds rect.Rect, out *command.Buffer, ok bool)

func (*Window) TreePushNamed

func (win *Window) TreePushNamed(type_ TreeType, name, title string, initial_open bool) bool

Creates a new collapsable section inside win. Returns true when the section is open. Widgets that are inside this collapsable section should be added to win only when this function returns true. Once you are done adding elements to the collapsable section call TreePop. Initial_open will determine whether this collapsable section will be initially open. Type_ will determine the style of this collapsable section.

func (*Window) WidgetBounds

func (win *Window) WidgetBounds() rect.Rect

Returns the position and size of the next widget that will be added to the current row. Note that the return value is in scaled units.

type WindowFlags

type WindowFlags int
const (
	WindowBorder WindowFlags = 1 << iota
	WindowBorderHeader
	WindowMovable
	WindowScalable
	WindowClosable
	WindowDynamic
	WindowNoScrollbar
	WindowNoHScrollbar
	WindowTitle
	WindowContextualReplace
	WindowNonmodal

	WindowDefaultFlags = WindowBorder | WindowMovable | WindowScalable | WindowClosable | WindowTitle
)

type WindowWalkFn

type WindowWalkFn func(title string, data interface{}, docked bool, splitSize int, rect rect.Rect)

Directories

Path Synopsis
clipboard
command
internal/assets
label
rect
style