desck 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +21 -0
- package/README.md +176 -0
- package/desck.cjs +2 -0
- package/elm.json +39 -0
- package/justfile +13 -0
- package/package.json +25 -0
- package/public/index.html +30 -0
- package/public/palette.json +16 -0
- package/public/projects/something.json +139 -0
- package/public/projects/template.json +69 -0
- package/public/script.js +490 -0
- package/public/style.css +471 -0
- package/public/svg/backface.svg +1 -0
- package/public/svg/courts.svg +30 -0
- package/public/svg/digits.svg +18 -0
- package/public/svg/suits.svg +43 -0
- package/server.cjs +316 -0
- package/settings.json +10 -0
- package/src/Card.elm +38 -0
- package/src/ColorPicker.elm +113 -0
- package/src/Deck.elm +571 -0
- package/src/DeckView.elm +415 -0
- package/src/Layout.elm +224 -0
- package/src/Main.elm +3743 -0
- package/src/Palette.elm +302 -0
- package/src/Project.elm +1029 -0
- package/src/Rect.elm +292 -0
- package/src/SaveFile.elm +422 -0
- package/src/Theme.elm +99 -0
- package/src/Util.elm +337 -0
- package/src/Vec.elm +196 -0
- package/src/Zone.elm +364 -0
package/src/Rect.elm
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
module Rect exposing (..)
|
|
2
|
+
|
|
3
|
+
import Vec exposing (Vec2)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
type alias Rect =
|
|
7
|
+
{ pos : Vec2
|
|
8
|
+
, size : Vec2
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
type RectCoordinate
|
|
13
|
+
= PosX
|
|
14
|
+
| PosY
|
|
15
|
+
| SizeX
|
|
16
|
+
| SizeY
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
rect2 : Vec2 -> Vec2 -> Rect
|
|
20
|
+
rect2 pos size =
|
|
21
|
+
{ pos = pos
|
|
22
|
+
, size = size
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
rect4 : Float -> Float -> Float -> Float -> Rect
|
|
27
|
+
rect4 x y w h =
|
|
28
|
+
rect2 (Vec.vec2 x y) (Vec.vec2 w h)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
rightCorner : Rect -> Vec2
|
|
32
|
+
rightCorner rect =
|
|
33
|
+
Vec.add rect.pos rect.size
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
includeRect : Rect -> Rect -> Rect
|
|
37
|
+
includeRect r rect =
|
|
38
|
+
let
|
|
39
|
+
pos =
|
|
40
|
+
Vec.vec2 (min rect.pos.x r.pos.x) (min rect.pos.y r.pos.y)
|
|
41
|
+
|
|
42
|
+
corner =
|
|
43
|
+
Vec.max (rightCorner rect) (rightCorner r)
|
|
44
|
+
in
|
|
45
|
+
{ pos = pos
|
|
46
|
+
, size = Vec.sub corner pos
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
includeVec : Rect -> Vec2 -> Rect
|
|
51
|
+
includeVec r v =
|
|
52
|
+
includeRect r (rect2 v Vec.zero)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
toPoints : Rect -> List Vec2
|
|
56
|
+
toPoints r =
|
|
57
|
+
[ r.pos
|
|
58
|
+
, Vec.vec2 (r.pos.x + r.size.x) r.pos.y
|
|
59
|
+
, Vec.vec2 (r.pos.x + r.size.x) (r.pos.y + r.size.y)
|
|
60
|
+
, Vec.vec2 r.pos.x (r.pos.y + r.size.y)
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
fromPoints : List Vec2 -> Rect
|
|
65
|
+
fromPoints points =
|
|
66
|
+
let
|
|
67
|
+
r =
|
|
68
|
+
rect2 (Vec.average points) Vec.zero
|
|
69
|
+
in
|
|
70
|
+
List.foldl (\p a -> includeVec a p) r points
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
enlarge : Float -> Rect -> Rect
|
|
74
|
+
enlarge f r =
|
|
75
|
+
let
|
|
76
|
+
v =
|
|
77
|
+
Vec.scale f Vec.one
|
|
78
|
+
|
|
79
|
+
v2 =
|
|
80
|
+
Vec.scale (f * 0.5) Vec.one
|
|
81
|
+
in
|
|
82
|
+
{ pos = Vec.sub r.pos v2
|
|
83
|
+
, size = Vec.add r.size v
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
shrink : Float -> Rect -> Rect
|
|
88
|
+
shrink f r =
|
|
89
|
+
let
|
|
90
|
+
v =
|
|
91
|
+
Vec.scale f Vec.one
|
|
92
|
+
|
|
93
|
+
v2 =
|
|
94
|
+
Vec.scale (f * 0.5) Vec.one
|
|
95
|
+
in
|
|
96
|
+
{ pos = Vec.add r.pos v2
|
|
97
|
+
, size = Vec.sub r.size v
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
changeSize : Vec2 -> Rect -> Rect
|
|
102
|
+
changeSize v r =
|
|
103
|
+
let
|
|
104
|
+
v2 =
|
|
105
|
+
Vec.scale 0.5 v
|
|
106
|
+
in
|
|
107
|
+
rect2 (Vec.add r.pos v2) (Vec.add r.size (Vec.scale -1.0 v))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
scale : Float -> Rect -> Rect
|
|
111
|
+
scale f r =
|
|
112
|
+
let
|
|
113
|
+
size =
|
|
114
|
+
Vec.scale f r.size
|
|
115
|
+
|
|
116
|
+
change =
|
|
117
|
+
Vec.sub r.size size
|
|
118
|
+
in
|
|
119
|
+
changeSize change r
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
normalizeRect : Vec2 -> Vec2 -> Rect
|
|
123
|
+
normalizeRect a b =
|
|
124
|
+
let
|
|
125
|
+
pos =
|
|
126
|
+
Vec.min a b
|
|
127
|
+
|
|
128
|
+
corner =
|
|
129
|
+
Vec.max a b
|
|
130
|
+
in
|
|
131
|
+
rect2 pos (Vec.sub corner pos)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
hasPoint : Vec2 -> Rect -> Bool
|
|
135
|
+
hasPoint p r =
|
|
136
|
+
r.pos.x <= p.x && r.pos.y <= p.y && r.pos.x + r.size.x >= p.x && r.pos.y + r.size.y >= p.y
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
hasRect : Rect -> Rect -> Bool
|
|
140
|
+
hasRect a b =
|
|
141
|
+
hasPoint b.pos a
|
|
142
|
+
&& hasPoint (Vec.add b.pos b.size) a
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
overlaps : Rect -> Rect -> Bool
|
|
146
|
+
overlaps a b =
|
|
147
|
+
rectanglesIntersect ( a.pos.x, a.pos.y )
|
|
148
|
+
( a.pos.x + a.size.x, a.pos.y + a.size.y )
|
|
149
|
+
( b.pos.x, b.pos.y )
|
|
150
|
+
( b.pos.x + b.size.x, b.pos.y + b.size.y )
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
rectangleContains : Vec2 -> Vec2 -> Vec2 -> Vec2 -> Bool
|
|
154
|
+
rectangleContains a1 b1 a2 b2 =
|
|
155
|
+
let
|
|
156
|
+
r =
|
|
157
|
+
normalizeRect a1 b1
|
|
158
|
+
|
|
159
|
+
c1 =
|
|
160
|
+
r.pos
|
|
161
|
+
|
|
162
|
+
d1 =
|
|
163
|
+
rightCorner r
|
|
164
|
+
in
|
|
165
|
+
c1.x < a2.x && d1.x > b2.x && c1.y < a2.y && d1.y > b2.y
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
rectanglesIntersect : ( Float, Float ) -> ( Float, Float ) -> ( Float, Float ) -> ( Float, Float ) -> Bool
|
|
169
|
+
rectanglesIntersect ( x1a, y1a ) ( x1b, y1b ) ( x2a, y2a ) ( x2b, y2b ) =
|
|
170
|
+
let
|
|
171
|
+
x1_min =
|
|
172
|
+
min x1a x1b
|
|
173
|
+
|
|
174
|
+
y1_min =
|
|
175
|
+
min y1a y1b
|
|
176
|
+
|
|
177
|
+
x1_max =
|
|
178
|
+
max x1a x1b
|
|
179
|
+
|
|
180
|
+
y1_max =
|
|
181
|
+
max y1a y1b
|
|
182
|
+
|
|
183
|
+
x2_min =
|
|
184
|
+
min x2a x2b
|
|
185
|
+
|
|
186
|
+
y2_min =
|
|
187
|
+
min y2a y2b
|
|
188
|
+
|
|
189
|
+
x2_max =
|
|
190
|
+
max x2a x2b
|
|
191
|
+
|
|
192
|
+
y2_max =
|
|
193
|
+
max y2a y2b
|
|
194
|
+
in
|
|
195
|
+
not (x1_max < x2_min || x2_max < x1_min || y1_max < y2_min || y2_max < y1_min)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
modifyRect : Rect -> Rect -> RectCoordinate -> Float -> Rect
|
|
199
|
+
modifyRect rect factor rc v =
|
|
200
|
+
let
|
|
201
|
+
{ pos, size } =
|
|
202
|
+
rect
|
|
203
|
+
in
|
|
204
|
+
case rc of
|
|
205
|
+
PosX ->
|
|
206
|
+
{ rect | pos = Vec.setX (v * factor.pos.x) pos }
|
|
207
|
+
|
|
208
|
+
PosY ->
|
|
209
|
+
{ rect | pos = Vec.setY (v * factor.pos.y) pos }
|
|
210
|
+
|
|
211
|
+
SizeX ->
|
|
212
|
+
{ rect | size = Vec.setX (v * factor.size.x) size }
|
|
213
|
+
|
|
214
|
+
SizeY ->
|
|
215
|
+
{ rect | size = Vec.setY (v * factor.size.y) size }
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
minSized : Vec2 -> Rect -> Rect
|
|
219
|
+
minSized minSize rect =
|
|
220
|
+
{ rect | size = Vec.vec2 (max minSize.x rect.size.x) (max minSize.y rect.size.y) }
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
center : Rect -> Vec2
|
|
224
|
+
center r =
|
|
225
|
+
Vec.half r.size
|
|
226
|
+
|> Vec.add r.pos
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
rectString : Rect -> String
|
|
230
|
+
rectString r =
|
|
231
|
+
String.fromFloat r.pos.x
|
|
232
|
+
++ " "
|
|
233
|
+
++ String.fromFloat r.pos.y
|
|
234
|
+
++ " "
|
|
235
|
+
++ String.fromFloat r.size.x
|
|
236
|
+
++ " "
|
|
237
|
+
++ String.fromFloat r.size.y
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
showRect : Rect -> String
|
|
241
|
+
showRect r =
|
|
242
|
+
Vec.show r.pos ++ " : " ++ Vec.show r.size
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
area : Rect -> Float
|
|
246
|
+
area r =
|
|
247
|
+
r.size.x * r.size.y
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
fitToCenter : Vec2 -> Vec2 -> Rect
|
|
251
|
+
fitToCenter viewport window =
|
|
252
|
+
let
|
|
253
|
+
imgWidth =
|
|
254
|
+
viewport.x
|
|
255
|
+
|
|
256
|
+
imgHeight =
|
|
257
|
+
viewport.y
|
|
258
|
+
|
|
259
|
+
winWidth =
|
|
260
|
+
window.x
|
|
261
|
+
|
|
262
|
+
winHeight =
|
|
263
|
+
window.y
|
|
264
|
+
|
|
265
|
+
ratio =
|
|
266
|
+
min (winWidth / imgWidth) (winHeight / imgHeight)
|
|
267
|
+
|
|
268
|
+
w =
|
|
269
|
+
imgWidth * ratio
|
|
270
|
+
|
|
271
|
+
h =
|
|
272
|
+
imgHeight * ratio
|
|
273
|
+
in
|
|
274
|
+
{ pos = Vec2 ((winWidth - w) / 2.0) ((winHeight - h) / 2.0), size = Vec2 w h }
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
clamp : Rect -> Vec2 -> Vec2
|
|
278
|
+
clamp r p =
|
|
279
|
+
Vec.vec2 (Basics.clamp r.pos.x (r.pos.x + r.size.x) p.x) (Basics.clamp r.pos.y (r.pos.y + r.size.y) p.y)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
type alias Rotation =
|
|
283
|
+
{ angle : Float
|
|
284
|
+
, pivot : Vec2
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
angled : Float -> Rotation
|
|
289
|
+
angled a =
|
|
290
|
+
{ pivot = Vec.half Vec.one
|
|
291
|
+
, angle = a
|
|
292
|
+
}
|
package/src/SaveFile.elm
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
module SaveFile exposing (..)
|
|
2
|
+
|
|
3
|
+
import Card exposing (Card)
|
|
4
|
+
import Deck exposing (encodeModel, modelDecoder)
|
|
5
|
+
import Json.Decode as D exposing (Decoder)
|
|
6
|
+
import Json.Decode.Pipeline exposing (optional, required)
|
|
7
|
+
import Json.Encode exposing (Value, bool, float, int, list, null, object, string)
|
|
8
|
+
import Palette exposing (Color(..), Palette, colorAsString, colorFromString)
|
|
9
|
+
import Project exposing (Project)
|
|
10
|
+
import Rect exposing (Rect, Rotation)
|
|
11
|
+
import Theme
|
|
12
|
+
import Util exposing (..)
|
|
13
|
+
import Vec exposing (Vec2)
|
|
14
|
+
import Zone exposing (Anchor, Arrow, Border, Grid, Head, Stamp, Text, Zone, headFromString, headString)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
-- TODO implement version field
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
type alias Settings =
|
|
22
|
+
{ embedSymbols : Bool
|
|
23
|
+
, stripData : Bool
|
|
24
|
+
, mapColors : Bool
|
|
25
|
+
, mapFont : Bool
|
|
26
|
+
, primaryFont : Maybe String
|
|
27
|
+
, secondaryFont : Maybe String
|
|
28
|
+
, heightPixels : Int
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
default_settings : Settings
|
|
33
|
+
default_settings =
|
|
34
|
+
{ embedSymbols = True
|
|
35
|
+
, stripData = False
|
|
36
|
+
, mapColors = True
|
|
37
|
+
, mapFont = True
|
|
38
|
+
, primaryFont = Nothing
|
|
39
|
+
, secondaryFont = Nothing
|
|
40
|
+
, heightPixels = 128
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
type alias SaveFile =
|
|
45
|
+
{ name : String
|
|
46
|
+
, project : Project
|
|
47
|
+
, palette : Palette
|
|
48
|
+
, settings : Settings
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
-- hsl : Float -> Float -> Float -> C.Color
|
|
54
|
+
-- hsl h s l =
|
|
55
|
+
-- C.fromHsla { hue = h, saturation = s, lightness = l, alpha = 1.0 }
|
|
56
|
+
-- colorDecoder : Decoder Color
|
|
57
|
+
-- colorDecoder =
|
|
58
|
+
-- D.map3 hsl
|
|
59
|
+
-- (D.field "h" D.float)
|
|
60
|
+
-- (D.field "s" D.float)
|
|
61
|
+
-- (D.field "l" D.float)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
anchorDecoder : Decoder Anchor
|
|
65
|
+
anchorDecoder =
|
|
66
|
+
enumDecoder
|
|
67
|
+
(\s -> Just <| Zone.anchorFromString s)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
paletteDecoder : Decoder Palette
|
|
71
|
+
paletteDecoder =
|
|
72
|
+
D.succeed Palette
|
|
73
|
+
|> required "black" D.string
|
|
74
|
+
|> required "white" D.string
|
|
75
|
+
|> required "red" D.string
|
|
76
|
+
|> required "orange" D.string
|
|
77
|
+
|> required "yellow" D.string
|
|
78
|
+
|> required "green" D.string
|
|
79
|
+
|> required "cyan" D.string
|
|
80
|
+
|> required "blue" D.string
|
|
81
|
+
|> required "violet" D.string
|
|
82
|
+
|> required "pink" D.string
|
|
83
|
+
|> required "darkGray" D.string
|
|
84
|
+
|> required "midGray" D.string
|
|
85
|
+
|> required "lightGray" D.string
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
-- encodeColor : C.Color -> Value
|
|
90
|
+
-- encodeColor c =
|
|
91
|
+
-- let
|
|
92
|
+
-- { hue, saturation, lightness } =
|
|
93
|
+
-- C.toHsla c
|
|
94
|
+
-- in
|
|
95
|
+
-- object
|
|
96
|
+
-- [ ( "h", float hue )
|
|
97
|
+
-- , ( "s", float saturation )
|
|
98
|
+
-- , ( "l", float lightness )
|
|
99
|
+
-- ]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
encodePalette : Palette -> Value
|
|
103
|
+
encodePalette p =
|
|
104
|
+
object
|
|
105
|
+
[ ( "black", string p.black )
|
|
106
|
+
, ( "white", string p.white )
|
|
107
|
+
, ( "red", string p.red )
|
|
108
|
+
, ( "orange", string p.orange )
|
|
109
|
+
, ( "yellow", string p.yellow )
|
|
110
|
+
, ( "green", string p.green )
|
|
111
|
+
, ( "cyan", string p.cyan )
|
|
112
|
+
, ( "blue", string p.blue )
|
|
113
|
+
, ( "violet", string p.violet )
|
|
114
|
+
, ( "pink", string p.pink )
|
|
115
|
+
, ( "darkGray", string p.darkGray )
|
|
116
|
+
, ( "midGray", string p.midGray )
|
|
117
|
+
, ( "lightGray", string p.lightGray )
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
color : Color -> Value
|
|
122
|
+
color c =
|
|
123
|
+
string <| colorAsString c
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
encodeArrow : Arrow -> Value
|
|
127
|
+
encodeArrow a =
|
|
128
|
+
object
|
|
129
|
+
[ ( "from", string a.from )
|
|
130
|
+
, ( "to", string a.to )
|
|
131
|
+
, ( "id", string a.id )
|
|
132
|
+
, ( "fill", color a.fill )
|
|
133
|
+
, ( "width", float a.width )
|
|
134
|
+
, ( "head", string <| headString a.head )
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
fromResult : Result a b -> Decoder b
|
|
139
|
+
fromResult result =
|
|
140
|
+
case result of
|
|
141
|
+
Ok a ->
|
|
142
|
+
D.succeed a
|
|
143
|
+
|
|
144
|
+
Err _ ->
|
|
145
|
+
D.fail "error decoding"
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
vec2Decoder : Decoder Vec2
|
|
149
|
+
vec2Decoder =
|
|
150
|
+
D.map2 Vec2
|
|
151
|
+
(D.field "x" D.float)
|
|
152
|
+
(D.field "y" D.float)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
rectDecoder : Decoder Rect
|
|
156
|
+
rectDecoder =
|
|
157
|
+
D.map2 Rect
|
|
158
|
+
(D.field "pos" vec2Decoder)
|
|
159
|
+
(D.field "size" vec2Decoder)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
cardDecoder : Decoder Card
|
|
163
|
+
cardDecoder =
|
|
164
|
+
D.map7 Card
|
|
165
|
+
(D.field "model" modelDecoder)
|
|
166
|
+
(D.field "rect" rectDecoder)
|
|
167
|
+
(D.field "rot" rotDecoder)
|
|
168
|
+
(D.field "front" D.bool)
|
|
169
|
+
(D.field "highlight" D.bool)
|
|
170
|
+
(D.field "id" D.string)
|
|
171
|
+
(D.field "z" D.int)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
paletteColorDecoder : Decoder Color
|
|
175
|
+
paletteColorDecoder =
|
|
176
|
+
D.string
|
|
177
|
+
|> D.andThen
|
|
178
|
+
(\str ->
|
|
179
|
+
D.succeed <| colorFromString str
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
borderDecode : Decoder Border
|
|
184
|
+
borderDecode =
|
|
185
|
+
D.map3 Border
|
|
186
|
+
(D.field "color" paletteColorDecoder)
|
|
187
|
+
(D.field "width" D.int)
|
|
188
|
+
(D.field "dash" D.int)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
textDecoder : Decoder Text
|
|
192
|
+
textDecoder =
|
|
193
|
+
D.map5 Text
|
|
194
|
+
(D.field "label" D.string)
|
|
195
|
+
(D.field "color" paletteColorDecoder)
|
|
196
|
+
(D.field "size" D.int)
|
|
197
|
+
(D.field "primary" D.bool)
|
|
198
|
+
(D.field "anchor" anchorDecoder)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
gridDecoder : Decoder Grid
|
|
202
|
+
gridDecoder =
|
|
203
|
+
D.map2 Grid
|
|
204
|
+
(D.field "rows" D.int)
|
|
205
|
+
(D.field "columns" D.int)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
rotDecoder : Decoder Rotation
|
|
209
|
+
rotDecoder =
|
|
210
|
+
D.map2 Rotation
|
|
211
|
+
(D.field "angle" D.float)
|
|
212
|
+
(D.field "pivot" vec2Decoder)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
zoneDecoder : Decoder Zone
|
|
216
|
+
zoneDecoder =
|
|
217
|
+
D.map7 Zone
|
|
218
|
+
(D.field "rect" rectDecoder)
|
|
219
|
+
(D.field "rot" rotDecoder)
|
|
220
|
+
(D.field "id" D.string)
|
|
221
|
+
(D.field "fill" paletteColorDecoder)
|
|
222
|
+
(D.field "border" borderDecode)
|
|
223
|
+
(D.field "text" textDecoder)
|
|
224
|
+
(D.field "grid" gridDecoder)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
headDecoder : Decoder Head
|
|
228
|
+
headDecoder =
|
|
229
|
+
enumDecoder
|
|
230
|
+
(\s -> Just <| headFromString s)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
arrowDecoder : Decoder Arrow
|
|
234
|
+
arrowDecoder =
|
|
235
|
+
D.map6 Arrow
|
|
236
|
+
(D.field "from" D.string)
|
|
237
|
+
(D.field "to" D.string)
|
|
238
|
+
(D.field "id" D.string)
|
|
239
|
+
(D.field "fill" paletteColorDecoder)
|
|
240
|
+
(D.field "width" D.float)
|
|
241
|
+
(D.field "head" headDecoder)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
settingsDecoder : Decoder Settings
|
|
245
|
+
settingsDecoder =
|
|
246
|
+
D.succeed Settings
|
|
247
|
+
|> optional "embedSymbols" D.bool False
|
|
248
|
+
|> optional "stripData" D.bool False
|
|
249
|
+
|> optional "mapColors" D.bool True
|
|
250
|
+
|> optional "mapFont" D.bool True
|
|
251
|
+
|> optional "primaryFont" (D.nullable D.string) Nothing
|
|
252
|
+
|> optional "secondaryFont" (D.nullable D.string) Nothing
|
|
253
|
+
|> optional "heightPixels" D.int 128
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
stampDecoder : Decoder Stamp
|
|
257
|
+
stampDecoder =
|
|
258
|
+
D.map5 Stamp
|
|
259
|
+
(D.field "pos" vec2Decoder)
|
|
260
|
+
(D.field "id" D.string)
|
|
261
|
+
(D.field "text" textDecoder)
|
|
262
|
+
(D.field "fill" paletteColorDecoder)
|
|
263
|
+
(D.field "radius" D.float)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
projectDecoder : Decoder Project
|
|
267
|
+
projectDecoder =
|
|
268
|
+
D.succeed Project
|
|
269
|
+
|> required "description" D.string
|
|
270
|
+
|> required "background" paletteColorDecoder
|
|
271
|
+
|> required "viewport" rectDecoder
|
|
272
|
+
|> required "cards" (D.list cardDecoder)
|
|
273
|
+
|> required "zones" (D.list zoneDecoder)
|
|
274
|
+
|> required "arrows" (D.list arrowDecoder)
|
|
275
|
+
|> required "stamps" (D.list stampDecoder)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
saveFileDecoder : Decoder SaveFile
|
|
279
|
+
saveFileDecoder =
|
|
280
|
+
D.succeed SaveFile
|
|
281
|
+
|> required "name" D.string
|
|
282
|
+
|> required "project" projectDecoder
|
|
283
|
+
|> optional "palette" paletteDecoder Theme.default
|
|
284
|
+
|> optional "settings" settingsDecoder default_settings
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
decodeSaveFile : String -> Result D.Error SaveFile
|
|
288
|
+
decodeSaveFile s =
|
|
289
|
+
D.decodeString saveFileDecoder s
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
encodeVec2 : Vec2 -> Value
|
|
293
|
+
encodeVec2 p =
|
|
294
|
+
object
|
|
295
|
+
[ ( "x", float <| p.x )
|
|
296
|
+
, ( "y", float <| p.y )
|
|
297
|
+
]
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
encodeRect : Rect -> Value
|
|
301
|
+
encodeRect r =
|
|
302
|
+
object
|
|
303
|
+
[ ( "pos", encodeVec2 r.pos )
|
|
304
|
+
, ( "size", encodeVec2 r.size )
|
|
305
|
+
]
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
encodeRot : Rotation -> Value
|
|
309
|
+
encodeRot r =
|
|
310
|
+
object
|
|
311
|
+
[ ( "angle", float r.angle )
|
|
312
|
+
, ( "pivot", encodeVec2 r.pivot )
|
|
313
|
+
]
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
encodeCard : Card -> Value
|
|
317
|
+
encodeCard c =
|
|
318
|
+
object
|
|
319
|
+
[ ( "model", encodeModel c.model )
|
|
320
|
+
, ( "rect", encodeRect c.rect )
|
|
321
|
+
, ( "rot", encodeRot c.rot )
|
|
322
|
+
, ( "front", bool c.front )
|
|
323
|
+
, ( "highlight", bool c.highlight )
|
|
324
|
+
, ( "id", string c.id )
|
|
325
|
+
, ( "z", int c.z )
|
|
326
|
+
]
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
encodeBorder : Border -> Value
|
|
330
|
+
encodeBorder b =
|
|
331
|
+
object
|
|
332
|
+
[ ( "color", color b.color )
|
|
333
|
+
, ( "width", int b.width )
|
|
334
|
+
, ( "dash", int b.dash )
|
|
335
|
+
]
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
encodeGrid : Grid -> Value
|
|
339
|
+
encodeGrid g =
|
|
340
|
+
object
|
|
341
|
+
[ ( "rows", int g.rows )
|
|
342
|
+
, ( "columns", int g.columns )
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
encodeAnchor : Anchor -> Value
|
|
347
|
+
encodeAnchor a =
|
|
348
|
+
string <| Zone.anchorString a
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
encodeText : Text -> Value
|
|
352
|
+
encodeText t =
|
|
353
|
+
object
|
|
354
|
+
[ ( "label", string t.label )
|
|
355
|
+
, ( "color", color t.color )
|
|
356
|
+
, ( "size", int t.size )
|
|
357
|
+
, ( "primary", bool t.primary )
|
|
358
|
+
, ( "anchor", encodeAnchor t.anchor )
|
|
359
|
+
]
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
encodeZone : Zone -> Value
|
|
363
|
+
encodeZone z =
|
|
364
|
+
object
|
|
365
|
+
[ ( "id", string z.id )
|
|
366
|
+
, ( "rect", encodeRect z.rect )
|
|
367
|
+
, ( "rot", encodeRot z.rot )
|
|
368
|
+
, ( "fill", color z.fill )
|
|
369
|
+
, ( "border", encodeBorder z.border )
|
|
370
|
+
, ( "text", encodeText z.text )
|
|
371
|
+
, ( "grid", encodeGrid z.grid )
|
|
372
|
+
]
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
encodeStamp : Stamp -> Value
|
|
376
|
+
encodeStamp s =
|
|
377
|
+
object
|
|
378
|
+
[ ( "pos", encodeVec2 s.pos )
|
|
379
|
+
, ( "id", string s.id )
|
|
380
|
+
, ( "text", encodeText s.text )
|
|
381
|
+
, ( "fill", color s.fill )
|
|
382
|
+
, ( "radius", float s.radius )
|
|
383
|
+
]
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
encodeSettings : Settings -> Value
|
|
387
|
+
encodeSettings settings =
|
|
388
|
+
object
|
|
389
|
+
[ ( "embedSymbols", bool settings.embedSymbols )
|
|
390
|
+
, ( "stripData", bool settings.stripData )
|
|
391
|
+
, ( "mapColors", bool settings.mapColors )
|
|
392
|
+
, ( "mapFont", bool settings.mapFont )
|
|
393
|
+
, ( "primaryFont"
|
|
394
|
+
, Maybe.map string settings.primaryFont |> Maybe.withDefault null
|
|
395
|
+
)
|
|
396
|
+
, ( "secondaryFont"
|
|
397
|
+
, Maybe.map string settings.secondaryFont |> Maybe.withDefault null
|
|
398
|
+
)
|
|
399
|
+
]
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
encodeProject : Project -> Value
|
|
403
|
+
encodeProject project =
|
|
404
|
+
object
|
|
405
|
+
[ ( "description", string project.description )
|
|
406
|
+
, ( "background", color project.background )
|
|
407
|
+
, ( "viewport", encodeRect project.viewport )
|
|
408
|
+
, ( "cards", list encodeCard project.cards )
|
|
409
|
+
, ( "zones", list encodeZone project.zones )
|
|
410
|
+
, ( "arrows", list encodeArrow project.arrows )
|
|
411
|
+
, ( "stamps", list encodeStamp project.stamps )
|
|
412
|
+
]
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
encodeSaveFile : SaveFile -> Value
|
|
416
|
+
encodeSaveFile pf =
|
|
417
|
+
object
|
|
418
|
+
[ ( "name", string pf.name )
|
|
419
|
+
, ( "project", encodeProject pf.project )
|
|
420
|
+
, ( "palette", encodePalette pf.palette )
|
|
421
|
+
, ( "settings", encodeSettings pf.settings )
|
|
422
|
+
]
|