Designing cross-platform GUI apps with Fyne

Adding Items

When the user taps on the add button created in Listing 3, a new item will be added to the to-do list. To do this, you make a more useful tapped handler for the button. Instead of logging to the console, you will use the code in Listing 6, which asks for a new item to be added and then clears the input text to get ready for another to-do item.

Listing 6

Adding a To-Do Item via Tapping

add := widget.NewButtonWithIcon("",
theme.ContentAddIcon(),
func() {
  addTODO(input.Text)
  input.SetText("")
})

Because some users prefer to run an app from the keyboard, you will also want this functionality when the user hits Return or Enter. Thankfully, the Entry widget has an OnSubmitted callback that you can set as shown in Listing 7.

Listing 7

Adding a To-Do Item via the Keyboard

input.OnSubmitted = func(item string) {
  addTODO(item)
  input.SetText("")
}

Both handlers call a new addTODO function, which simply appends a new item to the slice and refreshes the list (see Listing 8).

Listing 8

data.go

01 package main
02
03 import "fyne.io/fyne/v2"
04
05 func addTODO(todo string) {
06   todos = append(todos, todo)
07   list.Refresh()
08 }
09
10 func deleteTODO(todo string) {
11   for i, text := range todos {
12     if text != todo {
13       continue
14     }
15
16     todos = append(todos[:i], todos[i+1:]...)
17     break
18   }
19   list.Refresh()
20 }

Populating the List

Now that you have some data to display, you need to tell the list how to update accordingly. To do this, you add some code to the third callback of the List widget. This code will set the Check widget's text and make sure that it is not checked (because the list currently only has pending to-do items). Listing 9 achieves this using a replacement callback function.

Listing 9

Displaying To-Do Content

01 func(id widget.ListItemID, o fyne.CanvasObject) {
02   check := o.(*widget.Check)
03   check.SetChecked(false)
04   check.Text = todos[id]
05   check.Refresh()
06 }

Line 1 of Listing 9 makes sure you can use the Check widget's functionality. The list does not know what type of content it displays, so you need to do a type cast to match the widget you created in the second callback function. With this in place, you will see your to-do list – all that is left is to delete them!

Deleting Items

The to-do list is only keeping track of pending items, so you want to remove any to-do item once it is checked. For this, you can set the OnChanged callback to your Check widget (Listing 10), much like you set OnSubmitted on the Entry widget.

Listing 10

Deleting To-Do Items

check.OnChanged = func(done bool) {
  if !done {
    return
  }
  deleteTODO(check.Text)
}

The OnChanged callback will be called if the item is checked or unchecked – which is why you first test that it is being marked as completed using the bool parameter. Assuming it should be deleted, you call the helper function deleteTODO from Listing 8.

The method shown in Listing 8 is a little complicated because there is no built-in way to delete an item from a slice in Go. Listing 8 performs "re-slicing," which sets the to-do list to a join of two other lists (a list for before and one for after the item is deleted). The code then refreshes the list as before, so your item disappears. If you run your app once more, you will see that it is empty, but you can add new items and mark them as done as often as you like, as shown in Figure 3.

Figure 3: You can now input your to-do items.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Wheat and Chaff

    If you want to keep only the good photos from your digital collection, you have to find and delete the fails. Mike Schilli writes a graphical application with Go and the Fyne framework to help you cull your photo library.

  • Treasure Hunt

    A geolocation guessing game based on the popular Wordle evaluates a player's guesses based on the distance from and direction to the target location. Mike Schilli turns this concept into a desktop game in Go using the photos from his private collection.

  • Chip Shot

    We all know that the Fyne framework for Go can be used to create GUIs for the desktop, but you can also write games with it. Mike Schilli takes on a classic from the soccer field.

  • Straight to the Point

    With the Fyne framework, Go offers an easy-to-use graphical interface for all popular platforms. As a sample application, Mike uses an algorithm to draw arrows onto images.

  • Magic Cargo

    To be able to power up and shut down his NAS and check the current status without getting out of his chair, Mike Schilli programs a graphical interface that sends a Magic Packet in this month's column.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News