Rev 72261 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/grDevices/man/getGraphicsEvent.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2014 R Core Team% Distributed under GPL 2 or later\name{getGraphicsEvent}\alias{getGraphicsEvent}\alias{setGraphicsEventHandlers}\alias{getGraphicsEventEnv}\alias{setGraphicsEventEnv}\title{Wait for a mouse or keyboard event from a graphics window}\description{This function waits for input from a graphics window in theform of a mouse or keyboard event.}\usage{getGraphicsEvent(prompt = "Waiting for input",onMouseDown = NULL, onMouseMove = NULL,onMouseUp = NULL, onKeybd = NULL,onIdle = NULL,consolePrompt = prompt)setGraphicsEventHandlers(which = dev.cur(), ...)getGraphicsEventEnv(which = dev.cur())setGraphicsEventEnv(which = dev.cur(), env)}\arguments{\item{prompt}{prompt to be displayed to the user in the graphics window}\item{onMouseDown}{a function to respond to mouse clicks}\item{onMouseMove}{a function to respond to mouse movement}\item{onMouseUp}{a function to respond to mouse button releases}\item{onKeybd}{a function to respond to key presses}\item{onIdle}{a function to call when no events are pending}\item{consolePrompt}{prompt to be displayed to the user in the console}\item{which}{which graphics device does the call apply to?}\item{...}{items including handlers to be placed in the event environment}\item{env}{an environment to be used as the event environment}}\details{These functions allow user input from some graphics devices (currentlyonly the \code{windows()}, \code{X11(type = "Xlib")}and \code{X11(type = "cairo")} screen displaysin base \R{}). Event handlers may be installed to respond to eventsinvolving the mouse or keyboard.The functions are related as follows. If any of the first sixarguments to \code{getGraphicsEvent} are given, then it uses thosein a call to \code{setGraphicsEventHandlers} to replace any existinghandlers in the current device. This is for compatibility with pre-2.12.0 \R{}versions. The current normal way to set up event handlers is toset them using \code{setGraphicsEventHandlers} or \code{setGraphicsEventEnv} onone or more graphics devices, and then use \code{getGraphicsEvent()} withno arguments to retrieve event data.\code{getGraphicsEventEnv()} may be used to save the event environmentfor use later.The names of the arguments in \code{getGraphicsEvent} are special. Whenhandling events, the graphics system will look through the eventenvironment for functions named \code{onMouseDown}, \code{onMouseMove},\code{onMouseUp}, \code{onKeybd}, and \code{onIdle}, and use them asevent handlers. It will use\code{prompt} for a label on the graphics device. Two other special names are\code{which}, which will identify the graphics device, and\code{result}, where the result of the last eventhandler will be stored before being returned by \code{getGraphicsEvent()}.The mouse event handlers should be functions with header\code{function(buttons, x, y)}. The coordinates \code{x}and \code{y} will be passed to mouse event handlers in device independentcoordinates (i.e., the lower left corner of the window is \code{(0,0)},the upper right is \code{(1,1)}). The \code{buttons} argumentwill be a vector listing the buttonsthat are pressed at the time of the event, with 0 for left, 1 for middle, and 2for right.The keyboard event handler should be a function with header\code{function(key)}. A single element character vector will be passedto this handler, corresponding to the key press. Shift and other modifierkeys will have been processed, so \code{shift-a} will be passed as\code{"A"}. The following special keys may also be passed to the handler:\itemize{\item Control keys, passed as \code{"Ctrl-A"}, etc.\item Navigation keys, passed as one of\cr\code{"Left", "Up", "Right", "Down", "PgUp", "PgDn", "End", "Home"}\item Edit keys, passed as one of \code{"Ins", "Del"}\item Function keys, passed as one of \code{"F1", "F2", ...}}The idle event handler \code{onIdle} should be a function with noarguments. If the function is undefined or \code{NULL}, then R willtypically call a system function which (efficiently) waits for the nextevent to appear on a filehandle. Otherwise, the idle event handler willbe called whenever the event queue of the graphics device was found tobe empty, i.e. in an infinite loop. This feature is intended to allowanimations to respond to user input, and could be CPU-intensive.Currently, \code{onIdle} is only implemented for \code{X11()} devices.Note that calling \code{Sys.sleep()} is not recommended within an idlehandler - \code{Sys.sleep()} removes pending graphics events in order toallow users to move, close, or resize windows while it is executing.Events such as mouse and keyboard events occurring during\code{Sys.sleep()} are lost, and currently do not trigger the eventhandlers registered via \code{getGraphicsEvent} or\code{setGraphicsEventHandlers}.The event handlers are standard R functions, and will be executed as though calledfrom the event environment.In an interactive session, events will be processed until\itemize{\item one of the event handlers returnsa non-\code{NULL} value which will be returned as the value of\code{getGraphicsEvent}, or\item the user interrupts the function from theconsole.}}\value{When run interactively,\code{getGraphicsEvent} returns a non-\code{NULL} value returned from one of the event handlers.In a non-interactive session, \code{getGraphicsEvent} will return \code{NULL} immediately. Itwill also return \code{NULL} if the user closes the last window that has graphics handlers.\code{getGraphicsEventEnv} returns the current event environment for the graphics device,or \code{NULL} if none has been set.\code{setGraphicsEventEnv} and \code{setGraphicsEventHandlers} return the previousevent environment for the graphics device.}\author{Duncan Murdoch}\examples{# This currently only works on the Windows, X11(type = "Xlib"), and# X11(type = "cairo") screen devices...\dontrun{savepar <- par(ask = FALSE)dragplot <- function(..., xlim = NULL, ylim = NULL, xaxs = "r", yaxs = "r") {plot(..., xlim = xlim, ylim = ylim, xaxs = xaxs, yaxs = yaxs)startx <- NULLstarty <- NULLprevx <- NULLprevy <- NULLusr <- NULLdevset <- function()if (dev.cur() != eventEnv$which) dev.set(eventEnv$which)dragmousedown <- function(buttons, x, y) {startx <<- xstarty <<- yprevx <<- 0prevy <<- 0devset()usr <<- par("usr")eventEnv$onMouseMove <- dragmousemoveNULL}dragmousemove <- function(buttons, x, y) {devset()deltax <- diff(grconvertX(c(startx, x), "ndc", "user"))deltay <- diff(grconvertY(c(starty, y), "ndc", "user"))if (abs(deltax-prevx) + abs(deltay-prevy) > 0) {plot(..., xlim = usr[1:2]-deltax, xaxs = "i",ylim = usr[3:4]-deltay, yaxs = "i")prevx <<- deltaxprevy <<- deltay}NULL}mouseup <- function(buttons, x, y) {eventEnv$onMouseMove <- NULL}keydown <- function(key) {if (key == "q") return(invisible(1))eventEnv$onMouseMove <- NULLNULL}setGraphicsEventHandlers(prompt = "Click and drag, hit q to quit",onMouseDown = dragmousedown,onMouseUp = mouseup,onKeybd = keydown)eventEnv <- getGraphicsEventEnv()}dragplot(rnorm(1000), rnorm(1000))getGraphicsEvent()par(savepar)}}\keyword{iplot}