The slider: attribute is a Group. Its Layout properties are ignored. The slider: is drawn after contents: so that it always lies on top. The origin of the slider should always lie on the curve defined by the path and the sliderVal: attribute.
The sliderVal: attribute is a value between 0.0 and 1.0. This defines a point on the path: curve where the slider's origin is to be located. Given the sliderVal: and the path: you determine the point where the origin of the slider: should be located. If the sliderVal=0.0 then the origin of the slider group should be at the first point in the path. If the sliderVal=1.0 then the origin should be at the last point in the path. For values in between 0.0 and 1.0 the slider should move smoothly along the path. By taking the first derivative of the path: at that point you can determine a vector that is the direction of travel at that point. The slider should be rotated so that it's up direction is opposite to the direction of travel. This will make the slider appear to follow the path: and to stay aligned with it.
If Path receives a mouseDown() event that selects the slider then we begin dragging the slider. On every mouseMove() event we compute the nearest point on the path: curve and then use our linear length parameterization of the curve to compute a new value for sliderVal:. We then cause the display to update. This will make the slider drag along the path in a way that orients the slider to the path.
Whenever the sliderVal: is changed it modifies the value referenced by the model: selection path. Whenever that referenced value in the model is changed, it changes sliderVal:.
The Path object also implements Layout. It always reports min, desired, and max to be the values of the width: and height: attributes. If the Path is given a width or height different from these attributes, it should be scaled to fit the dimensions that it is given. This will allow Path to be embedded in a layout.
Select{ contents: [ Polygon{ points: [ {x:300,y:200 }, {x:600,y:500 }, {x:500,y:500 }, {x:500,y:600 }, {x:300,y:500 }, {x:100,y:600 }, {x:100,y:400 } ], border:{r:0,g:0,b:0},fill:{r:100,g:100,b:100} } ] }
Select{ contents: [ Curve{ points: [ {x:300,y:200 }, {x:600,y:500 }, {x:500,y:500 }, {x:500,y:600 }, {x:300,y:500 }, {x:100,y:600 }, {x:100,y:400 }, {x:300,y:200 } ], border:{r:0,g:0,b:0},fill:{r:100,g:100,b:100} } ] }
Select{ contents: [ Curve{ points: [ {x:300,y:200 }, {x:600,y:500 }, {x:500,y:500 }, {x:500,y:600 }, {x:300,y:500 }, {x:100,y:600 }, {x:100,y:400 }, {x:300,y:200 } ], border:{r:0,g:0,b:0} } ] }
Root{ contents:[ VStack{ contents:[ Button{ label:"zero", state:"idle", idle:{r:255,g:255,b:255}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["size" ], value:0.0, contents:[ Rect{ class:"active", left:10, top:610, width:300, height:200, thickness:2, border:{r:0,g:0,b:100} }, Text{ class:"label", text:"wrong", x:720,y:250, font:"sans-serif",size:30 } ] }, Path{ path: [ {x:500,y:100}, {x:100,y:300}, {x:600,y:400}, {x:700,y:500} ], contents: [ Curve{ points: [ {x:500,y:100}, {x:100,y:300}, {x:600,y:400}, {x:700,y:500} ], border:{r:255,g:0,b:0}, thickness:4 } ], slider: Group{ contents: [ Polygon{ points:[ {x:0,y:-50}, {x:20,y:-20}, {x:40,y:-20}, {x:40,y:10}, {x:0,y:20}, {x:-40,y:10}, {x:-40,y:-20}, {x:-20,y:20}], fill:{r:100, g:100, b:255} } ] }, sliderVal:1.0, width:800, height:600, model:[ "size" ] } ] } ], model:{ size:0.5, location:{ number:144, street:"Inglewood" }, age:55 } }