pdlua graphics
===

pdlua's graphics allow you to draw basic vector graphics and receive mouse events on pure-data and plugdata. Drawing functions are prefixed with 'gfx.', and should only be called from within the "paint" function.

NOTE: The "paint" method (see below) is required by all pdlua objects which want to utilize the graphics interface. Defining it automatically puts the object into graphics mode in which all graphics routines work as described below.


Painting:
--------------
You can paint by defining the "paint" function, for example:

function yourclass:paint(g)
    g:set_color(250, 200, 240)
    g:fill_all()
end


Mouse Events:
--------------
You can receive mouse events by defining the "mouse_down", "mouse_up", "mouse_move" and "mouse_drag" functions. Both pass the x,y coordinates as arguments. For example:

function yourclass:mouse_down(x, y)
    pd.post(tostring(x))
    pd.post(tostring(y))
end


API overview
--------------
-- Callback functions you can define

pd:Class:mouse_down(x, y)                                           -- Mouse down callback, called when the mouse is clicked
pd:Class:mouse_up(x, y)                                             -- Mouse up callback, called when the mouse button is released
pd:Class:mouse_move(x, y)                                           -- Mouse move callback, called when the mouse is moved while not being down
pd:Class:mouse_drag(x, y)                                           -- Mouse drag callback, called when the mouse is moved while also being down

-- Functions you can call
pd:Class:repaint()                                                -- Request a repaint, after this the "paint" callback will occur
pd:Class:paint(g)                                                 -- Paint callback, returns a graphics_context object (commonly called g) that you can call these drawing functions on:
g:set_size(w, h)                                                  -- Sets the size of the object.
width, height = g:get_size(w, h)                                  -- Gets the size of the object.

g:set_color(r, g, b, a=1.0)                                       -- Sets the color for the next drawing operation.

g:fill_ellipse(x, y, w, h)                                        -- Draws a filled ellipse at the specified position and size.
g:stroke_ellipse(x, y, w, h, line_width)                          -- Draws the outline of an ellipse at the specified position and size.

g:fill_rect(x, y, w, h)                                           -- Draws a filled rectangle at the specified position and size.
g:stroke_rect(x, y, w, h, line_width)                             -- Draws the outline of a rectangle at the specified position and size.

g:fill_rounded_rect(x, y, w, h, corner_radius)                    -- Draws a filled rounded rectangle at the specified position and size.
g:stroke_rounded_rect(x, y, w, h, corner_radius, line_width)      -- Draws the outline of a rounded rectangle at the specified position and size.

g:draw_line(x1, y1, x2, y2)                                       -- Draws a line between two points.
g:draw_text(text, x, y, w, fontsize)                              -- Draws text at the specified position and size.

g:fill_all()                                                      -- Fills the entire drawing area with the current color. Also will draw an object outline in the style of the host (ie. pure-data or plugdata)

g:translate(tx, ty)                                               -- Translates the coordinate system by the specified amounts.
g:scale(sx, sy)                                                   -- Scales the coordinate system by the specified factors. This will always happen after the translation
g:reset_transform()                                               -- Resets current scale and translation

p = Path(x, y)                                                    -- Initiates a new path at the specified point
p:line_to(x, y)                                                   -- Adds a line segment to the path.
p:quad_to(x1, y1, x2, y2)                                         -- Adds a quadratic Bezier curve to the path.
p:cubic_to(x1, y1, x2, y2, x3, y)                                 -- Adds a cubic Bezier curve to the path.
p:close_path()                                                    -- Closes the path.

g:stroke_path(p, line_width)                                      -- Draws the outline of the path with the specified line width.
g:fill_path(p)                                                    -- Fills the current path.

Basic example
---------------------

-- Create an object named "example"
local example = pd.Class:new():register("example")

function example:initialize(sel, atoms)
    self.inlets = 1
    self.circle_x = 10
    self.circle_y = 10

    return true
end

-- Receive mouse drag events
function example:mouse_drag(x, y)
    -- Set circle position
    self.circle_x = x - 15
    self.circle_y = y - 15

    -- Request a repaint
    self:repaint()
end

function example:paint()
    -- Fill background with color
    gfx.set_color(255, 0, 0, 1)
    gfx.fill_all()

    -- Draw an ellipse
    gfx.set_color(0, 255, 0, 1)
    gfx.fill_ellipse(self.circle_x, self.circle_y, 30, 30)
end
