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.NewWithIDcreates 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.Newcreates the app without an ID. It takes the ID from the app’smanifest.pxfmetadata, if there is one. PreferNewWithID.a.NewWindow(title)creates a window. It is not shown yet.w.Resizeasks 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:
| Method | What it does |
|---|---|
SetTitle, Title | Change 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 |
SetIcon | Set the window icon (defaults to the app icon) |
SetMainMenu | Add 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.