Layout

As we will be working with canvas APIs, as well as widgets and layouts, we will need to start by importing most of the Fyne sub-packages. In addition to canvas, where we get the basic image APIs, we will also use the theme package for accessing icons and the app package to launch our application. We don't need to import the image libraries, such as image/jpeg, because Fyne image widgets import them for us:

import (
"fyne.io/fyne"
"fyne.io/fyne/app"
"fyne.io/fyne/canvas"
"fyne.io/fyne/layout"
"fyne.io/fyne/theme"
"fyne.io/fyne/widget"
)

As with any Fyne application, we start by creating an application using app.New() and then create a window for the application by calling NewWindow() with an appropriate title:

func main() {
imageApp := app.New()
win := imageApp.NewWindow("GoImages")

...
}

Next, we will create the widgets for the main layout. To achieve a visually distinct navigation bar, let's use a toolbar as in the GoMail application. In addition to standard icon buttons, we also add a spacer (with widget.NewToolbarSpacer()) so that the second button is right aligned in the bar. We will come back to the navigation later to add the filename display and functionality.

Next, we use the widget.Group widget to visually group the file listing (we could use the widget.Box widget if the border-less look is preferred). Into the group, we append various labels that will serve as file placeholders. Lastly, we load the image view to show the placeholder file. The canvas.NewImageFromFile() function handles all of the image loading for us, as can be seen in the following code block:

func main() {
...

navBar := widget.NewToolbar(
widget.NewToolbarAction(theme.NavigateBackIcon(), func() {}),
widget.NewToolbarSpacer(),
widget.NewToolbarAction(theme.NavigateNextIcon(), func() {}))
fileList := widget.NewGroup("directory",
widget.NewLabel("Image 1"),
widget.NewLabel("Image 2"),
widget.NewLabel("Image 3"))
image := canvas.NewImageFromFile("shiny-hall.jpg")

...
}

For this application, a simple layout.BorderLayout will provide exactly the layout we are looking for. We create a new layout with navBar at the top and fileList on the left. The container also includes image, which will be stretched to fill the remaining space:

func main() {
...

container := fyne.NewContainerWithLayout(
layout.NewBorderLayout(navBar, nil, fileList, nil),
navBar, fileList, image,
)

...
}

Lastly, we set this container to be the content of our window, resize the whole window to be larger than the calculated minimum size, and show it. As before, we use ShowAndRun() as a shortcut to running the application with this first window:

func main() {
...

win.SetContent(container)
win.Resize(fyne.NewSize(640, 480))

win.ShowAndRun()
}

With all of this code in place, the example can be run. You should see a window very much like the following (assuming you are using the default dark theme):

A basic image viewer layout using default Fyne widgets