clutterhs-0.1: Graphics/UI/Clutter/BindingPool.chs
-- -*-haskell-*-
-- Clutter BindingPool
--
-- Author : Matthew Arsenault
--
-- Created: 11 Sep 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" #}
-- | Key Bindings — Pool for key bindings
module Graphics.UI.Clutter.BindingPool (
-- * Description
-- | BindingPool is a data structure holding a
-- set of key bindings. Each key binding associates a key symbol
-- (eventually with modifiers) to an action. A callback function is
-- associated to each action.
--
-- For a given key symbol and modifier mask combination there can be
-- only one action; for each action there can be only one
-- callback. There can be multiple actions with the same name, and the
-- same callback can be used to handle multiple key bindings.
--
-- Actors requiring key bindings should create a new
-- 'BindingPool' inside their class initialization function and
-- then install actions like this:
--
-- TODO: Replace C example
{-
-- @
-- static void
-- foo_class_init (FooClass *klass)
-- {
-- ClutterBindingPool *binding_pool;
--
-- binding_pool = clutter_binding_pool_get_for_class (klass);
--
-- clutter_binding_pool_install_action (binding_pool, "move-up",
-- CLUTTER_Up, 0,
-- G_CALLBACK (foo_action_move_up),
-- NULL, NULL);
-- clutter_binding_pool_install_action (binding_pool, "move-up",
-- CLUTTER_KP_Up, 0,
-- G_CALLBACK (foo_action_move_up),
-- NULL, NULL);
-- }
-- The callback has a signature of:
--
-- gboolean (* callback) (GObject *instance,
-- const gchar *action_name,
-- guint key_val,
-- ClutterModifierType modifiers,
-- gpointer user_data);
--
-- The actor should then override the \"key-press-event\" and use
-- 'bindingPoolActivate' to match a 'KeyEvent'
-- structure to one of the actions:
--
-- ClutterBindingPool *pool;
--
-- /* retrieve the binding pool for the type of the actor */
-- pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
--
-- /* activate any callback matching the key symbol and modifiers
-- * mask of the key event. the returned value can be directly
-- * used to signal that the actor has handled the event.
-- */
-- return clutter_binding_pool_activate (pool, G_OBJECT (actor),
-- key_event->keyval,
-- key_event->modifier_state);
--
-- @
-}
-- The 'bindingPoolActivate' function will return @False@ if no action
-- for the given key binding was found, if the action was blocked
-- (using 'bindingPoolBlockAction') or if the key binding handler
-- returned @False@.
--
-- 'BindingPool' is available since Clutter 1.0
--
-- * Class Hierarchy
-- |
-- @
-- | 'GObject'
-- | +----'BindingPool'
-- @
-- * Types
BindingPool,
--BindingActionFunc,
-- * Constructors
bindingPoolNew,
-- * Methods
--bindingPoolGetForClass,
bindingPoolFind,
bindingPoolInstallAction,
--bindingPoolInstallClosure,
bindingPoolOverrideAction,
--bindingPoolOverrideClosure,
bindingPoolFindAction,
bindingPoolRemoveAction,
bindingPoolBlockAction,
bindingPoolUnblockAction,
bindingPoolActivate
) where
{# import Graphics.UI.Clutter.Types #}
{# import Graphics.UI.Clutter.Utility #}
import C2HS
import System.Glib.GObject
import System.Glib.FFI
type KeyVal = Word
--TODO: Private, don't document
maybeBindingPool = maybeNullNew newBindingPool
-- | Creates a new 'BindingPool' that can be used to store key
-- bindings for an actor. The name must be a unique identifier for
-- the binding pool, so that 'bindingPoolFind' will be able to
-- return the correct binding pool.
--
-- [@name@] the name of the binding pool
--
-- [@Returns@] the newly created binding pool with the given name.
--
-- * Since 1.0
--
{# fun unsafe binding_pool_new as ^ { `String' } -> `BindingPool' newBindingPool* #}
--I don't understand this function. Looks dirty though.
--{# fun unsafe binding_pool_get_for_class as ^ {} -> `BindingPool' newBindingPool* #}
{# fun unsafe binding_pool_find as ^ { `String' } -> `Maybe BindingPool' maybeBindingPool* #}
bindingPoolInstallAction :: BindingPool -> String -> KeyVal -> [ModifierType] -> GCallback -> IO ()
bindingPoolInstallAction bp name keyval modif gCB = withBindingPool bp $ \bpPtr ->
withCString name $ \namePtr ->
--CHECKME: unsafe? Most likely safe, callback
let func = {# call binding_pool_install_action #}
mod = cFromModFlags modif
kc = cIntConv keyval
in do
gcbPtr <- newGCallback gCB
func bpPtr namePtr kc mod gcbPtr (castFunPtrToPtr gcbPtr) destroyFunPtr
bindingPoolOverrideAction :: BindingPool -> KeyVal -> [ModifierType] -> GCallback -> IO ()
bindingPoolOverrideAction bp keyval modif gCB = withBindingPool bp $ \bpPtr ->
--CHECKME: unsafe? Most likely safe, callback
let func = {# call binding_pool_override_action #}
mod = cFromModFlags modif
kc = cIntConv keyval
in do
gcbPtr <- newGCallback gCB
func bpPtr kc mod gcbPtr (castFunPtrToPtr gcbPtr) destroyFunPtr
{# fun unsafe binding_pool_find_action as ^
{ withBindingPool* `BindingPool', cIntConv `KeyVal', cFromModFlags `[ModifierType]' } -> `Maybe String' maybeString* #}
--FIXME: make list of modifiers, cFromFlags won't work since Flags instance won't work for ModifierType
-- | Removes the action matching the given key_val, modifiers pair, if
-- any exists.
--
-- [@pool@] a 'BindingPool'
--
-- [@key_val@] a key symbol
--
-- [@modifiers@] a list of modifiers
--
-- * Since 1.0
--
{# fun unsafe binding_pool_remove_action as ^
{ withBindingPool* `BindingPool', cIntConv `KeyVal', cFromModFlags `[ModifierType]' } -> `()' #}
-- | Blocks all the actions with name action_name inside pool.
--
-- [@pool@] a 'BindingPool'
--
-- [@action_name@] an action name
--
-- * Since 1.0
--
{# fun unsafe binding_pool_block_action as ^
{ withBindingPool* `BindingPool', `String' } -> `()' #}
-- | Unblocks all the actions with name action_name inside pool.
--
-- Unblocking an action does not cause the callback bound to it to be
-- invoked in case 'bindingPoolActivate' was called on an
-- action previously blocked with 'bindingPoolBlockAction'.
--
-- [@pool@] a 'BindingPool'
--
-- [@action_name@] an action name
--
-- * Since 1.0
--
{# fun unsafe binding_pool_unblock_action as ^
{ withBindingPool* `BindingPool', `String' } -> `()' #}
-- | Activates the callback associated to the action that is bound to the key_val and modifiers pair.
--
-- The callback has the following signature:
--
-- @
-- void (* callback) (GObject *gobject,
-- const gchar *action_name,
-- guint key_val,
-- ClutterModifierType modifiers,
-- gpointer user_data);
-- @
--
-- Where the GObject instance is gobject and the user data is the one
-- passed when installing the action with
-- 'bindingPoolInstallAction'.
--
-- If the action bound to the key_val, modifiers pair has been blocked
-- using 'bindingPoolBlockAction', the callback will not be
-- invoked, and this function will return @False@.
--
-- [@pool@] a 'BindingPool'
--
-- [@key_val@] the key symbol
--
-- [@modifiers@] bitmask for the modifiers
--
-- [@gobject@] a 'GObject'
--
-- [@Returns@] @True@ if an action was found and was activated
--
-- * Since 1.0
--
{# fun unsafe binding_pool_activate as ^ `(GObjectClass gobject)' =>
{ withBindingPool* `BindingPool',
cIntConv `KeyVal',
cFromModFlags `[ModifierType]',
withGObject* `gobject' } -> `Bool' #}