LiveCode Widgets: The “Spinner” Activity Indicator

by Peter Brett on December 9, 2016 5 comments

We recently launched a new LiveCode for FM product, which lets you use LiveCode to extend FileMaker solutions. While working on this product, we’ve had the opportunity to add some useful new features to LiveCode, which are now available in developer previews of LiveCode 9.

The new “spinner” widget is one of these new features, and it’s included in LiveCode 9 developer preview 2 onwards. It’s very useful as an activity indicator, showing users that your app is busy performing a task that will take some time to complete.

spinner

It’s dead easy to use: drag it from the tools palette onto your stack; when it’s visible, it spins around.  You can use the visible property of the widget to control when it’s displayed to the user.  Normally, it would make sense to display it in front of other content displayed on the screen.

Here are some tips that may help you use the spinner effectively.

Ensuring the spinner actually spins

The spinner widget will only update (rotate to its next notch) when the engine gets to do event processing, such as during a wait with messages statement.  There are several commands and functions which implicitly wait with messages internally, such as the url chunk.

However, if you are doing a slow computation, such as parsing a text file or loading data from a database, you may wish to add wait 0 with messages statement each time you make progress, so that the spinner continues to spin, and your users don’t think your app has frozen.

Making it clear that the app is “busy”

You may wish to hide or “dim” your app’s user interface while the app is busy.  For example, your app could use a “splash screen” card that displays a logo and a spinner widget while loading its resources and preparing to run.  This helps by providing additional visual cues to the user that the app’s user interface is not ready to respond yet.

Cancelling a long-running activity

Sometimes, you may have a very slow process that you can safely abandon. It can be useful to provide a “Cancel” button. Suppose you have a stack with a cancelButton and a spinnerWidget.  You can create a cancellable process using a script-local variable to store whether the process should continue:

-- In the script of the cancelButton
on mouseUp
   send "cancelOperation"
end mouseUp

-- In the stack script
local sCancelled

command doOperation
   set the visible of control "spinnerWidget" to true
   set the visible of control "cancelButton" to true
   put false into sCancelled

   repeat for each item to process
      -- (do something with the item)

      -- allow the spinner widget to spin, and
      -- for cancel button clicks to be handled
      wait 0 with messages
      if sCancelled then
         exit repeat
      end if
   end repeat

   if not sCancelled then
      -- (update the UI to reflect the results)
   end if
   set the visible of control "spinnerWidget" to false
   set the visible of control "cancelButton" to false
end doOperation

Indicating background processing

Sometimes your app may need to do some background processing, such as synchronising its state with a server, without needing to block the user interface.  You may wish to use a spinner widget in a peripheral part of the user interface, such as a status bar, to provide an unobtrusive indication that this is going on.

For example, an e-mail app might regularly check for new messages, but that shouldn’t necessarily block the user from carrying on reading or writing e-mails.

 

Peter BrettLiveCode Widgets: The “Spinner” Activity Indicator

Related Posts

Take a look at these posts

5 comments

Join the conversation
  • trevix - December 9, 2016 reply

    If I understand, this is practically like an animated gif or a scripted animation.
    We need a spinner that spin continuously while scripts are running (without wait with messages or idle)

    Peter Brett - December 15, 2016 reply

    Yes, this is very similar to a scripted animation. Currently, LiveCode is single-threaded, so it can only run one part of the program at a time. This is what imposes the requirement for wait with messages or idling. In the future, it may be possible to make LiveCode multi-threaded, so that scripts can do work on one CPU core while the screen is updated by code running on another core.

    Jonathan Lynch - December 15, 2016 reply

    This is easy to work around. I use a browser widget to play a gif animation of a spinning earth. The data for the gif animation is in a dataurl, so no need to reference an external file. Although LiveCode is not multithreaded, items presented through a captured browser window do keep running even while the LiveCode script is executing.

    The browser widget will always present as a square, so it helps to have a background object underneath the browser widget that helps it visually merge with the rest of the app.

  • Trevix - February 27, 2023 reply

    Reently I often get an error on my standalone, intercepted by the “errorDialog”.
    Unfortunatly the error is very difficult to understand:
    863,0,0,runtime
    864,0,0,cannot convert value
    865,0,0,spinner.lcb
    866,0,0,168
    897,0,0,1
    Shoudn’t the Spinner code have a Try/end try, so to collapse gently ?
    I have a bunch of spinners in my App. Should I move to a gif?

    Heather Laine - February 28, 2023 reply

    Thank you for this report. Could you help us further by submitting it in our Quality Center? We haven’t seen this behaviour, so if you can make a bug report for us we can investigate. Quality Center url is

    https://quality.livecode.com

Join the conversation

*