Skip to content
The app and its windows

The app and its windows

Every Bellui program has one app. The app owns the windows, the settings and the event loop. You create it once at the start of main.

Create the app

a := app.NewWithID("com.example.windows")
w := a.NewWindow("Main window")
w.Resize(geo.NewSize(420, 260))
  • app.NewWithID creates the app with a unique ID, written like a reverse domain name. The preferences API needs this ID to know where to store data.
  • app.New creates the app without an ID. It takes the ID from the app’s manifest.pxf metadata, if there is one. Prefer NewWithID.
  • a.NewWindow(title) creates a window. It is not shown yet.
  • w.Resize asks for a content size. The platform may not honour it exactly.

The app also gives you access to its Settings, Preferences, Storage, Clipboard and Lifecycle hooks. bellui.CurrentApp() returns the app from anywhere in your program.

Show a window and run

The complete program puts content in the window with w.SetContent and then calls bellui.ShowAndRun(w):

// An app with a main window that opens extra windows. Closing the main
// window quits the app; closing an extra window does not.
package main

import (
	"fmt"

	"github.com/belluikit/bellui"
	"github.com/belluikit/bellui/app"
	"github.com/belluikit/bellui/container"
	"github.com/belluikit/bellui/dialog"
	"github.com/belluikit/bellui/geo"
	"github.com/belluikit/bellui/widget"
)

func main() {
	a := app.NewWithID("com.example.windows")
	w := a.NewWindow("Main window")
	w.Resize(geo.NewSize(420, 260))

	// Closing this window quits the app, even if other windows are open.
	if m, ok := w.(bellui.MasterWindow); ok {
		m.SetMaster()
	}

	// Ask before closing. The window only closes when Close is called.
	w.SetCloseIntercept(func() {
		dialog.ShowConfirm("Quit?", "Close the main window and quit?", func(ok bool) {
			if ok {
				w.Close()
			}
		}, w)
	})

	count := 0
	open := widget.NewButton("Open another window", func() {
		count++
		extra := a.NewWindow(fmt.Sprintf("Window %d", count))
		extra.SetContent(widget.NewLabel("Close me: the app keeps running."))
		extra.Resize(geo.NewSize(300, 120))
		extra.SetOnClosed(func() {
			fmt.Println("closed", extra.Title())
		})
		extra.Show()
	})

	w.SetContent(container.NewVBox(
		widget.NewLabel("This is the main window."),
		open,
	))
	bellui.ShowAndRun(w)
}

bellui.ShowAndRun(w) is the same as calling w.Show() and then a.Run(). Run starts the event loop and blocks until the app quits, so it goes at the end of main. Show any other window with its own w.Show().

A Window has one content object. To show several things, put them in a container and set the container as the content. Other useful window methods:

MethodWhat it does
SetTitle, TitleChange or read the title bar text
SetFixedSize(true)Hint that the user should not resize the window
CenterOnScreen()Centre the window on its current monitor
SetFullScreen(true)Go full screen
SetPadded(false)Remove the inner padding around the content
SetIconSet the window icon (defaults to the app icon)
SetMainMenuAdd a menu bar
Hide()Hide the window without closing it
Canvas()The window’s canvas, for keyboard handlers and shortcuts

Multiple windows

Call a.NewWindow again for each extra window. How the extra windows appear depends on the platform:

  • Desktop: every window is a separate operating system window. Any number can be open at once.
  • Web: the first window fills the browser canvas. Extra windows appear as draggable windows inside it.
  • Mobile: windows form a stack and only the top one is visible. Opening a window covers the previous one, and closing it shows the previous one again.

In the example, the button opens a new window each time it is tapped:

count := 0
open := widget.NewButton("Open another window", func() {
	count++
	extra := a.NewWindow(fmt.Sprintf("Window %d", count))
	extra.SetContent(widget.NewLabel("Close me: the app keeps running."))
	extra.Resize(geo.NewSize(300, 120))
	extra.SetOnClosed(func() {
		fmt.Println("closed", extra.Title())
	})
	extra.Show()
})

SetOnClosed runs a function when that window closes.

When the app quits

On desktop, the app quits when its last window closes. You can change that in two ways.

Make one window the master. Closing a master window quits the app, even if other windows are still open. SetMaster is on the optional bellui.MasterWindow interface, so check for it:

// Closing this window quits the app, even if other windows are open.
if m, ok := w.(bellui.MasterWindow); ok {
	m.SetMaster()
}

Intercept the close. With SetCloseIntercept, the close button runs your function instead of closing the window. The window only closes when you call w.Close(). Use it to ask about unsaved work:

// Ask before closing. The window only closes when Close is called.
w.SetCloseIntercept(func() {
	dialog.ShowConfirm("Quit?", "Close the main window and quit?", func(ok bool) {
		if ok {
			w.Close()
		}
	}, w)
})

a.Quit() closes every window and stops the app. On mobile it does nothing: the operating system manages the app’s lifetime there.

Hide() only hides a window. It does not close it, and it does not make the app quit.