clutterhs-0.1: Graphics/UI/Clutter/Behaviour.chs
-- -*-haskell-*-
-- Clutter Behaviour
--
-- Author : Matthew Arsenault
--
-- Created: 2 Oct 2009
--
-- Copyright (C) 2009 Matthew Arsenault
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 3 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
{-# LANGUAGE ForeignFunctionInterface #-}
#include <clutter/clutter.h>
{# context lib="clutter" prefix="clutter" #}
-- | Class for providing behaviours to actors
module Graphics.UI.Clutter.Behaviour (
-- * Description
-- | 'Behaviour' is the base class for implementing behaviours. A
-- behaviour is a controller object for Actors; you can use a
-- behaviour to control one or more properties of an actor (such as
-- its opacity, or its position). A 'Behaviour' is driven by an
-- "alpha function" stored inside a 'Alpha' object; an alpha
-- function is a function depending solely on time. The alpha
-- function computes a value which is then applied to the properties
-- of the actors driven by a behaviour.
--
-- Clutter provides some pre-defined behaviours, like
-- 'BehaviourPath', which controls the position of a set of actors
-- making them "walk" along a set of nodes; 'BehaviourOpacity',
-- which controls the opacity of a set of actors; 'BehaviourScale',
-- which controls the width and height of a set of actors.
--
-- To visualize the effects of different alpha functions on a
-- 'Behaviour' implementation it is possible to take the
-- 'BehaviourPath' as an example:
--
-- * Figure 4. Effects of alpha functions on a path
-- <<file:///home/matt/src/clutterhs/doc/path-alpha-func.png>>
--
-- The actors position between the path's end points directly
-- correlates to the ClutterAlpha's current alpha value driving the
-- behaviour. With the ClutterAlpha's function set to 'AlphaRampInc'
-- the actor will follow the path at a constant velocity, but when
-- changing to 'AlphaSineInc' the actor initially accelerates before
-- quickly decelerating.
--
-- In order to implement a new behaviour you should subclass
-- 'Behaviour' and override the "alpha_notify" virtual function;
-- inside the overridden function you should obtain the alpha value
-- from the 'Alpha' instance bound to the behaviour and apply it
-- to the desiderd property (or properties) of every actor controlled
-- by the behaviour.
--
-- 'Behaviour' is available since Clutter 0.2
--
-- * Class Hierarchy
-- |
-- @
-- | 'GObject'
-- | +----'Behaviour'
-- | +----'BehaviourDepth'
-- | +----'BehaviourEllipse'
-- | +----'BehaviourOpacity'
-- | +----'BehaviourPath'
-- | +----'BehaviourRotate'
-- | +----'BehaviourScale'
-- @
-- * Types
Behaviour,
BehaviourClass,
BehaviourForeachFunc,
-- * Methods
behaviourApply,
behaviourRemove,
behaviourRemoveAll,
behaviourIsApplied,
behaviourActorsForeach,
behaviourGetActors, --Set actors??
behaviourGetNActors,
behaviourGetNthActor,
behaviourGetAlpha,
behaviourSetAlpha,
-- * Attributes
behaviourAlpha,
-- * Signals
onApplied,
afterApplied,
applied,
onRemoved,
afterRemoved,
removed
) where
{# import Graphics.UI.Clutter.Types #}
{# import Graphics.UI.Clutter.Signals #}
{# import Graphics.UI.Clutter.Utility #}
import C2HS
import System.Glib.Attributes
-- | Applies behave to actor. This function adds a reference on the actor.
--
-- [@behave@] a Behaviour
--
-- [@actor@] an Actor
--
-- * Since 0.2
--
{# fun unsafe behaviour_apply as ^ `(BehaviourClass behave, ActorClass actor)' =>
{ withBehaviourClass* `behave', withActorClass* `actor' } -> `()' #}
-- | Removes actor from the list of Actors to which behave
-- applies. This function removes a reference on the actor.
--
-- [@behave@] a Behaviour
--
-- [@actor@] an Actor
--
-- * Since 0.2
--
{# fun unsafe behaviour_remove as ^ `(BehaviourClass behave, ActorClass actor)' =>
{ withBehaviourClass* `behave', withActorClass* `actor' } -> `()' #}
-- | Removes every actor from the list that behave holds.
--
-- [@behave@] a Behaviour
--
-- * Since 0.4
--
{# fun unsafe behaviour_remove_all as ^ `(BehaviourClass behave)' =>
{ withBehaviourClass* `behave' } -> `()' #}
-- | Check if behave applied to actor.
--
-- [@behave@] a Behaviour
--
-- [@actor@] an Actor
--
-- [@Returns@] @True@ if actor has behaviour. @False@ otherwise.
--
-- * Since 0.4
--
{# fun unsafe behaviour_is_applied as ^ `(BehaviourClass behave, ActorClass actor)' =>
{ withBehaviourClass* `behave', withActorClass* `actor' } -> `Bool' #}
-- | Calls func for every actor driven by behave.
--
-- [@behave@] a Behaviour
--
-- [@func@] a function called for each actor
--
-- * Since 0.2
--
behaviourActorsForeach :: (BehaviourClass behave) => behave -> BehaviourForeachFunc -> IO ()
behaviourActorsForeach b func = withBehaviourClass b $ \bptr -> do
funcPtr <- newBehaviourForeachFunc func
{# call unsafe behaviour_actors_foreach #} bptr funcPtr nullPtr
freeHaskellFunPtr funcPtr
--CHECKME: unsafe?
--TODO: We could make a rw attribute even though clutter doesn't do that.
-- | Retrieves all the actors to which behave applies. It is not
-- recommended for derived classes to use this in there alpha notify
-- method but use behaviourActorsForeach as it avoids alot of
-- needless allocations.
--
-- [@behave@] a Behaviour
--
-- [@Returns@] a list of actors to which the behaviour applies.
--
-- * Since 0.2
--
{# fun unsafe behaviour_get_actors as ^
`(BehaviourClass behave)' => { withBehaviourClass* `behave' } -> `[Actor]' newActorList* #}
-- | Gets an actor the behaviour was applied to referenced by index
-- num.
--
-- [@behave@] a Behaviour
--
-- [@index@] the index of an actor to which this behaviour is applied.
--
-- [@Returns@] an @Just@ an Actor, or @Nothing@ if index is invalid.
--
-- * Since 0.2
--
{# fun unsafe behaviour_get_nth_actor as ^
`(BehaviourClass behave)' => { withBehaviourClass* `behave', `Int' } -> `Maybe Actor' maybeNewActor* #}
-- | Gets the number of actors this behaviour is applied too.
--
-- [@behave@] a Behaviour
--
-- [@Returns@] The number of applied actors
--
-- * Since 0.2
--
{# fun unsafe behaviour_get_n_actors as ^
`(BehaviourClass behave)' => { withBehaviourClass* `behave' } -> `Int' #}
-- | Retrieves the 'Alpha' object bound to behave.
--
-- [@behave@] a 'Behaviour'
--
-- [@Returns@] @Just@ The Alpha or @Nothing@
--
-- * Since 0.2
--
{# fun unsafe behaviour_get_alpha as ^
`(BehaviourClass behave)' => { withBehaviourClass* `behave' } -> `Maybe Alpha' maybeNewAlpha* #}
-- | Binds alpha to a Behaviour. The 'Alpha' object is what makes a
-- behaviour work: for each tick of the timeline used by 'Alpha' a
-- new value of the alpha parameter is computed by the alpha
-- function; the value should be used by the 'Behaviour' to update
-- one or more properties of the actors to which the behaviour
-- applies.
--
-- | If alpha is not @Nothing@, the Behaviour will take ownership of
-- the 'Alpha' instance.
--
-- [@behave@] a Behaviour
--
-- [@alpha@] @Just@ an Alpha or @Nothing@ to unset a previously set α
--
-- * Since 0.2
--
{# fun unsafe behaviour_set_alpha as ^
`(BehaviourClass behave)' => { withBehaviourClass* `behave', withMaybeAlpha* `Maybe Alpha' } -> `()' #}
-- | The 'Α' object used to drive this behaviour. An 'Alpha' object
-- binds a 'Timeline' and a function which computes a value (the
-- "alpha") depending on the time. Each time the alpha value changes
-- the alpha-notify virtual function is called.
--
-- * Since 0.2
--
behaviourAlpha :: (BehaviourClass self) => Attr self (Maybe Alpha)
behaviourAlpha = newNamedAttr "alpha" behaviourGetAlpha behaviourSetAlpha
onApplied, afterApplied :: (BehaviourClass behave) => behave -> (Actor -> IO ()) -> IO (ConnectId behave)
onApplied = connect_OBJECT__NONE "applied" False
afterApplied = connect_OBJECT__NONE "applied" True
-- | The ::apply signal is emitted each time the behaviour is applied to an actor.
--
-- [@actor@] the actor the behaviour was applied to.
--
-- * Since 0.4
--
applied :: (BehaviourClass behave) => Signal behave (Actor ->IO ())
applied = Signal (connect_OBJECT__NONE "applied")
onRemoved, afterRemoved :: (BehaviourClass behave) => behave -> (Actor -> IO ()) -> IO (ConnectId behave)
onRemoved = connect_OBJECT__NONE "removed" False
afterRemoved = connect_OBJECT__NONE "removed" True
-- | The ::removed signal is emitted each time a behaviour is not
-- applied to an actor anymore.
--
-- [@actor@] the removed actor
--
removed :: (BehaviourClass behave) => Signal behave (Actor ->IO ())
removed = Signal (connect_OBJECT__NONE "removed")