Commit 3466245b authored by Sumit Sahrawat's avatar Sumit Sahrawat

More refactoring

- Add `properties` to view properties of widgets.
- Remove use of `Numeric.Natural`.
- Add verification mechanisms to `Attr`.
parent 26addb62
......@@ -2,14 +2,15 @@
> Largely based on: https://github.com/ipython/ipython/wiki/IPEP-23:-Backbone.js-Widgets
> The messaging specification as detailed is riddled with the assumptions IHaskell's widget
> The messaging specification as detailed is riddled with assumptions IHaskell's widget
> implementation makes. It works for us, so it should work for everyone.
## Creating widgets
Let's say the user types in some code, and the only effect of that code is the creation of a widget.
The kernel will open a comm for the widget, and store a reference to that comm inside it. Then, to
notify the frontend about the creation of a widget, an initial state update is sent on the widget's comm.
notify the frontend about the creation of a widget, an initial state update is sent on the widget's
comm.
> The comm should be opened with a `target_name` of `"ipython.widget"`.
......@@ -22,7 +23,9 @@ The initial state update message looks like this:
}
```
Any *numeric* property initialized with the empty string is provided the default value by the frontend.
Any *numeric* property initialized with the empty string is provided the default value by the
frontend. Some numbers need to be sent as actual numbers (when non-null), whereas some (especially
those used by sliders) need to be sent as strings.
The initial state update must *at least* have the following fields:
......
......@@ -33,4 +33,4 @@ import IHaskell.Display.Widgets.String.Text as X
import IHaskell.Display.Widgets.String.TextArea as X
import IHaskell.Display.Widgets.Common as X
import IHaskell.Display.Widgets.Types as X (setField, getField)
import IHaskell.Display.Widgets.Types as X (setField, getField, properties)
......@@ -12,7 +12,7 @@ CheckBox,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -61,4 +61,4 @@ instance IHaskellWidget CheckBox where
key2 = "value" :: Text
Just (Object dict2) = HM.lookup key1 dict1
Just (Bool value) = HM.lookup key2 dict2
setField' widget SBoolValue value
void $ setField' widget SBoolValue value
......@@ -12,7 +12,7 @@ ToggleButton,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -66,4 +66,4 @@ instance IHaskellWidget ToggleButton where
key2 = "value" :: Text
Just (Object dict2) = HM.lookup key1 dict1
Just (Bool value) = HM.lookup key2 dict2
setField' widget SBoolValue value
void $ setField' widget SBoolValue value
......@@ -6,6 +6,7 @@
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module IHaskell.Display.Widgets.Common where
import Data.Aeson
......@@ -81,6 +82,11 @@ singletons [d|
deriving (Eq, Ord, Show)
|]
newtype StrInt = StrInt Integer deriving (Num, Ord, Eq, Enum)
instance ToJSON StrInt where
toJSON (StrInt x) = toJSON . pack $ show x
-- | Pre-defined border styles
data BorderStyleValue = NoBorder
| HiddenBorder
......
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Float.BoundedFloat.BoundedFloatText (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -68,4 +68,4 @@ instance IHaskellWidget BoundedFloatText where
newValue <- if abs value < 10 ^ 16
then return (Sci.toRealFloat value)
else throw LossOfPrecision
setField' widget SFloatValue newValue
void $ setField' widget SFloatValue newValue
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Float.BoundedFloat.FloatSlider (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -74,4 +74,4 @@ instance IHaskellWidget FloatSlider where
newValue <- if abs value < 10 ^ 16
then return (Sci.toRealFloat value)
else throw LossOfPrecision
setField' widget SFloatValue newValue
void $ setField' widget SFloatValue newValue
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Float.BoundedFloatRange.FloatRangeSlider (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -73,4 +73,4 @@ instance IHaskellWidget FloatRangeSlider where
Just (Object dict2) = HM.lookup key1 dict1
Just (Array values) = HM.lookup key2 dict2
[x, y] = map (\(Number x) -> Sci.toRealFloat x) $ V.toList values
setField' widget SFloatPairValue (x, y)
void $ setField' widget SFloatPairValue (x, y)
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Float.FloatText (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -65,4 +65,4 @@ instance IHaskellWidget FloatText where
newValue <- if abs value < 10 ^ 16
then return (Sci.toRealFloat value)
else throw LossOfPrecision
setField' widget SFloatValue newValue
void $ setField' widget SFloatValue newValue
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -68,4 +68,4 @@ instance IHaskellWidget BoundedIntText where
newValue <- if abs value < 10 ^ 16
then return (Sci.coefficient value)
else throw LossOfPrecision
setField' widget SIntValue newValue
void $ setField' widget SIntValue newValue
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Int.BoundedInt.IntSlider (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -74,4 +74,4 @@ instance IHaskellWidget IntSlider where
newValue <- if abs value < 10 ^ 16
then return (Sci.coefficient value)
else throw LossOfPrecision
setField' widget SIntValue newValue
void $ setField' widget SIntValue newValue
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Int.BoundedIntRange.IntRangeSlider (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -73,4 +73,4 @@ instance IHaskellWidget IntRangeSlider where
Just (Object dict2) = HM.lookup key1 dict1
Just (Array values) = HM.lookup key2 dict2
[x, y] = map (\(Number x) -> Sci.coefficient x) $ V.toList values
setField' widget SIntPairValue (x, y)
void $ setField' widget SIntPairValue (x, y)
......@@ -13,7 +13,7 @@ module IHaskell.Display.Widgets.Int.IntText (
import Prelude
import Control.Exception (throw, ArithException (LossOfPrecision))
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -65,4 +65,4 @@ instance IHaskellWidget IntText where
newValue <- if abs value < 10 ^ 16
then return (Sci.coefficient value)
else throw LossOfPrecision
setField' widget SIntValue newValue
void $ setField' widget SIntValue newValue
......@@ -12,7 +12,7 @@ Dropdown,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -68,13 +68,13 @@ instance IHaskellWidget Dropdown where
Just (String label) = HM.lookup key2 dict2
opts <- getField widget SOptions
case opts of
OptionLabels _ -> do
OptionLabels _ -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue label
OptionDict ps ->
case lookup label ps of
Nothing -> return ()
Just value -> do
Just value -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue value
triggerSelection widget
......@@ -12,7 +12,7 @@ RadioButtons,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -66,13 +66,13 @@ instance IHaskellWidget RadioButtons where
Just (String label) = HM.lookup key2 dict2
opts <- getField widget SOptions
case opts of
OptionLabels _ -> do
OptionLabels _ -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue label
OptionDict ps ->
case lookup label ps of
Nothing -> return ()
Just value -> do
Just value -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue value
triggerSelection widget
......@@ -12,7 +12,7 @@ Select,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -65,13 +65,13 @@ instance IHaskellWidget Select where
Just (String label) = HM.lookup key2 dict2
opts <- getField widget SOptions
case opts of
OptionLabels _ -> do
OptionLabels _ -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue label
OptionDict ps ->
case lookup label ps of
Nothing -> return ()
Just value -> do
Just value -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue value
triggerSelection widget
......@@ -12,7 +12,7 @@ SelectMultiple,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (fmap, join, sequence)
import Control.Monad (fmap, join, sequence, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -70,13 +70,13 @@ instance IHaskellWidget SelectMultiple where
labelList = map (\(String x) -> x) $ V.toList labels
opts <- getField widget SOptions
case opts of
OptionLabels _ -> do
OptionLabels _ -> void $ do
setField' widget SSelectedLabels labelList
setField' widget SSelectedValues labelList
OptionDict ps ->
case sequence $ map (`lookup` ps) labelList of
Nothing -> return ()
Just valueList -> do
Just valueList -> void $ do
setField' widget SSelectedLabels labelList
setField' widget SSelectedValues valueList
triggerSelection widget
......@@ -12,7 +12,7 @@ ToggleButtons,
-- To keep `cabal repl` happy when running from the ihaskell repo
import Prelude
import Control.Monad (when, join)
import Control.Monad (when, join, void)
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import Data.IORef (newIORef)
......@@ -73,13 +73,13 @@ instance IHaskellWidget ToggleButtons where
Just (String label) = HM.lookup key2 dict2
opts <- getField widget SOptions
case opts of
OptionLabels _ -> do
OptionLabels _ -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue label
OptionDict ps ->
case lookup label ps of
Nothing -> return ()
Just value -> do
Just value -> void $ do
setField' widget SSelectedLabel label
setField' widget SSelectedValue value
triggerSelection widget
......@@ -66,7 +66,7 @@ instance IHaskellWidget TextWidget where
case Map.lookup "sync_data" dict1 of
Just (Object dict2) ->
case Map.lookup "value" dict2 of
Just (String val) -> setField' tw SStringValue val
Just (String val) -> setField' tw SStringValue val >> return ()
Nothing -> return ()
Nothing ->
case Map.lookup "content" dict1 of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment