packages feed

processing 1.0.0.1 → 1.0.1.0

raw patch · 8 files changed

+332/−15 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Graphics.Web.Processing.Core.Interface: ALT :: KeyModifier
+ Graphics.Web.Processing.Core.Interface: ArrowKey :: ArrowKey -> Key
+ Graphics.Web.Processing.Core.Interface: BACKSPACE :: SpecialKey
+ Graphics.Web.Processing.Core.Interface: CONTROL :: KeyModifier
+ Graphics.Web.Processing.Core.Interface: CharKey :: Char -> Key
+ Graphics.Web.Processing.Core.Interface: DOWN :: ArrowKey
+ Graphics.Web.Processing.Core.Interface: ENTER :: SpecialKey
+ Graphics.Web.Processing.Core.Interface: ESC :: SpecialKey
+ Graphics.Web.Processing.Core.Interface: LEFT :: ArrowKey
+ Graphics.Web.Processing.Core.Interface: ModKey :: KeyModifier -> Key -> Key
+ Graphics.Web.Processing.Core.Interface: RETURN :: SpecialKey
+ Graphics.Web.Processing.Core.Interface: RIGHT :: ArrowKey
+ Graphics.Web.Processing.Core.Interface: SHIFT :: KeyModifier
+ Graphics.Web.Processing.Core.Interface: SpecialKey :: SpecialKey -> Key
+ Graphics.Web.Processing.Core.Interface: TAB :: SpecialKey
+ Graphics.Web.Processing.Core.Interface: UP :: ArrowKey
+ Graphics.Web.Processing.Core.Interface: data ArrowKey
+ Graphics.Web.Processing.Core.Interface: data Key
+ Graphics.Web.Processing.Core.Interface: data KeyModifier
+ Graphics.Web.Processing.Core.Interface: data SpecialKey
+ Graphics.Web.Processing.Core.Interface: matchKey :: (ProcMonad m, Monad (m KeyPressed)) => Var Proc_Bool -> Key -> m KeyPressed ()
+ Graphics.Web.Processing.Core.Types: KeyPressed :: KeyPressed
+ Graphics.Web.Processing.Core.Types: data KeyPressed
+ Graphics.Web.Processing.Core.Types: if_ :: ProcType a => Proc_Bool -> a -> a -> a
+ Graphics.Web.Processing.Core.Types: proc_keyPressed :: ProcScript -> Maybe (ProcCode KeyPressed)
+ Graphics.Web.Processing.Mid: instance Context KeyPressed
+ Graphics.Web.Processing.Simple: ALT :: KeyModifier
+ Graphics.Web.Processing.Simple: ArrowKey :: ArrowKey -> Key
+ Graphics.Web.Processing.Simple: BACKSPACE :: SpecialKey
+ Graphics.Web.Processing.Simple: CONTROL :: KeyModifier
+ Graphics.Web.Processing.Simple: CharKey :: Char -> Key
+ Graphics.Web.Processing.Simple: DOWN :: ArrowKey
+ Graphics.Web.Processing.Simple: ENTER :: SpecialKey
+ Graphics.Web.Processing.Simple: ESC :: SpecialKey
+ Graphics.Web.Processing.Simple: LEFT :: ArrowKey
+ Graphics.Web.Processing.Simple: ModKey :: KeyModifier -> Key -> Key
+ Graphics.Web.Processing.Simple: RETURN :: SpecialKey
+ Graphics.Web.Processing.Simple: RIGHT :: ArrowKey
+ Graphics.Web.Processing.Simple: SHIFT :: KeyModifier
+ Graphics.Web.Processing.Simple: SpecialKey :: SpecialKey -> Key
+ Graphics.Web.Processing.Simple: TAB :: SpecialKey
+ Graphics.Web.Processing.Simple: UP :: ArrowKey
+ Graphics.Web.Processing.Simple: data ArrowKey
+ Graphics.Web.Processing.Simple: data Key
+ Graphics.Web.Processing.Simple: data KeyModifier
+ Graphics.Web.Processing.Simple: data SpecialKey
- Graphics.Web.Processing.Core.Types: ProcScript :: ProcCode Preamble -> ProcCode Setup -> Maybe (ProcCode Draw) -> Maybe (ProcCode MouseClicked) -> Maybe (ProcCode MouseReleased) -> ProcScript
+ Graphics.Web.Processing.Core.Types: ProcScript :: ProcCode Preamble -> ProcCode Setup -> Maybe (ProcCode Draw) -> Maybe (ProcCode MouseClicked) -> Maybe (ProcCode MouseReleased) -> Maybe (ProcCode KeyPressed) -> ProcScript
- Graphics.Web.Processing.Simple: interactiveFigure :: CustomValue w => Maybe Int -> Maybe Int -> Int -> w -> (w -> Figure) -> (w -> Color) -> (Proc_Int -> w -> w) -> (Proc_Point -> w -> w) -> ProcScript
+ Graphics.Web.Processing.Simple: interactiveFigure :: CustomValue w => Maybe Int -> Maybe Int -> Int -> w -> (w -> Figure) -> (w -> Color) -> (Proc_Int -> w -> w) -> (Proc_Point -> w -> w) -> [(Key, w -> w)] -> ProcScript

Files

Graphics/Web/Processing/Core/Interface.hs view
@@ -41,6 +41,12 @@    , resetMatrix    -- * Mouse    , getMousePoint+   -- * Keyboard+   , Key (..)+   , ArrowKey (..)+   , KeyModifier (..)+   , SpecialKey (..)+   , matchKey    -- * Conditionals    , iff    -- * Others@@ -54,7 +60,9 @@ -- Internal import Graphics.Web.Processing.Core.Primal import Graphics.Web.Processing.Core.Monad-import Graphics.Web.Processing.Core.Var (readVar)+import Graphics.Web.Processing.Core.Var (writeVar,readVar)+--+import Control.Arrow (first)  ---- PREDEFINED VALUES @@ -289,6 +297,64 @@  x <- readVar $ varFromText "mouseX"  y <- readVar $ varFromText "mouseY"  return (x,y)++---- KEYBOARD++-- | Keyboard keys recognized by Processing.+data Key =+    CharKey Char+  | SpecialKey SpecialKey+  | ArrowKey ArrowKey+  | ModKey KeyModifier Key++-- | Arrow keys.+data ArrowKey = UP | DOWN | LEFT | RIGHT++-- | Key modifiers.+data KeyModifier = ALT | CONTROL | SHIFT++-- | Special keys.+data SpecialKey =+    BACKSPACE+  | TAB+  | ENTER+  | RETURN+  | ESC++--                      CODED                   UNCODED+keySplit :: Key -> ([Proc_KeyCode],Maybe (Either Proc_Key Proc_KeyCode))+keySplit (CharKey c) = ([],Just $ Left $ Key_Char c)+keySplit (SpecialKey BACKSPACE) = ([],Just $ Right $ KeyCode_BACKSPACE)+keySplit (SpecialKey TAB) = ([],Just $ Right $ KeyCode_TAB)+keySplit (SpecialKey ENTER) = ([],Just $ Right $ KeyCode_ENTER)+keySplit (SpecialKey RETURN) = ([],Just $ Right $ KeyCode_RETURN)+keySplit (SpecialKey ESC) = ([],Just $ Right $ KeyCode_ESC)+keySplit (ArrowKey UP) = ([KeyCode_UP], Nothing)+keySplit (ArrowKey DOWN) = ([KeyCode_DOWN], Nothing)+keySplit (ArrowKey LEFT) = ([KeyCode_LEFT], Nothing)+keySplit (ArrowKey RIGHT) = ([KeyCode_RIGHT], Nothing)+keySplit (ModKey m k) =+  let modToKeyCode :: KeyModifier -> Proc_KeyCode+      modToKeyCode ALT = KeyCode_ALT+      modToKeyCode CONTROL = KeyCode_CONTROL+      modToKeyCode SHIFT = KeyCode_SHIFT+  in  first (modToKeyCode m:) $ keySplit k++-- | This function takes a variable of type 'Proc_Bool' and a 'Key', and sets the variable to+--   'true' if the key pressed is the given 'Key'. Otherwise, the variable is set to 'false'.+matchKey :: (ProcMonad m, Monad (m KeyPressed)) => Var Proc_Bool -> Key -> m KeyPressed ()+matchKey v k = do+  let (codedKeys,uncodedKey) = keySplit k+  if null codedKeys+     then return ()+     else iff (Key_Var #== Key_CODED)+              (writeVar v $ foldr1 (#&&) $ fmap (KeyCode_Var #==) codedKeys)+              (writeVar v false)+  b <- readVar v+  case uncodedKey of+    Nothing -> return ()+    Just (Left  pk) -> writeVar v $ Key_Var     #== pk #&& b+    Just (Right ck) -> writeVar v $ KeyCode_Var #== ck #&& b  ---- SETUP 
Graphics/Web/Processing/Core/Primal.hs view
@@ -10,9 +10,10 @@   --   use of certain commands to specific contexts.     Preamble (..), Setup (..), Draw (..)   , MouseClicked (..), MouseReleased (..)-  -- ** Processing types+  , KeyPressed (..)+  -- ** @Proc_*@ types   -- *** Boolean-  , Proc_Bool, fromBool+  , Proc_Bool (..), fromBool   , true, false   , pnot, (#||), (#&&)   -- *** Int@@ -29,6 +30,9 @@   , Proc_Char , fromChar   -- *** Text   , Proc_Text, fromStText+  -- *** Keys+  , Proc_Key (..)+  , Proc_KeyCode (..)   -- ** Type class of proc types   , ProcType (..)   -- ** Conditionals@@ -85,6 +89,9 @@ -- | Code that is executed when the mouse is released. data MouseReleased = MouseReleased +-- | Code executed when a key is pressed.+data KeyPressed = KeyPressed+ -- PRETTY-HELPERS  pfunction :: Text -> [Doc] -> Doc@@ -145,7 +152,12 @@    | Char_NEq Proc_Char Proc_Char      -- Text    | Text_Eq Proc_Text Proc_Text-     deriving Eq+     -- Key+   | Key_Eq Proc_Key Proc_Key+   | KeyCode_Eq Proc_KeyCode Proc_KeyCode+   -- Conditional+ | Bool_Cond Proc_Bool Proc_Bool Proc_Bool+     deriving (Eq,Ord)  instance Extended Bool Proc_Bool where  extend True  = Proc_True @@ -174,6 +186,9 @@ docG :: Doc docG = fromText ">" +docCond :: Doc -> Doc -> Doc -> Doc+docCond _if _then _else = _if <+> fromText "?" <+> _then <+> fromText ":" <+> _else+ indentLevel :: Int indentLevel = 3 @@ -202,6 +217,9 @@  ppr (Char_Eq x y) = parens $ ppr x <+> docEq <+> ppr y  ppr (Char_NEq x y) = parens $ ppr x <+> docNEq <+> ppr y  ppr (Text_Eq x y) = ppr x <> fromText "." <> pfunction "equals" [ppr y]+ ppr (Key_Eq x y) = parens $ ppr x <+> docEq <+> ppr y+ ppr (KeyCode_Eq x y) = parens $ ppr x <+> docEq <+> ppr y+ ppr (Bool_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Value of 'True'. true :: Proc_Bool@@ -245,6 +263,8 @@    -- Functions  | Int_Abs Proc_Int  | Int_Floor Proc_Float+   -- Conditional+ | Int_Cond Proc_Bool Proc_Int Proc_Int    deriving Eq  instance Extended Int Proc_Int where@@ -262,6 +282,7 @@  ppr (Int_Var t) = fromText t  ppr (Int_Abs n) = pfunction "abs" [ppr n]  ppr (Int_Floor x) = pfunction "floor" [ppr x]+ ppr (Int_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Cast an 'Int' value. fromInt :: Int -> Proc_Int@@ -333,6 +354,8 @@  | Float_Floor Proc_Float -- Applies floor but it treats the result                           -- as a float. Only internal.  | Float_Noise Proc_Float Proc_Float+   -- Conditional+ | Float_Cond Proc_Bool Proc_Float Proc_Float    deriving (Eq,Ord)  instance Extended Float Proc_Float where@@ -359,6 +382,7 @@ recFloat f (Float_Arctangent x) = Float_Arctangent $ f x recFloat f (Float_Floor x) = Float_Floor $ f x recFloat f (Float_Noise x y) = Float_Noise (f x) (f y)+recFloat f (Float_Cond b x y) = Float_Cond b (f x) (f y) recFloat _ x = x  instance Pretty Proc_Float where @@ -380,6 +404,7 @@  ppr (Float_Arctangent x) = pfunction "atan" [ppr x]  ppr (Float_Floor x) = pfunction "floor" [ppr x]  ppr (Float_Noise x y) = pfunction "noise" [ppr x,ppr y]+ ppr (Float_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Cast a 'Float' value. fromFloat :: Float -> Proc_Float@@ -400,6 +425,7 @@ intToFloat (Int_Var t) = Float_Var t intToFloat (Int_Abs n) = Float_Abs $ intToFloat n intToFloat (Int_Floor x) = Float_Floor x+intToFloat (Int_Cond b x y) = Float_Cond b (intToFloat x) (intToFloat y)  -- | WARNING: 'signum' method is undefined. instance Num Proc_Float where@@ -434,16 +460,21 @@  atanh = error "Proc_Float: atanh method is undefined."  -- | Type of images.-data Proc_Image = Image_Var Text deriving Eq+data Proc_Image =+   Image_Var Text+ | Image_Cond Proc_Bool Proc_Image Proc_Image+   deriving Eq  instance Pretty Proc_Image where  ppr (Image_Var t) = fromText t+ ppr (Image_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Type of characters. data Proc_Char =    Proc_Char Char  | Char_Var Text-   deriving Eq+ | Char_Cond Proc_Bool Proc_Char Proc_Char+   deriving (Eq,Ord)  instance Extended Char Proc_Char where  extend = Proc_Char@@ -457,12 +488,15 @@ instance Pretty Proc_Char where  ppr (Proc_Char c) = enclose squote squote (char c)  ppr (Char_Var n) = fromText n+ ppr (Char_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Type of textual values. data Proc_Text =    Proc_Text Text  | Text_Var Text-   deriving Eq+   -- Conditional+ | Text_Cond Proc_Bool Proc_Text Proc_Text+   deriving (Eq,Ord)  instance Extended Text Proc_Text where  extend = Proc_Text@@ -470,8 +504,11 @@  patmatch _ = Nothing  instance Pretty Proc_Text where+ -- Wrong pretty-printer for text values. Fix it to+ -- escape characters.  ppr (Proc_Text t) = enclose dquote dquote (fromText t)  ppr (Text_Var n) = fromText n+ ppr (Text_Cond b x y) = parens $ docCond (ppr b) (ppr x) (ppr y)  -- | Cast a strict 'Text' value. fromStText :: Text -> Proc_Text@@ -480,6 +517,52 @@ instance IsString Proc_Text where  fromString = fromStText . fromString +-- | Type of keyboard keys.+data Proc_Key =+   Key_Var+ | Key_CODED+ | Key_Char Char+   deriving (Eq,Ord)++instance Pretty Proc_Key where+ ppr Key_Var = fromText "key"+ ppr Key_CODED = fromText "CODED"+ ppr (Key_Char c) = ppr $ fromChar c++-- | Type of keyboard key codes.+data Proc_KeyCode =+   KeyCode_Var+ | KeyCode_UP+ | KeyCode_DOWN+ | KeyCode_LEFT+ | KeyCode_RIGHT+ | KeyCode_ALT+ | KeyCode_CONTROL+ | KeyCode_SHIFT+ | KeyCode_BACKSPACE+ | KeyCode_TAB+ | KeyCode_ENTER+ | KeyCode_RETURN+ | KeyCode_ESC+ | KeyCode_DELETE+   deriving (Eq,Ord)++instance Pretty Proc_KeyCode where+ ppr KeyCode_Var = fromText "keyCode"+ ppr KeyCode_UP = fromText "UP"+ ppr KeyCode_DOWN = fromText "DOWN"+ ppr KeyCode_LEFT = fromText "LEFT"+ ppr KeyCode_RIGHT = fromText "RIGHT"+ ppr KeyCode_ALT = fromText "ALT"+ ppr KeyCode_CONTROL = fromText "CONTROL"+ ppr KeyCode_SHIFT = fromText "SHIFT"+ ppr KeyCode_BACKSPACE = fromText "BACKSPACE"+ ppr KeyCode_TAB = fromText "TAB"+ ppr KeyCode_ENTER = fromText "ENTER"+ ppr KeyCode_RETURN = fromText "RETURN"+ ppr KeyCode_ESC = fromText "ESC"+ ppr KeyCode_DELETE = fromText "DELETE"+ -- CODE  -- | A piece of Processing code.@@ -612,7 +695,27 @@  ----- CLASSES --- | Class of Processing value types.+-- | Class of Processing value types (@Proc_*@ types).+--+--   @Proc_*@ types are types from the world of Processing.+--   Some of them are similar to Haskell types, like 'Proc_Bool'+--   and 'Bool'. However, they are not equal. @Proc_*@ types+--   are instance of 'Eq'. However, you should instead use methods from+--   analog 'Proc_Eq' class. @Proc_*@ types contain expressions instead+--   of values. Think of @2+2@ instead of @4@. Under this situation,+--   @2+2 /= 3+1@, since they are different expressions, even if they+--   evaluate to the same value. Actually, you will get 'True'+--   from the evaluation of @2+2 == 3+1@, since the library is smart+--   enough to figure out they are the same value. But, please, don't+--   rely on this. Use the 'Proc_Eq' and 'Proc_Ord' classes instead.+--   They return Processing boolean expressions instead of 'Bool' values.+--   Anyway, the types of the library will try to force you to use @Proc_*@+--   types everywhere.+--+--   The reason this library stores expressions instead of values is that+--   it needs to handle things like @2+x@, where @x@ is an unknown value.+--   However, an effort is done to ensure that each expression is reduced+--   to its minimum extension. class ProcType a where  -- | Create a variable assignment, provided  --   the name of the variable and the value to asign.@@ -621,36 +724,44 @@  proc_arg :: a -> ProcArg  -- | Variable reading.  proc_read :: Var a -> a+ -- | Conditional value.+ proc_cond :: Proc_Bool -> a -> a -> a  instance ProcType Proc_Bool where  proc_asign = BoolAsign  proc_arg = BoolArg  proc_read (Var v) = Bool_Var v+ proc_cond = Bool_Cond  instance ProcType Proc_Int where  proc_asign = IntAsign  proc_arg = IntArg  proc_read (Var v) = Int_Var v+ proc_cond = Int_Cond  instance ProcType Proc_Float where  proc_asign = FloatAsign  proc_arg = FloatArg  proc_read (Var v) = Float_Var v+ proc_cond = Float_Cond  instance ProcType Proc_Image where  proc_asign = ImageAsign  proc_arg = ImageArg  proc_read (Var v) = Image_Var v+ proc_cond = Image_Cond  instance ProcType Proc_Char where  proc_asign = CharAsign  proc_arg = CharArg  proc_read (Var v) = Char_Var v+ proc_cond = Char_Cond  instance ProcType Proc_Text where  proc_asign =  TextAsign  proc_arg = TextArg  proc_read (Var v) = Text_Var v+ proc_cond = Text_Cond  infix 4 #==, #/= @@ -681,6 +792,12 @@ instance Proc_Eq Proc_Text where  (#==) = Text_Eq +instance Proc_Eq Proc_Key where+ (#==) = Key_Eq++instance Proc_Eq Proc_KeyCode where+ (#==) = KeyCode_Eq+ infix 4 #<=, #<, #>=, #>  -- | 'Ord' class for @Proc_*@ values.@@ -809,6 +926,7 @@  , proc_draw  :: Maybe (ProcCode Draw)  , proc_mouseClicked :: Maybe (ProcCode MouseClicked)  , proc_mouseReleased :: Maybe (ProcCode MouseReleased)+ , proc_keyPressed :: Maybe (ProcCode KeyPressed)    }  -- | Empty script.@@ -819,6 +937,7 @@  , proc_draw = Nothing  , proc_mouseClicked = Nothing  , proc_mouseReleased = Nothing+ , proc_keyPressed = Nothing    }  pvoid :: Pretty a => Text -> Maybe a -> Doc@@ -834,4 +953,5 @@    , pvoid "draw" $ proc_draw ps    , pvoid "mouseClicked" $ proc_mouseClicked ps    , pvoid "mouseReleased" $ proc_mouseReleased ps+   , pvoid "keyPressed" $ proc_keyPressed ps      ]
Graphics/Web/Processing/Core/Types.hs view
@@ -15,7 +15,8 @@   , Draw (..)   , MouseClicked (..)   , MouseReleased (..)-  -- * Processing types+  , KeyPressed (..)+  -- * @Proc_*@ types   , ProcType   -- ** Bool   , Proc_Bool, true, false@@ -40,6 +41,8 @@   -- * Processing classes   , Proc_Eq (..)   , Proc_Ord (..)+  -- * Conditional values+  , if_   ) where  import Graphics.Web.Processing.Core.Primal@@ -58,3 +61,7 @@ --   write it directly in a file. renderFile :: FilePath -> ProcScript -> IO () renderFile fp = T.writeFile fp . renderScript++-- | Conditional value.+if_ :: ProcType a => Proc_Bool -> a -> a -> a+if_ = proc_cond
Graphics/Web/Processing/Mid.hs view
@@ -122,8 +122,10 @@  assignM = addCode . assignM  writeComment = addCode . writeComment  iff b (EventM e1) (EventM e2) = do-   let s1 = execState e1 emptyEventState-       s2 = execState e2 emptyEventState+   n0 <- liftProc getVarNumber+   let s1 = execState e1 $ emptyEventState { event_code = setVarNumber n0 }+       n1 = fst $ runProcMWith n0 $ event_code s1 >> getVarNumber+       s2 = execState e2 $ EventState { event_preamble = return () , event_code = setVarNumber n1 }    addPCode $ event_preamble s1    addPCode $ event_preamble s2    addCode $ iff b (event_code s1) (event_code s2)@@ -137,10 +139,11 @@     , script_draw :: Maybe (ProcM Draw ())     , script_mouseClicked :: Maybe (ProcM MouseClicked ())     , script_mouseReleased :: Maybe (ProcM MouseReleased ())+    , script_keyPressed :: Maybe (ProcM KeyPressed ())       }  emptyScriptState :: ScriptState c-emptyScriptState = ScriptState (return ()) Nothing Nothing Nothing Nothing+emptyScriptState = ScriptState (return ()) Nothing Nothing Nothing Nothing Nothing  -- | Scripter monad. This monad is where Processing code is written. --   Because of some implementation details, 'ScriptM' has a context @c@.@@ -178,6 +181,7 @@                      (f script_draw)                      (f script_mouseClicked)                      (f script_mouseReleased)+                     (f script_keyPressed)  -- | Context of an event. The context determines which functions can be used. --   'Preamble' is not an instance of 'Context' to avoid using 'Preamble' as@@ -197,6 +201,9 @@ instance Context MouseReleased where  addEvent _ c s = s { script_mouseReleased = Just c } +instance Context KeyPressed where+ addEvent _ c s = s { script_keyPressed = Just c }+ -- | Set an event. Different events are specified by the instances of the --   'Context' class. --@@ -226,6 +233,7 @@     , proc_draw = fmap execProcM $ script_draw s     , proc_mouseClicked = fmap execProcM $ script_mouseClicked s     , proc_mouseReleased = fmap execProcM $ script_mouseReleased s+    , proc_keyPressed = fmap execProcM $ script_keyPressed s       }  -- Variables
Graphics/Web/Processing/Optimize.hs view
@@ -21,6 +21,18 @@ import Control.Applicative ((<$>)) import Control.Arrow (second) +boolops :: Proc_Bool -> Int+boolops (Proc_Neg x) = 1 + boolops x+boolops (Proc_Or x y) = 1 + boolops x + boolops y+boolops (Proc_And x y) = 1 + boolops x + boolops y+boolops (Float_Eq x y) = 1 + numOps x + numOps y+boolops (Float_NEq x y) = 1 + numOps x + numOps y+boolops (Float_LE x y) = 1 + numOps x + numOps y+boolops (Float_L x y) = 1 + numOps x + numOps y+boolops (Float_GE x y) = 1 + numOps x + numOps y+boolops (Float_G x y) = 1 + numOps x + numOps y+boolops _ = 0+ -- | Number of operations needed to calculate the --   value of a given 'Proc_Float' value. numOps :: Proc_Float -> Int@@ -43,6 +55,7 @@ numOps (Float_Arctangent x) = 1 + numOps x numOps (Float_Floor x) = 1 + numOps x numOps (Float_Noise x y) = 1 + numOps x + numOps y+numOps (Float_Cond b x y) = boolops b + max (numOps x) (numOps y)  ----------------------------------------------------- -----------------------------------------------------@@ -100,6 +113,7 @@ browseFloat f@(Float_Arctangent x) = addFloat f >> browseFloat x browseFloat f@(Float_Floor x) = addFloat f >> browseFloat x browseFloat f@(Float_Noise x y) = addFloat f >> browseFloat x >> browseFloat y+browseFloat f@(Float_Cond _ x y) = addFloat f >> browseFloat x >> browseFloat y browseFloat _ = return ()  execCounter :: FloatCounter a -> FloatSet@@ -266,17 +280,20 @@               _draw               _mouseClicked               _mouseReleased+              _keyPressed                )   = let (n1,_setup')         = subsOptimize 1 _setup         (n2,_draw')          = maybe (n1,Nothing) (second Just . subsOptimize n1) _draw         (n3,_mouseClicked')  = maybe (n2,Nothing) (second Just . subsOptimize n2) _mouseClicked         (n4,_mouseReleased') = maybe (n3,Nothing) (second Just . subsOptimize n3) _mouseReleased-        vs = fmap (\n -> CreateVar $ FloatAsign (optVarName n) 0) [1 .. n4 - 1]+        (n5,_keyPressed')    = maybe (n4,Nothing) (second Just . subsOptimize n4) _keyPressed+        vs = fmap (\n -> CreateVar $ FloatAsign (optVarName n) 0) [1 .. n5 - 1]     in ProcScript (_preamble <> subsComment (mconcat vs))                    _setup'                    _draw'                    _mouseClicked'                    _mouseReleased'+                   _keyPressed'  subsComment :: ProcCode Preamble -> ProcCode Preamble subsComment c =
Graphics/Web/Processing/Simple.hs view
@@ -60,6 +60,12 @@    , animateFigure      -- ** Interactive    , interactiveFigure+     -- *** Keyboard+   , Key (..)+   , ArrowKey (..)+   , KeyModifier (..)+   , SpecialKey (..)+     -- *** Custom values      -- | Module re-export for convenience.    , module Graphics.Web.Processing.Mid.CustomVar    ) where@@ -255,15 +261,20 @@                           --   It is passed the number of frames from the                           --   beginning.   -> (Proc_Point -> w -> w) -- ^ Function called each time the mouse is clicked.+  -> [(Key,w -> w)] -- ^ Key events. List of pairs, where the first component is+                    --   a 'Key' and the second component is the reaction to that+                    --   'Key'.   -> ProcScript-interactiveFigure mw mh framerate s0 _print bg step onclick = execScriptM $ do+interactiveFigure mw mh framerate s0 _print bg step onclick keyevents = execScriptM $ do   let w = maybe screenWidth  fromInt mw       h = maybe screenHeight fromInt mh   v <- newVarC s0+  keyv <- newVar true   on Setup $ do      setFrameRate $ fromInt framerate   on Draw $ do      size w h+     translate (intToFloat w/2) (intToFloat h/2)      writeComment "Read state"      s <- readVarC v      writeComment "Background color"@@ -279,3 +290,13 @@      writeComment "Mouse event"      p <- getMousePoint      writeVarC v $ onclick p s+  on KeyPressed $ mapM_ (keyEvent v keyv) keyevents++keyEvent :: CustomValue w+         => CustomVar w -> Var Proc_Bool -> (Key,w -> w) -> EventM KeyPressed ()+keyEvent v keyv (k,f) = do+  matchKey keyv k+  b <- readVar keyv+  iff b (readVarC v >>= writeVarC v . f)+        (return ())+  writeVar keyv true
+ examples/keys.hs view
@@ -0,0 +1,77 @@++{- Keyboard interaction demo++One of the squares in a 3x3 matrix of squares+is black and the rest is white. Use WASD keys+to change the position of the black square.++-}++import Graphics.Web.Processing.Simple+import Graphics.Web.Processing.Html++main :: IO ()+main = writeHtml "processing.js" "keydemo.pde" "Keyboard demo" "keydemo.html" theScript++---------------+-- 0 | 1 | 2 --+-- 3 | 4 | 5 --+-- 6 | 7 | 8 --+---------------++-- | State indicates the current position.+type State = Proc_Int++theScript :: ProcScript+theScript =+  interactiveFigure+    Nothing+    Nothing+    30+    4+    cubes+    (const $ Color 255 255 255 255)+    (const id)+    (const id)+    keyEvents++cubew :: Proc_Float+cubew = 40++cubew2 :: Proc_Float+cubew2 = cubew/2++corner :: Proc_Point+corner = let w = cubew + cubew2+         in  (negate w,w)++-- | Addition of points.+(<+>) :: Proc_Point -> Proc_Point -> Proc_Point+(a,b) <+> (c,d) = (a+c,b+d)++cubeUnit :: Proc_Bool -> Proc_Int -> Figure+cubeUnit b n = + let q = if_ b 0 255+     c = Color q q q 255+     (d,m) = divMod n 3+     p = corner <+> (cubew * intToFloat m, negate $ cubew * intToFloat d)+ in  FillColor c $ Rectangle p cubew cubew++cubes :: State -> Figure+cubes n = mconcat $ fmap (\i -> cubeUnit (n #== i) i) [0 .. 8]++keyEvents :: [(Key,State -> State)]+keyEvents = [+   ( CharKey 'w'+   , (\n -> if_ (n #< 3) n (n - 3))+     )+ , ( CharKey 'a'+   , (\n -> if_ (mod n 3 #== 0) n (n - 1))+     )+ , ( CharKey 's'+   , (\n -> if_ (n #> 5) n (n + 3))+     )+ , ( CharKey 'd'+   , (\n -> if_ (mod n 3 #== 2) n (n + 1))+     )+ ]
processing.cabal view
@@ -1,5 +1,5 @@ Name: processing-Version: 1.0.0.1+Version: 1.0.1.0 Author: Daniel Díaz Category: Graphics Build-type: Simple@@ -56,6 +56,7 @@   readme.md   examples/twist.hs   examples/mill.hs+  examples/keys.hs  Source-repository head   type: git