Lively Kernel canvas
//
DraftNewSliderMorph40
10000.7605608101384954Wikicontroltrue
10000.016930732161259815Wikicontroltrue
10000.00005082058077018364Wikicontroltrue
100011.530511290851061Wikicontroltrue
nulltrueif($morph('slider'))$morph('slider').remove()m=newSliderMorph2(newRectangle(0,0,30,100));m.openInWorld();m.setPosition(pt(100,100))m.name="slider"m.setValue(0.3)7truetruefalsetruetruefalse
false1truefalsetruetruefalse
nullfalsetruenullfalse
falsenullfalse
false
false
falsenullfalsefalsenullnullnullnullfalse
10.3
nullfalsetruenullfalse
widgets2.jsfalsenullfalse
false
false
falsenullfalse
http://localhost/lk/webwerkstatt/draft/truetruetruetrue
truetrue
1truetruetrue
connection.js(notparsed)falsetruefalse0false
Localcodefalsetruefalse0false
widgets2.jsfalsetruefalse0false1862nullnulltruefalsenullnulltruetrue
1true
null
null
null
nulltruetrue
SliderMorph2falsetruefalse0false217-1nullnullnulltruetruetrue
1true
null
null
null
nulltruetrue
-----falsetruefalse0false217
-1nullnullnulltruetruetrue
1true
null
null
null
nulltruetrue
module('draft.widgets2').requires().toRun(function(){BoxMorph.subclass("SliderMorph2",{documentation:"Slider/scrollcontrol",mss:12,//minimumslidersizeformals:{Value:{byDefault:0},//from:function(value){alert('from!'+value);returnvalue;}},SliderExtent:{mode:"-",byDefault:0}},style:{borderWidth:1,borderColor:Color.black},selfModelClass:PlainRecord.prototype.create({Value:{byDefault:0},SliderExtent:{byDefault:0}}),connections:['value'],initialize:function($super,initialBounds,scaleIfAny){$super(initialBounds);//thisdefaultselfconnectionmaygetoverwrittenby,eg,connectModel()...varmodelClass=this.selfModelClass;varmodel=newmodelClass({},{});this.connectModel(model.newRelay({Value:"Value",SliderExtent:"SliderExtent"}));this.valueScale=(scaleIfAny===undefined)?1.0:scaleIfAny;varslider=Morph.makeRectangle(0,0,this.mss,this.mss);slider.relayMouseEvents(this,{onMouseDown:"sliderPressed",onMouseMove:"sliderMoved",onMouseUp:"sliderReleased"});this.slider=this.addMorph(slider);this.slider.linkToStyles(['slider']);this.adjustForNewBounds();this.adjustFill();returnthis;},onDeserialize:function(){if(!this.slider){console.warn('nosliderin%s,%s',this,this.textContent);return;}this.slider.relayMouseEvents(this,{onMouseDown:"sliderPressed",onMouseMove:"sliderMoved",onMouseUp:"sliderReleased"});//TODO:removethisworkaroundsbyserializingobserverrelationsshipsif(this.formalModel&&this.formalModel.addObserver){this.formalModel.addObserver(this)}},vertical:function(){varbnds=this.shape.bounds();returnbnds.height>bnds.width;},applyStyle:function($super,spec){$super(spec);//needtocalladjusttoupdategraphics,butonlyaftersliderexistsif(this.slider){this.adjustForNewBounds();this.adjustFill();}},adjustForNewBounds:function($super){$super();this.adjustSliderParts();},adjustSliderParts:function($super){//Thismethodadjuststhesliderforchangesinvalueaswellasgeometryvarval=this.getScaledValue();varbnds=this.shape.bounds();varext=this.getSliderExtent();if(this.vertical()){//morevertical...varelevPix=Math.max(ext*bnds.height,this.mss);//thicknessofelevatorinpixelsvartopLeft=pt(0,(bnds.height-elevPix)*val);varsliderExt=pt(bnds.width,elevPix);}else{//morehorizontal...varelevPix=Math.max(ext*bnds.width,this.mss);//thicknessofelevatorinpixelsvartopLeft=pt((bnds.width-elevPix)*val,0);varsliderExt=pt(elevPix,bnds.height);}this.slider.setBounds(bnds.topLeft().addPt(topLeft).extent(sliderExt));//this.slider.shapeRoundEdgesBy((this.vertical()?sliderExt.x:sliderExt.y)/2);this.slider.shapeRoundEdgesBy(Math.min(sliderExt.x,sliderExt.y)/2);},adjustFill:function(){varfill=this.slider.getFill();vargfx=lively.paint;if(fillinstanceoflively.paint.LinearGradient){vardirection=this.vertical()?gfx.LinearGradient.EastWest:gfx.LinearGradient.NorthSouth;varbaseColor=fill.stops[0].color();this.setFill(newgfx.LinearGradient([newgfx.Stop(0,baseColor,1),newgfx.Stop(0.5,baseColor.lighter(2)),newgfx.Stop(1,baseColor)],direction));//FIXME:justflipthegradientthis.slider.setFill(newgfx.LinearGradient([newgfx.Stop(0,baseColor),newgfx.Stop(1,fill.stops[1].color())],direction));this.setBorderWidth(this.slider.getBorderWidth());}elseif(fill){this.setFill(fill.lighter());}},sliderPressed:function(evt,slider){//Note:wantsetMouseFocustoalsocachethetransformandrecordthehitPoint.//Ideallythereafteronlyhavetosay,eg,morph.setPosition(evt.hand.adjustedMousePoint)this.hitPoint=this.localize(evt.mousePoint).subPt(this.slider.bounds().topLeft());},sliderMoved:function(evt,slider){if(!evt.mouseButtonPressed)return;//Computethevaluefromanewmousepoint,andemititvarp=this.localize(evt.mousePoint).subPt(this.hitPoint);varbnds=this.shape.bounds();varext=this.getSliderExtent();if(this.vertical()){//morevertical...varelevPix=Math.max(ext*bnds.height,this.mss);//thicknessofelevatorinpixelsvarnewValue=p.y/(bnds.height-elevPix);}else{//morehorizontal...varelevPix=Math.max(ext*bnds.width,this.mss);//thicknessofelevatorinpixelsvarnewValue=p.x/(bnds.width-elevPix);}if(isNaN(newValue))newValue=0;this.setScaledValue(this.clipValue(newValue));this.adjustForNewBounds();},sliderReleased:Functions.Empty,handlesMouseDown:function(evt){return!evt.isCommandKey();},onMouseDown:function(evt){this.requestKeyboardFocus(evt.hand);varinc=this.getSliderExtent();varnewValue=this.getValue();vardelta=this.localize(evt.mousePoint).subPt(this.slider.bounds().center());if(this.vertical()?delta.y>0:delta.x>0)newValue+=inc;elsenewValue-=inc;if(isNaN(newValue))newValue=0;this.setScaledValue(this.clipValue(newValue));this.adjustForNewBounds();},onMouseMove:function($super,evt){//Overridensowon'tdragmeifmousepressedif(evt.mouseButtonPressed)return;return$super(evt);},clipValue:function(val){returnMath.min(1.0,Math.max(0,0,val.roundTo(0.0001)));},updateView:function(aspect,controller){//obsoletesoon?varp=this.modelPlug;if(!p)return;if(aspect==p.getValue||aspect=='all'){this.onValueUpdate(this.getValue());}elseif(aspect==p.getSliderExtent||aspect=='all'){this.onSliderExtentUpdate(this.getSliderExtent());}},onSliderExtentUpdate:function(extent){this.adjustForNewBounds();},onValueUpdate:function(value){this.adjustForNewBounds();this.value=value//forconnect},getScaledValue:function(){return(this.getValue()||0)/this.valueScale;//FIXMEremove0},setScaledValue:function(value){returnthis.setValue(value*this.valueScale);},takesKeyboardFocus:Functions.True,setHasKeyboardFocus:function(newSetting){returnnewSetting;//noneedtoremember},onKeyPress:Functions.Empty,onKeyDown:function(evt){vardelta=0;if(this.vertical()){switch(evt.getKeyCode()){caseEvent.KEY_DOWN:delta=1;break;caseEvent.KEY_UP:delta=-1;break;default:returnfalse;}}else{switch(evt.getKeyCode()){caseEvent.KEY_RIGHT:delta=1;break;caseEvent.KEY_LEFT:delta=-1;break;default:returnfalse;}}this.setScaledValue(this.clipValue(this.getScaledValue()+delta*(this.getSliderExtent())));this.adjustForNewBounds();evt.stop();returntrue;}});})//endofmodule bnds.width; \n\t},\n\t\n\tapplyStyle: function($super, spec) {\n\t\t$super(spec);\n\t\t// need to call adjust to update graphics, but only after slider exists\n\t\tif (this.slider) {\n\t\t\tthis.adjustForNewBounds(); \n\t\t\tthis.adjustFill();\n\t\t}\n\t},\n\t\n\tadjustForNewBounds: function($super) {\n\t\t$super();\n\t\tthis.adjustSliderParts();\n\t},\n\t\n\tadjustSliderParts: function($super) {\n\t\t// This method adjusts the slider for changes in value as well as geometry\n\t\tvar val = this.getScaledValue();\n\t\tvar bnds = this.shape.bounds();\n\t\tvar ext = this.getSliderExtent(); \n\n\t\n\t\tif (this.vertical()) { // more vertical...\n\t\t\tvar elevPix = Math.max(ext*bnds.height, this.mss); // thickness of elevator in pixels\n\t\t\tvar topLeft = pt(0, (bnds.height - elevPix)*val);\n\t\t\tvar sliderExt = pt(bnds.width, elevPix); \n\t\t} else { // more horizontal...\n\t\t\tvar elevPix = Math.max(ext*bnds.width, this.mss); // thickness of elevator in pixels\n\t\t\tvar topLeft = pt((bnds.width - elevPix)*val, 0);\n\t\t\tvar sliderExt = pt(elevPix, bnds.height); \n\t\t}\n\t\tthis.slider.setBounds(bnds.topLeft().addPt(topLeft).extent(sliderExt));\n\n\t\t//this.slider.shapeRoundEdgesBy((this.vertical() ? sliderExt.x : sliderExt.y)/2);\n\t\tthis.slider.shapeRoundEdgesBy(Math.min(sliderExt.x, sliderExt.y)/2);\n\t},\n\n\tadjustFill: function() {\n\t\tvar fill = this.slider.getFill();\n\t\tvar gfx = lively.paint;\n\t\tif (fill instanceof lively.paint.LinearGradient) {\n\t\t\tvar direction = this.vertical() ? gfx.LinearGradient.EastWest : gfx.LinearGradient.NorthSouth;\n\t\t\tvar baseColor = fill.stops[0].color();\n\t\t\tthis.setFill(new gfx.LinearGradient([new gfx.Stop(0, baseColor, 1), \n\t\t\t\t\t\t\t new gfx.Stop(0.5, baseColor.lighter(2)),\n\t\t\t\t\t\t\t new gfx.Stop(1, baseColor)], direction));\n\t\t\t// FIXME: just flip the gradient\n\t\t\tthis.slider.setFill(\n\t\t\t\tnew gfx.LinearGradient([ new gfx.Stop(0, baseColor),\n\t\t\t\tnew gfx.Stop(1, fill.stops[1].color())], direction));\n\t\t\tthis.setBorderWidth(this.slider.getBorderWidth());\n\t\t} else if (fill) {\n\t\t\tthis.setFill(fill.lighter());\n\t\t}\t\t\n\t},\n\t\n\tsliderPressed: function(evt, slider) {\n\t\t//\t Note: want setMouseFocus to also cache the transform and record the hitPoint.\n\t\t//\t Ideally thereafter only have to say, eg, morph.setPosition(evt.hand.adjustedMousePoint)\n\t\tthis.hitPoint = this.localize(evt.mousePoint).subPt(this.slider.bounds().topLeft());\n\t},\n\t\n\tsliderMoved: function(evt, slider) {\n\t\tif (!evt.mouseButtonPressed) return;\n\n\t\t// Compute the value from a new mouse point, and emit it\n\t\tvar p = this.localize(evt.mousePoint).subPt(this.hitPoint);\n\t\tvar bnds = this.shape.bounds();\n\t\tvar ext = this.getSliderExtent(); \n\t\n\t\tif (this.vertical()) { // more vertical...\n\t\t\tvar elevPix = Math.max(ext*bnds.height,this.mss); // thickness of elevator in pixels\n\t\t\tvar newValue = p.y / (bnds.height-elevPix); \n\t\t} else { // more horizontal...\n\t\t\tvar elevPix = Math.max(ext*bnds.width,this.mss); // thickness of elevator in pixels\n\t\t\tvar newValue = p.x / (bnds.width-elevPix); \n\t\t}\n\t\t\n\t\tif (isNaN(newValue)) newValue = 0;\n\t\tthis.setScaledValue(this.clipValue(newValue));\n\t\tthis.adjustForNewBounds(); \n\t},\n\n\tsliderReleased: Functions.Empty,\n\t\n\thandlesMouseDown: function(evt) { return !evt.isCommandKey(); },\n\n\tonMouseDown: function(evt) {\n\t\tthis.requestKeyboardFocus(evt.hand);\n\t\tvar inc = this.getSliderExtent();\n\t\tvar newValue = this.getValue();\n\n\t\tvar delta = this.localize(evt.mousePoint).subPt(this.slider.bounds().center());\n\t\tif (this.vertical() ? delta.y > 0 : delta.x > 0) newValue += inc;\n\t\telse newValue -= inc;\n\t\n\t\tif (isNaN(newValue)) newValue = 0;\n\t\tthis.setScaledValue(this.clipValue(newValue));\n\t\tthis.adjustForNewBounds(); \n\t},\n\t\n\tonMouseMove: function($super, evt) {\n\t\t// Overriden so won't drag me if mouse pressed\n\t\tif (evt.mouseButtonPressed) return;\n\t\treturn $super(evt);\n\t},\n\t\n\tclipValue: function(val) { \n\t\treturn Math.min(1.0,Math.max(0,0,val.roundTo(0.0001))); \n\t},\n\n\tupdateView: function(aspect, controller) { // obsolete soon ?\n\t\tvar p = this.modelPlug;\n\t\tif (!p) return;\n\t\tif (aspect == p.getValue || aspect == 'all') {\n\t\t\tthis.onValueUpdate(this.getValue());\n\t\t} else if (aspect == p.getSliderExtent || aspect == 'all')\t{\n\t\t\tthis.onSliderExtentUpdate(this.getSliderExtent()); \n\t\t}\n\t},\n\n\tonSliderExtentUpdate: function(extent) {\n\t\tthis.adjustForNewBounds();\n\t},\n\n\tonValueUpdate: function(value) {\n\t\tthis.adjustForNewBounds();\n\t\tthis.value = value // for connect\n\t},\n\n\tgetScaledValue: function() {\n\t\treturn (this.getValue() || 0) / this.valueScale; // FIXME remove 0\n\t},\n\n\tsetScaledValue: function(value) {\n\t\treturn this.setValue(value * this.valueScale);\n\t},\n\t\n\ttakesKeyboardFocus: Functions.True,\n\t\n\tsetHasKeyboardFocus: function(newSetting) { \n\t\treturn newSetting; // no need to remember\n\t},\n\n\tonKeyPress: Functions.Empty,\n\n\tonKeyDown: function(evt) {\n\t\tvar delta = 0;\n\t\tif (this.vertical()) {\n\t\t\tswitch (evt.getKeyCode()) {\n\t\t\tcase Event.KEY_DOWN: delta = 1; break;\n\t\t\tcase Event.KEY_UP:\tdelta = -1; break;\n\t\t\tdefault: return false;\n\t\t\t} \n\t\t} else {\n\t\t\tswitch (evt.getKeyCode()) {\n\t\t\tcase Event.KEY_RIGHT: delta = 1; break;\t\n\t\t\tcase Event.KEY_LEFT: delta = -1; break;\n\t\t\tdefault: return false;\n\t\t\t}\t \n\t\t}\n\t\tthis.setScaledValue(this.clipValue(this.getScaledValue() + delta * (this.getSliderExtent())));\n\t\tthis.adjustForNewBounds();\n\t\tevt.stop();\n\t\treturn true;\n\t}\n\n});\n\n\n\n}) // end of module"]]>221truetrue2000000
bnds.width; \n\t},\n\t\n\tapplyStyle: function($super, spec) {\n\t\t$super(spec);\n\t\t// need to call adjust to update graphics, but only after slider exists\n\t\tif (this.slider) {\n\t\t\tthis.adjustForNewBounds(); \n\t\t\tthis.adjustFill();\n\t\t}\n\t},\n\t\n\tadjustForNewBounds: function($super) {\n\t\t$super();\n\t\tthis.adjustSliderParts();\n\t},\n\t\n\tadjustSliderParts: function($super) {\n\t\t// This method adjusts the slider for changes in value as well as geometry\n\t\tvar val = this.getScaledValue();\n\t\tvar bnds = this.shape.bounds();\n\t\tvar ext = this.getSliderExtent(); \n\n\t\n\t\tif (this.vertical()) { // more vertical...\n\t\t\tvar elevPix = Math.max(ext*bnds.height, this.mss); // thickness of elevator in pixels\n\t\t\tvar topLeft = pt(0, (bnds.height - elevPix)*val);\n\t\t\tvar sliderExt = pt(bnds.width, elevPix); \n\t\t} else { // more horizontal...\n\t\t\tvar elevPix = Math.max(ext*bnds.width, this.mss); // thickness of elevator in pixels\n\t\t\tvar topLeft = pt((bnds.width - elevPix)*val, 0);\n\t\t\tvar sliderExt = pt(elevPix, bnds.height); \n\t\t}\n\t\tthis.slider.setBounds(bnds.topLeft().addPt(topLeft).extent(sliderExt));\n\n\t\t//this.slider.shapeRoundEdgesBy((this.vertical() ? sliderExt.x : sliderExt.y)/2);\n\t\tthis.slider.shapeRoundEdgesBy(Math.min(sliderExt.x, sliderExt.y)/2);\n\t},\n\n\tadjustFill: function() {\n\t\tvar fill = this.slider.getFill();\n\t\tvar gfx = lively.paint;\n\t\tif (fill instanceof lively.paint.LinearGradient) {\n\t\t\tvar direction = this.vertical() ? gfx.LinearGradient.EastWest : gfx.LinearGradient.NorthSouth;\n\t\t\tvar baseColor = fill.stops[0].color();\n\t\t\tthis.setFill(new gfx.LinearGradient([new gfx.Stop(0, baseColor, 1), \n\t\t\t\t\t\t\t new gfx.Stop(0.5, baseColor.lighter(2)),\n\t\t\t\t\t\t\t new gfx.Stop(1, baseColor)], direction));\n\t\t\t// FIXME: just flip the gradient\n\t\t\tthis.slider.setFill(\n\t\t\t\tnew gfx.LinearGradient([ new gfx.Stop(0, baseColor),\n\t\t\t\tnew gfx.Stop(1, fill.stops[1].color())], direction));\n\t\t\tthis.setBorderWidth(this.slider.getBorderWidth());\n\t\t} else if (fill) {\n\t\t\tthis.setFill(fill.lighter());\n\t\t}\t\t\n\t},\n\t\n\tsliderPressed: function(evt, slider) {\n\t\t//\t Note: want setMouseFocus to also cache the transform and record the hitPoint.\n\t\t//\t Ideally thereafter only have to say, eg, morph.setPosition(evt.hand.adjustedMousePoint)\n\t\tthis.hitPoint = this.localize(evt.mousePoint).subPt(this.slider.bounds().topLeft());\n\t},\n\t\n\tsliderMoved: function(evt, slider) {\n\t\tif (!evt.mouseButtonPressed) return;\n\n\t\t// Compute the value from a new mouse point, and emit it\n\t\tvar p = this.localize(evt.mousePoint).subPt(this.hitPoint);\n\t\tvar bnds = this.shape.bounds();\n\t\tvar ext = this.getSliderExtent(); \n\t\n\t\tif (this.vertical()) { // more vertical...\n\t\t\tvar elevPix = Math.max(ext*bnds.height,this.mss); // thickness of elevator in pixels\n\t\t\tvar newValue = p.y / (bnds.height-elevPix); \n\t\t} else { // more horizontal...\n\t\t\tvar elevPix = Math.max(ext*bnds.width,this.mss); // thickness of elevator in pixels\n\t\t\tvar newValue = p.x / (bnds.width-elevPix); \n\t\t}\n\t\t\n\t\tif (isNaN(newValue)) newValue = 0;\n\t\tthis.setScaledValue(this.clipValue(newValue));\n\t\tthis.adjustForNewBounds(); \n\t},\n\n\tsliderReleased: Functions.Empty,\n\t\n\thandlesMouseDown: function(evt) { return !evt.isCommandKey(); },\n\n\tonMouseDown: function(evt) {\n\t\tthis.requestKeyboardFocus(evt.hand);\n\t\tvar inc = this.getSliderExtent();\n\t\tvar newValue = this.getValue();\n\n\t\tvar delta = this.localize(evt.mousePoint).subPt(this.slider.bounds().center());\n\t\tif (this.vertical() ? delta.y > 0 : delta.x > 0) newValue += inc;\n\t\telse newValue -= inc;\n\t\n\t\tif (isNaN(newValue)) newValue = 0;\n\t\tthis.setScaledValue(this.clipValue(newValue));\n\t\tthis.adjustForNewBounds(); \n\t},\n\t\n\tonMouseMove: function($super, evt) {\n\t\t// Overriden so won't drag me if mouse pressed\n\t\tif (evt.mouseButtonPressed) return;\n\t\treturn $super(evt);\n\t},\n\t\n\tclipValue: function(val) { \n\t\treturn Math.min(1.0,Math.max(0,0,val.roundTo(0.0001))); \n\t},\n\n\tupdateView: function(aspect, controller) { // obsolete soon ?\n\t\tvar p = this.modelPlug;\n\t\tif (!p) return;\n\t\tif (aspect == p.getValue || aspect == 'all') {\n\t\t\tthis.onValueUpdate(this.getValue());\n\t\t} else if (aspect == p.getSliderExtent || aspect == 'all')\t{\n\t\t\tthis.onSliderExtentUpdate(this.getSliderExtent()); \n\t\t}\n\t},\n\n\tonSliderExtentUpdate: function(extent) {\n\t\tthis.adjustForNewBounds();\n\t},\n\n\tonValueUpdate: function(value) {\n\t\tthis.adjustForNewBounds();\n\t\tthis.value = value // for connect\n\t},\n\n\tgetScaledValue: function() {\n\t\treturn (this.getValue() || 0) / this.valueScale; // FIXME remove 0\n\t},\n\n\tsetScaledValue: function(value) {\n\t\treturn this.setValue(value * this.valueScale);\n\t},\n\t\n\ttakesKeyboardFocus: Functions.True,\n\t\n\tsetHasKeyboardFocus: function(newSetting) { \n\t\treturn newSetting; // no need to remember\n\t},\n\n\tonKeyPress: Functions.Empty,\n\n\tonKeyDown: function(evt) {\n\t\tvar delta = 0;\n\t\tif (this.vertical()) {\n\t\t\tswitch (evt.getKeyCode()) {\n\t\t\tcase Event.KEY_DOWN: delta = 1; break;\n\t\t\tcase Event.KEY_UP:\tdelta = -1; break;\n\t\t\tdefault: return false;\n\t\t\t} \n\t\t} else {\n\t\t\tswitch (evt.getKeyCode()) {\n\t\t\tcase Event.KEY_RIGHT: delta = 1; break;\t\n\t\t\tcase Event.KEY_LEFT: delta = -1; break;\n\t\t\tdefault: return false;\n\t\t\t}\t \n\t\t}\n\t\tthis.setScaledValue(this.clipValue(this.getScaledValue() + delta * (this.getSliderExtent())));\n\t\tthis.adjustForNewBounds();\n\t\tevt.stop();\n\t\treturn true;\n\t}\n\n});\n\n\n\n}) // end of module"]]>truetrue
1truetruetrue
Addmodulefalsenullfalsetrue
Loadallfalsenullfalsetrue
LineNofalsenullfalsetrue
Refreshfalsenullfalsetrue
Evalonfalsenullfalsetrue
Sortfalsenullfalsetrue
Viewas...falsenullfalse
classesfalsenullfalsetruetruetrue
functionsfalsenullfalsetruetruetrue
objectsfalsenullfalsetruetruetrue
truetrue
nullfalsenullnullnullnullfalsenull62