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
4cb50d5a
Commit
4cb50d5a
authored
Aug 20, 2015
by
Sumit Sahrawat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for more expressive arguments
parent
1310fffc
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
42 deletions
+47
-42
Interactive.hs
...skell-widgets/src/IHaskell/Display/Widgets/Interactive.hs
+47
-42
No files found.
ihaskell-display/ihaskell-widgets/src/IHaskell/Display/Widgets/Interactive.hs
View file @
4cb50d5a
...
...
@@ -12,10 +12,9 @@
module
IHaskell.Display.Widgets.Interactive
(
interactive
,
ArgList
,
(
.&
),
pattern
ArgNil
,
uncurryArgList
,
uncurryHList
,
Rec
(
..
),
Argument
(
..
),
)
where
import
Data.Text
...
...
@@ -41,7 +40,7 @@ import IHaskell.Display.Widgets.Float.BoundedFloat.FloatSlider
import
IHaskell.Display.Widgets.Output
data
WidgetConf
a
where
WidgetConf
::
RecAll
Attr
(
WidgetFields
(
SuitableWidget
a
))
ToPairs
WidgetConf
::
(
RecAll
Attr
(
WidgetFields
(
SuitableWidget
a
))
ToPairs
,
FromWidget
a
)
=>
WrappedWidget
(
SuitableWidget
a
)
(
SuitableHandler
a
)
(
SuitableField
a
)
a
->
WidgetConf
a
...
...
@@ -53,21 +52,9 @@ type family WithTypes (ts :: [*]) (r :: *) :: * where
WithTypes
'[
]
r
=
r
WithTypes
(
x
':
xs
)
r
=
(
x
->
WithTypes
xs
r
)
-- | Abstract heterogeneous list of arguments
newtype
ArgList
ts
=
ArgList
{
getList
::
HList
ts
}
-- | Providing syntax to prevent having to use vinyl record style (@Identity x :& xs@) everywhere
infixr
9
.&
(
.&
)
::
t
->
ArgList
ts
->
ArgList
(
t
':
ts
)
x
.&
ArgList
y
=
ArgList
(
Identity
x
:&
y
)
-- | Alias for empty arglist
pattern
ArgNil
=
ArgList
RNil
-- | Convert a function to one accepting an ArgList
uncurryArgList
::
WithTypes
ts
r
->
ArgList
ts
->
r
uncurryArgList
f
(
ArgList
RNil
)
=
f
uncurryArgList
f
(
ArgList
(
Identity
x
:&
xs
))
=
uncurryArgList
(
f
x
)
(
ArgList
xs
)
uncurryHList
::
WithTypes
ts
r
->
HList
ts
->
r
uncurryHList
f
RNil
=
f
uncurryHList
f
(
Identity
x
:&
xs
)
=
uncurryHList
(
f
x
)
xs
-- Consistent type variables are required to make things play nicely with vinyl
data
Constructor
a
where
...
...
@@ -75,7 +62,7 @@ data Constructor a where
=>
IO
(
IPythonWidget
(
SuitableWidget
a
))
->
Constructor
a
newtype
Getter
a
=
Getter
(
IPythonWidget
(
SuitableWidget
a
)
->
IO
a
)
newtype
EventSetter
a
=
EventSetter
(
IPythonWidget
(
SuitableWidget
a
)
->
IO
()
->
IO
()
)
newtype
ValueSetter
a
=
ValueSetter
(
IPythonWidget
(
SuitableWidget
a
)
->
a
->
IO
()
)
newtype
Initializer
a
=
Initializer
(
IPythonWidget
(
SuitableWidget
a
)
->
Argument
a
->
IO
()
)
newtype
Trigger
a
=
Trigger
(
IPythonWidget
(
SuitableWidget
a
)
->
IO
()
)
data
RequiredWidget
a
where
RequiredWidget
::
RecAll
Attr
(
WidgetFields
(
SuitableWidget
a
))
ToPairs
...
...
@@ -96,11 +83,11 @@ applyEventSetters (EventSetter setter :& xs) (RequiredWidget widget :& ws) handl
setter
widget
handler
applyEventSetters
xs
ws
handler
applyValueSetters
::
Rec
ValueSetter
ts
->
Rec
RequiredWidget
ts
->
HLis
t
ts
->
IO
()
applyValueSetter
s
RNil
RNil
RNil
=
return
()
applyValueSetters
(
ValueSetter
setter
:&
xs
)
(
RequiredWidget
widget
:&
ws
)
(
Identity
value
:&
vs
)
=
do
setter
widget
value
applyValueSetters
x
s
ws
vs
setInitialValues
::
Rec
Initializer
ts
->
Rec
RequiredWidget
ts
->
Rec
Argumen
t
ts
->
IO
()
setInitialValue
s
RNil
RNil
RNil
=
return
()
setInitialValues
(
Initializer
initializer
:&
fs
)
(
RequiredWidget
widget
:&
ws
)
(
argument
:&
vs
)
=
do
initializer
widget
argument
setInitialValues
f
s
ws
vs
extractConstructor
::
WidgetConf
x
->
Constructor
x
extractConstructor
(
WidgetConf
wr
)
=
Constructor
$
construct
wr
...
...
@@ -114,11 +101,10 @@ extractEventSetter (WidgetConf wr) = EventSetter $ setEvent wr
extractTrigger
::
WidgetConf
x
->
Trigger
x
extractTrigger
(
WidgetConf
wr
)
=
Trigger
$
trigger
wr
extract
ValueSetter
::
WidgetConf
x
->
ValueSett
er
x
extract
ValueSetter
(
WidgetConf
wr
)
=
ValueSetter
$
setValue
w
r
extract
Initializer
::
WidgetConf
x
->
Initializ
er
x
extract
Initializer
(
WidgetConf
wr
)
=
Initializer
initialize
r
createWidget
::
Constructor
a
->
IO
(
RequiredWidget
a
)
createWidget
::
Constructor
a
->
IO
(
RequiredWidget
a
)
createWidget
(
Constructor
con
)
=
fmap
RequiredWidget
con
mkChildren
::
Rec
RequiredWidget
a
->
[
ChildWidget
]
...
...
@@ -134,22 +120,22 @@ instance MakeConfs '[] where
instance
(
FromWidget
t
,
MakeConfs
ts
)
=>
MakeConfs
(
t
':
ts
)
where
mkConfs
_
=
WidgetConf
wrapped
:&
mkConfs
(
Proxy
::
Proxy
ts
)
-- | Interacting with a function on ArgList instead of values
interactive
::
(
IHaskellDisplay
r
,
MakeConfs
ts
)
=>
(
ArgList
ts
->
r
)
->
ArgLis
t
ts
->
IO
FlexBox
=>
(
HList
ts
->
r
)
->
Rec
Argumen
t
ts
->
IO
FlexBox
interactive
func
=
let
confs
=
mkConfs
Proxy
in
liftToWidgets
func
confs
-- | Transform a function (ArgList ts -> r) to one using widgets to fill the ArgList, accepting
-- default values for those widgets and returning all widgets as a composite FlexBox widget with
-- and embedded OutputWidget for display.
-- | Transform a function (HList ts -> r) to one which:
-- 1) Uses widgets to accept the arguments
-- 2) Accepts initial values for the arguments
-- 3) Creates a compound FlexBox widget with an embedded OutputWidget for display
liftToWidgets
::
IHaskellDisplay
r
=>
(
ArgList
ts
->
r
)
->
Rec
WidgetConf
ts
->
ArgLis
t
ts
->
IO
FlexBox
liftToWidgets
func
rc
def
vals
=
do
=>
(
HList
ts
->
r
)
->
Rec
WidgetConf
ts
->
Rec
Argumen
t
ts
->
IO
FlexBox
liftToWidgets
func
rc
init
vals
=
do
let
constructors
=
rmap
extractConstructor
rc
getters
=
rmap
extractGetter
rc
eventSetters
=
rmap
extractEventSetter
rc
valueSetters
=
rmap
extractValueSett
er
rc
initializers
=
rmap
extractInitializ
er
rc
triggers
=
rmap
extractTrigger
rc
bx
<-
mkFlexBox
...
...
@@ -160,13 +146,14 @@ liftToWidgets func rc defvals = do
let
handler
=
do
vals
<-
applyGetters
getters
widgets
replaceOutput
out
$
func
$
ArgList
vals
replaceOutput
out
$
func
vals
-- Apply handler to all widgets
applyEventSetters
eventSetters
widgets
handler
-- Set default values for all widgets
applyValueSetters
valueSetters
widgets
$
getList
defvals
-- Set initial values for all widgets
setInitialValues
initializers
widgets
initvals
-- applyValueSetters valueSetters widgets $ getList defvals
setField
out
Width
500
setField
bx
Orientation
VerticalOrientation
...
...
@@ -197,32 +184,50 @@ setEvent (WrappedWidget _ h _) widget = setField widget h
trigger
::
WrappedWidget
w
h
f
a
->
IPythonWidget
w
->
IO
()
trigger
(
WrappedWidget
_
h
_
)
=
triggerEvent
h
class
(
RecAll
Attr
(
WidgetFields
(
SuitableWidget
a
))
ToPairs
)
=>
FromWidget
a
where
class
RecAll
Attr
(
WidgetFields
(
SuitableWidget
a
))
ToPairs
=>
FromWidget
a
where
type
SuitableWidget
a
::
WidgetType
type
SuitableHandler
a
::
S
.
Field
type
SuitableField
a
::
S
.
Field
data
Argument
a
initializer
::
IPythonWidget
(
SuitableWidget
a
)
->
Argument
a
->
IO
()
wrapped
::
WrappedWidget
(
SuitableWidget
a
)
(
SuitableHandler
a
)
(
SuitableField
a
)
a
instance
FromWidget
Bool
where
type
SuitableWidget
Bool
=
CheckBoxType
type
SuitableHandler
Bool
=
S
.
ChangeHandler
type
SuitableField
Bool
=
S
.
BoolValue
data
Argument
Bool
=
BoolVal
Bool
initializer
w
(
BoolVal
b
)
=
setField
w
BoolValue
b
wrapped
=
WrappedWidget
mkCheckBox
ChangeHandler
BoolValue
instance
FromWidget
Text
where
type
SuitableWidget
Text
=
TextType
type
SuitableHandler
Text
=
S
.
SubmitHandler
type
SuitableField
Text
=
S
.
StringValue
data
Argument
Text
=
TextVal
Text
initializer
w
(
TextVal
txt
)
=
setField
w
StringValue
txt
wrapped
=
WrappedWidget
mkTextWidget
SubmitHandler
StringValue
instance
FromWidget
Integer
where
type
SuitableWidget
Integer
=
IntSliderType
type
SuitableHandler
Integer
=
S
.
ChangeHandler
type
SuitableField
Integer
=
S
.
IntValue
data
Argument
Integer
=
IntVal
Integer
|
IntRange
(
Integer
,
Integer
,
Integer
)
wrapped
=
WrappedWidget
mkIntSlider
ChangeHandler
IntValue
initializer
w
(
IntVal
int
)
=
setField
w
IntValue
int
initializer
w
(
IntRange
(
v
,
l
,
u
))
=
do
setField
w
IntValue
v
setField
w
MinInt
l
setField
w
MaxInt
u
instance
FromWidget
Double
where
type
SuitableWidget
Double
=
FloatSliderType
type
SuitableHandler
Double
=
S
.
ChangeHandler
type
SuitableField
Double
=
S
.
FloatValue
data
Argument
Double
=
FloatVal
Double
|
FloatRange
(
Double
,
Double
,
Double
)
wrapped
=
WrappedWidget
mkFloatSlider
ChangeHandler
FloatValue
initializer
w
(
FloatVal
d
)
=
setField
w
FloatValue
d
initializer
w
(
FloatRange
(
v
,
l
,
u
))
=
do
setField
w
FloatValue
v
setField
w
MinFloat
l
setField
w
MaxFloat
u
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