# Cursor

A cursor is a small pixbuf [gr/pix] drawn on top of a bigger one and that can
move around. The challenge here is to be able to draw what was "under" the
cursor when the cursor moves.

The idea is that the cursor has a temporary pixbuf that holds the image *under*
it. When it is initialized, it copies the contents of its "parent" buffer into
itself, then it draws itself into the parent buffer.

When the cursor moves, it copies back its contents into the parent buffer, then
moves itself, then copies the contents of the parent buffer into itself, and
then draws itself into the parent.

When the parent draws anything, it checks if the drawing touches the cursor
area. If it does, before drawing, it offloads its content into the parent, then
the parent draws its thing, then the cursor refreshes its buffer and draws
itself again.

By default, the cursor is drawn as a simple rectangle of a single color, but
whatever you draw into it becomes the new cursor.

## Global cursor and mouse

This unit supplies a "cursor" value which is a pointer to the "global" cursor
and it supplies a ready-to-loopadd word "handlemouse", which ties "cursor" to
"mouse" [io/mouse].

Therefore, on a typical system, what you'll want to do is to set "mouse", set
"cursor" and then add "handlemouse" to your loop [lib/loop]. You then have a
moving cursor. Example code:

  needs lib/loop gr/cursor io/mouse
  screen newcursor to cursor
  newmousefromdriver to mouse
  screen width screen height 1 configuremouse
  ' handlemouse loopadd

## API

### Values

cursor  Pointer to the global cursor

### Struct

extends Pixbuf struct Cursor
  fields parent tmppix curx cury
endstruct

parent  The pixbuf upon which this cursor is drawn
tmppix  A pixbuf where the parent content under the cursor is kept
curx    Current X position of the cursor within the parent
cury    Current Y position of the cursor within the parent

### Words

newcursor ( parent -- cursor )
  Create a new cursor. Allocates a buffer, initializes itself to pos 0,0 and
  makes its first initial copy of the parent buffer.

movecursor ( x y cursor -- )
  Copies cursor's buffer to parent at old position, move cursor then copy
  parent buffer into cursor at new position, then draw the cursor at new
  position.

handlemouse ( -- )
  Calls "mouseupdate" [io/mouse] and then sets "cursor" to the new mouse
  position, unless mouse is currently hidden with "hidemouse".

hidemouse ( -- )
  Until "showmouse" is called, inhibits "handlemouse" from updating cursor.

showmouse ( -- )
  Undo "hidemouse" effect.
