gui

package module
v0.22.1 Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2024 License: BSD-3-Clause Imports: 12 Imported by: 0

README

gui

Package gui implements a abstraction layer for Go visual elements.

Hello World Example

// This creates a simple hello world window
package main

import 	(
	"log"
	"go.wit.com/gui"
)

var myGui *gui.Node // This is your gui object

func main() {
	myGui = gui.New().Default()

    helloworld()

    // go will sit here until the window exits
    // intermittently, it will show toolkit statistics
    gui.Watchdog()
}

// This initializes the first window and 2 tabs
func helloworld() {
	window := myGui.NewWindow()

	group := window.NewGroup("a group of widgets")
	group.NewButton("hello", func() {
		log.Println("world")
	})
}

Build

This will build the simple hello world example above.

go install go.wit.com/apps/helloworld@latest

A more extensive list of applications can be found on go.wit.com.

Build Toolkit Plugins

This is an example of how to build the console based toolkit plugin built against the gocui package.

GO111MODULE=off go get go.wit.com/toolkits/gocui
cd ~/go/src/go.wit.com/toolkits/gocui
go build -v -buildmode=plugin -o ~/go/lib/toolkits/gocui.so

Toolkits

The toolkits are compiled as plugins and communicate only over a channel to your application. This way, the toolkits are isolated and you don't have to care about what the user uses to display things when you write your application. Also, that allows the control panels to run in both a traditional GUI like GTK or in the console like ncurses.

There are two working toolkits. One is written to the andlabs package which provides a native linux, macos and windows. The second one is terminal window based using gocui. (There is a 3rd one using STDIN/STDOUT as a template to create new toolkit plugins.) Also, GO doesn't support plugins on Windows so the native Windows GUI awaits someone to fix that.

The next step is to allow this to work against go-gtk and go-qt.

Others potential plugins: Fyne, WASM, native macos & windows, android and hopefully also things like libSDL, faiface/pixel, slint

General Thoughts

A primary design purpose for this toolkit is to be able to develop a modern set of control panels for linux. Specifically a DNS and IPv6 control panel. Since the toolkit interface plugins are cross platform, these control panels should be able to run on the Macos and Windows also.

Definitions:

* Toolkit: the underlying GUI library (MacOS gui, Windows gui, gtk, qt, etc)
* Node: A binary tree of all the underlying widgets

Principles:

* Make code using this package simple to use
* Hide complexity internally here
* Isolate the GUI toolkit
* Widget names should try to match [Wikipedia Graphical widget]
* When in doubt, search upward in the binary tree
* It's ok to guess. Try to do something sensible.

Bugs

"The author's idea of friendly may differ to that of many other people."

-- quote from the minimalistic window manager 'evilwm'

References

Useful links and other external things which might be useful

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CHANGE *log.LogFlag
View Source
var GUI *log.LogFlag
View Source
var GUIVERSION string
View Source
var INFO *log.LogFlag
View Source
var NODE *log.LogFlag
View Source
var NOW *log.LogFlag
View Source
var PLUG *log.LogFlag
View Source
var WARN *log.LogFlag

Functions

func ArgToolkit

func ArgToolkit() string

used for command line options. This allows you to control the toolkit settings from the command line

--debugger      # opens the debugger
--gui andlabs   # loads the GTK toolkit on linux or Cocoa on mac
--gui gocui     # runs your program in the terminal in ncurses-like mode

func Indent

func Indent(b bool, a ...interface{})

func StandardExit

func StandardExit()

The window is destroyed and the application exits TODO: properly exit the plugin since Quit() doesn't do it

func Watchdog

func Watchdog()

This program sits here. This goroutine can be used like a watchdog timer TODO: handle toolkit panics here?

Types

type ArgsGui

type ArgsGui struct {
	GuiPlugin  string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"`
	GuiVerbose bool   `arg:"--gui-verbose" help:"enable all logging"`
}

This struct can be used with the go-arg package. These are the generic default command line arguments for the 'GUI' package

type Grid

type Grid struct {
	Width  int
	Height int
}

type GridOffset

type GridOffset struct {
	X int
	Y int
}

type Node

type Node struct {
	WidgetType widget.WidgetType

	// this function is run when there are mouse or keyboard events
	Custom func()

	// used for anything that needs a range (for example: a slider)
	X int
	Y int

	// the grid widget max width and height
	// the max height can be implemented in the toolkit plugin
	// to restrict the number of rows to display
	W int
	H int

	// where the next widget should be put in this grid
	NextW int
	NextH int

	// if this widget is in a grid, this is the position of a widget
	AtW int
	AtH int
	// contains filtered or unexported fields
}

func New

func New() *Node

There should only be one of these per application This is due to restrictions by being cross platform some toolkit's on some operating systems don't support more than one Keep things simple. Do the default expected thing whenever possible

func NewWindow added in v0.20.5

func NewWindow(title string) *Node

This creates a window off the root of the binary tree

func RawBox added in v0.20.8

func RawBox() *Node

this is an experiment. I like to think of this package like 'Sierpinski' It's like it's in a fractional dimension because it doesn't exist the toolkits are the things that make it visible to us. Here, we can think abstractly about how the data is formed make something that can't be seen at all

func RawMirror added in v0.20.8

func RawMirror(m *Node) *Node

make a mirror widget without a parent

func RawWindow added in v0.20.5

func RawWindow(title string) *Node

func TreeRoot

func TreeRoot() *Node

returns the root of the binary tree change the names to 'Tree' as I think the name is better

func (*Node) AddText

func (n *Node) AddText(str string) bool

add a new text string to widgets that support multiple string values These must be unique. return false if the string already exists

func (*Node) Append added in v0.20.8

func (parent *Node) Append(n *Node)

func (*Node) AppendText

func (n *Node) AppendText(str string)

appends text to the existing text TODO: this is an experiement

func (*Node) At

func (n *Node) At(w int, h int) *Node

func (*Node) Bool

func (n *Node) Bool() bool

func (*Node) Box added in v0.20.5

func (parent *Node) Box() *Node

func (*Node) Checked

func (n *Node) Checked() bool

func (*Node) Children

func (n *Node) Children() []*Node

func (*Node) CloseToolkit

func (n *Node) CloseToolkit(name string) bool

func (*Node) Default

func (n *Node) Default() *Node

try to load andlabs, if that doesn't work, fall back to the console

func (*Node) Delete

func (n *Node) Delete(d *Node)

func (*Node) Disable

func (n *Node) Disable() *Node

disables a widget so the user can see it, but can not interact or change it.

func (*Node) Draw

func (n *Node) Draw() *Node

TODO: should do this recursively (on a window only)

func (*Node) Dump

func (n *Node) Dump()

func (*Node) Enable

func (n *Node) Enable() *Node

enables a widget so the user can see it and work/click/etc on it by default, widgets are enabled when they are created

func (*Node) Expand

func (n *Node) Expand() *Node

func (*Node) GetProgName

func (n *Node) GetProgName() string

func (*Node) Hidden

func (n *Node) Hidden() bool

is the widget currently viewable?

func (*Node) Hide

func (n *Node) Hide() *Node

func (*Node) Horizontal

func (n *Node) Horizontal() *Node

func (*Node) InitEmbed

func (n *Node) InitEmbed(resFS embed.FS) *Node

func (*Node) Int

func (n *Node) Int() int

func (*Node) IsMirror added in v0.20.8

func (n *Node) IsMirror() bool

func (*Node) ListChildren

func (n *Node) ListChildren(dump bool)

func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {

func (*Node) ListToolkits

func (n *Node) ListToolkits()

func (*Node) LoadToolkit

func (n *Node) LoadToolkit(name string) *Node

func (*Node) LoadToolkitEmbed

func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node

func (*Node) Margin

func (n *Node) Margin() *Node

func (*Node) Mirror added in v0.20.8

func (parent *Node) Mirror(m *Node) *Node

an experiemental idea basically, this is like a cell in a spreadsheet that is viable in one place but also exists sonewhere else

func (*Node) NewBox

func (parent *Node) NewBox(progname string, b bool) *Node

func (*Node) NewButton

func (parent *Node) NewButton(name string, custom func()) *Node

func (*Node) NewCheckbox

func (parent *Node) NewCheckbox(name string) *Node

func (*Node) NewCombobox

func (parent *Node) NewCombobox() *Node

func (*Node) NewDropdown

func (parent *Node) NewDropdown() *Node

func (*Node) NewEntryLine

func (parent *Node) NewEntryLine(name string) *Node

func (*Node) NewEntrybox added in v0.20.5

func (parent *Node) NewEntrybox(name string) *Node

func (*Node) NewGrid

func (parent *Node) NewGrid(progname string, w int, h int) *Node

func (*Node) NewGroup

func (parent *Node) NewGroup(name string) *Node

TODO: make a "Group" a "Grid" ? probably since right now group is just a pre-canned andlabs/ui gtk,macos,windows thing

func (*Node) NewHorizontalBox

func (parent *Node) NewHorizontalBox(progname string) *Node

func (*Node) NewImage

func (parent *Node) NewImage(name string) *Node

func (*Node) NewLabel

func (parent *Node) NewLabel(text string) *Node

func (*Node) NewSeparator

func (parent *Node) NewSeparator(progname string) *Node

func (*Node) NewSlider

func (parent *Node) NewSlider(progname string, x int, y int) *Node

func (*Node) NewSpinner

func (parent *Node) NewSpinner(progname string, x int, y int) *Node

func (*Node) NewTextbox

func (parent *Node) NewTextbox(name string) *Node

func (*Node) NewVerticalBox

func (parent *Node) NewVerticalBox(progname string) *Node

func (*Node) NewWindow

func (parent *Node) NewWindow(title string) *Node

func (*Node) NextRow added in v0.20.5

func (n *Node) NextRow() *Node

func (*Node) Pad

func (n *Node) Pad() *Node

func (*Node) Parent

func (n *Node) Parent() *Node

returns the parent widget

func (*Node) ParentVisable

func (n *Node) ParentVisable() bool

returns true if the parent is not visable to the user in which case events are not sent to the toolkit

func (*Node) RawGrid added in v0.20.5

func (parent *Node) RawGrid() *Node

func (*Node) RawWindow

func (parent *Node) RawWindow(title string) *Node

allow window create without actually sending it to the toolkit

func (*Node) Ready

func (n *Node) Ready() bool

func (*Node) SetBool

func (n *Node) SetBool(b bool)

func (*Node) SetChecked

func (n *Node) SetChecked(b bool) *Node

func (*Node) SetExpand

func (n *Node) SetExpand(b bool) *Node

func (*Node) SetInt added in v0.18.0

func (n *Node) SetInt(i int)

func (*Node) SetLabel

func (n *Node) SetLabel(label string) *Node

This will set the visable name for widgets that have text displayed that is not editable by the user For example, a button, window, group, checkbox

func (*Node) SetProgName

func (n *Node) SetProgName(s string) *Node

should get the reference name used for programming and debugging

TODO: ensure these are unique and make a way to look them up myButton = myGroup.NewButton("hit ball", nil).SetName("HIT") myButton.GetName() should return "HIT" n = Find("HIT") should return myButton

func (*Node) SetText

func (n *Node) SetText(text string) *Node

What "SetText" means depends on the type of widget should this be a different name?

func (*Node) SetVisable

func (n *Node) SetVisable(b bool)

func (*Node) Show

func (n *Node) Show() *Node

func (*Node) StandardClose

func (n *Node) StandardClose()

The window is destroyed but the application does not quit

func (*Node) StandardExit

func (n *Node) StandardExit()

The window is destroyed and the application exits TODO: properly exit the plugin since Quit() doesn't do it

func (*Node) String

func (n *Node) String() string

func (*Node) Strings

func (n *Node) Strings() []string

func (*Node) TestDraw

func (n *Node) TestDraw()

when a window is redrawn, every widget in the window needs to be sent to the toolkit

func (*Node) Unmargin

func (n *Node) Unmargin() *Node

func (*Node) Unpad

func (n *Node) Unpad() *Node

func (*Node) Vertical

func (n *Node) Vertical() *Node

func (*Node) WindowVisable

func (n *Node) WindowVisable() bool

returns true if the window is not visable to the user in which case events are not sent to the toolkit TODO: fix this so ParentVisable() works

type RangeMovedToWidget

type RangeMovedToWidget struct {
	Low  int
	High int
}

Range(1, 10) includes the values 1 and 10 almost all toolkits use integers so there doesn't seem to be a good idea to use 'type any' here as it just makes things more complicated for no good reason

type Symbol

type Symbol any

Jump to

Keyboard shortcuts

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