---
title: "Idle Callback"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Idle Callback}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
## 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](https://twitter.com/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
```{r eval = FALSE}
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)
```