@@ -3,8 +3,8 @@ module GridKit.Example.Example where
3
3
import Prelude hiding (div )
4
4
5
5
import Data.Array ((..))
6
- import Data.Int (toNumber , floor )
7
- import Data.Lens (Lens , (+~), (-~), (%~))
6
+ import Data.Int (toNumber , floor , even )
7
+ import Data.Lens (Lens' , (+~), (-~), (%~))
8
8
import Data.Lens.Record (prop )
9
9
import Data.Maybe
10
10
import Data.Number (fromString )
@@ -22,9 +22,12 @@ import Svg.Elements as S
22
22
import Svg.Attributes as S
23
23
24
24
import GridKit.KeyHandler
25
+ import GridKit.UIComponent
25
26
import View.ReactiveInput as ReactiveInput
26
- import View.GridKit.Grid as Grid
27
- import View.GridKit.Point as Point
27
+ import View.GridKit.Grid (Grid (..))
28
+ import View.GridKit.Point (Point (..))
29
+ import View.GridKit.Rect (Rect (..))
30
+
28
31
29
32
type Input = { }
30
33
@@ -40,44 +43,54 @@ type State =
40
43
, keyHelpVisible :: Boolean
41
44
}
42
45
43
- _logScale :: ∀ a b r . Lens { logScale :: a | r } { logScale :: b | r } a b
46
+ _logScale :: Lens' State Number
44
47
_logScale = prop (SProxy :: SProxy " logScale" )
45
48
46
- _keyHelpVisible :: ∀ a b r . Lens { keyHelpVisible :: a | r } { keyHelpVisible :: b | r } a b
49
+ _keyHelpVisible :: Lens' State Boolean
47
50
_keyHelpVisible = prop (SProxy :: SProxy " keyHelpVisible" )
48
51
49
- type ChildSlots =
50
- ( grid :: Grid.Slot Unit
51
- , point :: Point.Slot Int
52
- )
52
+ initialState :: State
53
+ initialState =
54
+ { logSpacing: 1.0
55
+ , logScale: 0.0
56
+ , posX: 0.0
57
+ , posY: 0.0
58
+ , radius: 0.5
59
+ , count: 10.0
60
+ , keyHelpVisible: false
61
+ }
62
+
53
63
54
- ui :: ∀ q m . MonadEffect m => H.Component HTML q Input Void m
64
+ data Thing = PointThing Point | RectThing Rect
65
+
66
+ instance uiComponentThing :: UIComponent Thing where
67
+ toSVG transform (PointThing p) = toSVG transform p
68
+ toSVG transform (RectThing r) = toSVG transform r
69
+
70
+ newtype Model = Model
71
+ { grid :: Grid
72
+ , things :: Array Thing
73
+ }
55
74
75
+ instance uiComponentModel :: UIComponent Model where
76
+ toSVG transform (Model { grid, things }) = toSVG transform grid <> toSVG transform things
77
+
78
+
79
+ ui :: ∀ q m . MonadEffect m => H.Component HTML q Input Void m
56
80
ui = ReactiveInput .mkComponent
57
- { initialState:
58
- { logSpacing: 1.0
59
- , logScale: 0.0
60
- , posX: 0.0
61
- , posY: 0.0
62
- , radius: 0.5
63
- , count: 10.0
64
- , keyHelpVisible: false
65
- }
81
+ { initialState
66
82
, render
67
83
, handleAction
68
84
, handleInput: \_ -> pure unit
69
85
}
70
86
71
- handleAction :: ∀ m . MonadEffect m => Input -> Action -> H.HalogenM State Action ChildSlots Void m Unit
87
+ handleAction :: ∀ m . MonadEffect m => Input -> Action -> H.HalogenM State Action () Void m Unit
72
88
handleAction _ (ChangeState f) = H .modify_ f
73
89
74
- render :: ∀ m . MonadEffect m => Input -> State -> H.ComponentHTML Action ChildSlots m
90
+ render :: ∀ m . MonadEffect m => Input -> State -> H.ComponentHTML Action () m
75
91
render _ { logSpacing, logScale, posX, posY, radius, count, keyHelpVisible } = div
76
92
[ tabIndex 0 , keys.onKeyDown ]
77
- [ S .svg [ S .width (_x size), S .height (_y size) ] $
78
- [ grid gridInput ] <>
79
- ((1 .. floor count) <#> \n ->
80
- point n { position: rotate (toNumber n * 2.0 * pi / count) `transform` point2 radius 0.0 , model2svg })
93
+ [ S .svg [ S .width (_x size), S .height (_y size) ] $ toSVG model2svg model <#> fromPlainHTML
81
94
, p_ [ input [ type_ InputRange , H .min 0.0 , H .max 2.0 , step Any , value (show logSpacing)
82
95
, onValueInput $ \s -> s # fromString <#> \v -> ChangeState (_ { logSpacing = v })
83
96
]
@@ -124,10 +137,17 @@ render _ { logSpacing, logScale, posX, posY, radius, count, keyHelpVisible } = d
124
137
125
138
model2svg = range `containedIn` size
126
139
127
- range = Box { topLeft: (vec2 (-0.5 ) (- 0.5 ) - pos) * pure scaling
128
- , bottomRight: (vec2 0.5 0.5 - pos) * pure scaling
140
+ range = Box { topLeft: pure (-0.5 * scaling ) - pos
141
+ , bottomRight: pure ( 0.5 * scaling) - pos
129
142
}
130
143
144
+ model = Model { grid: Grid { gridSpacing: pow 10.0 logSpacing, size }
145
+ , things: (1 .. floor count) <#> \n ->
146
+ let center = rotate (toNumber n * 2.0 * pi / count) `transform` point2 radius 0.0 in
147
+ if even n then RectThing $ Rect { topLeft: center - vec2 0.05 0.05 , size: vec2 0.1 0.1 }
148
+ else PointThing $ Point center
149
+ }
150
+
131
151
zoomInKey = keyHandler
132
152
[ Shortcut metaKey " Equal" , Shortcut ctrlKey " Equal" ]
133
153
(Just $ text " Zoom in" )
@@ -142,12 +162,6 @@ render _ { logSpacing, logScale, posX, posY, radius, count, keyHelpVisible } = d
142
162
, popupAction: ChangeState $ _keyHelpVisible %~ not
143
163
}
144
164
145
- grid :: ∀ m . MonadEffect m => Grid.Input -> H.ComponentHTML Action ChildSlots m
146
- grid input = slot (SProxy :: SProxy " grid" ) unit Grid .ui input (const Nothing )
147
-
148
- point :: ∀ m . MonadEffect m => Int -> Point.Input -> H.ComponentHTML Action ChildSlots m
149
- point id input = slot (SProxy :: SProxy " point" ) id Point .ui input (const Nothing )
150
-
151
165
152
166
containedIn :: Box Number -> Vec2 Number -> AffineTransform Number
153
167
containedIn range size = translate svgCenter * scale scaleMin * translate (-rangeCenter)
0 commit comments