Skip to content
James Doyle edited this page Dec 24, 2017 · 15 revisions

In this example we will make a program that asks the user to enter their name, then prints it.

First, here's the complete (short!) program. I'll discuss each part afterward.

package main

import (
	"github.com/andlabs/ui"
)

func main() {
	err := ui.Main(func() {
		name := ui.NewEntry()
		button := ui.NewButton("Greet")
		greeting := ui.NewLabel("")
		box := ui.NewVerticalBox()
		box.Append(ui.NewLabel("Enter your name:"), false)
		box.Append(name, false)
		box.Append(button, false)
		box.Append(greeting, false)
		window := ui.NewWindow("Hello", 200, 100, false)
		window.SetMargined(true)
		window.SetChild(box)
		button.OnClicked(func(*ui.Button) {
			greeting.SetText("Hello, " + name.Text() + "!")
		})
		window.OnClosing(func(*ui.Window) bool {
			ui.Quit()
			return true
		})
		window.Show()
	})
	if err != nil {
		panic(err)
	}
}

TODO rewrite everything below

Running Package UI

var window ui.Window

First, we declare a global variable of type ui.Window. Windows hold other controls; all controls must belong to a Window in order for them to be visible on screen. (A Window is itself not a control.) For technical reasons, we keep the Window global so as to prevent it (and thus its children) from being moved around in memory (as it would have been if it was a stack variable).

	go ui.Do(func() {...})

You'll notice that all our UI work is done inside a closure passed to the function ui.Do(). Most windowing systems actually hate being run on multiple threads, so ui.Do() is a compromise to keep things nice and serialized for the underlying OS. Except for event handlers, all UI code should be passed to ui.Do().

We run ui.Do() as a goroutine because it will wait for the function to finish running before it returns, and we haven't even launched the UI main loop yet.

	err := ui.Go()
	if err != nil {
		panic(err)
	}

ui.Go() is the package ui main loop. It initializes the underlying window system, allocating its own resources, and then enters the main loop, not returning until ui.Stop() is called. (This is also why we use a goroutine for ui.Do().) If an error occurs during initialization, it will be returned.

Building the UI

		name := ui.NewEntry()
		button := ui.NewButton("Greet")
		greeting := ui.NewLabel("")

These few assignments should be straightforward: we create a text field, a button, and a label where our greeting will go.

		stack := ui.NewVerticalStack(
			ui.NewLabel("Enter your name:"),
			name,
			button,
			greeting)

Controls in package ui are arranged using layout containers, similar to how GTK+ and Qt do things. The most basic of these is the stack, which arranges controls horizontally or vertically, giving each control the same height or width (respectively). In this case, we use a vertical stack to arrange our controls vertically. We also add an extra instructional label; since we don't need to do anything with it later, we add it directly without saving it in a variable.

		window = ui.NewWindow("Hello", 200, 100, stack)

Now we are ready to create the window. ui.NewWindow() takes four parameters: the title of the window, its width in pixels, its height in pixels, and the control that the window holds. A window can only hold one control, and our stack is a control, so we simply give the stack to the new window. All the controls we created before become part of the window automatically.

Events

		button.OnClicked(func() {
			greeting.SetText("Hello, " + name.Text() + "!")
		})

We assign an event handler to run when the button is clicked. Event handlers are simply functions that get run a la ui.Do() when the event arrives. You can safely work with the UI in an event handler, and invocations of ui.Do() from other goroutines won't run while an event handler is running. The body of the event handler should be straightforward.

		window.OnClosing(func() bool {
			ui.Stop()
			return true
		})

We want to quit gracefully when the user closes the window. w.OnClosing() is an event like the OnClicked() event earlier, with the exception that the handler returns a boolean value that determines whether the window should be closed. In this case, we merely call ui.Stop() to schedule a shutdown of the package ui main loop and return true to close the window. The main loop will stop on its own a short time later.

Finishing Up

		window.Show()

All that's left now is to show the window.

Build and run this program. (In windows , you should use this : go build -ldflags -H=windowsgui main.go ) You should see this on a Linux system:

example screenshot

And this if you are on OSX:

example screenshot osx

And there you have it! You should be good to go for now; the rest of this wiki covers more complex parts of the package.

Clone this wiki locally