@@ -11,6 +11,7 @@ import Data.Map as M
1111import Data.Maybe (Maybe (..), fromMaybe , maybe )
1212import Data.Number (exp )
1313import Data.Ratio ((%))
14+ import Data.Tuple (Tuple (..))
1415import Halogen as H
1516import Halogen.HTML as HH
1617import Halogen.HTML.Core as HC
@@ -21,7 +22,8 @@ import Halogen.Svg.Attributes as SA
2122import Halogen.Svg.Elements as SE
2223import ProtoVoices.Common (MBS (..))
2324import ProtoVoices.Folding (Graph , GraphSlice , GraphTransition )
24- import ProtoVoices.Model (DoubleOrnament (..), Edge , LeftOrnament (..), Note , NoteExplanation (..), Notes , Parents , Piece , RightOrnament (..), SliceId , StartStop (..), Styles , explHasParent , getInnerNotes , getParents , setHoriExplParent , setLeftExplParent , setRightExplParent )
25+ import ProtoVoices.Model (DoubleOrnament (..), Edge , LeftOrnament (..), Note , NoteExplanation (..), Notes , Parents , Piece , RightOrnament (..), SliceId , StartStop (..), Styles , edgeIds , explHasParent , getInnerNotes , getParents , setHoriExplParent , setLeftExplParent , setRightExplParent )
26+ import ProtoVoices.RenderSVG as RenderSVG
2527import ProtoVoices.Validation (EdgeError (..), NoteError (..), SliceError (..), Validation )
2628import Web.UIEvent.MouseEvent (ctrlKey )
2729
@@ -82,18 +84,29 @@ defaultCSS =
8284 .slice {
8385 fill: lightgray;
8486 }
87+ .transition {
88+ stroke: lightgray;
89+ }
8590 .test {
8691 fill: red;
8792 }
93+ """ <> RenderSVG .defaultStyles <>
94+ """
8895}
8996@layer ui {
97+ .node {
98+ stroke: none;
99+ }
90100 .slice {
91101 rx: 5px;
102+ stroke: none;
92103 }
104+
93105 .hidden {
94106 display: inline !important;
95107 stroke: lightgray;
96108 }
109+
97110 .selected {
98111 fill: #1e90ff;
99112 }
@@ -106,6 +119,17 @@ defaultCSS =
106119 .error {
107120 fill: red;
108121 }
122+
123+
124+ .transition.selected, .edge.selected {
125+ stroke: #1e90ff;
126+ }
127+ .edge.warning {
128+ stroke: #ffa500;
129+ }
130+ .edge.error {
131+ stroke: red;
132+ }
109133}
110134"""
111135
@@ -146,26 +170,27 @@ derive instance eqSelectionStatus :: Eq SelectionStatus
146170renderSlice :: forall p . AppSettings -> Selection -> Validation -> Styles -> GraphSlice -> HH.HTML p GraphAction
147171renderSlice sett selection validation styles { slice: { id, notes, x, parents }, depth: d } = case notes of
148172 Inner inotes ->
149- SE .g []
150- $
151- [ SE .rect $
152- [ SA .x svgx
153- , SA .y svgy
154- , SA .width noteSize
155- , SA .height $ offset 1
156- , SA .class_ $ HH.ClassName $ " slice " <> sliceClasses <> if selected then " selected" else if activeParent then " related" else if sliceInvalid then " error" else " "
157- ] <> selectionAttr
158- , SE .element (HH.ElemName " text" )
159- [ SA .x (svgx + noteSize / 2.0 )
160- , SA .y svgy
161- , SA .textAnchor SA.AnchorMiddle
162- , SA .dominantBaseline SA.BaselineMiddle
163- , HP .style " pointer-events: none;"
164- , SA .class_ $ HH.ClassName $ " slice-label " <> sliceClasses
165- ]
166- [ HH .text sliceLabel ]
167- ]
168- <> mapWithIndex mknote inotes
173+ SE .g [] $
174+ [ SE .g [ SA .class_ $ HH.ClassName sliceClasses ]
175+ [ SE .rect $
176+ [ SA .x svgx
177+ , SA .y svgy
178+ , SA .width noteSize
179+ , SA .height $ offset 1
180+ , SA .class_ $ HH.ClassName $ " slice " <> sliceClasses <> if selected then " selected" else if activeParent then " related" else if sliceInvalid then " error" else " "
181+ ] <> selectionAttr
182+ , SE .element (HH.ElemName " text" )
183+ [ SA .x (svgx + noteSize / 2.0 )
184+ , SA .y svgy
185+ , SA .textAnchor SA.AnchorMiddle
186+ , SA .dominantBaseline SA.BaselineMiddle
187+ , HP .style " pointer-events: none;"
188+ , SA .class_ $ HH.ClassName " slice-label"
189+ ]
190+ [ HH .text sliceLabel ]
191+ ]
192+ ]
193+ <> mapWithIndex mknote inotes
169194 startstop -> mknode (show startstop) (show startstop) (scalex sett x) (scaley sett d) (if activeParent then Related else NotSelected ) Nothing [] " "
170195 where
171196 svgx = scalex sett x - (noteSize / 2.0 )
@@ -201,11 +226,6 @@ renderSlice sett selection validation styles { slice: { id, notes, x, parents },
201226 , SA .y $ ycoord - (offset 1 / 2.0 )
202227 , SA .width noteSize
203228 , SA .height $ offset 1
204- -- , SA.fill
205- -- $ case selStatus of
206- -- NotSelected -> white
207- -- Selected -> selColorInner
208- -- Related -> selColorInner'
209229 , SA .class_ $ HH.ClassName $ " node " <> classes <> case selStatus of
210230 NotSelected -> " "
211231 Selected -> " selected"
@@ -273,8 +293,8 @@ renderSlice sett selection validation styles { slice: { id, notes, x, parents },
273293
274294 label = maybe " " (\s -> " - " <> s.label) style
275295
276- renderTrans :: forall p . AppSettings -> Selection -> Validation -> M.Map SliceId GraphSlice -> GraphTransition -> HH.HTML p GraphAction
277- renderTrans sett selection validation slices { id, left, right, edges } =
296+ renderTrans :: forall p . AppSettings -> Selection -> Validation -> Styles -> M.Map SliceId GraphSlice -> GraphTransition -> HH.HTML p GraphAction
297+ renderTrans sett selection validation styles slices { id, left, right, edges } =
278298 fromMaybe (HH .text " " )
279299 $ do
280300 { depth: yl, slice: { x: xl, notes: nl } } <- M .lookup left slices
@@ -285,41 +305,70 @@ renderTrans sett selection validation slices { id, left, right, edges } =
285305 bar =
286306 [ SE .line
287307 $
288- [ SA .x1 $ scalex sett xl
308+ [ SA .id $ show id
309+ , SA .x1 $ scalex sett xl
289310 , SA .y1 $ scaley sett yl
290311 , SA .x2 $ scalex sett xr
291312 , SA .y2 $ scaley sett yr
292313 , SA .stroke if transSelected then selColorOuter else lightgray
293- , SA .strokeWidth $ if topLevel then (noteSize / 2.0 ) else 5.0
314+ , SA .strokeWidth $ if topLevel then (noteSize / 2.0 ) else 7.0
315+ , SA .class_ $ HH.ClassName $ " transition " <> transClasses <> if transSelected then " selected" else " "
294316 ]
295317 <> selectionAttr
318+ , SE .text [ SA .textAnchor SA.AnchorMiddle , SA .dominantBaseline SA.Auto ]
319+ [ SE .element (H.ElemName " textPath" )
320+ [ SA .href $ " #" <> show id
321+ -- SA.path
322+ -- [ SA.m SA.Abs (scalex sett xl) (scaley sett yl)
323+ -- , SA.l SA.Abs (scalex sett xr) (scaley sett yr)
324+ -- ]
325+ , HP .attr (HH.AttrName " startOffset" ) " 50%"
326+ ]
327+ [ HH .text transLabel ]
328+ ]
296329 ]
297330
298331 mkedge :: Boolean -> Edge -> HH.HTML p GraphAction
299- mkedge isPassing edge@{ left: p1, right: p2 } =
300- SE .line
301- [ SA .x1 $ scalex sett xl
302- , SA .y1 $ scaley sett yl + offset offl
303- , SA .x2 $ scalex sett xr
304- , SA .y2 $ scaley sett yr + offset offr
305- , SA .stroke
306- if edgeSelected then
307- selColorInner
308- else case M .lookup edge validation.edges of
309- Just ESNotUsed -> warnColor
310- Just ESNotStepwise -> errColor
311- Just ESNotRepetition -> errColor
312- _ -> black
313- , SA .strokeWidth 1.0
314- , HP .attr (HH.AttrName " stroke-dasharray" ) (if isPassing then " 6,3" else " " )
315- ]
332+ mkedge isPassing edge@{ left: p1, right: p2 } = SE .g []
333+ [ SE .line
334+ [ SA .x1 $ x1
335+ , SA .y1 $ y1
336+ , SA .x2 $ x2
337+ , SA .y2 $ y2
338+ , SA .strokeWidth 1.0
339+ , HP .attr (HH.AttrName " stroke-dasharray" ) (if isPassing then " 6,3" else " " )
340+ , SA .class_ $ HH.ClassName $ " edge " <> edgeClasses <>
341+ if edgeSelected then
342+ " selected"
343+ else case M .lookup edge validation.edges of
344+ Just ESNotUsed -> " warning"
345+ Just ESNotStepwise -> " error"
346+ Just ESNotRepetition -> " error"
347+ _ -> " "
348+ ]
349+ , SE .text [ SA .textAnchor SA.AnchorMiddle , SA .dominantBaseline SA.Hanging ]
350+ [ SE .element (H.ElemName " textPath" )
351+ [ SA .path [ SA .m SA.Abs x1 y1, SA .l SA.Abs x2 y2 ]
352+ , HP .attr (HH.AttrName " startOffset" ) " 50%"
353+ ]
354+ [ HH .text edgeLabel ]
355+ ]
356+ ]
316357 where
317358 offl = findPitchIndex p1 nl
318-
319359 offr = findPitchIndex p2 nr
320360
361+ x1 = scalex sett xl
362+ x2 = scalex sett xr
363+ y1 = scaley sett yl + offset offl
364+ y2 = scaley sett yr + offset offr
365+
321366 edgeSelected = noteIsSelected selection p1 || noteIsSelected selection p2
322367
368+ edgeStyle = M .lookup (edgeIds edge) styles.edges
369+ edgeClasses = maybe " " (_.classes) edgeStyle
370+ edgeLabel = maybe " " (_.label) edgeStyle
371+
323372 edgeLines = map (mkedge false ) (A .fromFoldable edges.regular) <> map (mkedge true ) (A .fromFoldable edges.passing)
324373 pure $ SE .g [] (bar <> edgeLines)
325374 where
@@ -330,6 +379,10 @@ renderTrans sett selection validation slices { id, left, right, edges } =
330379 , HE .onClick $ \_ -> Select (if transSelected then SelNone else SelTrans id)
331380 ]
332381
382+ transStyle = M .lookup id styles.transitions
383+ transClasses = maybe " " (_.classes) transStyle
384+ transLabel = maybe " " (_.label) transStyle
385+
333386renderHori
334387 :: forall p
335388 . AppSettings
@@ -427,7 +480,7 @@ renderReduction sett piece graph validation styles selection =
427480
428481 svgSlices = map (renderSlice sett selection validation styles) $ fromFoldable $ M .values slices
429482
430- svgTranss = map (renderTrans sett selection validation slices) $ fromFoldable $ M .values transitions
483+ svgTranss = map (renderTrans sett selection validation styles slices) $ fromFoldable $ M .values transitions
431484
432485 svgHoris = map (renderHori sett selection slices) $ fromFoldable horis
433486
0 commit comments