Communicating with the GUI

To add the code that handles updating the GUI and responding to user events, we will need to save references to some widgets that have been created; mainly the widget.Label toolbar and the main view, canvas.Image. By storing these references, we can update their content later.

Additionally, we will add a []string to list images for the directory we are accessing and save int index of the current image so that we can calculate the previous and the next. Once those are created, we can fill in the content of our previousImage() and nextImage() functions to call a new chooseImage() function that will update the display:

var images []string
var index int

var image *canvas.Image
var label *widget.Label


func previousImage() {
if index == 0 {
return
}

chooseImage(index-1)
}

func nextImage() {
if index == len(images)-1 {
return
}

chooseImage(index+1)
}

The chooseImage() function accesses the file path from the image list that will be loaded later and uses this information to update our user interface. From path, we call label.SetText() to show the filename and then set image.File to update the path for the main image display:

func chooseImage(id int) {
path := images[id]
label.SetText(filepath.Base(path))
image.File = path
canvas.Refresh(image)
index = id
}

To most easily implement the click handling behavior in order to choose an image from the list, we will change from widget.Label to widget.Button items. As the buttons have a different color background, we should tidy up the display by using layout.BorderLayout so that the buttons fill the available space. Finally, because buttons are taller than labels, we update the minSize() preview code to be relative to the button's minimum height rather than the previous inline icon size defined by the theme:

func makeRow(id int, path string) fyne.CanvasObject {
filename := filepath.Base(path)
button := widget.NewButton(filename, func() {
chooseImage(id)
})

preview := canvas.NewImageFromFile(path)
iconHeight := button.MinSize().Height
preview.SetMinSize(fyne.NewSize(int(float32(iconHeight)*1.5),
iconHeight))

return fyne.NewContainerWithLayout(
layout.NewBorderLayout(nil, nil, preview, nil),
preview, button)
}

Next, we need to add a getImageList() function that will access the list of images in a directory. The contents of this function are identical to the same function in Chapter 8Shiny – Experimental Go GUI API, so it is omitted here for brevity. With that in place, we can update our makeList() function, which now takes a dir parameter, to load the image file list and create the new rows using makeRow(), as well as populating our stored images list:

func makeList(dir string) *widget.Group {
files := getImageList(dir)
group := widget.NewGroup(filepath.Base(dir))

for idx, name := range files {
path := filepath.Join(dir, name)
images = append(images, path)

group.Append(makeRow(idx, path))
}

return group
}

We then update the creation of the fileList in main() function to pass a directory path to load:

fileList := makeList(dirpath)

As with the previous GoImages code, we can use the built-in flag handling to allow users to specify the directory to display. The code is listed here and we can invoke it simply by setting the preceding dirpath variable to the result of parseArgs() (if you add this code, remember to import the flag, fmt, and os packages):

func parseArgs() string {
dir, _ := os.Getwd()

flag.Usage = func() {
fmt.Println("goimages takes a single, optional, directory parameter")
}
flag.Parse()

if len(flag.Args()) > 1 {
flag.Usage()
os.Exit(2)
} else if len(flag.Args()) == 1 {
dir = flag.Args()[0]

if _, err := ioutil.ReadDir(dir); os.IsNotExist(err) {
fmt.Println("Directory", dir, "does not exist or could not be read")
os.Exit(1)
}
}

return dir
}

Updating all of the preceding code should result in our complete image viewer application. If you'd prefer to access the complete code, this can be downloaded from this book's source code repository on GitHub:

Our completed image viewer showing a wallpaper directory

As with the previous GoMail example, we can load this interface using the light theme by specifying FYNE_THEME=light in the command-line environment:

The same app and directory with the Fyne light theme
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.249.198