From 0f5544dcc5de6bd44a755153fff6f542c3a8bcf9 Mon Sep 17 00:00:00 2001 From: fjenett Date: Mon, 13 Jun 2011 17:23:36 +0000 Subject: [PATCH] HTML5 input element examples for js mode --- .../Environment/Input/lockedIn/lockedIn.pde | 32 ++- .../HTML5/Input/colorRange/colorRange.pde | 40 ++++ .../HTML5/Input/colorRange/inteface.js | 19 ++ .../HTML5/Input/variableInputs/interface.js | 208 ++++++++++++++++++ .../Input/variableInputs/variableInputs.pde | 199 +++++++++++++++++ 5 files changed, 493 insertions(+), 5 deletions(-) create mode 100644 javascript/examples/HTML5/Input/colorRange/colorRange.pde create mode 100644 javascript/examples/HTML5/Input/colorRange/inteface.js create mode 100644 javascript/examples/HTML5/Input/variableInputs/interface.js create mode 100644 javascript/examples/HTML5/Input/variableInputs/variableInputs.pde diff --git a/javascript/examples/Environment/Input/lockedIn/lockedIn.pde b/javascript/examples/Environment/Input/lockedIn/lockedIn.pde index 17c328df2..52e33c6d5 100644 --- a/javascript/examples/Environment/Input/lockedIn/lockedIn.pde +++ b/javascript/examples/Environment/Input/lockedIn/lockedIn.pde @@ -1,5 +1,5 @@ /** - * Promt for user input + * This example demonstrates how to promt for user input */ String password = null; @@ -12,6 +12,9 @@ void setup () textFont(createFont("Arial", 22)); textAlign(CENTER); + + rectMode(CENTER); + noStroke(); } void draw () @@ -27,15 +30,29 @@ void draw () { background( 100 ); + fill(255,0,0); + pushMatrix(); + translate(width/2,height/3); + rotate(HALF_PI/2); rect(0,0,40,10); + rotate(HALF_PI); rect(0,0,40,10); + popMatrix(); + fill( 255 ); - text( "LOCKED, click to unlock", width/2, height/2); + text( "LOCKED, click to unlock", width/2, 2*(height/3)); } else { background( 255 ); + fill(0,255,0); + pushMatrix(); + translate(width/2,height/3+10); + rotate(-HALF_PI/2); rect(15,0,40,10); + rotate(-HALF_PI); rect(5,0,20,10); + popMatrix(); + fill( 0 ); - text( "UNLOCKED\nwill lock in "+int(ceil((nextLock-millis())/1000))+" secs", width/2, height/2); + text( "UNLOCKED\nwill lock in "+int(ceil((nextLock-millis())/1000))+" secs", width/2, 2*(height/3)); if ( nextLock-millis() < 0 ) locked = true; } @@ -59,18 +76,23 @@ void mousePressed () else if ( locked ) { String passTry = js.promtForInput( "Enter your password", "" ); - while ( passTry != null && !passTry.equals(password) ) + while ( testLocked(passTry) ) { passTry = js.promtForInput( "Nope, try again", "" ); if ( passTry == null ) break; } - locked = passTry != null && !passTry.equals(password); + locked = testLocked(passTry); if ( !locked ) nextLock = millis() + 5000; } } } +boolean testLocked ( String passTry ) +{ + return passTry == null || !passTry.equals(password); +} + // this is needed to define a way for us to be able to call out diff --git a/javascript/examples/HTML5/Input/colorRange/colorRange.pde b/javascript/examples/HTML5/Input/colorRange/colorRange.pde new file mode 100644 index 000000000..bdd30aaf7 --- /dev/null +++ b/javascript/examples/HTML5/Input/colorRange/colorRange.pde @@ -0,0 +1,40 @@ +/** + * This examples shows you how to interact with the HTML5 range input.
+ * + *
+ * + * + *

+ * (Slider by Firefox currently not supported.)
+ */ + + float rangeValue = 0; + float gColorValue = 0; + + void setup () + { + size(300,200); + colorMode(HSB); + } + + void draw () + { + background(gColorValue, 200, 120); + + float c = int(map( rangeValue, 0, 100, 0, 255 )); + + fill( c, 200, 150 ); + stroke( c, 180, 100 ); + + float x = map( rangeValue, 1, 100, 0, width ); + + ellipse( x, height/2, 50, 50 ); + + gColorValue += (c-gColorValue)/30.0; + } + + /* this is being called from JavaScript when the range slider is changed */ + void newRangeValue ( float v ) + { + rangeValue = v; + } diff --git a/javascript/examples/HTML5/Input/colorRange/inteface.js b/javascript/examples/HTML5/Input/colorRange/inteface.js new file mode 100644 index 000000000..3185b1911 --- /dev/null +++ b/javascript/examples/HTML5/Input/colorRange/inteface.js @@ -0,0 +1,19 @@ + +// wait for page contents to load: +// add page load listener +window.onload = function () { + tryFindSketch(); +} + +function tryFindSketch () { + var sketch = Processing.instances[0]; + if ( sketch == undefined ) + return setTimeout(tryFindSketch, 200); // try again .. + + // get slider from DOM + var range = document.getElementById("form-range"); + // add listener + range.onchange = function () { + sketch.newRangeValue( range.value ); + } +} diff --git a/javascript/examples/HTML5/Input/variableInputs/interface.js b/javascript/examples/HTML5/Input/variableInputs/interface.js new file mode 100644 index 000000000..d1522f3e4 --- /dev/null +++ b/javascript/examples/HTML5/Input/variableInputs/interface.js @@ -0,0 +1,208 @@ +window.onload = function () { + tryFindSketch(); +} + +function tryFindSketch () { + var sketch = Processing.instances[0]; + if ( sketch == undefined ) return setTimeout(tryFindSketch, 200); + + var controller = new Controller(sketch,"form-form"); + sketch.setController(controller); +} + +/** + * Maybe someone wants to take over and make this into a + * full-fledged interface library? + */ +var Controller = (function(){ + + function Controller () { + var sketch = arguments[0]; + var form = document.getElementById(arguments[1]); + form.onsubmit = function () {return false}; + var inputs = {}; + + this.createInputElement = function ( id, type, labelStr ) { + var input = document.createElement('input'); + input.id = id; + input.name = id; + input.type = type; + if ( labelStr !== undefined && labelStr !== '' ) + { + var label = document.createElement('label'); + label['for'] = id; + label.id = id+'-label'; + label.innerHTML = labelStr; + form.appendChild(label); + } + form.appendChild(input); + return input; + } + + this.addInputField = function ( l, t ) { + var id = createIdFromLabel(l); + if ( inputs[id] == undefined ) { + inputs[id] = this.createInputElement(id, t, l); + inputs[id].onchange = function(){ + changeFunc()(sketch, id, this.value); + return false; + } + } + return inputs[id]; + } + + this.addRange = function ( l, c, mi, mx ) { + var input = this.addInputField( l, "range" ); + input.value = c; + input.min = mi; + input.max = mx; + return input; + } + + this.addPassword = function ( l ) { + var input = this.addInputField ( l, "password" ); + return input; + } + + this.addEmail = function ( l ) { + var input = this.addInputField ( l, "email" ); + return input; + } + + this.addSearch = function ( l, c ) { + var input = this.addInputField ( l, "search" ); + input.value = c; + return input; + } + + this.addNumber = function ( l, c ) { + var input = this.addInputField ( l, "number" ); + input.value = c; + return input; + } + + this.addTelephone = function ( l, c ) { + var input = this.addInputField ( l, "tel" ); + input.value = c; + return input; + } + + this.addUrl = function ( l, c ) { + var input = this.addInputField ( l, "url" ); + input.value = c; + return input; + } + + this.addDate = function ( l, c ) { + var input = this.addInputField ( l, "date" ); + input.value = c; + return input; + } + + this.addCheckbox = function ( l, c ) { + var id = createIdFromLabel(l); + if ( inputs[id] == undefined ) { + inputs[id] = this.createInputElement(id, "checkbox", l); + inputs[id].onchange = function(){ + changeFunc()(sketch, id, this.checked); + return false; + } + } + inputs[id].checked = c ? 'checked' : ''; + return inputs[id]; + } + + this.addTextfield = function ( l, c ) { + var id = createIdFromLabel(l); + if ( inputs[id] == undefined ) { + inputs[id] = this.createInputElement(id, "text", l); + inputs[id].onchange = function(){ + changeFunc()(sketch, id, this.value); + return false; + } + } + inputs[id].value = c; + return inputs[id]; + } + + this.addTextarea = function ( l, c ) { + var id = createIdFromLabel(l); + if ( inputs[id] == undefined ) { + var label = document.createElement('label'); + label['for'] = id; + label.id = id+'-label'; + label.innerHTML = l; + form.appendChild(label); + inputs[id] = document.createElement('textarea'); + inputs[id].id = id; + inputs[id].name = id; + inputs[id].innerHTML = c; + inputs[id].onchange = function(){ + changeFunc()(sketch, id, this.value); + return false; + } + form.appendChild(inputs[id]); + } + inputs[id].value = c; + return inputs[id]; + } + + this.addSelection = function ( l, o ) { + var id = createIdFromLabel(l); + if ( inputs[id] == undefined ) { + var label = document.createElement('label'); + label['for'] = id; + label.id = id+'-label'; + label.innerHTML = l; + form.appendChild(label); + var select = document.createElement('select'); + select.id = id; + select.name = id; + if ( o !== undefined && o.length && o.length > 0 ) { + for ( var i = 0; i < o.length; i++ ) { + var value = o[i].length > 1 ? o[i][1] : i; + var option = document.createElement('option'); + option.innerHTML = o[i][0]; + option.value = value; + select.appendChild(option); + } + } + select.onchange = function( event ){ + changeFunc()(sketch, id, this.value); + return false; + } + inputs[id] = select; + form.appendChild(inputs[id]); + } + return inputs[id]; + } + this.addMenu = this.addSelection; + + this.setElementLabel = function ( element, labelStr ) { + var label = document.getElementById(element.id+'-label'); + if ( label && label.childNodes && label.childNodes.length > 0 ) { + label.childNodes[0].textContent = labelStr; + } else { + //console.log([element, label]); + } + } + } + + var changeFunc = function () { + return function ( sketch, id, value ) { + try { + sketch[id](value); + } catch (e) { + //console.log(e); + sketch.println( "Function \"void "+id+"(value)\" is not defined in your sketch."); + } + } + } + + var createIdFromLabel = function ( l ) { + return l.replace(/^[^-_a-z]/i,'_').replace(/[^-_a-z0-9]/gi,''); + } + + return Controller; + +})(); diff --git a/javascript/examples/HTML5/Input/variableInputs/variableInputs.pde b/javascript/examples/HTML5/Input/variableInputs/variableInputs.pde new file mode 100644 index 000000000..e213170f1 --- /dev/null +++ b/javascript/examples/HTML5/Input/variableInputs/variableInputs.pde @@ -0,0 +1,199 @@ +/** + * This examples shows you how to interact with diverse HTML inputs. It follows + * roughly the way that ControlP5 + * works for standard Processing.
+ * + *
+ * + * + */ + + /** + * This example is rather complicated. You can think of it having two parts: + * 1) the interface "stuff": setting it up, handle events + * 2) the layout based upon the values received from inputs + */ + + String[] menuItems; + + // dafault input values + int currentShape = 2; + float currentX = 0; + boolean hasStroke = true; + float hueValue = 0; + String fieldString = "Fancy Corp. Co."; + String areaString = "We are the fresh new company with "+ + "activities ranging from A to Z and from "+ + "alpha to omega."; + + void setup () + { + size(300,200); + + colorMode(HSB); + + currentX = 50; + + menuItems = new String[] { + new String[] {"Rectangle"}, new String[] {"Ellipse"}, + new String[] {"Star"}, new String[] {"Spirograph"} + }; + + textFont(createFont("Arial", 16)); + } + + /* drawing the layout */ + + void draw () + { + background( 200 ); + + strokeWeight(4); + + if ( hasStroke ) stroke( hueValue, 150, 95 ); + else noStroke(); + + fill( hueValue, 200, 150 ); + + pushMatrix(); + switch ( currentShape ) { + case 0: + rectMode(CENTER); + rect(currentX, height/4, 50, 50); + break; + case 1: + ellipse(currentX, height/4, 55, 55); + break; + case 2: + star(currentX, height/4, 17, 30); + break; + case 3: + spiro(currentX, height/4, 20); + break; + } + popMatrix(); + + fill( 0 ); + textSize(16); + textAlign( CENTER ); + float tWidth = textWidth(fieldString); + float tX = currentX; + if ( currentX-tWidth/2 < 25 ) + { + textAlign( LEFT ); + tX = currentX-25; + } + else if ( currentX+tWidth/2 > width-25 ) + { + textAlign( RIGHT ); + tX = currentX+25; + } + text( fieldString, tX, height/4+50 ); + + textSize(11.5); + textAlign( currentX > width/2 ? RIGHT : LEFT ); + int l, w; + if ( currentX <= width/2 ) + { + l = currentX-50+25; + w = width-l-25; + } + else + { + l = 25; + w = currentX+50-25-25; + } + text( areaString, l, height/4+70, w, height/2 ); + } + + void star ( float x, float y, float inner, float outer ) + { + beginShape(); + for ( int i = 0; i < 360; i+=36 ) + { + float r = radians(i + sin(frameCount/90.0)*25); + vertex( x + cos(r)*outer, y + sin(r)*outer ); + r = radians(i+(36/2)); + vertex( x + cos(r)*inner, y + sin(r)*inner ); + } + endShape(CLOSE); + } + + void spiro ( float x, float y, float rad ) + { + beginShape(); + for ( int i = 0; i < 360; i+=2 ) + { + float r = radians(i); + float r2 = radians(i*(sin(frameCount/240.0)+2)*2); + vertex( x + (cos(r)+cos(r2)/2)*rad, y + (sin(r)+sin(r2)/2)*rad ); + } + endShape(); + } + + /* interface related things */ + + void setController ( Controller ctlr ) + { + // labels are supposed to be existing function names + + InterfaceElement element = ctlr.addRange( "rangeCallback", currentX, 0, 100 ); + ctlr.setElementLabel( element, "Example range input field" ); + + element = ctlr.addCheckbox( "textBoxCallback", hasStroke ); + ctlr.setElementLabel( element, "A checkbox here" ); + + element = ctlr.addTextfield( "textFieldChanged", fieldString ); + ctlr.setElementLabel( element, "... and this is a textfield" ); + + element = ctlr.addTextarea( "calledByTextarea", areaString ); + ctlr.setElementLabel( element, "Ta-dah: a textarea" ); + + element = ctlr.addMenu( "theMenu", menuItems ); + ctlr.setElementLabel( element, "LBNL a select menu" ); + } + + /* callbacks */ + + void rangeCallback ( float value ) + { + currentX = map( value, 0, 100, 50, width-50 ); + } + + void textBoxCallback ( boolean value ) + { + hasStroke = value; + } + + void textFieldChanged ( String value ) + { + fieldString = value; + } + + void calledByTextarea ( String value ) + { + areaString = value; + } + + void theMenu ( String value ) + { + currentShape = int(value); + } + + /* ... and the interfaces */ + + /* explain InputElement to Processing */ + interface InputElement + { + String type; + String id; + Object value; + } + + /* explain Controller to Processing */ + interface Controller + { + InputElement addRange ( String label, float initialValue, float minValue, float maxValue ); + void setLabel ( InputElement element, String label ); + }