packages feed

typed-spreadsheet 1.1.0 → 1.1.1

raw patch · 5 files changed

+314/−146 lines, 5 filesdep ~asyncdep ~basedep ~diagrams-caironew-component:exe:typed-spreadsheet-example-cellnew-component:exe:typed-spreadsheet-example-text

Dependency ranges changed: async, base, diagrams-cairo, diagrams-gtk, diagrams-lib, foldl, gtk, microlens, transformers

Files

+ exec/Cell.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE ApplicativeDo     #-}+{-# LANGUAGE OverloadedStrings #-}++import Typed.Spreadsheet++main :: IO ()+main = cellUI "Example program" $ do+    a <- checkBox   "a"+    b <- spinButton "b" 1+    c <- spinButton "c" 0.1+    d <- entry      "d"+    return+        [ ("a"    , display  a     )+        , ("b + c", display (b + c))+        , ("d"    , display  d     )+        ]
exec/Graphics.hs view
@@ -1,6 +1,6 @@+{-# LANGUAGE ApplicativeDo     #-} {-# LANGUAGE OverloadedStrings #-} -import Diagrams.Backend.Cairo (Cairo) import Diagrams.Prelude import Typed.Spreadsheet @@ -16,13 +16,9 @@ toColor Purple = purple  main :: IO ()-main = graphicalUI "Example program" logic-  where-    logic = combine <$> radioButton      "Color"        Red [Orange .. Purple]-                    <*> spinButtonAt 100 "Radius"       1-                    <*> spinButton       "X Coordinate" 1-                    <*> spinButton       "Y Coordinate" 1--    combine :: AColor -> Double -> Double -> Double -> Diagram Cairo-    combine color r x y =-        circle r # fc (toColor color) # translate (r2 (x, y))+main = graphicalUI "Example program" $ do+    color <- radioButton                   "Color"        Red [Orange .. Purple]+    r     <- spinButtonAt    100           "Radius"       1+    x     <- hscaleWithRange (-200) 200 0  "X Coordinate" 10+    y     <- vscaleWithRange (-200) 200 0  "Y Coordinate" 10+    return (circle r # fc (toColor color) # translate (r2 (x, y)))
exec/Text.hs view
@@ -1,14 +1,12 @@+{-# LANGUAGE ApplicativeDo     #-} {-# LANGUAGE OverloadedStrings #-} -import Control.Applicative import Typed.Spreadsheet  main :: IO ()-main = textUI "Example program" logic-  where-    logic = combine <$> checkBox   "a"-                    <*> spinButton "b" 1-                    <*> spinButton "c" 0.1-                    <*> entry      "d"--    combine a b c d = display (a, b + c, d)+main = textUI "Example program" $ do+    a <- checkBox   "a"+    b <- spinButton "b" 1+    c <- spinButton "c" 0.1+    d <- entry      "d"+    return (display (a, b + c, d))
src/Typed/Spreadsheet.hs view
@@ -1,22 +1,21 @@ {-# LANGUAGE ExistentialQuantification  #-} {-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE ApplicativeDo              #-}  -- | The following program: --+-- > {-# LANGUAGE ApplicativeDo     #-} -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Control.Applicative -- > import Typed.Spreadsheet -- >  -- > main :: IO ()--- > main = textUI "Example program" logic--- >   where--- >     logic = combine <$> checkBox   "a"--- >                     <*> spinButton "b" 1--- >                     <*> spinButton "c" 0.1--- >                     <*> entry      "d"--- > --- >     combine a b c d = display (a, b + c, d)+-- > main = textUI "Example program" $ do+-- >     a <- checkBox   "a"+-- >     b <- spinButton "b" 1+-- >     c <- spinButton "c" 0.1+-- >     d <- entry      "d"+-- >     return (display (a, b + c, d)) -- -- ... creates a user interface that looks like this: --@@ -27,27 +26,11 @@ -- -- <<http://i.imgur.com/TTxgSwN.png User interface after user input>> ----- Once @ghc-8.0@ is out then you can simplify the above program even further--- using the `ApplicativeDo` extension:------ > {-# LANGUAGE ApplicativeDo     #-}--- > {-# LANGUAGE OverloadedStrings #-}--- > --- > import Typed.Spreadsheet--- > --- > main :: IO ()--- > main = textUI "Example program" (do--- >     a <- checkBox   "a"--- >     b <- spinButton "b" 1--- >     c <- spinButton "c" 0.1--- >     d <- entry      "d"--- >     return (display (a, b + c, d)) )--- -- This library also supports graphical output, like in the following program: --+-- > {-# LANGUAGE ApplicativeDo     #-} -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Diagrams.Backend.Cairo (Cairo) -- > import Diagrams.Prelude -- > import Typed.Spreadsheet -- > @@ -63,16 +46,12 @@ -- > toColor Purple = purple -- >  -- > main :: IO ()--- > main = graphicalUI "Example program" logic--- >   where--- >     logic = combine <$> radioButton       "Color"    Red [Orange .. Purple]--- >                     <*> spinButtonAt 100  "Radius"       1--- >                     <*> spinButton        "X Coordinate" 1--- >                     <*> spinButton        "Y Coordinate" 1--- > --- >     combine :: AColor -> Double -> Double -> Double -> Diagram Cairo--- >     combine color r x y =--- >         circle r # fc (toColor color) # translate (r2 (x, y))+-- > main = graphicalUI "Example program" $ do+-- >     color <- radioButton      "Color"        Red [Orange .. Purple]+-- >     r     <- spinButtonAt 100 "Radius"       1+-- >     x     <- spinButton       "X Coordinate" 1+-- >     y     <- spinButton       "Y Coordinate" 1+-- >     return (circle r # fc (toColor color) # translate (r2 (x, y))) -- -- This produces a canvas that colors, resizes, and moves a circle in response -- to user input:@@ -84,9 +63,8 @@ -- * You build primitive `Updatable` values using `checkBox`, `spinButton`, --   `entry`, or `radioButton`, each of which corresponds to a control on the --   left panel of the user interface--- * You transform or combine `Updatable` values using `Functor` and---   `Applicative` operations.  Composite values update whenever one of their---   substituent values update+-- * Combine `Updatable` values using @ApplicativeDo@ notation.  Composite values+--   update whenever one of their substituent values update -- * You consume an @(`Updatable` `Text`)@ value using `textUI`, which displays --   the continuously updating value in the right panel of the user interface --@@ -96,9 +74,13 @@ -- > $ stack build --install-ghc             # Builds the executable -- > $ stack exec typed-spreadsheet-example  # Runs the executable ----- That project includes the code for the above example in @exec/Main.hs@.  Just--- modify that file and rebuild to play with the example.+-- ... or if you are using OS X, then build the project using: --+-- > $ stack --stack-yaml=osx.yaml build --install-ghc+--+-- That project includes the code for the above examples in the @exec/@+-- subdirectory.  Just modify that file and rebuild to play with the example.+-- -- NOTE: You must compile your program with the @-threaded@ flag.  The example -- project takes care of this. --@@ -108,6 +90,7 @@     -- * Types       Updatable     , textUI+    , cellUI     , graphicalUI      -- * Controls@@ -119,6 +102,12 @@     -- * Controls with Defaults     , checkBoxAt     , spinButtonAt+    , hscale+    , hscaleAt+    , hscaleWithRange+    , vscale+    , vscaleAt+    , vscaleWithRange     , entryAt      -- * Utilities@@ -129,23 +118,22 @@     ) where  import Control.Applicative-import Control.Concurrent (threadDelay) import Control.Concurrent.STM (STM) import Control.Foldl (Fold(..)) import Control.Monad.IO.Class (liftIO)-import Data.Monoid import Data.String (IsString(..)) import Data.Text (Text) import Diagrams.Backend.Cairo (Cairo)-import Diagrams.Backend.Gtk (renderToGtk) import Diagrams.Prelude (Diagram, r2, reflectY, translate, (#)) import Lens.Micro (_Left, _Right) import Graphics.UI.Gtk (AttrOp((:=))) +import qualified Control.Concurrent import qualified Control.Concurrent.STM   as STM-import qualified Control.Concurrent.Async as Async-import qualified Control.Foldl            as Fold-import qualified Data.Text                as Text+import qualified Control.Concurrent.Async+import qualified Control.Foldl+import qualified Data.Text+import qualified Diagrams.Backend.Gtk import qualified Graphics.UI.Gtk          as Gtk  data Cell a = forall e . Cell (IO (STM e, Fold e a))@@ -162,7 +150,10 @@           where             input = fmap Left inputF <|> fmap Right inputX -            fold = Fold.handles _Left foldF <*> Fold.handles _Right foldX+            fold  = do+                f <- Control.Foldl.handles _Left foldF+                x <- Control.Foldl.handles _Right foldX+                return (f x)  -- | An updatable input value data Updatable a = Updatable (Control -> Cell a)@@ -225,10 +216,12 @@  -- | Use a `Control` to obtain updatable input `Updatable`s data Control = Control-    { _checkBoxAt   :: Bool -> Text -> Cell Bool-    , _spinButtonAt :: Double -> Text -> Double -> Cell Double-    , _entryAt      :: Text -> Text -> Cell Text-    , _radioButton  :: forall a . Show a => Text -> a -> [a] -> Cell a+    { _checkBoxAt      :: Bool -> Text -> Cell Bool+    , _spinButtonAt    :: Double -> Text -> Double -> Cell Double+    , _hscaleWithRange :: Double -> Double -> Double -> Text -> Double -> Cell Double+    , _vscaleWithRange :: Double -> Double -> Double -> Text -> Double -> Cell Double+    , _entryAt         :: Text -> Text -> Cell Text+    , _radioButton     :: forall a . Show a => Text -> a -> [a] -> Cell a     }  -- | Build a `Text`-based user interface@@ -253,8 +246,10 @@         vAdjust <- Gtk.textViewGetVadjustment textView         scrolledWindow <- Gtk.scrolledWindowNew (Just hAdjust) (Just vAdjust)         Gtk.set scrolledWindow-            [ Gtk.containerChild           := textView-            , Gtk.scrolledWindowShadowType := Gtk.ShadowIn+            [ Gtk.containerChild                 := textView+            , Gtk.scrolledWindowShadowType       := Gtk.ShadowIn+            , Gtk.scrolledWindowHscrollbarPolicy := Gtk.PolicyAutomatic+            , Gtk.scrolledWindowVscrollbarPolicy := Gtk.PolicyAutomatic             ]         Gtk.boxPackStart hBox scrolledWindow Gtk.PackGrow 0         return textBuffer@@ -263,6 +258,57 @@     processTextEvent textBuffer txt =         Gtk.set textBuffer [ Gtk.textBufferText := txt ] +-- | Build a cell-based user interface+cellUI+    :: Text+    -- ^ Window title+    -> Updatable [(Text, Text)]+    -- ^ Program logic+    -> IO ()+cellUI = ui cellSetup processCellEvent+  where+    cellSetup :: Gtk.HBox -> IO Gtk.VBox+    cellSetup hBox = do+        vbox <- Gtk.vBoxNew False 5+        Gtk.boxPackStart hBox vbox Gtk.PackGrow 0+        return vbox++    processCellEvent :: Gtk.VBox -> [(Text, Text)] -> IO ()+    processCellEvent vbox keyVals = do+        cells <- Gtk.containerGetChildren vbox+        mapM_ (Gtk.containerRemove vbox) cells++        let createCell (key, val) = do+                textView   <- Gtk.textViewNew+                textBuffer <- Gtk.get textView Gtk.textViewBuffer+                Gtk.set textView+                    [ Gtk.textViewEditable      := False+                    , Gtk.textViewCursorVisible := False+                    ]+                Gtk.set textBuffer [ Gtk.textBufferText := val ]+                hAdjust <- Gtk.textViewGetHadjustment textView+                vAdjust <- Gtk.textViewGetVadjustment textView+                scrolledWindow <- do+                    Gtk.scrolledWindowNew (Just hAdjust) (Just vAdjust)+                Gtk.set scrolledWindow+                    [ Gtk.containerChild :=+                        textView+                    , Gtk.scrolledWindowShadowType :=+                        Gtk.ShadowIn+                    , Gtk.scrolledWindowHscrollbarPolicy :=+                        Gtk.PolicyAutomatic+                    , Gtk.scrolledWindowVscrollbarPolicy :=+                        Gtk.PolicyAutomatic+                    ]+                frame <- Gtk.frameNew+                Gtk.set frame+                    [ Gtk.containerChild := scrolledWindow+                    , Gtk.frameLabel     := key+                    ]+                Gtk.boxPackStart vbox frame Gtk.PackNatural 0+        mapM_ createCell keyVals+        Gtk.widgetShowAll vbox+ -- | Build a `Diagram`-based user interface graphicalUI     :: Text@@ -284,7 +330,8 @@         (w, h) <- Gtk.widgetGetSize drawingArea         let w' = fromIntegral w / 2         let h' = fromIntegral h / 2-        renderToGtk drawWindow (diagram # reflectY # translate (r2 (w', h')))+        let diagram' = diagram # reflectY # translate (r2 (w', h'))+        Diagrams.Backend.Gtk.renderToGtk drawWindow diagram'  -- | Shared logic for `textUI` and `graphicalUI` ui  :: (Gtk.HBox -> IO a)@@ -334,8 +381,46 @@              Gtk.boxPackStart vBox frame Gtk.PackNatural 0             Gtk.widgetShowAll vBox-            return (STM.takeTMVar tmvar, Fold.lastDef s0) )+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef s0) ) +    let __hscaleWithRange :: Double -> Double -> Double -> Text -> Double -> Cell Double+        __hscaleWithRange minY maxY s0 label stepY = Cell (do+            tmvar      <- STM.newEmptyTMVarIO+            slider <- Gtk.hScaleNewWithRange minY maxY stepY+            Gtk.set slider+                [ Gtk.rangeValue    := s0+                ]+            _  <- Gtk.onRangeValueChanged slider (do+                n <- Gtk.get slider Gtk.rangeValue+                STM.atomically (STM.putTMVar tmvar n) )+            frame <- Gtk.frameNew+            Gtk.set frame+                [ Gtk.containerChild := slider+                , Gtk.frameLabel     := label+                ]+            Gtk.boxPackStart vBox frame Gtk.PackNatural 0+            Gtk.widgetShowAll vBox+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef s0) )++    let __vscaleWithRange :: Double -> Double -> Double -> Text -> Double -> Cell Double+        __vscaleWithRange minY maxY s0 label stepY = Cell (do+            tmvar      <- STM.newEmptyTMVarIO+            slider <- Gtk.vScaleNewWithRange minY maxY stepY+            Gtk.set slider+                [ Gtk.rangeValue    := (-s0)+                ]+            _  <- Gtk.onRangeValueChanged slider (do+                n <- Gtk.get slider Gtk.rangeValue+                STM.atomically (STM.putTMVar tmvar (-n)) )+            frame <- Gtk.frameNew+            Gtk.set frame+                [ Gtk.containerChild := slider+                , Gtk.frameLabel     := label+                ]+            Gtk.boxPackStart hBox frame Gtk.PackNatural 0+            Gtk.widgetShowAll hBox+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef s0) )+     let __checkBoxAt :: Bool -> Text -> Cell Bool         __checkBoxAt s0 label = Cell (do             checkButton <- Gtk.checkButtonNewWithLabel label@@ -348,7 +433,7 @@              Gtk.boxPackStart vBox checkButton Gtk.PackNatural 0             Gtk.widgetShowAll vBox-            return (STM.takeTMVar tmvar, Fold.lastDef s0) )+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef s0) )      let __entryAt :: Text -> Text -> Cell Text         __entryAt s0 label = Cell (do@@ -368,7 +453,7 @@              Gtk.boxPackStart vBox frame Gtk.PackNatural 0             Gtk.widgetShowAll frame-            return (STM.takeTMVar tmvar, Fold.lastDef s0) )+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef s0) )      let __radioButton :: Show a => Text -> a -> [a] -> Cell a         __radioButton label x xs = Cell (do@@ -376,13 +461,13 @@              vBoxRadio <- Gtk.vBoxNew False 5 -            let makeButton f a = do-                    button <- f (show a)+            let makeButton f y = do+                    button <- f (show y)                     Gtk.boxPackStart vBoxRadio button Gtk.PackNatural 0                     _ <- Gtk.on button Gtk.toggled (do                         active <- Gtk.get button Gtk.toggleButtonActive                         if active-                            then STM.atomically (STM.putTMVar tmvar a)+                            then STM.atomically (STM.putTMVar tmvar y)                             else return () )                     return button @@ -396,13 +481,15 @@                 ]             Gtk.boxPackStart vBox frame Gtk.PackNatural 0             Gtk.widgetShowAll frame-            return (STM.takeTMVar tmvar, Fold.lastDef x) )+            return (STM.takeTMVar tmvar, Control.Foldl.lastDef x) )      let control = Control-            { _checkBoxAt   = __checkBoxAt-            , _spinButtonAt = __spinButtonAt-            , _entryAt      = __entryAt-            , _radioButton  = __radioButton+            { _checkBoxAt      = __checkBoxAt+            , _spinButtonAt    = __spinButtonAt+            , _hscaleWithRange = __hscaleWithRange+            , _vscaleWithRange = __vscaleWithRange+            , _entryAt         = __entryAt+            , _radioButton     = __radioButton             }      doneTMVar <- STM.newEmptyTMVarIO@@ -410,7 +497,7 @@     let run (Cell m) = do             (stm, Fold step begin done) <- Gtk.postGUISync m             -- I don't know why this delay is necessary for diagrams output-            threadDelay 200000+            Control.Concurrent.threadDelay 200000             let loop x = do                     let b = done x                     Gtk.postGUISync (process a b)@@ -428,9 +515,9 @@         Gtk.mainQuit         return False ))     Gtk.widgetShowAll window-    Async.withAsync (run (k control)) (\a -> do+    Control.Concurrent.Async.withAsync (run (k control)) (\s -> do         Gtk.mainGUI-        Async.wait a )+        Control.Concurrent.Async.wait s )  -- | A check box that returns `True` if selected and `False` if unselected checkBox@@ -448,12 +535,30 @@     -> Updatable Double spinButton = spinButtonAt 0 +-- | A `Double` horizontal slider+hscale+    :: Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+hscale = hscaleAt 0++-- | A `Double` vertical slider+vscale+    :: Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+vscale = vscaleAt 0+ -- | A `Text` entry entry     :: Text     -- ^ Label     -> Updatable Text-entry = entryAt Text.empty+entry = entryAt Data.Text.empty  -- | A control that selects from one or more mutually exclusive choices radioButton@@ -490,6 +595,60 @@ spinButtonAt s0 label x =     Updatable (\control -> _spinButtonAt control s0 label x) +-- | Same as `hscaleButton` except that you can specify the initial state+hscaleAt+    :: Double+    -- ^ Initial state+    -> Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+hscaleAt = hscaleWithRange (fromIntegral (minBound :: Int)) (fromIntegral (maxBound :: Int))++-- | Same as `hscaleButton` except that you can specify the range and initial state+hscaleWithRange+    :: Double+    -- ^ Minimum value+    -> Double+    -- ^ Maximum value+    -> Double+    -- ^ Initial state+    -> Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+hscaleWithRange b0 b1 s0 label x =+    Updatable (\control -> _hscaleWithRange control b0 b1 s0 label x)++-- | Same as `vscaleButton` except that you can specify the initial state+vscaleAt+    :: Double+    -- ^ Initial state+    -> Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+vscaleAt = vscaleWithRange (fromIntegral (minBound :: Int)) (fromIntegral (maxBound :: Int))++-- | Same as `vscaleButton` except that you can specify the range and initial state+vscaleWithRange+    :: Double+    -- ^ Minimum value+    -> Double+    -- ^ Maximum value+    -> Double+    -- ^ Initial state+    -> Text+    -- ^ Label+    -> Double+    -- ^ Step size+    -> Updatable Double+vscaleWithRange b0 b1 s0 label x =+    Updatable (\control -> _vscaleWithRange control b0 b1 s0 label x)+ -- | Same as `entry` except that you can specify the initial state entryAt     :: Text@@ -501,34 +660,25 @@  -- | Convert a `Show`able value to `Text` display :: Show a => a -> Text-display = Text.pack . show+display = Data.Text.pack . show  -- $examples -- -- Mortgage calculator: --+-- > {-# LANGUAGE ApplicativeDo     #-} -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Control.Applicative--- > import Data.Monoid--- > import Data.Text (Text) -- > import Typed.Spreadsheet -- > --- > payment :: Double -> Double -> Double -> Text--- > payment mortgageAmount numberOfYears yearlyInterestRate--- >     =  "Monthly payment: $"--- >     <> display (mortgageAmount * (i * (1 + i) ^ n) / ((1 + i) ^ n - 1))--- >   where--- >     n = truncate (numberOfYears * 12)--- >     i = yearlyInterestRate / 12 / 100--- > --- > logic :: Updatable Text--- > logic = payment <$> spinButton "Mortgage Amount"          1000--- >                 <*> spinButton "Number of years"             1--- >                 <*> spinButton "Yearly interest rate (%)"    0.01--- >  -- > main :: IO ()--- > main = textUI "Mortgage payment" logic+-- > main = textUI "Mortgage payment" $ do+-- >   mortgageAmount     <- spinButton "Mortgage Amount"          1000+-- >   numberOfYears      <- spinButton "Number of years"             1+-- >   yearlyInterestRate <- spinButton "Yearly interest rate (%)"    0.01+-- >   let n = truncate (numberOfYears * 12)+-- >   let i = yearlyInterestRate / 12 / 100+-- >   return ("Monthly payment: $" <> display (mortgageAmount * (i * (1 + i) ^ n) / ((1 + i) ^ n - 1))) -- -- Example input and output: --@@ -538,7 +688,6 @@ -- -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Data.Monoid -- > import Typed.Spreadsheet -- >  -- > noun = entry "Noun"@@ -564,28 +713,25 @@ -- -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Diagrams.Backend.Cairo (Cairo) -- > import Diagrams.Prelude -- > import Typed.Spreadsheet -- >  -- > main :: IO ()--- > main = graphicalUI "Example program" logic--- >   where--- >     logic = combine <$> spinButtonAt 50  "Amplitude (Pixels)"   0.1--- >                     <*> spinButtonAt 0.1 "Frequency (Pixels⁻¹)" 0.001--- >                     <*> spinButtonAt 90  "Phase (Degrees)"      1+-- > main = graphicalUI "Example program" $ do+-- >     amplitude <- spinButtonAt 50  "Amplitude (Pixels)"   0.1+-- >     frequency <- spinButtonAt 0.1 "Frequency (Pixels⁻¹)" 0.001+-- >     phase     <- spinButtonAt 90  "Phase (Degrees)"      1 -- > --- >     combine :: Double -> Double -> Double -> Diagram Cairo--- >     combine amplitude frequency phase = strokeP (fromVertices points) <> axes--- >       where--- >         axes = arrowBetween (p2 (0, 0)) (p2 ( 100,    0))+-- >     let axes = arrowBetween (p2 (0, 0)) (p2 ( 100,    0)) -- >             <> arrowBetween (p2 (0, 0)) (p2 (-100,    0)) -- >             <> arrowBetween (p2 (0, 0)) (p2 (   0,  100)) -- >             <> arrowBetween (p2 (0, 0)) (p2 (   0, -100)) -- > --- >         f x = amplitude * cos (frequency * x + phase * pi / 180)+-- >     let f x = amplitude * cos (frequency * x + phase * pi / 180) -- > --- >         points = map (\x -> p2 (x, f x)) [-100, -99 .. 100]+-- >     let points = map (\x -> p2 (x, f x)) [-100, -99 .. 100]+-- > +-- >     return (strokeP (fromVertices points) <> axes) -- -- Example input and output: --@@ -595,21 +741,16 @@ -- -- > {-# LANGUAGE OverloadedStrings #-} -- > --- > import Diagrams.Backend.Cairo (Cairo) -- > import Diagrams.Prelude -- > import Diagrams.TwoD.Factorization (factorDiagram') -- > import Typed.Spreadsheet -- >  -- > main :: IO ()--- > main = graphicalUI "Factor diagram" logic--- >   where--- >     logic = combine <$> spinButtonAt 3 "Factor #1" 1--- >                     <*> spinButtonAt 3 "Factor #2" 1--- >                     <*> spinButtonAt 3 "Factor #3" 1--- > --- >     combine :: Double -> Double -> Double -> Diagram Cairo--- >     combine x y z =--- >         factorDiagram' [truncate x, truncate y, truncate z] # scale 10+-- > main = graphicalUI "Factor diagram" $ do+-- >     x <- spinButtonAt 3 "Factor #1" 1+-- >     y <- spinButtonAt 3 "Factor #2" 1+-- >     z <- spinButtonAt 3 "Factor #3" 1+-- >     return (factorDiagram' [truncate x, truncate y, truncate z] # scale 10) -- -- Example input and output: --
typed-spreadsheet.cabal view
@@ -1,5 +1,5 @@ Name: typed-spreadsheet-Version: 1.1.0+Version: 1.1.1 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3@@ -9,6 +9,7 @@ Maintainer: Gabriel439@gmail.com Bug-Reports: https://github.com/Gabriel439/Haskell-Typed-Spreadsheet-Library/issues Synopsis: Typed and composable spreadsheets+Tested-With: GHC == 8.0.2, GHC == 8.2.2 Description:     This library provides a typed and composable API for building spreadsheets.     This differs from traditional spreadsheets in a few important ways:@@ -31,35 +32,51 @@ Library     Hs-Source-Dirs: src     Build-Depends:-        base           >= 4      && < 5   ,-        async          >= 2.0    && < 2.1 ,-        diagrams-cairo >= 1.3    && < 1.4 ,-        diagrams-gtk   >= 1.3    && < 1.4 ,-        diagrams-lib   >= 1.3    && < 1.4 ,-        foldl          >= 1.1    && < 1.2 ,-        gtk            >= 0.13   && < 0.14,-        microlens                   < 0.4 ,+        base           >= 4.9    && < 5   ,+        async          >= 2.0    && < 2.2 ,+        diagrams-cairo >= 1.3    && < 1.5 ,+        diagrams-gtk   >= 1.3    && < 1.5 ,+        diagrams-lib   >= 1.3    && < 1.5 ,+        foldl          >= 1.1    && < 1.3 ,+        gtk            >= 0.13   && < 0.15,+        microlens                   < 0.5 ,         stm                         < 2.5 ,         text                        < 1.3 ,-        transformers  >= 0.2.0.0 && < 0.5+        transformers  >= 0.2.0.0 && < 0.6+    if os(darwin)+      frameworks: Cocoa     Exposed-Modules: Typed.Spreadsheet     GHC-Options: -O2 -Wall -Executable typed-spreadsheet-example+Executable typed-spreadsheet-example-text     Hs-Source-Dirs: exec     Main-Is: Text.hs     Build-Depends:-        base >= 4 && < 5  ,-        text         < 1.3,+        base >= 4.9 && < 5  ,+        text           < 1.3,         typed-spreadsheet+    if os(darwin)+      frameworks: Cocoa     GHC-Options: -O2 -Wall -threaded +Executable typed-spreadsheet-example-cell+    Hs-Source-Dirs: exec+    Main-Is: Cell.hs+    Build-Depends:+        base >= 4.9 && < 5  ,+        text           < 1.3,+        typed-spreadsheet+    if os(darwin)+      frameworks: Cocoa+    GHC-Options: -Wall -threaded+ Executable typed-spreadsheet-example-graphics     Hs-Source-Dirs: exec     Main-Is: Graphics.hs     Build-Depends:         base           >= 4   && < 5  ,-        diagrams-cairo >= 1.3 && < 1.4,-        diagrams-lib   >= 1.3 && < 1.4,+        diagrams-lib   >= 1.3 && < 1.5,         typed-spreadsheet+    if os(darwin)+      frameworks: Cocoa     GHC-Options: -O2 -Wall -threaded