diva.js 7.2.4 → 7.2.6
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/README.md +65 -11
- package/build/diva.debug.js +29165 -0
- package/build/diva.esm.js +17 -0
- package/build/diva.js +17 -0
- package/package.json +16 -3
- package/.clang-format +0 -7
- package/.github/workflows/npm-publish.yml +0 -45
- package/Makefile +0 -75
- package/elm.json +0 -32
- package/review/elm.json +0 -52
- package/review/src/ReviewConfig.elm +0 -87
- package/scripts/elm-esm.sh +0 -40
- package/scripts/minify-css.mjs +0 -31
- package/src/Filters.elm +0 -1044
- package/src/Main.elm +0 -1217
- package/src/Model.elm +0 -213
- package/src/Msg.elm +0 -59
- package/src/Utilities.elm +0 -46
- package/src/View/CollectionExplorer.elm +0 -172
- package/src/View/Helpers.elm +0 -86
- package/src/View/HtmlRenderer.elm +0 -136
- package/src/View/Icons.elm +0 -159
- package/src/View/ManifestInfoModal.elm +0 -363
- package/src/View/PageViewModal.elm +0 -1046
- package/src/View/Sidebar.elm +0 -786
- package/src/View/Toolbar.elm +0 -189
- package/src/View.elm +0 -244
- package/src/diva.ts +0 -802
- package/src/filters.ts +0 -1843
- package/src/styles/app.css +0 -328
- package/src/styles/collection.css +0 -75
- package/src/styles/modal.css +0 -388
- package/src/styles/sidebar.css +0 -215
- package/src/styles/theme.css +0 -39
- package/src/styles/toolbar.css +0 -154
- package/src/viewer-element.ts +0 -1307
- package/testing/index.html +0 -52
- package/testing/testing.html +0 -231
- package/tsconfig.json +0 -12
|
@@ -1,1046 +0,0 @@
|
|
|
1
|
-
module View.PageViewModal exposing (viewPageViewModal)
|
|
2
|
-
|
|
3
|
-
import Filters exposing (FilterFloatValue(..), FilterIntValue(..), FilterStringValue(..), FilterToggle(..))
|
|
4
|
-
import Html exposing (Html, button, div, img, input, label, option, select, span, text, textarea)
|
|
5
|
-
import Html.Attributes as HA exposing (alt, checked, classList, id, rows, src, type_, value)
|
|
6
|
-
import Html.Events exposing (onCheck, onClick, onInput)
|
|
7
|
-
import Html.Lazy as Lazy
|
|
8
|
-
import IIIF.Language exposing (extractLabelFromLanguageMap)
|
|
9
|
-
import IIIF.Presentation exposing (toLabel)
|
|
10
|
-
import Model exposing (Model, PageImage, currentManifest, getPageAt)
|
|
11
|
-
import Msg exposing (Msg(..))
|
|
12
|
-
import Set
|
|
13
|
-
import Utilities exposing (disabledIf)
|
|
14
|
-
import View.Helpers exposing (emptyHtml, viewButton)
|
|
15
|
-
import View.Icons as Icons
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
viewPageViewModal : Model -> Html Msg
|
|
19
|
-
viewPageViewModal model =
|
|
20
|
-
if model.pageViewOpen then
|
|
21
|
-
div
|
|
22
|
-
[ classList
|
|
23
|
-
[ ( "modal-overlay", True )
|
|
24
|
-
, ( "is-fullscreen", model.pageViewFullscreen )
|
|
25
|
-
]
|
|
26
|
-
]
|
|
27
|
-
[ div
|
|
28
|
-
[ classList
|
|
29
|
-
[ ( "modal", True )
|
|
30
|
-
, ( "is-fullscreen", model.pageViewFullscreen )
|
|
31
|
-
, ( "is-page-view", not model.pageViewFullscreen )
|
|
32
|
-
]
|
|
33
|
-
]
|
|
34
|
-
[ viewModalHeader model
|
|
35
|
-
, viewModalBody model
|
|
36
|
-
]
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
else
|
|
40
|
-
emptyHtml
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
adaptiveOffsetRange : Model -> RangeRowConfig
|
|
44
|
-
adaptiveOffsetRange model =
|
|
45
|
-
{ label = "Offset"
|
|
46
|
-
, min = "-50"
|
|
47
|
-
, max = "50"
|
|
48
|
-
, step = Just "1"
|
|
49
|
-
, value = String.fromInt model.filters.adaptiveOffset
|
|
50
|
-
, display = String.fromInt model.filters.adaptiveOffset
|
|
51
|
-
, onInput = UserUpdatedFilterInt IntAdaptiveOffset
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
blueChannelConfig : Model -> ChannelConfig
|
|
56
|
-
blueChannelConfig model =
|
|
57
|
-
{ gammaEnabled = model.filters.altBlueGammaEnabled
|
|
58
|
-
, gamma = model.filters.altBlueGamma
|
|
59
|
-
, gammaToggle = ToggleAltBlueGamma
|
|
60
|
-
, gammaInput = IntAltBlueGamma
|
|
61
|
-
, sigmoidEnabled = model.filters.altBlueSigmoidEnabled
|
|
62
|
-
, sigmoid = model.filters.altBlueSigmoid
|
|
63
|
-
, sigmoidToggle = ToggleAltBlueSigmoid
|
|
64
|
-
, sigmoidInput = IntAltBlueSigmoid
|
|
65
|
-
, hueEnabled = model.filters.altBlueHueEnabled
|
|
66
|
-
, hue = model.filters.altBlueHue
|
|
67
|
-
, hueToggle = ToggleAltBlueHue
|
|
68
|
-
, hueInput = IntAltBlueHue
|
|
69
|
-
, hueWindow = model.filters.altBlueHueWindow
|
|
70
|
-
, hueWindowInput = IntAltBlueHueWindow
|
|
71
|
-
, vibranceEnabled = model.filters.altBlueVibranceEnabled
|
|
72
|
-
, vibrance = model.filters.altBlueVibrance
|
|
73
|
-
, vibranceToggle = ToggleAltBlueVibrance
|
|
74
|
-
, vibranceInput = IntAltBlueVibrance
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
type alias ChannelConfig =
|
|
79
|
-
{ gammaEnabled : Bool
|
|
80
|
-
, gamma : Int
|
|
81
|
-
, gammaToggle : FilterToggle
|
|
82
|
-
, gammaInput : FilterIntValue
|
|
83
|
-
, sigmoidEnabled : Bool
|
|
84
|
-
, sigmoid : Int
|
|
85
|
-
, sigmoidToggle : FilterToggle
|
|
86
|
-
, sigmoidInput : FilterIntValue
|
|
87
|
-
, hueEnabled : Bool
|
|
88
|
-
, hue : Int
|
|
89
|
-
, hueToggle : FilterToggle
|
|
90
|
-
, hueInput : FilterIntValue
|
|
91
|
-
, hueWindow : Int
|
|
92
|
-
, hueWindowInput : FilterIntValue
|
|
93
|
-
, vibranceEnabled : Bool
|
|
94
|
-
, vibrance : Int
|
|
95
|
-
, vibranceToggle : FilterToggle
|
|
96
|
-
, vibranceInput : FilterIntValue
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
colourAdjustToggleRanges : Model -> List ToggleRangeRowConfig
|
|
101
|
-
colourAdjustToggleRanges model =
|
|
102
|
-
[ { label = "Brightness"
|
|
103
|
-
, checked = model.filters.brightnessEnabled
|
|
104
|
-
, onToggle = ToggleBrightness
|
|
105
|
-
, min = "-255"
|
|
106
|
-
, max = "255"
|
|
107
|
-
, step = Nothing
|
|
108
|
-
, value = String.fromInt model.filters.brightness
|
|
109
|
-
, display = String.fromInt model.filters.brightness
|
|
110
|
-
, onInput = UserUpdatedFilterInt IntBrightness
|
|
111
|
-
}
|
|
112
|
-
, { label = "Contrast"
|
|
113
|
-
, checked = model.filters.contrastEnabled
|
|
114
|
-
, onToggle = ToggleContrast
|
|
115
|
-
, min = "0"
|
|
116
|
-
, max = "4"
|
|
117
|
-
, step = Just "0.1"
|
|
118
|
-
, value = String.fromFloat model.filters.contrast
|
|
119
|
-
, display = String.fromFloat model.filters.contrast
|
|
120
|
-
, onInput = UserUpdatedFilterFloat FloatContrast
|
|
121
|
-
}
|
|
122
|
-
, { label = "Gamma"
|
|
123
|
-
, checked = model.filters.gammaEnabled
|
|
124
|
-
, onToggle = ToggleGamma
|
|
125
|
-
, min = "0.1"
|
|
126
|
-
, max = "4"
|
|
127
|
-
, step = Just "0.1"
|
|
128
|
-
, value = String.fromFloat model.filters.gamma
|
|
129
|
-
, display = String.fromFloat model.filters.gamma
|
|
130
|
-
, onInput = UserUpdatedFilterFloat FloatGamma
|
|
131
|
-
}
|
|
132
|
-
, { label = "Saturation"
|
|
133
|
-
, checked = model.filters.saturationEnabled
|
|
134
|
-
, onToggle = ToggleSaturation
|
|
135
|
-
, min = "-100"
|
|
136
|
-
, max = "100"
|
|
137
|
-
, step = Nothing
|
|
138
|
-
, value = String.fromInt model.filters.saturation
|
|
139
|
-
, display = String.fromInt model.filters.saturation
|
|
140
|
-
, onInput = UserUpdatedFilterInt IntSaturation
|
|
141
|
-
}
|
|
142
|
-
, { label = "Vibrance"
|
|
143
|
-
, checked = model.filters.vibranceEnabled
|
|
144
|
-
, onToggle = ToggleVibrance
|
|
145
|
-
, min = "-100"
|
|
146
|
-
, max = "100"
|
|
147
|
-
, step = Nothing
|
|
148
|
-
, value = String.fromInt model.filters.vibrance
|
|
149
|
-
, display = String.fromInt model.filters.vibrance
|
|
150
|
-
, onInput = UserUpdatedFilterInt IntVibrance
|
|
151
|
-
}
|
|
152
|
-
, { label = "Hue"
|
|
153
|
-
, checked = model.filters.hueEnabled
|
|
154
|
-
, onToggle = ToggleHue
|
|
155
|
-
, min = "-100"
|
|
156
|
-
, max = "100"
|
|
157
|
-
, step = Nothing
|
|
158
|
-
, value = String.fromInt model.filters.hue
|
|
159
|
-
, display = String.fromInt model.filters.hue
|
|
160
|
-
, onInput = UserUpdatedFilterInt IntHue
|
|
161
|
-
}
|
|
162
|
-
, { label = "Red"
|
|
163
|
-
, checked = model.filters.ccRedEnabled
|
|
164
|
-
, onToggle = ToggleCcRed
|
|
165
|
-
, min = "-100"
|
|
166
|
-
, max = "100"
|
|
167
|
-
, step = Nothing
|
|
168
|
-
, value = String.fromInt model.filters.ccRed
|
|
169
|
-
, display = String.fromInt model.filters.ccRed
|
|
170
|
-
, onInput = UserUpdatedFilterInt IntCcRed
|
|
171
|
-
}
|
|
172
|
-
, { label = "Green"
|
|
173
|
-
, checked = model.filters.ccGreenEnabled
|
|
174
|
-
, onToggle = ToggleCcGreen
|
|
175
|
-
, min = "-100"
|
|
176
|
-
, max = "100"
|
|
177
|
-
, step = Nothing
|
|
178
|
-
, value = String.fromInt model.filters.ccGreen
|
|
179
|
-
, display = String.fromInt model.filters.ccGreen
|
|
180
|
-
, onInput = UserUpdatedFilterInt IntCcGreen
|
|
181
|
-
}
|
|
182
|
-
, { label = "Blue"
|
|
183
|
-
, checked = model.filters.ccBlueEnabled
|
|
184
|
-
, onToggle = ToggleCcBlue
|
|
185
|
-
, min = "-100"
|
|
186
|
-
, max = "100"
|
|
187
|
-
, step = Nothing
|
|
188
|
-
, value = String.fromInt model.filters.ccBlue
|
|
189
|
-
, display = String.fromInt model.filters.ccBlue
|
|
190
|
-
, onInput = UserUpdatedFilterInt IntCcBlue
|
|
191
|
-
}
|
|
192
|
-
]
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
colourmapPresets : List (Html Msg)
|
|
196
|
-
colourmapPresets =
|
|
197
|
-
[ option [ value "gray" ] [ text "Gray" ]
|
|
198
|
-
, option [ value "hot" ] [ text "Hot" ]
|
|
199
|
-
, option [ value "cool" ] [ text "Cool" ]
|
|
200
|
-
]
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
convolutionPresets : List (Html Msg)
|
|
204
|
-
convolutionPresets =
|
|
205
|
-
[ option [ value "sharpen" ] [ text "Sharpen" ]
|
|
206
|
-
, option [ value "blur" ] [ text "Blur" ]
|
|
207
|
-
, option [ value "edge" ] [ text "Edge" ]
|
|
208
|
-
, option [ value "emboss" ] [ text "Emboss" ]
|
|
209
|
-
]
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
currentPageLabelFor : Model -> String
|
|
213
|
-
currentPageLabelFor model =
|
|
214
|
-
model.selectedIndex
|
|
215
|
-
|> Maybe.andThen (\index -> getPageAt index model.pages)
|
|
216
|
-
|> Maybe.map .label
|
|
217
|
-
|> Maybe.withDefault ""
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
enhancementToggleRanges : Model -> List ToggleRangeRowConfig
|
|
221
|
-
enhancementToggleRanges model =
|
|
222
|
-
[ { label = "Normalize"
|
|
223
|
-
, checked = model.filters.normalizeEnabled
|
|
224
|
-
, onToggle = ToggleNormalize
|
|
225
|
-
, min = "0"
|
|
226
|
-
, max = "2"
|
|
227
|
-
, step = Just "0.1"
|
|
228
|
-
, value = String.fromFloat model.filters.normalizeStrength
|
|
229
|
-
, display = String.fromFloat model.filters.normalizeStrength
|
|
230
|
-
, onInput = UserUpdatedFilterFloat FloatNormalizeStrength
|
|
231
|
-
}
|
|
232
|
-
, { label = "Unsharp"
|
|
233
|
-
, checked = model.filters.unsharpEnabled
|
|
234
|
-
, onToggle = ToggleUnsharp
|
|
235
|
-
, min = "0"
|
|
236
|
-
, max = "3"
|
|
237
|
-
, step = Just "0.1"
|
|
238
|
-
, value = String.fromFloat model.filters.unsharpAmount
|
|
239
|
-
, display = String.fromFloat model.filters.unsharpAmount
|
|
240
|
-
, onInput = UserUpdatedFilterFloat FloatUnsharpAmount
|
|
241
|
-
}
|
|
242
|
-
, { label = "Adaptive Threshold"
|
|
243
|
-
, checked = model.filters.adaptiveEnabled
|
|
244
|
-
, onToggle = ToggleAdaptive
|
|
245
|
-
, min = "3"
|
|
246
|
-
, max = "51"
|
|
247
|
-
, step = Just "2"
|
|
248
|
-
, value = String.fromInt model.filters.adaptiveWindow
|
|
249
|
-
, display = String.fromInt model.filters.adaptiveWindow
|
|
250
|
-
, onInput = UserUpdatedFilterInt IntAdaptiveWindow
|
|
251
|
-
}
|
|
252
|
-
]
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
greenChannelConfig : Model -> ChannelConfig
|
|
256
|
-
greenChannelConfig model =
|
|
257
|
-
{ gammaEnabled = model.filters.altGreenGammaEnabled
|
|
258
|
-
, gamma = model.filters.altGreenGamma
|
|
259
|
-
, gammaToggle = ToggleAltGreenGamma
|
|
260
|
-
, gammaInput = IntAltGreenGamma
|
|
261
|
-
, sigmoidEnabled = model.filters.altGreenSigmoidEnabled
|
|
262
|
-
, sigmoid = model.filters.altGreenSigmoid
|
|
263
|
-
, sigmoidToggle = ToggleAltGreenSigmoid
|
|
264
|
-
, sigmoidInput = IntAltGreenSigmoid
|
|
265
|
-
, hueEnabled = model.filters.altGreenHueEnabled
|
|
266
|
-
, hue = model.filters.altGreenHue
|
|
267
|
-
, hueToggle = ToggleAltGreenHue
|
|
268
|
-
, hueInput = IntAltGreenHue
|
|
269
|
-
, hueWindow = model.filters.altGreenHueWindow
|
|
270
|
-
, hueWindowInput = IntAltGreenHueWindow
|
|
271
|
-
, vibranceEnabled = model.filters.altGreenVibranceEnabled
|
|
272
|
-
, vibrance = model.filters.altGreenVibrance
|
|
273
|
-
, vibranceToggle = ToggleAltGreenVibrance
|
|
274
|
-
, vibranceInput = IntAltGreenVibrance
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
manifestTitleFor : Model -> String
|
|
279
|
-
manifestTitleFor model =
|
|
280
|
-
currentManifest model
|
|
281
|
-
|> Maybe.map (\m -> toLabel m |> extractLabelFromLanguageMap model.detectedLanguage)
|
|
282
|
-
|> Maybe.withDefault ""
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
morphKernelOptions : List (Html Msg)
|
|
286
|
-
morphKernelOptions =
|
|
287
|
-
[ option [ value "3" ] [ text "3x3" ]
|
|
288
|
-
, option [ value "5" ] [ text "5x5" ]
|
|
289
|
-
, option [ value "7" ] [ text "7x7" ]
|
|
290
|
-
]
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
morphOperationOptions : List (Html Msg)
|
|
294
|
-
morphOperationOptions =
|
|
295
|
-
[ option [ value "erode" ] [ text "Erode" ]
|
|
296
|
-
, option [ value "dilate" ] [ text "Dilate" ]
|
|
297
|
-
]
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
pcaModes : List (Html Msg)
|
|
301
|
-
pcaModes =
|
|
302
|
-
[ option [ value "pca-rgb" ] [ text "PCA (RGB)" ]
|
|
303
|
-
, option [ value "pca1" ] [ text "PCA Component 1" ]
|
|
304
|
-
, option [ value "pca2" ] [ text "PCA Component 2" ]
|
|
305
|
-
, option [ value "pca3" ] [ text "PCA Component 3" ]
|
|
306
|
-
]
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
pseudoColourModes : List (Html Msg)
|
|
310
|
-
pseudoColourModes =
|
|
311
|
-
[ option [ value "rg" ] [ text "Red–Green Diff" ]
|
|
312
|
-
, option [ value "gb" ] [ text "Green–Blue Diff" ]
|
|
313
|
-
, option [ value "rb" ] [ text "Red–Blue Diff" ]
|
|
314
|
-
, option [ value "luma" ] [ text "Luma False Colour" ]
|
|
315
|
-
, option [ value "cmy" ] [ text "CMY False Colour" ]
|
|
316
|
-
, option [ value "heat" ] [ text "Heat Map" ]
|
|
317
|
-
]
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
type alias RangeRowConfig =
|
|
321
|
-
{ label : String
|
|
322
|
-
, min : String
|
|
323
|
-
, max : String
|
|
324
|
-
, step : Maybe String
|
|
325
|
-
, value : String
|
|
326
|
-
, display : String
|
|
327
|
-
, onInput : String -> Msg
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
redChannelConfig : Model -> ChannelConfig
|
|
332
|
-
redChannelConfig model =
|
|
333
|
-
{ gammaEnabled = model.filters.altRedGammaEnabled
|
|
334
|
-
, gamma = model.filters.altRedGamma
|
|
335
|
-
, gammaToggle = ToggleAltRedGamma
|
|
336
|
-
, gammaInput = IntAltRedGamma
|
|
337
|
-
, sigmoidEnabled = model.filters.altRedSigmoidEnabled
|
|
338
|
-
, sigmoid = model.filters.altRedSigmoid
|
|
339
|
-
, sigmoidToggle = ToggleAltRedSigmoid
|
|
340
|
-
, sigmoidInput = IntAltRedSigmoid
|
|
341
|
-
, hueEnabled = model.filters.altRedHueEnabled
|
|
342
|
-
, hue = model.filters.altRedHue
|
|
343
|
-
, hueToggle = ToggleAltRedHue
|
|
344
|
-
, hueInput = IntAltRedHue
|
|
345
|
-
, hueWindow = model.filters.altRedHueWindow
|
|
346
|
-
, hueWindowInput = IntAltRedHueWindow
|
|
347
|
-
, vibranceEnabled = model.filters.altRedVibranceEnabled
|
|
348
|
-
, vibrance = model.filters.altRedVibrance
|
|
349
|
-
, vibranceToggle = ToggleAltRedVibrance
|
|
350
|
-
, vibranceInput = IntAltRedVibrance
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
type alias ToggleRangeRowConfig =
|
|
355
|
-
{ label : String
|
|
356
|
-
, checked : Bool
|
|
357
|
-
, onToggle : FilterToggle
|
|
358
|
-
, min : String
|
|
359
|
-
, max : String
|
|
360
|
-
, step : Maybe String
|
|
361
|
-
, value : String
|
|
362
|
-
, display : String
|
|
363
|
-
, onInput : String -> Msg
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
toneToggleRanges : Model -> List ToggleRangeRowConfig
|
|
368
|
-
toneToggleRanges model =
|
|
369
|
-
[ { label = "Threshold"
|
|
370
|
-
, checked = model.filters.thresholdEnabled
|
|
371
|
-
, onToggle = ToggleThreshold
|
|
372
|
-
, min = "0"
|
|
373
|
-
, max = "255"
|
|
374
|
-
, step = Nothing
|
|
375
|
-
, value = String.fromInt model.filters.threshold
|
|
376
|
-
, display = String.fromInt model.filters.threshold
|
|
377
|
-
, onInput = UserUpdatedFilterInt IntThreshold
|
|
378
|
-
}
|
|
379
|
-
]
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
viewAdvancedColourAdjustGroup : Model -> Html Msg
|
|
383
|
-
viewAdvancedColourAdjustGroup model =
|
|
384
|
-
viewFilterGroup model
|
|
385
|
-
"advanced-colour-adjust"
|
|
386
|
-
"Advanced colour adjust"
|
|
387
|
-
(viewFilterRow
|
|
388
|
-
[ button
|
|
389
|
-
[ HA.class "filter-reset"
|
|
390
|
-
, type_ "button"
|
|
391
|
-
, onClick UserResetAltColourAdjust
|
|
392
|
-
]
|
|
393
|
-
[ text "Reset sliders" ]
|
|
394
|
-
]
|
|
395
|
-
:: viewChannelRows "Red" (redChannelConfig model)
|
|
396
|
-
++ viewChannelRows "Green" (greenChannelConfig model)
|
|
397
|
-
++ viewChannelRows "Blue" (blueChannelConfig model)
|
|
398
|
-
)
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
viewChannelRows : String -> ChannelConfig -> List (Html Msg)
|
|
402
|
-
viewChannelRows channelName config =
|
|
403
|
-
[ viewToggleRangeRow
|
|
404
|
-
{ label = channelName ++ " Gamma"
|
|
405
|
-
, checked = config.gammaEnabled
|
|
406
|
-
, onToggle = config.gammaToggle
|
|
407
|
-
, min = "0"
|
|
408
|
-
, max = "100"
|
|
409
|
-
, step = Just "1"
|
|
410
|
-
, value = String.fromInt config.gamma
|
|
411
|
-
, display = String.fromInt config.gamma
|
|
412
|
-
, onInput = UserUpdatedFilterInt config.gammaInput
|
|
413
|
-
}
|
|
414
|
-
, viewToggleRangeRow
|
|
415
|
-
{ label = channelName ++ " Sigmoid"
|
|
416
|
-
, checked = config.sigmoidEnabled
|
|
417
|
-
, onToggle = config.sigmoidToggle
|
|
418
|
-
, min = "0"
|
|
419
|
-
, max = "100"
|
|
420
|
-
, step = Just "1"
|
|
421
|
-
, value = String.fromInt config.sigmoid
|
|
422
|
-
, display = String.fromInt config.sigmoid
|
|
423
|
-
, onInput = UserUpdatedFilterInt config.sigmoidInput
|
|
424
|
-
}
|
|
425
|
-
, viewToggleRangeRow
|
|
426
|
-
{ label = channelName ++ " Hue Boost"
|
|
427
|
-
, checked = config.hueEnabled
|
|
428
|
-
, onToggle = config.hueToggle
|
|
429
|
-
, min = "-100"
|
|
430
|
-
, max = "100"
|
|
431
|
-
, step = Just "1"
|
|
432
|
-
, value = String.fromInt config.hue
|
|
433
|
-
, display = String.fromInt config.hue
|
|
434
|
-
, onInput = UserUpdatedFilterInt config.hueInput
|
|
435
|
-
}
|
|
436
|
-
, viewRangeRow
|
|
437
|
-
{ label = channelName ++ " Hue Window"
|
|
438
|
-
, min = "2"
|
|
439
|
-
, max = "30"
|
|
440
|
-
, step = Just "1"
|
|
441
|
-
, value = String.fromInt config.hueWindow
|
|
442
|
-
, display = String.fromInt config.hueWindow
|
|
443
|
-
, onInput = UserUpdatedFilterInt config.hueWindowInput
|
|
444
|
-
}
|
|
445
|
-
, viewToggleRangeRow
|
|
446
|
-
{ label = channelName ++ " Vibrance"
|
|
447
|
-
, checked = config.vibranceEnabled
|
|
448
|
-
, onToggle = config.vibranceToggle
|
|
449
|
-
, min = "0"
|
|
450
|
-
, max = "100"
|
|
451
|
-
, step = Just "1"
|
|
452
|
-
, value = String.fromInt config.vibrance
|
|
453
|
-
, display = String.fromInt config.vibrance
|
|
454
|
-
, onInput = UserUpdatedFilterInt config.vibranceInput
|
|
455
|
-
}
|
|
456
|
-
]
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
viewColourAdjustGroup : Model -> Html Msg
|
|
460
|
-
viewColourAdjustGroup model =
|
|
461
|
-
viewFilterGroup model
|
|
462
|
-
"colour-adjust"
|
|
463
|
-
"Colour Adjust"
|
|
464
|
-
(List.map viewToggleRangeRow (colourAdjustToggleRanges model))
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
viewColourInput : String -> (String -> Msg) -> Html Msg
|
|
468
|
-
viewColourInput colourValue onChange =
|
|
469
|
-
input
|
|
470
|
-
[ HA.class "filter-color-input"
|
|
471
|
-
, type_ "color"
|
|
472
|
-
, value colourValue
|
|
473
|
-
, onInput onChange
|
|
474
|
-
]
|
|
475
|
-
[]
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
viewColourmapGroup : Model -> Html Msg
|
|
479
|
-
viewColourmapGroup model =
|
|
480
|
-
viewFilterGroup model
|
|
481
|
-
"colourmap"
|
|
482
|
-
"Colourmap"
|
|
483
|
-
[ viewFilterRow
|
|
484
|
-
[ viewToggle "Colourmap" model.filters.colourmapEnabled ToggleColourmap
|
|
485
|
-
, viewSelect model.filters.colourmapPreset (UserUpdatedFilterString StringColourmapPreset) colourmapPresets
|
|
486
|
-
]
|
|
487
|
-
, viewRangeRow
|
|
488
|
-
{ label = "Center"
|
|
489
|
-
, min = "0"
|
|
490
|
-
, max = "255"
|
|
491
|
-
, step = Nothing
|
|
492
|
-
, value = String.fromInt model.filters.colourmapCenter
|
|
493
|
-
, display = String.fromInt model.filters.colourmapCenter
|
|
494
|
-
, onInput = UserUpdatedFilterInt IntColourmapCenter
|
|
495
|
-
}
|
|
496
|
-
]
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
viewConvolutionGroup : Model -> Html Msg
|
|
500
|
-
viewConvolutionGroup model =
|
|
501
|
-
viewFilterGroup model
|
|
502
|
-
"convolution"
|
|
503
|
-
"Convolution"
|
|
504
|
-
[ viewFilterRow
|
|
505
|
-
[ viewToggle "Kernel" model.filters.convolutionEnabled ToggleConvolution
|
|
506
|
-
, viewSelect model.filters.convolutionPreset (UserUpdatedFilterString StringConvolutionPreset) convolutionPresets
|
|
507
|
-
]
|
|
508
|
-
]
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
viewEnhancementGroup : Model -> Html Msg
|
|
512
|
-
viewEnhancementGroup model =
|
|
513
|
-
viewFilterGroup model
|
|
514
|
-
"enhancement"
|
|
515
|
-
"Enhancement"
|
|
516
|
-
(List.map viewToggleRangeRow (enhancementToggleRanges model)
|
|
517
|
-
++ [ viewRangeRow (adaptiveOffsetRange model) ]
|
|
518
|
-
)
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
viewFilterGroup : Model -> String -> String -> List (Html Msg) -> Html Msg
|
|
522
|
-
viewFilterGroup model groupId title items =
|
|
523
|
-
let
|
|
524
|
-
isExpanded =
|
|
525
|
-
Set.member groupId model.filterGroupExpanded
|
|
526
|
-
in
|
|
527
|
-
div [ HA.class "filter-group" ]
|
|
528
|
-
(button
|
|
529
|
-
[ classList
|
|
530
|
-
[ ( "filter-title-button", True )
|
|
531
|
-
, ( "is-collapsed", not isExpanded )
|
|
532
|
-
]
|
|
533
|
-
, onClick (UserToggledFilterGroup groupId)
|
|
534
|
-
]
|
|
535
|
-
[ span
|
|
536
|
-
[ classList
|
|
537
|
-
[ ( "filter-title-icon", True )
|
|
538
|
-
, ( "is-expanded", isExpanded )
|
|
539
|
-
]
|
|
540
|
-
]
|
|
541
|
-
[]
|
|
542
|
-
, span [] [ text title ]
|
|
543
|
-
]
|
|
544
|
-
:: (if isExpanded then
|
|
545
|
-
items
|
|
546
|
-
|
|
547
|
-
else
|
|
548
|
-
[]
|
|
549
|
-
)
|
|
550
|
-
)
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
viewFilterJsonGroup : Model -> Html Msg
|
|
554
|
-
viewFilterJsonGroup model =
|
|
555
|
-
viewFilterGroup model
|
|
556
|
-
"filter-json"
|
|
557
|
-
"Import / Export Filter Settings"
|
|
558
|
-
[ viewFilterRow
|
|
559
|
-
[ button
|
|
560
|
-
[ HA.class "filter-reset"
|
|
561
|
-
, type_ "button"
|
|
562
|
-
, onClick UserCopiedFilterJson
|
|
563
|
-
]
|
|
564
|
-
[ text "Show JSON" ]
|
|
565
|
-
, button
|
|
566
|
-
[ HA.class "filter-reset"
|
|
567
|
-
, type_ "button"
|
|
568
|
-
, onClick UserAppliedFilterJson
|
|
569
|
-
]
|
|
570
|
-
[ text "Apply" ]
|
|
571
|
-
]
|
|
572
|
-
, textarea
|
|
573
|
-
[ HA.class "filter-json"
|
|
574
|
-
, value model.filtersJsonInput
|
|
575
|
-
, onInput UserUpdatedFilterJsonInput
|
|
576
|
-
, rows 6
|
|
577
|
-
]
|
|
578
|
-
[]
|
|
579
|
-
, case model.filtersJsonError of
|
|
580
|
-
Just err ->
|
|
581
|
-
div [ HA.class "filter-json-error" ] [ text err ]
|
|
582
|
-
|
|
583
|
-
Nothing ->
|
|
584
|
-
emptyHtml
|
|
585
|
-
]
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
viewFilterRow : List (Html Msg) -> Html Msg
|
|
589
|
-
viewFilterRow items =
|
|
590
|
-
div [ HA.class "filter-row" ] items
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
viewImageChoiceItem : Int -> Int -> PageImage -> Html Msg
|
|
594
|
-
viewImageChoiceItem selectedIndex index image =
|
|
595
|
-
let
|
|
596
|
-
isActive =
|
|
597
|
-
index == selectedIndex
|
|
598
|
-
in
|
|
599
|
-
button
|
|
600
|
-
[ classList
|
|
601
|
-
[ ( "page-view-choice", True )
|
|
602
|
-
, ( "ui-card", True )
|
|
603
|
-
, ( "ui-card--dark", True )
|
|
604
|
-
, ( "is-active", isActive )
|
|
605
|
-
]
|
|
606
|
-
, type_ "button"
|
|
607
|
-
, onClick (UserClickedPageViewImageChoice index)
|
|
608
|
-
]
|
|
609
|
-
[ img
|
|
610
|
-
[ HA.class "page-view-choice-thumb"
|
|
611
|
-
, src image.thumbUrl
|
|
612
|
-
, alt image.label
|
|
613
|
-
]
|
|
614
|
-
[]
|
|
615
|
-
, span
|
|
616
|
-
[ HA.class "page-view-choice-label" ]
|
|
617
|
-
[ text image.label ]
|
|
618
|
-
]
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
viewImageChoicesSidebar : List PageImage -> Int -> Html Msg
|
|
622
|
-
viewImageChoicesSidebar images selectedIndex =
|
|
623
|
-
div
|
|
624
|
-
[ HA.class "page-view-choices" ]
|
|
625
|
-
(List.indexedMap (\index image -> Lazy.lazy3 viewImageChoiceItem selectedIndex index image) images)
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
viewMirrorRow : Model -> Html Msg
|
|
629
|
-
viewMirrorRow model =
|
|
630
|
-
viewFilterRow
|
|
631
|
-
[ viewToggle "Mirror" model.filters.flip ToggleFlip ]
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
viewModalBody : Model -> Html Msg
|
|
635
|
-
viewModalBody model =
|
|
636
|
-
let
|
|
637
|
-
currentPage =
|
|
638
|
-
model.selectedIndex
|
|
639
|
-
|> Maybe.andThen (\index -> getPageAt index model.pages)
|
|
640
|
-
|
|
641
|
-
hasChoices =
|
|
642
|
-
Maybe.map (\page -> List.length page.images > 1) currentPage
|
|
643
|
-
|> Maybe.withDefault False
|
|
644
|
-
in
|
|
645
|
-
div
|
|
646
|
-
[ classList
|
|
647
|
-
[ ( "modal-body", True )
|
|
648
|
-
, ( "is-no-gap", True )
|
|
649
|
-
, ( "is-fullscreen", model.pageViewFullscreen )
|
|
650
|
-
, ( "is-with-choices", hasChoices )
|
|
651
|
-
, ( "is-no-sidebar", not model.pageViewSidebarVisible )
|
|
652
|
-
, ( "is-with-choices-no-sidebar", hasChoices && not model.pageViewSidebarVisible )
|
|
653
|
-
]
|
|
654
|
-
]
|
|
655
|
-
(case ( hasChoices, currentPage, model.pageViewSidebarVisible ) of
|
|
656
|
-
( True, Just page, True ) ->
|
|
657
|
-
[ viewImageChoicesSidebar page.images model.pageViewImageIndex
|
|
658
|
-
, viewModalViewer model.pageViewFullscreen False
|
|
659
|
-
, viewModalSidebar model
|
|
660
|
-
]
|
|
661
|
-
|
|
662
|
-
( True, Just page, False ) ->
|
|
663
|
-
[ viewImageChoicesSidebar page.images model.pageViewImageIndex
|
|
664
|
-
, viewModalViewer model.pageViewFullscreen False
|
|
665
|
-
]
|
|
666
|
-
|
|
667
|
-
( _, _, True ) ->
|
|
668
|
-
[ viewModalViewer model.pageViewFullscreen True
|
|
669
|
-
, viewModalSidebar model
|
|
670
|
-
]
|
|
671
|
-
|
|
672
|
-
_ ->
|
|
673
|
-
[ viewModalViewer model.pageViewFullscreen True
|
|
674
|
-
]
|
|
675
|
-
)
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
viewModalHeader : Model -> Html Msg
|
|
679
|
-
viewModalHeader model =
|
|
680
|
-
let
|
|
681
|
-
manifestTitle =
|
|
682
|
-
manifestTitleFor model
|
|
683
|
-
|
|
684
|
-
pageLabel =
|
|
685
|
-
currentPageLabelFor model
|
|
686
|
-
|
|
687
|
-
( prevDisabled, nextDisabled ) =
|
|
688
|
-
case model.selectedIndex of
|
|
689
|
-
Just index ->
|
|
690
|
-
( index <= 0
|
|
691
|
-
, index >= (List.length model.pages - 1)
|
|
692
|
-
)
|
|
693
|
-
|
|
694
|
-
Nothing ->
|
|
695
|
-
( True
|
|
696
|
-
, True
|
|
697
|
-
)
|
|
698
|
-
|
|
699
|
-
( fullscreenIcon, fullscreenLabel ) =
|
|
700
|
-
if model.pageViewFullscreen then
|
|
701
|
-
( Icons.fromFullscreen, "Exit fullscreen" )
|
|
702
|
-
|
|
703
|
-
else
|
|
704
|
-
( Icons.toFullscreen, "Fullscreen" )
|
|
705
|
-
|
|
706
|
-
( sidebarIcon, sidebarLabel ) =
|
|
707
|
-
if model.pageViewSidebarVisible then
|
|
708
|
-
( Icons.hideSidebar, "Hide filters" )
|
|
709
|
-
|
|
710
|
-
else
|
|
711
|
-
( Icons.showSidebar, "Show filters" )
|
|
712
|
-
in
|
|
713
|
-
div
|
|
714
|
-
[ HA.class "modal-header" ]
|
|
715
|
-
[ div
|
|
716
|
-
[ HA.class "modal-title-stack" ]
|
|
717
|
-
(div [ HA.class "modal-title" ] [ text "Page View" ]
|
|
718
|
-
:: (if String.isEmpty manifestTitle then
|
|
719
|
-
[]
|
|
720
|
-
|
|
721
|
-
else
|
|
722
|
-
[ div [ HA.class "modal-subtitle" ] [ text manifestTitle ] ]
|
|
723
|
-
)
|
|
724
|
-
++ (if String.isEmpty pageLabel then
|
|
725
|
-
[]
|
|
726
|
-
|
|
727
|
-
else
|
|
728
|
-
[ div [ HA.class "modal-subtitle is-muted" ] [ text pageLabel ] ]
|
|
729
|
-
)
|
|
730
|
-
)
|
|
731
|
-
, div
|
|
732
|
-
[ HA.class "modal-actions" ]
|
|
733
|
-
[ viewButton
|
|
734
|
-
{ label = "Previous Page"
|
|
735
|
-
, icon = Icons.prevPage
|
|
736
|
-
, onClickMsg = disabledIf prevDisabled UserClickedPageViewPrev
|
|
737
|
-
, isFullscreen = model.fullscreen
|
|
738
|
-
}
|
|
739
|
-
, viewButton
|
|
740
|
-
{ label = "Next Page"
|
|
741
|
-
, icon = Icons.nextPage
|
|
742
|
-
, onClickMsg = disabledIf nextDisabled UserClickedPageViewNext
|
|
743
|
-
, isFullscreen = model.fullscreen
|
|
744
|
-
}
|
|
745
|
-
, viewButton
|
|
746
|
-
{ label = "Save view"
|
|
747
|
-
, icon = Icons.downloadSelection
|
|
748
|
-
, onClickMsg = Just UserClickedSaveFilteredImage
|
|
749
|
-
, isFullscreen = model.fullscreen
|
|
750
|
-
}
|
|
751
|
-
, viewButton
|
|
752
|
-
{ label = "Reset Filters"
|
|
753
|
-
, icon = Icons.reset
|
|
754
|
-
, onClickMsg = Just UserResetAllFilters
|
|
755
|
-
, isFullscreen = model.fullscreen
|
|
756
|
-
}
|
|
757
|
-
, viewButton
|
|
758
|
-
{ label = sidebarLabel
|
|
759
|
-
, icon = sidebarIcon
|
|
760
|
-
, onClickMsg = Just UserToggledPageViewSidebar
|
|
761
|
-
, isFullscreen = model.fullscreen
|
|
762
|
-
}
|
|
763
|
-
, viewButton
|
|
764
|
-
{ label = fullscreenLabel
|
|
765
|
-
, icon = fullscreenIcon
|
|
766
|
-
, onClickMsg = Just UserToggledPageViewFullscreen
|
|
767
|
-
, isFullscreen = model.fullscreen
|
|
768
|
-
}
|
|
769
|
-
, div
|
|
770
|
-
[ HA.class "modal-close-action" ]
|
|
771
|
-
[ viewButton
|
|
772
|
-
{ label = ""
|
|
773
|
-
, icon = Icons.close
|
|
774
|
-
, onClickMsg = Just UserClickedClosePageView
|
|
775
|
-
, isFullscreen = model.fullscreen
|
|
776
|
-
}
|
|
777
|
-
]
|
|
778
|
-
]
|
|
779
|
-
]
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
viewModalSidebar : Model -> Html Msg
|
|
783
|
-
viewModalSidebar model =
|
|
784
|
-
div
|
|
785
|
-
[ HA.class "modal-sidebar" ]
|
|
786
|
-
[ Lazy.lazy viewTransformGroup model
|
|
787
|
-
, Lazy.lazy viewToneGroup model
|
|
788
|
-
, Lazy.lazy viewColourAdjustGroup model
|
|
789
|
-
, Lazy.lazy viewMorphologyGroup model
|
|
790
|
-
, Lazy.lazy viewConvolutionGroup model
|
|
791
|
-
, Lazy.lazy viewColourmapGroup model
|
|
792
|
-
, Lazy.lazy viewPseudoColourGroup model
|
|
793
|
-
, Lazy.lazy viewPcaGroup model
|
|
794
|
-
, Lazy.lazy viewAdvancedColourAdjustGroup model
|
|
795
|
-
, Lazy.lazy viewEnhancementGroup model
|
|
796
|
-
, Lazy.lazy viewFilterJsonGroup model
|
|
797
|
-
]
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
viewModalViewer : Bool -> Bool -> Html Msg
|
|
801
|
-
viewModalViewer fullscreen isOuterLeft =
|
|
802
|
-
div
|
|
803
|
-
[ classList
|
|
804
|
-
[ ( "modal-viewer", True )
|
|
805
|
-
, ( "is-fullscreen", fullscreen )
|
|
806
|
-
, ( "is-outer-left", isOuterLeft )
|
|
807
|
-
]
|
|
808
|
-
]
|
|
809
|
-
[ div
|
|
810
|
-
[ HA.class "modal-canvas"
|
|
811
|
-
, id "filter-viewer"
|
|
812
|
-
]
|
|
813
|
-
[]
|
|
814
|
-
]
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
viewMorphologyGroup : Model -> Html Msg
|
|
818
|
-
viewMorphologyGroup model =
|
|
819
|
-
viewFilterGroup model
|
|
820
|
-
"morphology"
|
|
821
|
-
"Morphology"
|
|
822
|
-
[ viewFilterRow
|
|
823
|
-
[ viewToggle "Morph" model.filters.morphEnabled ToggleMorph
|
|
824
|
-
, viewSelect model.filters.morphOperation (UserUpdatedFilterString StringMorphOperation) morphOperationOptions
|
|
825
|
-
, viewSelect (String.fromInt model.filters.morphKernel) (UserUpdatedFilterInt IntMorphKernel) morphKernelOptions
|
|
826
|
-
]
|
|
827
|
-
]
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
viewPcaGroup : Model -> Html Msg
|
|
831
|
-
viewPcaGroup model =
|
|
832
|
-
viewFilterGroup model
|
|
833
|
-
"pca"
|
|
834
|
-
"Visible area PCA"
|
|
835
|
-
[ viewFilterRow
|
|
836
|
-
[ viewToggle "Visible area PCA" model.filters.globalPcaEnabled ToggleGlobalPca
|
|
837
|
-
, viewSelect model.filters.pcaMode (UserUpdatedFilterString StringPcaMode) pcaModes
|
|
838
|
-
]
|
|
839
|
-
, viewRangeRow
|
|
840
|
-
{ label = "Hue Rotation"
|
|
841
|
-
, min = "-180"
|
|
842
|
-
, max = "180"
|
|
843
|
-
, step = Just "1"
|
|
844
|
-
, value = String.fromInt model.filters.pcaHue
|
|
845
|
-
, display = String.fromInt model.filters.pcaHue ++ "deg"
|
|
846
|
-
, onInput = UserUpdatedFilterInt IntPcaHue
|
|
847
|
-
}
|
|
848
|
-
]
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
viewPseudoColourGroup : Model -> Html Msg
|
|
852
|
-
viewPseudoColourGroup model =
|
|
853
|
-
viewFilterGroup model
|
|
854
|
-
"pseudo-colour"
|
|
855
|
-
"Pseudo Colour"
|
|
856
|
-
[ viewFilterRow
|
|
857
|
-
[ viewToggle "Pseudo-colour" model.filters.pseudoColourEnabled TogglePseudoColour
|
|
858
|
-
, viewSelect model.filters.pseudoColourMode (UserUpdatedFilterString StringPseudoColourMode) pseudoColourModes
|
|
859
|
-
]
|
|
860
|
-
, viewRangeRow
|
|
861
|
-
{ label = "Red Weight"
|
|
862
|
-
, min = "0"
|
|
863
|
-
, max = "2"
|
|
864
|
-
, step = Just "0.01"
|
|
865
|
-
, value = String.fromFloat model.filters.pseudoColourRed
|
|
866
|
-
, display = String.fromFloat model.filters.pseudoColourRed
|
|
867
|
-
, onInput = UserUpdatedFilterFloat FloatPseudoColourRed
|
|
868
|
-
}
|
|
869
|
-
, viewRangeRow
|
|
870
|
-
{ label = "Green Weight"
|
|
871
|
-
, min = "0"
|
|
872
|
-
, max = "2"
|
|
873
|
-
, step = Just "0.01"
|
|
874
|
-
, value = String.fromFloat model.filters.pseudoColourGreen
|
|
875
|
-
, display = String.fromFloat model.filters.pseudoColourGreen
|
|
876
|
-
, onInput = UserUpdatedFilterFloat FloatPseudoColourGreen
|
|
877
|
-
}
|
|
878
|
-
, viewRangeRow
|
|
879
|
-
{ label = "Blue Weight"
|
|
880
|
-
, min = "0"
|
|
881
|
-
, max = "2"
|
|
882
|
-
, step = Just "0.01"
|
|
883
|
-
, value = String.fromFloat model.filters.pseudoColourBlue
|
|
884
|
-
, display = String.fromFloat model.filters.pseudoColourBlue
|
|
885
|
-
, onInput = UserUpdatedFilterFloat FloatPseudoColourBlue
|
|
886
|
-
}
|
|
887
|
-
, viewFilterRow
|
|
888
|
-
[ viewToggle "Replace Colour" model.filters.colourReplaceEnabled ToggleColourReplace ]
|
|
889
|
-
, viewFilterRow
|
|
890
|
-
[ span [ HA.class "filter-label" ] [ text "Source" ]
|
|
891
|
-
, viewColourInput model.filters.colourReplaceSource (UserUpdatedFilterString StringColourReplaceSource)
|
|
892
|
-
, span [ HA.class "filter-label" ] [ text "Target" ]
|
|
893
|
-
, viewColourInput model.filters.colourReplaceTarget (UserUpdatedFilterString StringColourReplaceTarget)
|
|
894
|
-
]
|
|
895
|
-
, viewRangeRow
|
|
896
|
-
{ label = "Tolerance"
|
|
897
|
-
, min = "0"
|
|
898
|
-
, max = "255"
|
|
899
|
-
, step = Just "1"
|
|
900
|
-
, value = String.fromInt model.filters.colourReplaceTolerance
|
|
901
|
-
, display = String.fromInt model.filters.colourReplaceTolerance
|
|
902
|
-
, onInput = UserUpdatedFilterInt IntColourReplaceTolerance
|
|
903
|
-
}
|
|
904
|
-
, viewRangeRow
|
|
905
|
-
{ label = "Strength"
|
|
906
|
-
, min = "0"
|
|
907
|
-
, max = "1"
|
|
908
|
-
, step = Just "0.01"
|
|
909
|
-
, value = String.fromFloat model.filters.colourReplaceBlend
|
|
910
|
-
, display = String.fromFloat model.filters.colourReplaceBlend
|
|
911
|
-
, onInput = UserUpdatedFilterFloat FloatColourReplaceBlend
|
|
912
|
-
}
|
|
913
|
-
, viewFilterRow
|
|
914
|
-
[ viewToggle "Preserve Luminance" model.filters.colourReplacePreserveLum ToggleColourReplacePreserveLum ]
|
|
915
|
-
]
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
viewRangeInput : String -> String -> Maybe String -> String -> (String -> Msg) -> Html Msg
|
|
919
|
-
viewRangeInput minValue maxValue stepValue currentValue onChange =
|
|
920
|
-
let
|
|
921
|
-
baseAttrs =
|
|
922
|
-
[ type_ "range"
|
|
923
|
-
, HA.min minValue
|
|
924
|
-
, HA.max maxValue
|
|
925
|
-
, value currentValue
|
|
926
|
-
, onInput onChange
|
|
927
|
-
]
|
|
928
|
-
|
|
929
|
-
attrs =
|
|
930
|
-
case stepValue of
|
|
931
|
-
Just stepSize ->
|
|
932
|
-
HA.step stepSize :: baseAttrs
|
|
933
|
-
|
|
934
|
-
Nothing ->
|
|
935
|
-
baseAttrs
|
|
936
|
-
in
|
|
937
|
-
input (HA.class "filter-range-input" :: attrs) []
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
viewRangeRow : RangeRowConfig -> Html Msg
|
|
941
|
-
viewRangeRow config =
|
|
942
|
-
div [ HA.class "filter-range-group" ]
|
|
943
|
-
[ div [ HA.class "filter-range-header" ]
|
|
944
|
-
[ span [ HA.class "filter-label" ] [ text config.label ]
|
|
945
|
-
, span [ HA.class "filter-value" ] [ text config.display ]
|
|
946
|
-
]
|
|
947
|
-
, viewRangeInput config.min config.max config.step config.value config.onInput
|
|
948
|
-
]
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
viewRotationRow : Model -> Html Msg
|
|
952
|
-
viewRotationRow model =
|
|
953
|
-
div [ HA.class "filter-range-group" ]
|
|
954
|
-
[ div [ HA.class "filter-range-header" ]
|
|
955
|
-
[ span [ HA.class "filter-label" ] [ text "Rotation" ]
|
|
956
|
-
, span [ HA.class "filter-range-header-right" ]
|
|
957
|
-
[ span [ HA.class "filter-value" ]
|
|
958
|
-
[ text (String.fromInt model.filters.rotation ++ "°") ]
|
|
959
|
-
, button
|
|
960
|
-
[ HA.class "filter-reset"
|
|
961
|
-
, type_ "button"
|
|
962
|
-
, onClick (UserUpdatedFilterInt IntRotation "0")
|
|
963
|
-
]
|
|
964
|
-
[ text "Reset" ]
|
|
965
|
-
]
|
|
966
|
-
]
|
|
967
|
-
, viewRangeInput "-180"
|
|
968
|
-
"180"
|
|
969
|
-
(Just "1")
|
|
970
|
-
(String.fromInt model.filters.rotation)
|
|
971
|
-
(UserUpdatedFilterInt IntRotation)
|
|
972
|
-
]
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
viewSelect : String -> (String -> Msg) -> List (Html Msg) -> Html Msg
|
|
976
|
-
viewSelect currentValue onChange options =
|
|
977
|
-
select
|
|
978
|
-
[ HA.class "filter-select"
|
|
979
|
-
, onInput onChange
|
|
980
|
-
, value currentValue
|
|
981
|
-
]
|
|
982
|
-
options
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
viewToggle : String -> Bool -> FilterToggle -> Html Msg
|
|
986
|
-
viewToggle labelText isChecked toggle =
|
|
987
|
-
label [ HA.class "filter-toggle" ]
|
|
988
|
-
[ input
|
|
989
|
-
[ type_ "checkbox"
|
|
990
|
-
, checked isChecked
|
|
991
|
-
, onCheck (UserToggledFilter toggle)
|
|
992
|
-
]
|
|
993
|
-
[]
|
|
994
|
-
, text labelText
|
|
995
|
-
]
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
viewToggleRangeRow : ToggleRangeRowConfig -> Html Msg
|
|
999
|
-
viewToggleRangeRow config =
|
|
1000
|
-
div [ HA.class "filter-range-group" ]
|
|
1001
|
-
[ div [ HA.class "filter-range-header" ]
|
|
1002
|
-
[ label [ HA.class "filter-toggle is-inline" ]
|
|
1003
|
-
[ input
|
|
1004
|
-
[ type_ "checkbox"
|
|
1005
|
-
, checked config.checked
|
|
1006
|
-
, onCheck (UserToggledFilter config.onToggle)
|
|
1007
|
-
]
|
|
1008
|
-
[]
|
|
1009
|
-
, text config.label
|
|
1010
|
-
]
|
|
1011
|
-
, span [ HA.class "filter-value" ] [ text config.display ]
|
|
1012
|
-
]
|
|
1013
|
-
, viewRangeInput config.min config.max config.step config.value config.onInput
|
|
1014
|
-
]
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
viewToggleRows : List ( String, Bool, FilterToggle ) -> List (Html Msg)
|
|
1018
|
-
viewToggleRows items =
|
|
1019
|
-
List.map
|
|
1020
|
-
(\( labelText, isChecked, toggle ) ->
|
|
1021
|
-
viewToggle labelText isChecked toggle
|
|
1022
|
-
)
|
|
1023
|
-
items
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
viewToneGroup : Model -> Html Msg
|
|
1027
|
-
viewToneGroup model =
|
|
1028
|
-
viewFilterGroup model
|
|
1029
|
-
"tone"
|
|
1030
|
-
"Tone"
|
|
1031
|
-
(viewToggleRows
|
|
1032
|
-
[ ( "Grayscale", model.filters.grayscale, ToggleGrayscale )
|
|
1033
|
-
, ( "Invert", model.filters.invert, ToggleInvert )
|
|
1034
|
-
]
|
|
1035
|
-
++ List.map viewToggleRangeRow (toneToggleRanges model)
|
|
1036
|
-
)
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
viewTransformGroup : Model -> Html Msg
|
|
1040
|
-
viewTransformGroup model =
|
|
1041
|
-
viewFilterGroup model
|
|
1042
|
-
"transform"
|
|
1043
|
-
"Transform"
|
|
1044
|
-
[ viewRotationRow model
|
|
1045
|
-
, viewMirrorRow model
|
|
1046
|
-
]
|