Run a function continually while window is valid

An idle callback is an R function that will be run continually while the UI window is valid - regardless of what the user is doing.

Thanks to ozjimbob for this great example!

Video

In this example, at each timestep the rain() function updates the size of the current effect for all the current rain drops.

If the user changes values in the UI, then this will be used to updated the appearance of the rain drops.

Code

library(grid)
library(tickle)


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Open a double-buffered graphics device that renders nice and fast
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x11(type = 'dbcairo', antialias = 'none')
dev.control(displaylist = 'inhibit')


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Reactive variables controlled by the UI
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size <- reactive_dbl(value=6)
rate <- reactive_dbl(value=10)


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Raindrops data: coordinates and current size
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
df = data.frame(x=runif(10,-1,1),y=runif(10,-1,1),size=rep(1,10))


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Plot the current rain drops
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rain <- function() {
  df <<- tail(df,1000)
  df2 <- data.frame(x=runif(rate(),-1,1),y=runif(rate(),-1,1),size=rep(size(),rate()))
  df <<- rbind(df,df2)
  df$size <<- df$size * 0.9
  dev.hold()
  plot(df$y,df$x,cex=df$size,xlim=c(-1,1),ylim=c(-1,1))
  dev.flush()
}


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define the UI.  
# The idle callback is attached to the top level window.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ui_spec <- tic_window(
  idle_func = rain, idle_fps = 10,
  tic_col(
    tic_label("Raindrops", style = 'h3'),
    tic_separator(),
    tic_row(
      tic_label("Thickness"),
      tic_slider(variable = size, from = 6, to = 20),
      tic_label("Rate"),
      tic_slider(variable = rate, from = 1, to = 40)
    )
  )
)


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Render the UI
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
win <- render_ui(ui_spec)