Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
f9abfc19
Commit
f9abfc19
authored
Jul 25, 2021
by
David Davó
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Started controller widget
parent
be8e61f9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
271 additions
and
6 deletions
+271
-6
ihaskell-widgets.cabal
ihaskell-display/ihaskell-widgets/ihaskell-widgets.cabal
+4
-0
Widgets.hs
...-display/ihaskell-widgets/src/IHaskell/Display/Widgets.hs
+4
-0
Common.hs
...y/ihaskell-widgets/src/IHaskell/Display/Widgets/Common.hs
+7
-0
Controller.hs
...ets/src/IHaskell/Display/Widgets/Controller/Controller.hs
+81
-0
ControllerAxis.hs
...src/IHaskell/Display/Widgets/Controller/ControllerAxis.hs
+57
-0
ControllerButton.hs
...c/IHaskell/Display/Widgets/Controller/ControllerButton.hs
+58
-0
Singletons.hs
...askell-widgets/src/IHaskell/Display/Widgets/Singletons.hs
+7
-0
Types.hs
...ay/ihaskell-widgets/src/IHaskell/Display/Widgets/Types.hs
+53
-6
No files found.
ihaskell-display/ihaskell-widgets/ihaskell-widgets.cabal
View file @
f9abfc19
...
@@ -62,12 +62,16 @@ library
...
@@ -62,12 +62,16 @@ library
-- Modules included in this library but not exported.
-- Modules included in this library but not exported.
other-modules: IHaskell.Display.Widgets.Button
other-modules: IHaskell.Display.Widgets.Button
IHaskell.Display.Widgets.ColorPicker
IHaskell.Display.Widgets.ColorPicker
IHaskell.Display.Widgets.DatePicker
IHaskell.Display.Widgets.Box.Box
IHaskell.Display.Widgets.Box.Box
IHaskell.Display.Widgets.Box.SelectionContainer.Accordion
IHaskell.Display.Widgets.Box.SelectionContainer.Accordion
IHaskell.Display.Widgets.Box.SelectionContainer.Tab
IHaskell.Display.Widgets.Box.SelectionContainer.Tab
IHaskell.Display.Widgets.Bool.CheckBox
IHaskell.Display.Widgets.Bool.CheckBox
IHaskell.Display.Widgets.Bool.ToggleButton
IHaskell.Display.Widgets.Bool.ToggleButton
IHaskell.Display.Widgets.Bool.Valid
IHaskell.Display.Widgets.Bool.Valid
IHaskell.Display.Widgets.Controller.Controller
IHaskell.Display.Widgets.Controller.ControllerAxis
IHaskell.Display.Widgets.Controller.ControllerButton
IHaskell.Display.Widgets.Int.IntText
IHaskell.Display.Widgets.Int.IntText
IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText
IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText
IHaskell.Display.Widgets.Int.BoundedInt.IntProgress
IHaskell.Display.Widgets.Int.BoundedInt.IntProgress
...
...
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets.hs
View file @
f9abfc19
...
@@ -12,6 +12,10 @@ import IHaskell.Display.Widgets.Bool.CheckBox as X
...
@@ -12,6 +12,10 @@ import IHaskell.Display.Widgets.Bool.CheckBox as X
import
IHaskell.Display.Widgets.Bool.ToggleButton
as
X
import
IHaskell.Display.Widgets.Bool.ToggleButton
as
X
import
IHaskell.Display.Widgets.Bool.Valid
as
X
import
IHaskell.Display.Widgets.Bool.Valid
as
X
import
IHaskell.Display.Widgets.Controller.Controller
as
X
import
IHaskell.Display.Widgets.Controller.ControllerAxis
as
X
import
IHaskell.Display.Widgets.Controller.ControllerButton
as
X
import
IHaskell.Display.Widgets.Int.IntText
as
X
import
IHaskell.Display.Widgets.Int.IntText
as
X
import
IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText
as
X
import
IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText
as
X
import
IHaskell.Display.Widgets.Int.BoundedInt.IntProgress
as
X
import
IHaskell.Display.Widgets.Int.BoundedInt.IntProgress
as
X
...
...
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Common.hs
View file @
f9abfc19
...
@@ -103,6 +103,13 @@ pattern Interval = S.SInterval
...
@@ -103,6 +103,13 @@ pattern Interval = S.SInterval
pattern
ShowRepeat
=
S
.
SShowRepeat
pattern
ShowRepeat
=
S
.
SShowRepeat
pattern
Concise
=
S
.
SConcise
pattern
Concise
=
S
.
SConcise
pattern
DateValue
=
S
.
SDateValue
pattern
DateValue
=
S
.
SDateValue
pattern
Pressed
=
S
.
SPressed
pattern
Name
=
S
.
SName
pattern
Mapping
=
S
.
SMapping
pattern
Connected
=
S
.
SConnected
pattern
Timestamp
=
S
.
STimestamp
pattern
Buttons
=
S
.
SButtons
pattern
Axes
=
S
.
SAxes
-- | Close a widget's comm
-- | Close a widget's comm
closeWidget
::
IHaskellWidget
w
=>
w
->
IO
()
closeWidget
::
IHaskellWidget
w
=>
w
->
IO
()
...
...
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Controller/Controller.hs
0 → 100644
View file @
f9abfc19
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module
IHaskell.Display.Widgets.Controller.Controller
(
-- * The Controller Widget
Controller
-- * Constructor
,
mkController
)
where
-- To keep `cabal repl` happy when running from the ihaskell repo
import
Prelude
import
Control.Monad
(
void
)
import
Data.Aeson
import
Data.Aeson.Types
(
parse
)
import
Data.Text
(
Text
)
import
Data.IORef
(
newIORef
)
import
Data.Maybe
(
fromJust
,
isJust
)
import
qualified
Data.Scientific
as
Sci
import
Data.Vinyl
(
Rec
(
..
),
(
<+>
))
import
IHaskell.Display
import
IHaskell.Eval.Widgets
import
IHaskell.IPython.Message.UUID
as
U
import
IHaskell.Display.Widgets.Singletons
(
Field
,
SField
)
import
IHaskell.Display.Widgets.Types
import
IHaskell.Display.Widgets.Common
-- | 'Controller' represents an Controller widget from IPython.html.widgets.
type
Controller
=
IPythonWidget
'C
o
ntrollerType
-- | Create a new widget
mkController
::
IO
Controller
mkController
=
do
-- Default properties, with a random uuid
wid
<-
U
.
random
let
domAttrs
=
defaultCoreWidget
<+>
defaultDOMWidget
"ControllerView"
"ControllerModel"
ctrlAttrs
=
(
Index
=:+
0
)
:&
(
Name
=:!
""
)
:&
(
Mapping
=:!
""
)
:&
(
Connected
=:!
False
)
:&
(
Timestamp
=:!
0.0
)
:&
(
Buttons
=:!
[]
)
:&
(
Axes
=:!
[]
)
:&
(
ChangeHandler
=::
pure
()
)
:&
RNil
widgetState
=
WidgetState
$
domAttrs
<+>
ctrlAttrs
stateIO
<-
newIORef
widgetState
let
widget
=
IPythonWidget
wid
stateIO
-- Open a comm for this widget, and store it in the kernel state
widgetSendOpen
widget
$
toJSON
widgetState
-- Return the widget
return
widget
instance
IHaskellWidget
Controller
where
getCommUUID
=
uuid
comm
widget
val
_
=
case
nestedObjectLookup
val
[
"state"
]
of
Just
(
Object
o
)
->
do
parseAndSet
Name
"name"
parseAndSet
Mapping
"mapping"
parseAndSet
Connected
"connected"
parseAndSet
Timestamp
"timestamp"
triggerChange
widget
where
parseAndSet
f
s
=
case
parse
(
.:
s
)
o
of
Success
x
->
void
$
setField'
widget
f
x
_
->
pure
()
_
->
pure
()
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Controller/ControllerAxis.hs
0 → 100644
View file @
f9abfc19
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module
IHaskell.Display.Widgets.Controller.ControllerAxis
(
-- * The ControllerAxis Widget
ControllerAxis
-- * Constructor
,
mkControllerAxis
)
where
-- To keep `cabal repl` happy when running from the ihaskell repo
import
Prelude
import
Control.Monad
(
void
)
import
Data.Aeson
import
Data.IORef
(
newIORef
)
import
qualified
Data.Scientific
as
Sci
import
Data.Vinyl
(
Rec
(
..
),
(
<+>
))
import
IHaskell.Display
import
IHaskell.Eval.Widgets
import
IHaskell.IPython.Message.UUID
as
U
import
IHaskell.Display.Widgets.Types
import
IHaskell.Display.Widgets.Common
-- | 'ControllerAxis' represents an ControllerAxis widget from IPython.html.widgets.
type
ControllerAxis
=
IPythonWidget
'C
o
ntrollerAxisType
-- | Create a new widget
mkControllerAxis
::
IO
ControllerAxis
mkControllerAxis
=
do
-- Default properties, with a random uuid
wid
<-
U
.
random
let
domAttrs
=
defaultCoreWidget
<+>
defaultDOMWidget
"ControllerAxisView"
"ControllerAxisModel"
axisAttrs
=
(
FloatValue
=:!
0.0
)
:&
(
ChangeHandler
=::
pure
()
)
:&
RNil
widgetState
=
WidgetState
$
domAttrs
<+>
axisAttrs
stateIO
<-
newIORef
widgetState
let
widget
=
IPythonWidget
wid
stateIO
-- Open a comm for this widget, and store it in the kernel state
widgetSendOpen
widget
$
toJSON
widgetState
-- Return the widget
return
widget
instance
IHaskellWidget
ControllerAxis
where
getCommUUID
=
uuid
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Controller/ControllerButton.hs
0 → 100644
View file @
f9abfc19
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module
IHaskell.Display.Widgets.Controller.ControllerButton
(
-- * The ControllerButton Widget
ControllerButton
-- * Constructor
,
mkControllerButton
)
where
-- To keep `cabal repl` happy when running from the ihaskell repo
import
Prelude
import
Control.Monad
(
void
)
import
Data.Aeson
import
Data.IORef
(
newIORef
)
import
qualified
Data.Scientific
as
Sci
import
Data.Vinyl
(
Rec
(
..
),
(
<+>
))
import
IHaskell.Display
import
IHaskell.Eval.Widgets
import
IHaskell.IPython.Message.UUID
as
U
import
IHaskell.Display.Widgets.Types
import
IHaskell.Display.Widgets.Common
-- | 'ControllerButton' represents an ControllerButton widget from IPython.html.widgets.
type
ControllerButton
=
IPythonWidget
'C
o
ntrollerButtonType
-- | Create a new widget
mkControllerButton
::
IO
ControllerButton
mkControllerButton
=
do
-- Default properties, with a random uuid
wid
<-
U
.
random
let
domAttrs
=
defaultCoreWidget
<+>
defaultDOMWidget
"ControllerButtonView"
"ControllerButtonModel"
btnAttrs
=
(
FloatValue
=:!
0.0
)
:&
(
Pressed
=:!
False
)
:&
(
ChangeHandler
=::
pure
()
)
:&
RNil
widgetState
=
WidgetState
$
domAttrs
<+>
btnAttrs
stateIO
<-
newIORef
widgetState
let
widget
=
IPythonWidget
wid
stateIO
-- Open a comm for this widget, and store it in the kernel state
widgetSendOpen
widget
$
toJSON
widgetState
-- Return the widget
return
widget
instance
IHaskellWidget
ControllerButton
where
getCommUUID
=
uuid
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Singletons.hs
View file @
f9abfc19
...
@@ -109,5 +109,12 @@ singletons
...
@@ -109,5 +109,12 @@ singletons
| ShowRepeat
| ShowRepeat
| Concise
| Concise
| DateValue
| DateValue
| Pressed
| Name
| Mapping
| Connected
| Timestamp
| Buttons
| Axes
deriving (Eq, Ord, Show)
deriving (Eq, Ord, Show)
|]
|]
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Types.hs
View file @
f9abfc19
...
@@ -248,12 +248,22 @@ type family FieldType (f :: Field) :: * where
...
@@ -248,12 +248,22 @@ type family FieldType (f :: Field) :: * where
FieldType
'S
.
ShowRepeat
=
Bool
FieldType
'S
.
ShowRepeat
=
Bool
FieldType
'S
.
Concise
=
Bool
FieldType
'S
.
Concise
=
Bool
FieldType
'S
.
DateValue
=
Date
FieldType
'S
.
DateValue
=
Date
FieldType
'S
.
Pressed
=
Bool
FieldType
'S
.
Name
=
Text
FieldType
'S
.
Mapping
=
Text
FieldType
'S
.
Connected
=
Bool
FieldType
'S
.
Timestamp
=
Double
FieldType
'S
.
Buttons
=
[
IPythonWidget
'C
o
ntrollerButtonType
]
FieldType
'S
.
Axes
=
[
IPythonWidget
'C
o
ntrollerAxisType
]
-- | Can be used to put different widgets in a list. Useful for dealing with children widgets.
-- | Can be used to put different widgets in a list. Useful for dealing with children widgets.
data
ChildWidget
=
forall
w
.
RecAll
Attr
(
WidgetFields
w
)
ToPairs
=>
ChildWidget
(
IPythonWidget
w
)
data
ChildWidget
=
forall
w
.
RecAll
Attr
(
WidgetFields
w
)
ToPairs
=>
ChildWidget
(
IPythonWidget
w
)
instance
ToJSON
(
IPythonWidget
w
)
where
toJSON
x
=
toJSON
.
pack
$
"IPY_MODEL_"
++
uuidToString
(
uuid
x
)
instance
ToJSON
ChildWidget
where
instance
ToJSON
ChildWidget
where
toJSON
(
ChildWidget
x
)
=
toJSON
.
pack
$
"IPY_MODEL_"
++
uuidToString
(
uuid
x
)
toJSON
(
ChildWidget
x
)
=
toJSON
x
-- Will use a custom class rather than a newtype wrapper with an orphan instance. The main issue is
-- Will use a custom class rather than a newtype wrapper with an orphan instance. The main issue is
-- the need of a Bounded instance for Float / Double.
-- the need of a Bounded instance for Float / Double.
...
@@ -314,6 +324,9 @@ data WidgetType = ButtonType
...
@@ -314,6 +324,9 @@ data WidgetType = ButtonType
|
BoxType
|
BoxType
|
AccordionType
|
AccordionType
|
TabType
|
TabType
|
ControllerButtonType
|
ControllerAxisType
|
ControllerType
-- Fields associated with a widget
-- Fields associated with a widget
...
@@ -390,6 +403,11 @@ type family WidgetFields (w :: WidgetType) :: [Field] where
...
@@ -390,6 +403,11 @@ type family WidgetFields (w :: WidgetType) :: [Field] where
WidgetFields
'B
o
xType
=
BoxClass
WidgetFields
'B
o
xType
=
BoxClass
WidgetFields
'A
c
cordionType
=
SelectionContainerClass
WidgetFields
'A
c
cordionType
=
SelectionContainerClass
WidgetFields
'T
a
bType
=
SelectionContainerClass
WidgetFields
'T
a
bType
=
SelectionContainerClass
WidgetFields
'C
o
ntrollerType
=
CoreWidgetClass
:++
DOMWidgetClass
:++
[
'S
.
Index
,
'S
.
Name
,
'S
.
Mapping
,
'S
.
Connected
,
'S
.
Timestamp
,
'S
.
Buttons
,
'S
.
Axes
,
'S
.
ChangeHandler
]
WidgetFields
'C
o
ntrollerAxisType
=
CoreWidgetClass
:++
DOMWidgetClass
:++
'[
'S
.
FloatValue
,
'S
.
ChangeHandler
]
WidgetFields
'C
o
ntrollerButtonType
=
CoreWidgetClass
:++
DOMWidgetClass
:++
[
'S
.
FloatValue
,
'S
.
Pressed
,
'S
.
ChangeHandler
]
-- Wrapper around a field's value. A dummy value is sent as an empty string to the frontend.
-- Wrapper around a field's value. A dummy value is sent as an empty string to the frontend.
data
AttrVal
a
=
Dummy
a
data
AttrVal
a
=
Dummy
a
...
@@ -405,6 +423,7 @@ data Attr (f :: Field) where
...
@@ -405,6 +423,7 @@ data Attr (f :: Field) where
=>
{
_value
::
AttrVal
(
FieldType
f
)
=>
{
_value
::
AttrVal
(
FieldType
f
)
,
_verify
::
FieldType
f
->
IO
(
FieldType
f
)
,
_verify
::
FieldType
f
->
IO
(
FieldType
f
)
,
_field
::
Field
,
_field
::
Field
,
_ro
::
Bool
}
->
Attr
f
}
->
Attr
f
getFieldType
::
Attr
f
->
TypeRep
getFieldType
::
Attr
f
->
TypeRep
...
@@ -658,14 +677,39 @@ instance ToPairs (Attr 'S.Concise) where
...
@@ -658,14 +677,39 @@ instance ToPairs (Attr 'S.Concise) where
instance
ToPairs
(
Attr
'S
.
DateValue
)
where
instance
ToPairs
(
Attr
'S
.
DateValue
)
where
toPairs
x
=
[
"value"
.=
toJSON
x
]
toPairs
x
=
[
"value"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Pressed
)
where
toPairs
x
=
[
"pressed"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Name
)
where
toPairs
x
=
[
"name"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Mapping
)
where
toPairs
x
=
[
"mapping"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Connected
)
where
toPairs
x
=
[
"connected"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Timestamp
)
where
toPairs
x
=
[
"timestamp"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Buttons
)
where
toPairs
x
=
[
"buttons"
.=
toJSON
x
]
instance
ToPairs
(
Attr
'S
.
Axes
)
where
toPairs
x
=
[
"axes"
.=
toJSON
x
]
-- | Store the value for a field, as an object parametrized by the Field. No verification is done
-- | Store the value for a field, as an object parametrized by the Field. No verification is done
-- for these values.
-- for these values.
(
=::
)
::
(
SingI
f
,
Typeable
(
FieldType
f
))
=>
Sing
f
->
FieldType
f
->
Attr
f
(
=::
)
::
(
SingI
f
,
Typeable
(
FieldType
f
))
=>
Sing
f
->
FieldType
f
->
Attr
f
s
=::
x
=
Attr
{
_value
=
Real
x
,
_verify
=
return
,
_field
=
reflect
s
}
s
=::
x
=
Attr
{
_value
=
Real
x
,
_verify
=
return
,
_field
=
reflect
s
,
_ro
=
False
}
-- | Store the value for a field, with a custom verification
-- | Store the value for a field, with a custom verification
(
=:.
)
::
(
SingI
f
,
Typeable
(
FieldType
f
))
=>
Sing
f
->
(
FieldType
f
,
FieldType
f
->
IO
(
FieldType
f
)
)
->
Attr
f
(
=:.
)
::
(
SingI
f
,
Typeable
(
FieldType
f
))
=>
Sing
f
->
(
FieldType
f
,
FieldType
f
->
IO
(
FieldType
f
)
)
->
Attr
f
s
=:.
(
x
,
v
)
=
Attr
{
_value
=
Real
x
,
_verify
=
v
,
_field
=
reflect
s
}
s
=:.
(
x
,
v
)
=
Attr
{
_value
=
Real
x
,
_verify
=
v
,
_field
=
reflect
s
,
_ro
=
False
}
-- | Store the value for a field, making it read only from the frontend
(
=:!
)
::
(
SingI
f
,
Typeable
(
FieldType
f
))
=>
Sing
f
->
FieldType
f
->
Attr
f
s
=:!
x
=
Attr
{
_value
=
Real
x
,
_verify
=
return
,
_field
=
reflect
s
,
_ro
=
True
}
-- | If the number is in the range, return it. Otherwise raise the appropriate (over/under)flow
-- | If the number is in the range, return it. Otherwise raise the appropriate (over/under)flow
-- exception.
-- exception.
...
@@ -685,7 +729,7 @@ rangeSliderVerification _ = Ex.throw $ Ex.AssertionFailed "There should be two i
...
@@ -685,7 +729,7 @@ rangeSliderVerification _ = Ex.throw $ Ex.AssertionFailed "There should be two i
-- | Store a numeric value, with verification mechanism for its range.
-- | Store a numeric value, with verification mechanism for its range.
ranged
::
(
SingI
f
,
Num
(
FieldType
f
),
Ord
(
FieldType
f
),
Typeable
(
FieldType
f
))
ranged
::
(
SingI
f
,
Num
(
FieldType
f
),
Ord
(
FieldType
f
),
Typeable
(
FieldType
f
))
=>
Sing
f
->
(
FieldType
f
,
FieldType
f
)
->
AttrVal
(
FieldType
f
)
->
Attr
f
=>
Sing
f
->
(
FieldType
f
,
FieldType
f
)
->
AttrVal
(
FieldType
f
)
->
Attr
f
ranged
s
range
x
=
Attr
x
(
rangeCheck
range
)
(
reflect
s
)
ranged
s
range
x
=
Attr
x
(
rangeCheck
range
)
(
reflect
s
)
False
-- | Store a numeric value, with the invariant that it stays non-negative. The value set is set as a
-- | Store a numeric value, with the invariant that it stays non-negative. The value set is set as a
-- dummy value if it's equal to zero.
-- dummy value if it's equal to zero.
...
@@ -698,6 +742,7 @@ s =:+ val = Attr
...
@@ -698,6 +742,7 @@ s =:+ val = Attr
val
)
val
)
(
rangeCheck
(
0
,
upperBound
))
(
rangeCheck
(
0
,
upperBound
))
(
reflect
s
)
(
reflect
s
)
False
-- | Get a field from a singleton Adapted from: http://stackoverflow.com/a/28033250/2388535
-- | Get a field from a singleton Adapted from: http://stackoverflow.com/a/28033250/2388535
reflect
::
forall
(
f
::
Field
)
.
(
SingI
f
)
=>
Sing
f
->
Field
reflect
::
forall
(
f
::
Field
)
.
(
SingI
f
)
=>
Sing
f
->
Field
...
@@ -903,15 +948,17 @@ data IPythonWidget (w :: WidgetType) =
...
@@ -903,15 +948,17 @@ data IPythonWidget (w :: WidgetType) =
,
state
::
IORef
(
WidgetState
w
)
,
state
::
IORef
(
WidgetState
w
)
}
}
-- | Change the value for a field, and notify the frontend about it.
-- | Change the value for a field, and notify the frontend about it.
Doesn't work if the field is read only.
setField
::
(
f
∈
WidgetFields
w
,
IHaskellWidget
(
IPythonWidget
w
),
ToPairs
(
Attr
f
))
setField
::
(
f
∈
WidgetFields
w
,
IHaskellWidget
(
IPythonWidget
w
),
ToPairs
(
Attr
f
))
=>
IPythonWidget
w
->
SField
f
->
FieldType
f
->
IO
()
=>
IPythonWidget
w
->
SField
f
->
FieldType
f
->
IO
()
setField
widget
sfield
fval
=
do
setField
widget
sfield
fval
=
do
attr
<-
getAttr
widget
sfield
when
(
_ro
attr
)
$
error
(
"The field "
++
show
sfield
++
" is read only"
)
!
newattr
<-
setField'
widget
sfield
fval
!
newattr
<-
setField'
widget
sfield
fval
let
pairs
=
toPairs
newattr
let
pairs
=
toPairs
newattr
unless
(
null
pairs
)
$
widgetSendUpdate
widget
(
object
pairs
)
unless
(
null
pairs
)
$
widgetSendUpdate
widget
(
object
pairs
)
-- | Change the value of a field, without notifying the frontend. For internal use.
-- | Change the value of a field, without notifying the frontend
and without checking if is read only
. For internal use.
setField'
::
(
f
∈
WidgetFields
w
,
IHaskellWidget
(
IPythonWidget
w
))
setField'
::
(
f
∈
WidgetFields
w
,
IHaskellWidget
(
IPythonWidget
w
))
=>
IPythonWidget
w
->
SField
f
->
FieldType
f
->
IO
(
Attr
f
)
=>
IPythonWidget
w
->
SField
f
->
FieldType
f
->
IO
(
Attr
f
)
setField'
widget
sfield
val
=
do
setField'
widget
sfield
val
=
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment