Example:
Root{ contents:[ all the presentation objects ], model:Employee{ name:"George", address:"1414 Mockingbird Lane", age:42 } }For purposes of being able to see the effects of the various widgets, this object should write its model attribute to the console after processing every mouseUp() event. This will make it easy to see the impact of the various widgets on the model.
The objects should respond to the Interactable methods in the following ways:
The state logic is:
If a mouseUp() occurs while the button is in the active state then the model attribute should be used as a path from the Root's model to identify an attribute to be changed. The model attribute should be changed to the value of the Button's value attribute.
Example:
Button{ label:"Hit", contents:[ Ellipse{ class:"active", left:100, top:200, width:100, height:50 } Ellipse{ left:110, top:210, width:80, height:30, fill:{r:255, g:255, b:255 } }, Text{ class:"label", x:120, y:230, font:"sans-serif", size:15} ], state:"idle" }The Text object will have its text attribute replaced by "Hit" and the color of the first Ellipse object will change in response to the mouse.
Within contents there should be at least one object 'class:"up"'. If a mouseUp() event occurs while such an object is selected then the current value should be changed by value+step, provided it does not exceed max.
Within contents there should be at least one object 'class:"down"'. If a mouseUp() event occurs while such an object is selected then the current value should be changed by value-step, provided it does not go below min.
Within contents there should be at least one object 'class:"slide"'. If a mouseUp() event occurs while such an object is selected then it is saved and the slider becomes active. mouseMove() events while the mouse button is down should move the slider vertically but not horizontally. The location of the slider should change the current value so that when the slider is at the top, the value is max, and when the slider is at the bottom its value is min. There should also be an object with 'class:"range"'. This is generally a Rect or Line. This object defines the range of movement for the slide object.
The model attribute contains a path from the Root object's model to the value controlled by this slider. Whenever the current value of the slider is changes, the model attribute and the Root object should be used to find the correct location in the model and change it to the new value. Whenever the model value changes the ScrollV object should change the location of the slider.
Example:
ScrollV{ state:"idle", idle:{r:0,g:0,b:0}, hover:{r:100,g:100,b:100}, active:{r:255,g:255,b:0}, model:["age"], max:100, min:0, step:1, contents:[ Rect{ class:"active", left:10,top:10, width:20, height:190, fill:{r:255,g:255,b:255}}, Rect{ class:"range", left:10, top:32, width:20, height:136, fill:{r:200,g:200,b:200} }, Polygon{ class:"up", points:[{x:12,y:30},{x:20,y:12},{x:28,y:30}], fill:{r:0,g:0,b:0} }, Polygon{ class:"down", points:[{x:12,y:170},{x:20,y:198},{x:28,y:170}], fill:{r:0,g:0,b:0} }, Rect{ class:"slide", left:12, top:100, width:26, height:30,fill:{r:0,g:0,b:0} } ] }
On key() events any normal events should add a character to text at the point in the string indicated by "cursor" and "cursor" should be incremented. If the key is backspace then the preceding character should be removed from the text string and cursor decremented.
Example:
TextBox{ state:"idle", idle:{r:0,g:0,b:0}, hover:{r:100,g:100,b:100}, active:{r:255,g:255,b:0}, model:["name"], edit:true, cursor:-1, contents: [ Rect{ class:"active", x:10,y:300, width:200, height:30 }, Text{ class:"content", x:20,y:320,font:"serif", size:15 } ] }
Root{ contents:[ Button{ label:"20", state:"idle", idle:{r:255,g:255,b:255}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["location", "street"], value:"Farmington", contents:[ Rect{ class:"active", left:10, top:10, width:300, height:200, thickness:2, border:{r:0,g:0,b:100} }, Text{ class:"label", text:"wrong", x:120,y:250, font:"sans-serif",size:30 } ] }, TextBox{state:"idle", idle:{r:200,g:200,b:200}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["location","street"], contents:[ Rect{ class:"active",left:100, top:400, width:400, height:200, fill:{r:255,g:255,b:255}}, Text{ edit:true, class:"content", text:"wrong", x:120,y:550, font:"serif",size:10 } ] } ], model:{ size:10, location:{ number:144, street:"Inglewood" }, age:55 } }
Root{ contents:[ Button{ label:"20", 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:20, contents:[ Rect{ class:"active", left:10, top:10, width:300, height:200, thickness:2, border:{r:0,g:0,b:100} }, Text{ class:"label", text:"wrong", x:120,y:250, font:"sans-serif",size:30 } ] }, ScrollV{ state:"idle", idle:{r:200,g:200,b:200}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["size"], max:50, min:0, step:1,model:["size"], contents:[ Rect{ class:"active",left:600, top:100, width:100, height:600, fill:{r:255,g:255,b:255}}, Rect{ class:"range",left:600, top:200, width:100, height:400, thickness:1, border:{r:0,g:0,b:0}}, Rect{ class:"up", left:600,top:100,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"down", left:600,top:600,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"slide", left:600,top:300,width:100,height:100,fill:{r:125,g:125,b:125} } ] }, ScrollV{ state:"idle", idle:{r:200,g:200,b:200}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["size"], max:50, min:0, step:1,model:["size"], contents:[ Rect{ class:"active",left:800, top:100, width:100, height:600, fill:{r:255,g:255,b:255}}, Rect{ class:"range",left:800, top:200, width:100, height:400, thickness:1, border:{r:0,g:0,b:0}}, Rect{ class:"up", left:800,top:100,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"down", left:800,top:600,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"slide", left:800,top:300,width:100,height:100,fill:{r:125,g:125,b:125} } ] }, ScrollH{state:"idle", idle:{r:200,g:200,b:200}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["size"], max:100, min:0, step:1, model:["age"], contents:[ Rect{ class:"active",left:100, top:800, width:700, height:100, fill:{r:255,g:255,b:255}}, Rect{ class:"range",left:200, top:800, width:500, height:100, thickness:1, border:{r:0,g:0,b:0}}, Rect{ class:"up", left:700,top:800,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"down", left:100,top:800,width:100,height:100,fill:{r:125,g:125,b:125} }, Rect{ class:"slide", left:600,top:800,width:100,height:100,fill:{r:125,g:125,b:125} } ] }, TextBox{state:"idle", idle:{r:200,g:200,b:200}, hover:{r:200,g:200,b:255}, active:{r:255,g:255,b:200}, model:["location","street"], contents:[ Rect{ class:"active",left:100, top:400, width:400, height:200, fill:{r:255,g:255,b:255}}, Text{ edit:true, class:"content", text:"wrong", x:120,y:550, font:"serif",size:10 } ] } ], model:{ size:10, location:{ number:144, street:"Inglewood" }, age:55 } }