From 0119797454535fb58cce7b71354d33abe0d7f78e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 18 Nov 2014 02:26:11 +0100 Subject: [PATCH 01/13] virtual keyboard rendered --- examples/virtualKeyboard.js | 235 ++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 examples/virtualKeyboard.js diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js new file mode 100644 index 0000000000..109196008d --- /dev/null +++ b/examples/virtualKeyboard.js @@ -0,0 +1,235 @@ +const KBD_UPPERCASE_DEFAULT = 0; +const KBD_LOWERCASE_DEFAULT = 1; +const KBD_UPPERCASE_HOVER = 2; +const KBD_LOWERCASE_HOVER = 3; +const KBD_BACKGROUND = 4; + +const KEYBOARD_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/keyboard.svg"; + +const KEYBOARD_HEIGHT = 434.1; +const KEYBOARD_WIDTH = 1174.7; + +const BOUND_X = 0; +const BOUND_Y = 1; +const BOUND_W = 2; +const BOUND_H = 3; + +const KEY_STATE_LOWER = 0; +const KEY_STATE_UPPER = 1; + +function KeyboardKey(keyboard, key_properties) { + this.event = key_properties.event != undefined ? + key_properties.event : 'keypress'; + this.bounds = key_properties.bounds; + this.states = key_properties.states; + this.keyboard = keyboard; + this.key_state = key_properties.key_state != undefined ? key_properties.key_state : KBD_LOWERCASE_HOVER; + // one overlay per bound vector [this.bounds] + this.overlays = []; + this.updatePosition = function() { + }; + this.containsCoord = function(x, y) { + for (var i = 0; i < this.bounds.length; i++) { + if (x >= this.bounds[i][BOUND_X] && + x <= (this.bounds[i][BOUND_X] + this.bounds[i][BOUND_W]) && + y >= this.bounds[i][BOUND_Y] && + y <= (this.bounds[i][BOUND_Y] + this.bounds[i][BOUND_H])) + { + return true; + } + } + return false; + }; + this.remove = function() { + for (var i = 0; i < this.overlays.length; i++) { + Overlays.deleteOverlay(this.overlays[i]); + } + }; + this.isLoaded = function() { + for (var i = 0; i < this.overlays.length; i++) { + if (!Overlays.isLoaded(this.overlays[i])) { + return false; + } + } + return true; + }; + for (var i = 0; i < this.bounds.length; i++) { + var newOverlay = Overlays.cloneOverlay(this.keyboard.background); + Overlays.editOverlay(newOverlay, { + x: 50 + this.bounds[i][BOUND_X], + y: 50 + this.bounds[i][BOUND_Y], + width: this.bounds[i][BOUND_W], + height: this.bounds[i][BOUND_H], + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.key_state) + this.bounds[i][BOUND_Y]}, + alpha: 1 + }); + this.overlays.push(newOverlay); + } +} + +function Keyboard() { + this.background = Overlays.addOverlay("image", { + x: 50, + y: 50, + width: KEYBOARD_WIDTH, + height: KEYBOARD_HEIGHT, + subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, + imageURL: KEYBOARD_URL, + alpha: 1 + }); + this.updatePosition = function() { + + }; + this.getFocussedKey = function() { + + }; + this.remove = function() { + Overlays.deleteOverlay(this.background); + for (var i = 0; i < this.keys.length; i++) { + this.keys[i].remove(); + } + }; + + this.onKeyPress = null; + this.onKeyDown = null; + this.onKeyUp = null; + this.onSubmit = null; + + this.keys = []; + // + // keyProperties contains the key data + // + // coords [[x,y,w,h],[x,y,w,h]] + // states array of 1 or 2 objects [lowercase, uppercase] each object contains a charCode and a char + var keyProperties = [ + {bounds: [[12, 12, 65, 52]], states: [{charCode: 192, char: '~'}]}, + {bounds: [[84, 12, 65, 52]], states: [{charCode: 192, char: '!'}]}, + {bounds: [[156, 12, 65, 52]], states: [{charCode: 192, char: '@'}]}, + {bounds: [[228, 12, 65, 52]], states: [{charCode: 192, char: '#'}]}, + {bounds: [[300, 12, 65, 52]], states: [{charCode: 192, char: '$'}]}, + {bounds: [[372, 12, 65, 52]], states: [{charCode: 192, char: '%'}]}, + {bounds: [[445, 12, 65, 52]], states: [{charCode: 192, char: '^'}]}, + {bounds: [[517, 12, 65, 52]], states: [{charCode: 192, char: '&'}]}, + {bounds: [[589, 12, 65, 52]], states: [{charCode: 192, char: '*'}]}, + {bounds: [[662, 12, 65, 52]], states: [{charCode: 192, char: '('}]}, + {bounds: [[734, 12, 65, 52]], states: [{charCode: 192, char: ')'}]}, + {bounds: [[806, 12, 65, 52]], states: [{charCode: 192, char: '_'}]}, + {bounds: [[881, 12, 65, 52]], states: [{charCode: 192, char: '{'}]}, + {bounds: [[953, 12, 65, 52]], states: [{charCode: 192, char: '}'}]}, + {bounds: [[1025, 12, 65, 52]], states: [{charCode: 192, char: '<'}]}, + {bounds: [[1097, 12, 65, 52]], states: [{charCode: 192, char: '>'}]}, + + {bounds: [[12, 71, 65, 63]], states: [{charCode: 192, char: '`'}]}, + {bounds: [[84, 71, 65, 63]], states: [{charCode: 192, char: '1'}]}, + {bounds: [[156, 71, 65, 63]], states: [{charCode: 192, char: '2'}]}, + {bounds: [[228, 71, 65, 63]], states: [{charCode: 192, char: '3'}]}, + {bounds: [[300, 71, 65, 63]], states: [{charCode: 192, char: '4'}]}, + {bounds: [[372, 71, 65, 63]], states: [{charCode: 192, char: '5'}]}, + {bounds: [[445, 71, 65, 63]], states: [{charCode: 192, char: '6'}]}, + {bounds: [[517, 71, 65, 63]], states: [{charCode: 192, char: '7'}], key_state: KBD_UPPERCASE_DEFAULT}, + {bounds: [[589, 71, 65, 63]], states: [{charCode: 192, char: '8'}]}, + {bounds: [[661, 71, 65, 63]], states: [{charCode: 192, char: '9'}]}, + {bounds: [[733, 71, 65, 63]], states: [{charCode: 192, char: '0'}]}, + {bounds: [[806, 71, 65, 63]], states: [{charCode: 192, char: '-'}]}, + {bounds: [[880, 71, 65, 63]], states: [{charCode: 192, char: '='}]}, + {bounds: [[953, 71, 65, 63]], states: [{charCode: 192, char: '+'}]}, + {bounds: [[1024, 71, 139, 63]], event: 'delete'}, + + // enter key has 2 bounds and one state + {bounds: [[11, 143, 98, 71], [11, 213, 121, 62]], event: 'enter'}, + + {bounds: [[118, 142, 64, 63]], states: [{charCode: 192, char: 'q'}, {charCode: 192, char: 'Q'}]}, + {bounds: [[190, 142, 64, 63]], states: [{charCode: 192, char: 'w'}, {charCode: 192, char: 'W'}]}, + {bounds: [[262, 142, 64, 63]], states: [{charCode: 192, char: 'e'}, {charCode: 192, char: 'E'}]}, + {bounds: [[334, 142, 64, 63]], states: [{charCode: 192, char: 'r'}, {charCode: 192, char: 'R'}]}, + {bounds: [[407, 142, 64, 63]], states: [{charCode: 192, char: 't'}, {charCode: 192, char: 'T'}]}, + {bounds: [[479, 142, 64, 63]], states: [{charCode: 192, char: 'y'}, {charCode: 192, char: 'Y'}]}, + {bounds: [[551, 142, 65, 63]], states: [{charCode: 192, char: 'u'}, {charCode: 192, char: 'U'}]}, + {bounds: [[623, 142, 65, 63]], states: [{charCode: 192, char: 'i'}, {charCode: 192, char: 'I'}]}, + {bounds: [[695, 142, 65, 63]], states: [{charCode: 192, char: 'o'}, {charCode: 192, char: 'O'}]}, + {bounds: [[768, 142, 64, 63]], states: [{charCode: 192, char: 'p'}, {charCode: 192, char: 'P'}]}, + {bounds: [[840, 142, 64, 63]], states: [{charCode: 192, char: '['}]}, + {bounds: [[912, 142, 65, 63]], states: [{charCode: 192, char: ']'}]}, + {bounds: [[984, 142, 65, 63]], states: [{charCode: 192, char: '\\'}]}, + {bounds: [[1055, 142, 65, 63]], states: [{charCode: 192, char: '|'}]}, + + {bounds: [[1126, 143, 35, 72], [1008, 214, 153, 62]], event: 'enter'}, + + {bounds: [[140, 213, 65, 63]], states: [{charCode: 192, char: 'a'}, {charCode: 192, char: 'A'}]}, + {bounds: [[211, 213, 64, 63]], states: [{charCode: 192, char: 's'}, {charCode: 192, char: 'S'}]}, + {bounds: [[283, 213, 65, 63]], states: [{charCode: 192, char: 'd'}, {charCode: 192, char: 'D'}]}, + {bounds: [[355, 213, 65, 63]], states: [{charCode: 192, char: 'f'}, {charCode: 192, char: 'F'}]}, + {bounds: [[428, 213, 64, 63]], states: [{charCode: 192, char: 'g'}, {charCode: 192, char: 'G'}]}, + {bounds: [[500, 213, 64, 63]], states: [{charCode: 192, char: 'h'}, {charCode: 192, char: 'H'}]}, + {bounds: [[572, 213, 65, 63]], states: [{charCode: 192, char: 'j'}, {charCode: 192, char: 'J'}]}, + {bounds: [[644, 213, 65, 63]], states: [{charCode: 192, char: 'k'}, {charCode: 192, char: 'K'}]}, + {bounds: [[716, 213, 65, 63]], states: [{charCode: 192, char: 'l'}, {charCode: 192, char: 'L'}]}, + {bounds: [[789, 213, 64, 63]], states: [{charCode: 192, char: ';'}]}, + {bounds: [[861, 213, 64, 63]], states: [{charCode: 192, char: '\''}]}, + {bounds: [[934, 213, 65, 63]], states: [{charCode: 192, char: ':'}]}, + + {bounds: [[12, 283, 157, 63]], event: 'shift'}, + + {bounds: [[176, 283, 65, 63]], states: [{charCode: 192, char: 'z'}, {charCode: 192, char: 'Z'}]}, + {bounds: [[249, 283, 64, 63]], states: [{charCode: 192, char: 'x'}, {charCode: 192, char: 'X'}]}, + {bounds: [[321, 283, 64, 63]], states: [{charCode: 192, char: 'c'}, {charCode: 192, char: 'C'}]}, + {bounds: [[393, 283, 64, 63]], states: [{charCode: 192, char: 'v'}, {charCode: 192, char: 'V'}]}, + {bounds: [[465, 283, 65, 63]], states: [{charCode: 192, char: 'b'}, {charCode: 192, char: 'B'}]}, + {bounds: [[537, 283, 65, 63]], states: [{charCode: 192, char: 'n'}, {charCode: 192, char: 'N'}]}, + {bounds: [[610, 283, 64, 63]], states: [{charCode: 192, char: 'm'}, {charCode: 192, char: 'M'}]}, + {bounds: [[682, 283, 64, 63]], states: [{charCode: 192, char: ','}]}, + {bounds: [[754, 283, 65, 63]], states: [{charCode: 192, char: '.'}]}, + {bounds: [[826, 283, 65, 63]], states: [{charCode: 192, char: '/'}]}, + {bounds: [[899, 283, 64, 63]], states: [{charCode: 192, char: '?'}], key_state: KBD_UPPERCASE_DEFAULT}, + + {bounds: [[972, 283, 190, 63]], event: 'shift'}, + + {bounds: [[249, 355, 573, 67]], states: [{charCode: 192, char: ' '}]}, + + {bounds: [[899, 355, 263, 67]], event: 'submit'} + + + + ]; + + this.keys_in_waitingline = []; + this.keys_being_downloaded = []; + + for (var i = 0; i < keyProperties.length; i++) { + //this.keys_in_waitingline.push(keyProperties[i]); + //this.keys.push(new KeyboardKey(this, keyProperties[i])); + } + var tthis = this; + this.keyboardtextureloaded = function() { + if (Overlays.isLoaded(tthis.background)) { + Script.clearInterval(tthis.keyboardtextureloaded_timer); + for (var i = 0; i < keyProperties.length; i++) { + tthis.keys.push(new KeyboardKey(tthis, keyProperties[i])); + } + } + }; + this.keyboardtextureloaded_timer = Script.setInterval(this.keyboardtextureloaded, 250); +} + +var keyboard = new Keyboard(); +keyboard.onKeyPress = function() { + print("Key press event test"); +}; + +function scriptEnding() { + keyboard.remove(); +} +function mousePressEvent(event) { + //var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + //if (clickedOverlay != 0) { + // Overlays.deleteOverlay(clickedOverlay); + //} +} + +function onUpdate() { + MyAvatar.getHeadFinalYaw(); + MyAvatar.getHeadFinalPitch(); +} + +Script.update.connect(onUpdate); +Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From d52f410c03d309542f2ffc33655e38676a360de0 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 18 Nov 2014 03:11:47 +0100 Subject: [PATCH 02/13] virtualKeyboard: added cursor which responds to HMD --- examples/virtualKeyboard.js | 67 ++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 109196008d..4e871a79ab 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -1,3 +1,16 @@ +// +// virtualKeyboard.js +// examples +// +// Created by Thijs Wenker on 11/18/14. +// Copyright 2014 High Fidelity, Inc. +// +// Control a virtual keyboard using your favorite HMD. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + const KBD_UPPERCASE_DEFAULT = 0; const KBD_LOWERCASE_DEFAULT = 1; const KBD_UPPERCASE_HOVER = 2; @@ -5,9 +18,15 @@ const KBD_LOWERCASE_HOVER = 3; const KBD_BACKGROUND = 4; const KEYBOARD_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/keyboard.svg"; +const CURSOR_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/cursor.svg"; -const KEYBOARD_HEIGHT = 434.1; const KEYBOARD_WIDTH = 1174.7; +const KEYBOARD_HEIGHT = 434.1; + +const CURSOR_WIDTH = 33.9; +const CURSOR_HEIGHT = 33.9; + +const VIEW_ANGLE = 60.0; const BOUND_X = 0; const BOUND_Y = 1; @@ -216,20 +235,42 @@ keyboard.onKeyPress = function() { print("Key press event test"); }; +function Cursor() { + var tthis = this; + var dimensions = Controller.getViewportDimensions(); + this.overlay = Overlays.addOverlay("image", { + x: dimensions.x / 2, + y: dimensions.y / 2, + width: CURSOR_WIDTH, + height: CURSOR_HEIGHT, + imageURL: CURSOR_URL, + alpha: 1 + }); + this.remove = function() { + Overlays.deleteOverlay(this.overlay); + }; + this.update = function() { + var screen_angle = 60; + var dimensions = Controller.getViewportDimensions(); + var editobject = {};//{x: dimensions.x / 2, y: dimensions.y / 2}; + if (MyAvatar.getHeadFinalYaw() <= (VIEW_ANGLE / 2) && MyAvatar.getHeadFinalYaw() >= -1 * (VIEW_ANGLE / 2)) { + angle = ((-1 * MyAvatar.getHeadFinalYaw()) + (VIEW_ANGLE / 2)) / VIEW_ANGLE; + editobject.x = angle * dimensions.x; + } + if (MyAvatar.getHeadFinalPitch() <= (VIEW_ANGLE / 2) && MyAvatar.getHeadFinalPitch() >= -1 * (VIEW_ANGLE / 2)) { + angle = ((-1 * MyAvatar.getHeadFinalPitch()) + (VIEW_ANGLE / 2)) / VIEW_ANGLE; + // print(angle * dimensions.y); + editobject.y = angle * dimensions.y; + } + Overlays.editOverlay(tthis.overlay, editobject); + }; + Script.update.connect(this.update); +} +var cursor = new Cursor(); function scriptEnding() { keyboard.remove(); -} -function mousePressEvent(event) { - //var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - //if (clickedOverlay != 0) { - // Overlays.deleteOverlay(clickedOverlay); - //} + cursor.remove(); + Overlays.deleteOverlay(cursor); } -function onUpdate() { - MyAvatar.getHeadFinalYaw(); - MyAvatar.getHeadFinalPitch(); -} - -Script.update.connect(onUpdate); Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From 7dc35bb3490cbf3e2465d188bc9cbbd41fae796b Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 19 Nov 2014 03:12:22 +0100 Subject: [PATCH 03/13] virtual-keyboard: - positioned in bottom - keyboard hover-able --- examples/virtualKeyboard.js | 185 ++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 38 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 4e871a79ab..41ddfa75ae 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -27,6 +27,7 @@ const CURSOR_WIDTH = 33.9; const CURSOR_HEIGHT = 33.9; const VIEW_ANGLE = 60.0; +const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; const BOUND_X = 0; const BOUND_Y = 1; @@ -36,13 +37,31 @@ const BOUND_H = 3; const KEY_STATE_LOWER = 0; const KEY_STATE_UPPER = 1; +var cursor = null; +var keyboard = new Keyboard(); + +keyboard.onKeyPress = function() { + print("Key press event test"); +}; + +keyboard.onFullyLoaded = function() { + print("Virtual-keyboard fully loaded."); + // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard + cursor = new Cursor(); + cursor.onUpdate = function(position) { + keyboard.setFocusPosition(position.x, position.y); + }; +}; + function KeyboardKey(keyboard, key_properties) { + var tthis = this; + this._focus = false; this.event = key_properties.event != undefined ? key_properties.event : 'keypress'; this.bounds = key_properties.bounds; this.states = key_properties.states; this.keyboard = keyboard; - this.key_state = key_properties.key_state != undefined ? key_properties.key_state : KBD_LOWERCASE_HOVER; + this.key_state = key_properties.key_state != undefined ? key_properties.key_state : KBD_LOWERCASE_DEFAULT; // one overlay per bound vector [this.bounds] this.overlays = []; this.updatePosition = function() { @@ -59,6 +78,33 @@ function KeyboardKey(keyboard, key_properties) { } return false; }; + this.updateState = function() { + tthis.setState(eval('KBD_' + (tthis.keyboard.shift ? 'UPPERCASE' : 'LOWERCASE') + '_' + (tthis._focus ? 'HOVER' : 'DEFAULT'))); + }; + this.blur = function() { + tthis._focus = false; + tthis.updateState(); + }; + this.focus = function() { + tthis._focus = true; + tthis.updateState(); + }; + this.setState = function(state) { + tthis.key_state = state; + for (var i = 0; i < tthis.bounds.length; i++) { + Overlays.editOverlay(tthis.overlays[i], { + subImage: {width: tthis.bounds[i][BOUND_W], height: tthis.bounds[i][BOUND_H], x: tthis.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * tthis.key_state) + tthis.bounds[i][BOUND_Y]} + }); + } + }; + this.updatePosition = function() { + for (var i = 0; i < tthis.bounds.length; i++) { + Overlays.editOverlay(tthis.overlays[i], { + x: tthis.keyboard.x + tthis.bounds[i][BOUND_X], + y: tthis.keyboard.y + tthis.bounds[i][BOUND_Y], + }); + } + }; this.remove = function() { for (var i = 0; i < this.overlays.length; i++) { Overlays.deleteOverlay(this.overlays[i]); @@ -67,7 +113,7 @@ function KeyboardKey(keyboard, key_properties) { this.isLoaded = function() { for (var i = 0; i < this.overlays.length; i++) { if (!Overlays.isLoaded(this.overlays[i])) { - return false; + return false; } } return true; @@ -75,8 +121,8 @@ function KeyboardKey(keyboard, key_properties) { for (var i = 0; i < this.bounds.length; i++) { var newOverlay = Overlays.cloneOverlay(this.keyboard.background); Overlays.editOverlay(newOverlay, { - x: 50 + this.bounds[i][BOUND_X], - y: 50 + this.bounds[i][BOUND_Y], + x: this.keyboard.x + this.bounds[i][BOUND_X], + y: this.keyboard.y + this.bounds[i][BOUND_Y], width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.key_state) + this.bounds[i][BOUND_Y]}, @@ -87,21 +133,66 @@ function KeyboardKey(keyboard, key_properties) { } function Keyboard() { + var tthis = this; + var dimensions = Controller.getViewportDimensions(); + this.focussed_key = -1; + this.shift = false; + this.x = (dimensions.x / 2) - (KEYBOARD_WIDTH / 2); + this.y = dimensions.y - KEYBOARD_HEIGHT; this.background = Overlays.addOverlay("image", { - x: 50, - y: 50, + x: this.x, + y: this.y, width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, imageURL: KEYBOARD_URL, alpha: 1 }); + + this.setFocusPosition = function(x, y) { + var localx = x - tthis.x; + var localy = y - tthis.y; + var new_focus_key = -1; + if (localx >= 0 && localy >= 0 && localx <= KEYBOARD_WIDTH && localy <= KEYBOARD_HEIGHT) { + for (var i = 0; i < tthis.keys.length; i++) { + if (tthis.keys[i].containsCoord(localx, localy)) { + //print(tthis.keys[i].states[0].char); + new_focus_key = i; + break; + } + } + } + if (new_focus_key != tthis.focussed_key) { + print(new_focus_key); + if (tthis.focussed_key != -1) { + tthis.keys[tthis.focussed_key].blur(); + } + tthis.focussed_key = new_focus_key; + if (tthis.focussed_key != -1) { + tthis.keys[tthis.focussed_key].focus(); + } + } + return tthis; + }; + + this.pressFocussedKey = function() { + if (tthis.focussed_key != -1) { + this.onKeyPress(tthis.keys[tthis.focussed_key]); + } + return tthis; + }; + this.updatePosition = function() { }; + this.getFocussedKey = function() { - + if (tthis.focussed_key == -1) { + return null; + } + return tthis.keys[tthis.focussed_key]; }; + this.remove = function() { Overlays.deleteOverlay(this.background); for (var i = 0; i < this.keys.length; i++) { @@ -113,6 +204,7 @@ function Keyboard() { this.onKeyDown = null; this.onKeyUp = null; this.onSubmit = null; + this.onFullyLoaded = null; this.keys = []; // @@ -145,7 +237,7 @@ function Keyboard() { {bounds: [[300, 71, 65, 63]], states: [{charCode: 192, char: '4'}]}, {bounds: [[372, 71, 65, 63]], states: [{charCode: 192, char: '5'}]}, {bounds: [[445, 71, 65, 63]], states: [{charCode: 192, char: '6'}]}, - {bounds: [[517, 71, 65, 63]], states: [{charCode: 192, char: '7'}], key_state: KBD_UPPERCASE_DEFAULT}, + {bounds: [[517, 71, 65, 63]], states: [{charCode: 192, char: '7'}]}, {bounds: [[589, 71, 65, 63]], states: [{charCode: 192, char: '8'}]}, {bounds: [[661, 71, 65, 63]], states: [{charCode: 192, char: '9'}]}, {bounds: [[733, 71, 65, 63]], states: [{charCode: 192, char: '0'}]}, @@ -199,48 +291,37 @@ function Keyboard() { {bounds: [[682, 283, 64, 63]], states: [{charCode: 192, char: ','}]}, {bounds: [[754, 283, 65, 63]], states: [{charCode: 192, char: '.'}]}, {bounds: [[826, 283, 65, 63]], states: [{charCode: 192, char: '/'}]}, - {bounds: [[899, 283, 64, 63]], states: [{charCode: 192, char: '?'}], key_state: KBD_UPPERCASE_DEFAULT}, + {bounds: [[899, 283, 64, 63]], states: [{charCode: 192, char: '?'}]}, {bounds: [[972, 283, 190, 63]], event: 'shift'}, {bounds: [[249, 355, 573, 67]], states: [{charCode: 192, char: ' '}]}, {bounds: [[899, 355, 263, 67]], event: 'submit'} - - - ]; - this.keys_in_waitingline = []; - this.keys_being_downloaded = []; - - for (var i = 0; i < keyProperties.length; i++) { - //this.keys_in_waitingline.push(keyProperties[i]); - //this.keys.push(new KeyboardKey(this, keyProperties[i])); - } - var tthis = this; this.keyboardtextureloaded = function() { if (Overlays.isLoaded(tthis.background)) { Script.clearInterval(tthis.keyboardtextureloaded_timer); for (var i = 0; i < keyProperties.length; i++) { tthis.keys.push(new KeyboardKey(tthis, keyProperties[i])); } + if (keyboard.onFullyLoaded != null) { + tthis.onFullyLoaded(); + } } }; this.keyboardtextureloaded_timer = Script.setInterval(this.keyboardtextureloaded, 250); } -var keyboard = new Keyboard(); -keyboard.onKeyPress = function() { - print("Key press event test"); -}; - function Cursor() { var tthis = this; var dimensions = Controller.getViewportDimensions(); + this.x = dimensions.x / 2; + this.y = dimensions.y / 2; this.overlay = Overlays.addOverlay("image", { - x: dimensions.x / 2, - y: dimensions.y / 2, + x: this.x, + y: this.y, width: CURSOR_WIDTH, height: CURSOR_HEIGHT, imageURL: CURSOR_URL, @@ -249,28 +330,56 @@ function Cursor() { this.remove = function() { Overlays.deleteOverlay(this.overlay); }; + this.getPosition = function() { + return {x: tthis.getX(), y: tthis.getY()}; + }; + this.getX = function() { + return tthis.x; + }; + this.getY = function() { + return tthis.y; + }; + this.onUpdate = null; this.update = function() { - var screen_angle = 60; var dimensions = Controller.getViewportDimensions(); - var editobject = {};//{x: dimensions.x / 2, y: dimensions.y / 2}; - if (MyAvatar.getHeadFinalYaw() <= (VIEW_ANGLE / 2) && MyAvatar.getHeadFinalYaw() >= -1 * (VIEW_ANGLE / 2)) { - angle = ((-1 * MyAvatar.getHeadFinalYaw()) + (VIEW_ANGLE / 2)) / VIEW_ANGLE; - editobject.x = angle * dimensions.x; + var editobject = {}; + if (MyAvatar.getHeadFinalYaw() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalYaw() >= -1 * VIEW_ANGLE_BY_TWO) { + angle = ((-1 * MyAvatar.getHeadFinalYaw()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; + tthis.x = angle * dimensions.x; + editobject.x = tthis.x - (CURSOR_WIDTH / 2); } - if (MyAvatar.getHeadFinalPitch() <= (VIEW_ANGLE / 2) && MyAvatar.getHeadFinalPitch() >= -1 * (VIEW_ANGLE / 2)) { - angle = ((-1 * MyAvatar.getHeadFinalPitch()) + (VIEW_ANGLE / 2)) / VIEW_ANGLE; - // print(angle * dimensions.y); - editobject.y = angle * dimensions.y; + if (MyAvatar.getHeadFinalPitch() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalPitch() >= -1 * VIEW_ANGLE_BY_TWO) { + angle = ((-1 * MyAvatar.getHeadFinalPitch()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; + tthis.y = angle * dimensions.y; + editobject.y = tthis.y - (CURSOR_HEIGHT / 2); + } + if (Object.keys(editobject).length > 0) { + Overlays.editOverlay(tthis.overlay, editobject); + if (tthis.onUpdate != null) { + tthis.onUpdate(tthis.getPosition()); + } } - Overlays.editOverlay(tthis.overlay, editobject); }; Script.update.connect(this.update); } -var cursor = new Cursor(); + +function keyPressEvent(key) { + if (key.text === "SPACE") { + print("pressed space"); + + for (var i = 0; i < keyboard.keys.length; i++) { + print(i + " = " + keyboard.keys[i].key_state); + } + } +} + function scriptEnding() { keyboard.remove(); cursor.remove(); Overlays.deleteOverlay(cursor); + Controller.releaseKeyEvents({text: "SPACE"}); } +Controller.captureKeyEvents({text: "SPACE"}); +Controller.keyPressEvent.connect(keyPressEvent); Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From 4eb4330e84560cf40e18b7b0f890904e03df71b7 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 19 Nov 2014 23:08:50 +0100 Subject: [PATCH 04/13] virtualkeyboard now scales to the viewportdimensions --- examples/virtualKeyboard.js | 79 ++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 41ddfa75ae..e99a70faed 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -39,6 +39,7 @@ const KEY_STATE_UPPER = 1; var cursor = null; var keyboard = new Keyboard(); +var text = null; keyboard.onKeyPress = function() { print("Key press event test"); @@ -46,6 +47,20 @@ keyboard.onKeyPress = function() { keyboard.onFullyLoaded = function() { print("Virtual-keyboard fully loaded."); + var dimensions = Controller.getViewportDimensions(); + text = Overlays.addOverlay("text", { + x: 0,//(dimensions.x / 2) - (KEYBOARD_WIDTH / 2), + y: dimensions.y - keyboard.height() - 60, + width: dimensions.x, + height: 50, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 0, green: 0, blue: 0}, + topMargin: 10, + leftMargin: 8, + font: {size: 28}, + text: "", + alpha: 0.8 + }); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard cursor = new Cursor(); cursor.onUpdate = function(position) { @@ -56,6 +71,7 @@ keyboard.onFullyLoaded = function() { function KeyboardKey(keyboard, key_properties) { var tthis = this; this._focus = false; + this._beingpressed = false; this.event = key_properties.event != undefined ? key_properties.event : 'keypress'; this.bounds = key_properties.bounds; @@ -81,6 +97,22 @@ function KeyboardKey(keyboard, key_properties) { this.updateState = function() { tthis.setState(eval('KBD_' + (tthis.keyboard.shift ? 'UPPERCASE' : 'LOWERCASE') + '_' + (tthis._focus ? 'HOVER' : 'DEFAULT'))); }; + this.updateColor = function() { + var colorIntensity = _beingpressed ? 128 : 255; + for (var i = 0; i < tthis.bounds.length; i++) { + Overlays.editOverlay(tthis.overlays[i], + {color: {red: colorIntensity, green: colorIntensity, blue: colorIntensity}} + ); + } + }; + this.press = function() { + tthis._beingpressed = true; + tthis.updateColor(); + }; + this.release = function() { + tthis._beingpressed = false; + tthis.updateColor(); + }; this.blur = function() { tthis._focus = false; tthis.updateState(); @@ -121,10 +153,10 @@ function KeyboardKey(keyboard, key_properties) { for (var i = 0; i < this.bounds.length; i++) { var newOverlay = Overlays.cloneOverlay(this.keyboard.background); Overlays.editOverlay(newOverlay, { - x: this.keyboard.x + this.bounds[i][BOUND_X], - y: this.keyboard.y + this.bounds[i][BOUND_Y], - width: this.bounds[i][BOUND_W], - height: this.bounds[i][BOUND_H], + x: this.keyboard.x + this.bounds[i][BOUND_X] * keyboard.scale, + y: this.keyboard.y + this.bounds[i][BOUND_Y] * keyboard.scale, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale, subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.key_state) + this.bounds[i][BOUND_Y]}, alpha: 1 }); @@ -136,22 +168,30 @@ function Keyboard() { var tthis = this; var dimensions = Controller.getViewportDimensions(); this.focussed_key = -1; + this.scale = dimensions.x / KEYBOARD_WIDTH; this.shift = false; - this.x = (dimensions.x / 2) - (KEYBOARD_WIDTH / 2); - this.y = dimensions.y - KEYBOARD_HEIGHT; + this.width = function() { + return KEYBOARD_WIDTH * tthis.scale; + }; + this.height = function() { + return KEYBOARD_HEIGHT * tthis.scale; + }; + this.x = (dimensions.x / 2) - (this.width() / 2); + this.y = dimensions.y - this.height(); this.background = Overlays.addOverlay("image", { x: this.x, y: this.y, - width: KEYBOARD_WIDTH, - height: KEYBOARD_HEIGHT, + width: this.width(), + height: this.height(), subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, imageURL: KEYBOARD_URL, alpha: 1 }); this.setFocusPosition = function(x, y) { - var localx = x - tthis.x; - var localy = y - tthis.y; + // set to local unscaled position + var localx = (x - tthis.x) / tthis.scale; + var localy = (y - tthis.y) / tthis.scale; var new_focus_key = -1; if (localx >= 0 && localy >= 0 && localx <= KEYBOARD_WIDTH && localy <= KEYBOARD_HEIGHT) { for (var i = 0; i < tthis.keys.length; i++) { @@ -163,7 +203,7 @@ function Keyboard() { } } if (new_focus_key != tthis.focussed_key) { - print(new_focus_key); + //print(new_focus_key); if (tthis.focussed_key != -1) { tthis.keys[tthis.focussed_key].blur(); } @@ -179,6 +219,7 @@ function Keyboard() { if (tthis.focussed_key != -1) { this.onKeyPress(tthis.keys[tthis.focussed_key]); } + return tthis; }; @@ -366,20 +407,22 @@ function Cursor() { function keyPressEvent(key) { if (key.text === "SPACE") { print("pressed space"); + } +} - for (var i = 0; i < keyboard.keys.length; i++) { - print(i + " = " + keyboard.keys[i].key_state); - } +function keyReleaseEvent(key) { + if (key.text === "SPACE") { + print("released space"); } } function scriptEnding() { keyboard.remove(); cursor.remove(); - Overlays.deleteOverlay(cursor); - Controller.releaseKeyEvents({text: "SPACE"}); + Overlays.deleteOverlay(text); + Controller.releaseKeyEvents({key: 32}); } - -Controller.captureKeyEvents({text: "SPACE"}); +Controller.captureKeyEvents({key: 32}); Controller.keyPressEvent.connect(keyPressEvent); +Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From fefe9bdb8768a75a86724d977f22443bd1b42475 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 20 Nov 2014 22:40:49 +0100 Subject: [PATCH 05/13] virtual-keyboard: rescale-able --- examples/virtualKeyboard.js | 60 ++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index e99a70faed..d7065e8c76 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -37,6 +37,7 @@ const BOUND_H = 3; const KEY_STATE_LOWER = 0; const KEY_STATE_UPPER = 1; +var windowDimensions = Controller.getViewportDimensions(); var cursor = null; var keyboard = new Keyboard(); var text = null; @@ -49,7 +50,7 @@ keyboard.onFullyLoaded = function() { print("Virtual-keyboard fully loaded."); var dimensions = Controller.getViewportDimensions(); text = Overlays.addOverlay("text", { - x: 0,//(dimensions.x / 2) - (KEYBOARD_WIDTH / 2), + x: 0, y: dimensions.y - keyboard.height() - 60, width: dimensions.x, height: 50, @@ -129,11 +130,13 @@ function KeyboardKey(keyboard, key_properties) { }); } }; - this.updatePosition = function() { + this.rescale = function() { for (var i = 0; i < tthis.bounds.length; i++) { Overlays.editOverlay(tthis.overlays[i], { - x: tthis.keyboard.x + tthis.bounds[i][BOUND_X], - y: tthis.keyboard.y + tthis.bounds[i][BOUND_Y], + x: tthis.keyboard.getX() + tthis.bounds[i][BOUND_X] * keyboard.scale, + y: tthis.keyboard.getY() + tthis.bounds[i][BOUND_Y] * keyboard.scale, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale }); } }; @@ -153,8 +156,8 @@ function KeyboardKey(keyboard, key_properties) { for (var i = 0; i < this.bounds.length; i++) { var newOverlay = Overlays.cloneOverlay(this.keyboard.background); Overlays.editOverlay(newOverlay, { - x: this.keyboard.x + this.bounds[i][BOUND_X] * keyboard.scale, - y: this.keyboard.y + this.bounds[i][BOUND_Y] * keyboard.scale, + x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, + y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, width: this.bounds[i][BOUND_W] * keyboard.scale, height: this.bounds[i][BOUND_H] * keyboard.scale, subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.key_state) + this.bounds[i][BOUND_Y]}, @@ -166,9 +169,8 @@ function KeyboardKey(keyboard, key_properties) { function Keyboard() { var tthis = this; - var dimensions = Controller.getViewportDimensions(); this.focussed_key = -1; - this.scale = dimensions.x / KEYBOARD_WIDTH; + this.scale = windowDimensions.x / KEYBOARD_WIDTH; this.shift = false; this.width = function() { return KEYBOARD_WIDTH * tthis.scale; @@ -176,22 +178,38 @@ function Keyboard() { this.height = function() { return KEYBOARD_HEIGHT * tthis.scale; }; - this.x = (dimensions.x / 2) - (this.width() / 2); - this.y = dimensions.y - this.height(); + this.getX = function() { + return (windowDimensions.x / 2) - (this.width() / 2); + }; + this.getY = function() { + return windowDimensions.y - this.height(); + }; this.background = Overlays.addOverlay("image", { - x: this.x, - y: this.y, + x: this.getX(), + y: this.getY(), width: this.width(), height: this.height(), subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, imageURL: KEYBOARD_URL, alpha: 1 }); + this.rescale = function() { + this.scale = windowDimensions.x / KEYBOARD_WIDTH; + Overlays.editOverlay(tthis.background, { + x: this.getX(), + y: this.getY(), + width: this.width(), + height: this.height() + }); + for (var i = 0; i < tthis.keys.length; i++) { + tthis.keys[i].rescale(); + } + }; this.setFocusPosition = function(x, y) { // set to local unscaled position - var localx = (x - tthis.x) / tthis.scale; - var localy = (y - tthis.y) / tthis.scale; + var localx = (x - tthis.getX()) / tthis.scale; + var localy = (y - tthis.getY()) / tthis.scale; var new_focus_key = -1; if (localx >= 0 && localy >= 0 && localx <= KEYBOARD_WIDTH && localy <= KEYBOARD_HEIGHT) { for (var i = 0; i < tthis.keys.length; i++) { @@ -382,16 +400,24 @@ function Cursor() { }; this.onUpdate = null; this.update = function() { - var dimensions = Controller.getViewportDimensions(); + var newWindowDimensions = Controller.getViewportDimensions(); + if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) { + windowDimensions = newWindowDimensions; + keyboard.rescale(); + Overlays.editOverlay(text, { + y: windowDimensions.y - keyboard.height() - 60, + width: windowDimensions.x + }); + } var editobject = {}; if (MyAvatar.getHeadFinalYaw() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalYaw() >= -1 * VIEW_ANGLE_BY_TWO) { angle = ((-1 * MyAvatar.getHeadFinalYaw()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.x = angle * dimensions.x; + tthis.x = angle * windowDimensions.x; editobject.x = tthis.x - (CURSOR_WIDTH / 2); } if (MyAvatar.getHeadFinalPitch() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalPitch() >= -1 * VIEW_ANGLE_BY_TWO) { angle = ((-1 * MyAvatar.getHeadFinalPitch()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.y = angle * dimensions.y; + tthis.y = angle * windowDimensions.y; editobject.y = tthis.y - (CURSOR_HEIGHT / 2); } if (Object.keys(editobject).length > 0) { From 2b57f68857530b5b630558aa60c9abd5e1532656 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 21 Nov 2014 02:07:11 +0100 Subject: [PATCH 06/13] virtual-keyboard: - shift key functions - keys show pressed while pressing them - keyboard.onKeyPress and onKeyRelease are functional --- examples/virtualKeyboard.js | 64 +++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index d7065e8c76..ce3677bec3 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -26,7 +26,9 @@ const KEYBOARD_HEIGHT = 434.1; const CURSOR_WIDTH = 33.9; const CURSOR_HEIGHT = 33.9; -const VIEW_ANGLE = 60.0; +// VIEW_ANGLE can be adjusted to your likings, the smaller the faster movement. +// Try setting it to 60 if it goes too fast for you. +const VIEW_ANGLE = 30.0; const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; const BOUND_X = 0; @@ -81,7 +83,12 @@ function KeyboardKey(keyboard, key_properties) { this.key_state = key_properties.key_state != undefined ? key_properties.key_state : KBD_LOWERCASE_DEFAULT; // one overlay per bound vector [this.bounds] this.overlays = []; - this.updatePosition = function() { + this.getKeyEvent = function() { + if (tthis.event == 'keypress') { + var state = tthis.states[(tthis.keyboard.shift ? 1 : 2) % tthis.states.length]; + return {key: state.charCode, char: state.char, event: tthis.event}; + } + return {event: tthis.event}; }; this.containsCoord = function(x, y) { for (var i = 0; i < this.bounds.length; i++) { @@ -99,7 +106,7 @@ function KeyboardKey(keyboard, key_properties) { tthis.setState(eval('KBD_' + (tthis.keyboard.shift ? 'UPPERCASE' : 'LOWERCASE') + '_' + (tthis._focus ? 'HOVER' : 'DEFAULT'))); }; this.updateColor = function() { - var colorIntensity = _beingpressed ? 128 : 255; + var colorIntensity = this._beingpressed ? 128 : 255; for (var i = 0; i < tthis.bounds.length; i++) { Overlays.editOverlay(tthis.overlays[i], {color: {red: colorIntensity, green: colorIntensity, blue: colorIntensity}} @@ -221,7 +228,6 @@ function Keyboard() { } } if (new_focus_key != tthis.focussed_key) { - //print(new_focus_key); if (tthis.focussed_key != -1) { tthis.keys[tthis.focussed_key].blur(); } @@ -235,14 +241,44 @@ function Keyboard() { this.pressFocussedKey = function() { if (tthis.focussed_key != -1) { - this.onKeyPress(tthis.keys[tthis.focussed_key]); + if (tthis.keys[tthis.focussed_key].event == 'shift') { + tthis.toggleShift(); + } else { + tthis.keys[tthis.focussed_key].press(); + } + if (this.onKeyPress != null) { + this.onKeyPress(tthis.keys[tthis.focussed_key].getKeyEvent()); + } } return tthis; }; - - this.updatePosition = function() { - + + this.releaseKeys = function() { + for (var i = 0; i < tthis.keys.length; i++) { + if (tthis.keys[i]._beingpressed) { + if (tthis.keys[i].event != 'shift') { + tthis.keys[i].release(); + } + if (this.onKeyRelease != null) { + this.onKeyRelease(tthis.keys[i].getKeyEvent()); + } + } + } + }; + + this.toggleShift = function() { + tthis.shift = !tthis.shift; + for (var i = 0; i < tthis.keys.length; i++) { + tthis.keys[i].updateState(); + if (tthis.keys[i].event == 'shift') { + if (tthis.shift) { + tthis.keys[i].press(); + continue; + } + tthis.keys[i].release(); + } + } }; this.getFocussedKey = function() { @@ -260,8 +296,7 @@ function Keyboard() { }; this.onKeyPress = null; - this.onKeyDown = null; - this.onKeyUp = null; + this.onKeyRelease = null; this.onSubmit = null; this.onFullyLoaded = null; @@ -354,7 +389,7 @@ function Keyboard() { {bounds: [[972, 283, 190, 63]], event: 'shift'}, - {bounds: [[249, 355, 573, 67]], states: [{charCode: 192, char: ' '}]}, + {bounds: [[249, 355, 573, 67]], states: [{charCode: 32, char: ' '}]}, {bounds: [[899, 355, 263, 67]], event: 'submit'} ]; @@ -375,9 +410,8 @@ function Keyboard() { function Cursor() { var tthis = this; - var dimensions = Controller.getViewportDimensions(); - this.x = dimensions.x / 2; - this.y = dimensions.y / 2; + this.x = windowDimensions.x / 2; + this.y = windowDimensions.y / 2; this.overlay = Overlays.addOverlay("image", { x: this.x, y: this.y, @@ -433,12 +467,14 @@ function Cursor() { function keyPressEvent(key) { if (key.text === "SPACE") { print("pressed space"); + keyboard.pressFocussedKey(); } } function keyReleaseEvent(key) { if (key.text === "SPACE") { print("released space"); + keyboard.releaseKeys(); } } From a60374e4c11de48cb8ed713d684226d5f518d33a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 21 Nov 2014 02:59:05 +0100 Subject: [PATCH 07/13] virtual-keyboard: added text-entity example --- examples/virtualKeyboard.js | 86 ++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index ce3677bec3..5829a4fd2b 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -6,6 +6,10 @@ // Copyright 2014 High Fidelity, Inc. // // Control a virtual keyboard using your favorite HMD. +// Usage: Enable VR-mode and go to First person mode, +// look at the key that you would like to press, and press the spacebar on your "REAL" keyboard. +// +// leased some code from newEditEntities.js for Text Entity example // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -20,6 +24,8 @@ const KBD_BACKGROUND = 4; const KEYBOARD_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/keyboard.svg"; const CURSOR_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/cursor.svg"; +const SPACEBAR_CHARCODE = 32; + const KEYBOARD_WIDTH = 1174.7; const KEYBOARD_HEIGHT = 434.1; @@ -31,6 +37,11 @@ const CURSOR_HEIGHT = 33.9; const VIEW_ANGLE = 30.0; const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; +const SPAWN_DISTANCE = 1; +const DEFAULT_TEXT_DIMENSION_X = 1; +const DEFAULT_TEXT_DIMENSION_Y = 1; +const DEFAULT_TEXT_DIMENSION_Z = 0.02; + const BOUND_X = 0; const BOUND_Y = 1; const BOUND_W = 2; @@ -43,9 +54,55 @@ var windowDimensions = Controller.getViewportDimensions(); var cursor = null; var keyboard = new Keyboard(); var text = null; +var textText = ""; +function appendChar(char) { + textText += char; + updateTextOverlay(); + Overlays.editOverlay(text, {text: textText}); +} +function deleteChar() { + if (textText.length > 0) { + textText = textText.substring(0, textText.length - 1); + updateTextOverlay(); + } +} +function updateTextOverlay() { + Overlays.editOverlay(text, {text: textText}); +} +keyboard.onKeyPress = function(event) { + if (event.event == 'keypress') { + appendChar(event.char); + } else if (event.event == 'enter') { + appendChar("\n"); + } +}; -keyboard.onKeyPress = function() { - print("Key press event test"); +keyboard.onKeyRelease = function(event) { + print("Key release event test"); + // you can cancel a key by releasing its focusing before releasing it + if (event.focus) { + if (event.event == 'delete') { + deleteChar(); + } else if (event.event == 'submit') { + print(textText); + + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + + if (position.x > 0 && position.y > 0 && position.z > 0) { + Entities.addEntity({ + type: "Text", + position: position, + dimensions: { x: DEFAULT_TEXT_DIMENSION_X, y: DEFAULT_TEXT_DIMENSION_Y, z: DEFAULT_TEXT_DIMENSION_Z }, + backgroundColor: { red: 0, green: 0, blue: 0 }, + textColor: { red: 255, green: 255, blue: 255 }, + text: textText, + lineHight: "0.1" + }); + } + textText = ""; + updateTextOverlay(); + } + } }; keyboard.onFullyLoaded = function() { @@ -53,9 +110,9 @@ keyboard.onFullyLoaded = function() { var dimensions = Controller.getViewportDimensions(); text = Overlays.addOverlay("text", { x: 0, - y: dimensions.y - keyboard.height() - 60, + y: dimensions.y - keyboard.height() - 260, width: dimensions.x, - height: 50, + height: 250, backgroundColor: { red: 255, green: 255, blue: 255}, color: { red: 0, green: 0, blue: 0}, topMargin: 10, @@ -86,9 +143,9 @@ function KeyboardKey(keyboard, key_properties) { this.getKeyEvent = function() { if (tthis.event == 'keypress') { var state = tthis.states[(tthis.keyboard.shift ? 1 : 2) % tthis.states.length]; - return {key: state.charCode, char: state.char, event: tthis.event}; + return {key: state.charCode, char: state.char, event: tthis.event, focus: tthis._focus}; } - return {event: tthis.event}; + return {event: tthis.event, focus: tthis._focus}; }; this.containsCoord = function(x, y) { for (var i = 0; i < this.bounds.length; i++) { @@ -221,7 +278,6 @@ function Keyboard() { if (localx >= 0 && localy >= 0 && localx <= KEYBOARD_WIDTH && localy <= KEYBOARD_HEIGHT) { for (var i = 0; i < tthis.keys.length; i++) { if (tthis.keys[i].containsCoord(localx, localy)) { - //print(tthis.keys[i].states[0].char); new_focus_key = i; break; } @@ -439,7 +495,7 @@ function Cursor() { windowDimensions = newWindowDimensions; keyboard.rescale(); Overlays.editOverlay(text, { - y: windowDimensions.y - keyboard.height() - 60, + y: windowDimensions.y - keyboard.height() - 260, width: windowDimensions.x }); } @@ -464,16 +520,14 @@ function Cursor() { Script.update.connect(this.update); } -function keyPressEvent(key) { - if (key.text === "SPACE") { - print("pressed space"); +function keyPressEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { keyboard.pressFocussedKey(); } } -function keyReleaseEvent(key) { - if (key.text === "SPACE") { - print("released space"); +function keyReleaseEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { keyboard.releaseKeys(); } } @@ -482,9 +536,9 @@ function scriptEnding() { keyboard.remove(); cursor.remove(); Overlays.deleteOverlay(text); - Controller.releaseKeyEvents({key: 32}); + Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); } -Controller.captureKeyEvents({key: 32}); +Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); Controller.keyPressEvent.connect(keyPressEvent); Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From e12f64bae41fe6d037fa4d2e4589048c56b7182d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sun, 23 Nov 2014 17:15:14 +0100 Subject: [PATCH 08/13] virtual-keyboard: - added keycodes - resizes the example text entity based on text size - adds the author of the text entity in the bottom right corner --- examples/virtualKeyboard.js | 171 +++++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 72 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 5829a4fd2b..cd2ce9f7ba 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -38,8 +38,6 @@ const VIEW_ANGLE = 30.0; const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; const SPAWN_DISTANCE = 1; -const DEFAULT_TEXT_DIMENSION_X = 1; -const DEFAULT_TEXT_DIMENSION_Y = 1; const DEFAULT_TEXT_DIMENSION_Z = 0.02; const BOUND_X = 0; @@ -50,11 +48,18 @@ const BOUND_H = 3; const KEY_STATE_LOWER = 0; const KEY_STATE_UPPER = 1; +const TEXT_MARGIN_TOP = 0.15; +const TEXT_MARGIN_LEFT = 0.15; +const TEXT_MARGIN_RIGHT = 0.17; +const TEXT_MARGIN_BOTTOM = 0.17; + var windowDimensions = Controller.getViewportDimensions(); var cursor = null; var keyboard = new Keyboard(); var text = null; var textText = ""; +var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); + function appendChar(char) { textText += char; updateTextOverlay(); @@ -88,15 +93,36 @@ keyboard.onKeyRelease = function(event) { var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textWidth(textSizeMeasureOverlay, textLines[textLine]); + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var usernameLine = "--" + GlobalServices.myUsername; + var usernameWidth = Overlays.textWidth(textSizeMeasureOverlay, usernameLine); + if (maxLineWidth < usernameWidth) { + maxLineWidth = usernameWidth; + } else { + var spaceableWidth = maxLineWidth - usernameWidth; + var spaceWidth = Overlays.textWidth(textSizeMeasureOverlay, " "); + var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); + for (var i = 0; i < numberOfSpaces; i++) { + usernameLine = " " + usernameLine; + } + } + var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; if (position.x > 0 && position.y > 0 && position.z > 0) { Entities.addEntity({ type: "Text", + rotation: MyAvatar.orientation, position: position, - dimensions: { x: DEFAULT_TEXT_DIMENSION_X, y: DEFAULT_TEXT_DIMENSION_Y, z: DEFAULT_TEXT_DIMENSION_Z }, + dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, backgroundColor: { red: 0, green: 0, blue: 0 }, textColor: { red: 255, green: 255, blue: 255 }, - text: textText, - lineHight: "0.1" + text: textText + "\n" + usernameLine }); } textText = ""; @@ -363,85 +389,85 @@ function Keyboard() { // coords [[x,y,w,h],[x,y,w,h]] // states array of 1 or 2 objects [lowercase, uppercase] each object contains a charCode and a char var keyProperties = [ - {bounds: [[12, 12, 65, 52]], states: [{charCode: 192, char: '~'}]}, - {bounds: [[84, 12, 65, 52]], states: [{charCode: 192, char: '!'}]}, - {bounds: [[156, 12, 65, 52]], states: [{charCode: 192, char: '@'}]}, - {bounds: [[228, 12, 65, 52]], states: [{charCode: 192, char: '#'}]}, - {bounds: [[300, 12, 65, 52]], states: [{charCode: 192, char: '$'}]}, - {bounds: [[372, 12, 65, 52]], states: [{charCode: 192, char: '%'}]}, - {bounds: [[445, 12, 65, 52]], states: [{charCode: 192, char: '^'}]}, - {bounds: [[517, 12, 65, 52]], states: [{charCode: 192, char: '&'}]}, - {bounds: [[589, 12, 65, 52]], states: [{charCode: 192, char: '*'}]}, - {bounds: [[662, 12, 65, 52]], states: [{charCode: 192, char: '('}]}, - {bounds: [[734, 12, 65, 52]], states: [{charCode: 192, char: ')'}]}, - {bounds: [[806, 12, 65, 52]], states: [{charCode: 192, char: '_'}]}, - {bounds: [[881, 12, 65, 52]], states: [{charCode: 192, char: '{'}]}, - {bounds: [[953, 12, 65, 52]], states: [{charCode: 192, char: '}'}]}, - {bounds: [[1025, 12, 65, 52]], states: [{charCode: 192, char: '<'}]}, - {bounds: [[1097, 12, 65, 52]], states: [{charCode: 192, char: '>'}]}, + {bounds: [[12, 12, 65, 52]], states: [{charCode: 126, char: '~'}]}, + {bounds: [[84, 12, 65, 52]], states: [{charCode: 33, char: '!'}]}, + {bounds: [[156, 12, 65, 52]], states: [{charCode: 64, char: '@'}]}, + {bounds: [[228, 12, 65, 52]], states: [{charCode: 35, char: '#'}]}, + {bounds: [[300, 12, 65, 52]], states: [{charCode: 36, char: '$'}]}, + {bounds: [[372, 12, 65, 52]], states: [{charCode: 37, char: '%'}]}, + {bounds: [[445, 12, 65, 52]], states: [{charCode: 94, char: '^'}]}, + {bounds: [[517, 12, 65, 52]], states: [{charCode: 38, char: '&'}]}, + {bounds: [[589, 12, 65, 52]], states: [{charCode: 42, char: '*'}]}, + {bounds: [[662, 12, 65, 52]], states: [{charCode: 40, char: '('}]}, + {bounds: [[734, 12, 65, 52]], states: [{charCode: 41, char: ')'}]}, + {bounds: [[806, 12, 65, 52]], states: [{charCode: 95, char: '_'}]}, + {bounds: [[881, 12, 65, 52]], states: [{charCode: 123, char: '{'}]}, + {bounds: [[953, 12, 65, 52]], states: [{charCode: 125, char: '}'}]}, + {bounds: [[1025, 12, 65, 52]], states: [{charCode: 60, char: '<'}]}, + {bounds: [[1097, 12, 65, 52]], states: [{charCode: 62, char: '>'}]}, - {bounds: [[12, 71, 65, 63]], states: [{charCode: 192, char: '`'}]}, - {bounds: [[84, 71, 65, 63]], states: [{charCode: 192, char: '1'}]}, - {bounds: [[156, 71, 65, 63]], states: [{charCode: 192, char: '2'}]}, - {bounds: [[228, 71, 65, 63]], states: [{charCode: 192, char: '3'}]}, - {bounds: [[300, 71, 65, 63]], states: [{charCode: 192, char: '4'}]}, - {bounds: [[372, 71, 65, 63]], states: [{charCode: 192, char: '5'}]}, - {bounds: [[445, 71, 65, 63]], states: [{charCode: 192, char: '6'}]}, - {bounds: [[517, 71, 65, 63]], states: [{charCode: 192, char: '7'}]}, - {bounds: [[589, 71, 65, 63]], states: [{charCode: 192, char: '8'}]}, - {bounds: [[661, 71, 65, 63]], states: [{charCode: 192, char: '9'}]}, - {bounds: [[733, 71, 65, 63]], states: [{charCode: 192, char: '0'}]}, - {bounds: [[806, 71, 65, 63]], states: [{charCode: 192, char: '-'}]}, - {bounds: [[880, 71, 65, 63]], states: [{charCode: 192, char: '='}]}, - {bounds: [[953, 71, 65, 63]], states: [{charCode: 192, char: '+'}]}, + {bounds: [[12, 71, 65, 63]], states: [{charCode: 96, char: '`'}]}, + {bounds: [[84, 71, 65, 63]], states: [{charCode: 49, char: '1'}]}, + {bounds: [[156, 71, 65, 63]], states: [{charCode: 50, char: '2'}]}, + {bounds: [[228, 71, 65, 63]], states: [{charCode: 51, char: '3'}]}, + {bounds: [[300, 71, 65, 63]], states: [{charCode: 52, char: '4'}]}, + {bounds: [[372, 71, 65, 63]], states: [{charCode: 53, char: '5'}]}, + {bounds: [[445, 71, 65, 63]], states: [{charCode: 54, char: '6'}]}, + {bounds: [[517, 71, 65, 63]], states: [{charCode: 55, char: '7'}]}, + {bounds: [[589, 71, 65, 63]], states: [{charCode: 56, char: '8'}]}, + {bounds: [[661, 71, 65, 63]], states: [{charCode: 57, char: '9'}]}, + {bounds: [[733, 71, 65, 63]], states: [{charCode: 48, char: '0'}]}, + {bounds: [[806, 71, 65, 63]], states: [{charCode: 45, char: '-'}]}, + {bounds: [[880, 71, 65, 63]], states: [{charCode: 61, char: '='}]}, + {bounds: [[953, 71, 65, 63]], states: [{charCode: 43, char: '+'}]}, {bounds: [[1024, 71, 139, 63]], event: 'delete'}, // enter key has 2 bounds and one state {bounds: [[11, 143, 98, 71], [11, 213, 121, 62]], event: 'enter'}, - {bounds: [[118, 142, 64, 63]], states: [{charCode: 192, char: 'q'}, {charCode: 192, char: 'Q'}]}, - {bounds: [[190, 142, 64, 63]], states: [{charCode: 192, char: 'w'}, {charCode: 192, char: 'W'}]}, - {bounds: [[262, 142, 64, 63]], states: [{charCode: 192, char: 'e'}, {charCode: 192, char: 'E'}]}, - {bounds: [[334, 142, 64, 63]], states: [{charCode: 192, char: 'r'}, {charCode: 192, char: 'R'}]}, - {bounds: [[407, 142, 64, 63]], states: [{charCode: 192, char: 't'}, {charCode: 192, char: 'T'}]}, - {bounds: [[479, 142, 64, 63]], states: [{charCode: 192, char: 'y'}, {charCode: 192, char: 'Y'}]}, - {bounds: [[551, 142, 65, 63]], states: [{charCode: 192, char: 'u'}, {charCode: 192, char: 'U'}]}, - {bounds: [[623, 142, 65, 63]], states: [{charCode: 192, char: 'i'}, {charCode: 192, char: 'I'}]}, - {bounds: [[695, 142, 65, 63]], states: [{charCode: 192, char: 'o'}, {charCode: 192, char: 'O'}]}, - {bounds: [[768, 142, 64, 63]], states: [{charCode: 192, char: 'p'}, {charCode: 192, char: 'P'}]}, - {bounds: [[840, 142, 64, 63]], states: [{charCode: 192, char: '['}]}, - {bounds: [[912, 142, 65, 63]], states: [{charCode: 192, char: ']'}]}, - {bounds: [[984, 142, 65, 63]], states: [{charCode: 192, char: '\\'}]}, - {bounds: [[1055, 142, 65, 63]], states: [{charCode: 192, char: '|'}]}, + {bounds: [[118, 142, 64, 63]], states: [{charCode: 113, char: 'q'}, {charCode: 81, char: 'Q'}]}, + {bounds: [[190, 142, 64, 63]], states: [{charCode: 119, char: 'w'}, {charCode: 87, char: 'W'}]}, + {bounds: [[262, 142, 64, 63]], states: [{charCode: 101, char: 'e'}, {charCode: 69, char: 'E'}]}, + {bounds: [[334, 142, 64, 63]], states: [{charCode: 114, char: 'r'}, {charCode: 82, char: 'R'}]}, + {bounds: [[407, 142, 64, 63]], states: [{charCode: 116, char: 't'}, {charCode: 84, char: 'T'}]}, + {bounds: [[479, 142, 64, 63]], states: [{charCode: 121, char: 'y'}, {charCode: 89, char: 'Y'}]}, + {bounds: [[551, 142, 65, 63]], states: [{charCode: 117, char: 'u'}, {charCode: 85, char: 'U'}]}, + {bounds: [[623, 142, 65, 63]], states: [{charCode: 105, char: 'i'}, {charCode: 73, char: 'I'}]}, + {bounds: [[695, 142, 65, 63]], states: [{charCode: 111, char: 'o'}, {charCode: 79, char: 'O'}]}, + {bounds: [[768, 142, 64, 63]], states: [{charCode: 112, char: 'p'}, {charCode: 80, char: 'P'}]}, + {bounds: [[840, 142, 64, 63]], states: [{charCode: 91, char: '['}]}, + {bounds: [[912, 142, 65, 63]], states: [{charCode: 93, char: ']'}]}, + {bounds: [[984, 142, 65, 63]], states: [{charCode: 92, char: '\\'}]}, + {bounds: [[1055, 142, 65, 63]], states: [{charCode: 124, char: '|'}]}, {bounds: [[1126, 143, 35, 72], [1008, 214, 153, 62]], event: 'enter'}, - {bounds: [[140, 213, 65, 63]], states: [{charCode: 192, char: 'a'}, {charCode: 192, char: 'A'}]}, - {bounds: [[211, 213, 64, 63]], states: [{charCode: 192, char: 's'}, {charCode: 192, char: 'S'}]}, - {bounds: [[283, 213, 65, 63]], states: [{charCode: 192, char: 'd'}, {charCode: 192, char: 'D'}]}, - {bounds: [[355, 213, 65, 63]], states: [{charCode: 192, char: 'f'}, {charCode: 192, char: 'F'}]}, - {bounds: [[428, 213, 64, 63]], states: [{charCode: 192, char: 'g'}, {charCode: 192, char: 'G'}]}, - {bounds: [[500, 213, 64, 63]], states: [{charCode: 192, char: 'h'}, {charCode: 192, char: 'H'}]}, - {bounds: [[572, 213, 65, 63]], states: [{charCode: 192, char: 'j'}, {charCode: 192, char: 'J'}]}, - {bounds: [[644, 213, 65, 63]], states: [{charCode: 192, char: 'k'}, {charCode: 192, char: 'K'}]}, - {bounds: [[716, 213, 65, 63]], states: [{charCode: 192, char: 'l'}, {charCode: 192, char: 'L'}]}, - {bounds: [[789, 213, 64, 63]], states: [{charCode: 192, char: ';'}]}, - {bounds: [[861, 213, 64, 63]], states: [{charCode: 192, char: '\''}]}, - {bounds: [[934, 213, 65, 63]], states: [{charCode: 192, char: ':'}]}, + {bounds: [[140, 213, 65, 63]], states: [{charCode: 97, char: 'a'}, {charCode: 65, char: 'A'}]}, + {bounds: [[211, 213, 64, 63]], states: [{charCode: 115, char: 's'}, {charCode: 83, char: 'S'}]}, + {bounds: [[283, 213, 65, 63]], states: [{charCode: 100, char: 'd'}, {charCode: 68, char: 'D'}]}, + {bounds: [[355, 213, 65, 63]], states: [{charCode: 102, char: 'f'}, {charCode: 70, char: 'F'}]}, + {bounds: [[428, 213, 64, 63]], states: [{charCode: 103, char: 'g'}, {charCode: 71, char: 'G'}]}, + {bounds: [[500, 213, 64, 63]], states: [{charCode: 104, char: 'h'}, {charCode: 72, char: 'H'}]}, + {bounds: [[572, 213, 65, 63]], states: [{charCode: 106, char: 'j'}, {charCode: 74, char: 'J'}]}, + {bounds: [[644, 213, 65, 63]], states: [{charCode: 107, char: 'k'}, {charCode: 75, char: 'K'}]}, + {bounds: [[716, 213, 65, 63]], states: [{charCode: 108, char: 'l'}, {charCode: 76, char: 'L'}]}, + {bounds: [[789, 213, 64, 63]], states: [{charCode: 59, char: ';'}]}, + {bounds: [[861, 213, 64, 63]], states: [{charCode: 39, char: '\''}]}, + {bounds: [[934, 213, 65, 63]], states: [{charCode: 58, char: ':'}]}, {bounds: [[12, 283, 157, 63]], event: 'shift'}, - {bounds: [[176, 283, 65, 63]], states: [{charCode: 192, char: 'z'}, {charCode: 192, char: 'Z'}]}, - {bounds: [[249, 283, 64, 63]], states: [{charCode: 192, char: 'x'}, {charCode: 192, char: 'X'}]}, - {bounds: [[321, 283, 64, 63]], states: [{charCode: 192, char: 'c'}, {charCode: 192, char: 'C'}]}, - {bounds: [[393, 283, 64, 63]], states: [{charCode: 192, char: 'v'}, {charCode: 192, char: 'V'}]}, - {bounds: [[465, 283, 65, 63]], states: [{charCode: 192, char: 'b'}, {charCode: 192, char: 'B'}]}, - {bounds: [[537, 283, 65, 63]], states: [{charCode: 192, char: 'n'}, {charCode: 192, char: 'N'}]}, - {bounds: [[610, 283, 64, 63]], states: [{charCode: 192, char: 'm'}, {charCode: 192, char: 'M'}]}, - {bounds: [[682, 283, 64, 63]], states: [{charCode: 192, char: ','}]}, - {bounds: [[754, 283, 65, 63]], states: [{charCode: 192, char: '.'}]}, - {bounds: [[826, 283, 65, 63]], states: [{charCode: 192, char: '/'}]}, - {bounds: [[899, 283, 64, 63]], states: [{charCode: 192, char: '?'}]}, + {bounds: [[176, 283, 65, 63]], states: [{charCode: 122, char: 'z'}, {charCode: 90, char: 'Z'}]}, + {bounds: [[249, 283, 64, 63]], states: [{charCode: 120, char: 'x'}, {charCode: 88, char: 'X'}]}, + {bounds: [[321, 283, 64, 63]], states: [{charCode: 99, char: 'c'}, {charCode: 67, char: 'C'}]}, + {bounds: [[393, 283, 64, 63]], states: [{charCode: 118, char: 'v'}, {charCode: 86, char: 'V'}]}, + {bounds: [[465, 283, 65, 63]], states: [{charCode: 98, char: 'b'}, {charCode: 66, char: 'B'}]}, + {bounds: [[537, 283, 65, 63]], states: [{charCode: 110, char: 'n'}, {charCode: 78, char: 'N'}]}, + {bounds: [[610, 283, 64, 63]], states: [{charCode: 109, char: 'm'}, {charCode: 77, char: 'M'}]}, + {bounds: [[682, 283, 64, 63]], states: [{charCode: 44, char: ','}]}, + {bounds: [[754, 283, 65, 63]], states: [{charCode: 46, char: '.'}]}, + {bounds: [[826, 283, 65, 63]], states: [{charCode: 47, char: '/'}]}, + {bounds: [[899, 283, 64, 63]], states: [{charCode: 63, char: '?'}]}, {bounds: [[972, 283, 190, 63]], event: 'shift'}, @@ -536,6 +562,7 @@ function scriptEnding() { keyboard.remove(); cursor.remove(); Overlays.deleteOverlay(text); + Overlays.deleteOverlay(textSizeMeasureOverlay); Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); } Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); From 5e2d1c33644a39d9aa65374c48ea5f3324e915af Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 4 Dec 2014 21:15:10 +0100 Subject: [PATCH 09/13] more comfortable movement setting --- examples/virtualKeyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index cd2ce9f7ba..58b44e8585 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -34,7 +34,7 @@ const CURSOR_HEIGHT = 33.9; // VIEW_ANGLE can be adjusted to your likings, the smaller the faster movement. // Try setting it to 60 if it goes too fast for you. -const VIEW_ANGLE = 30.0; +const VIEW_ANGLE = 40.0; const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; const SPAWN_DISTANCE = 1; From a7185738e9e961be7afe5e66c151024efb0fc097 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 5 Dec 2014 00:52:36 +0100 Subject: [PATCH 10/13] virtualkeyboard: scaling text in input box --- examples/virtualKeyboard.js | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 58b44e8585..3d00f934e2 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -56,6 +56,7 @@ const TEXT_MARGIN_BOTTOM = 0.17; var windowDimensions = Controller.getViewportDimensions(); var cursor = null; var keyboard = new Keyboard(); +var textFontSize = 9; var text = null; var textText = ""; var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); @@ -65,15 +66,39 @@ function appendChar(char) { updateTextOverlay(); Overlays.editOverlay(text, {text: textText}); } + function deleteChar() { if (textText.length > 0) { textText = textText.substring(0, textText.length - 1); updateTextOverlay(); } } + function updateTextOverlay() { - Overlays.editOverlay(text, {text: textText}); + var textwidth = Overlays.textWidth(text, textText); + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textWidth(text, textLines[textLine]); + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; + var maxFontSize = 240 / textLines.length; + textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; + var topMargin = (250 - (textFontSize * textLines.length)) / 2; + Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textWidth(text, textLines[textLine]); + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); } + keyboard.onKeyPress = function(event) { if (event.event == 'keypress') { appendChar(event.char); @@ -141,12 +166,13 @@ keyboard.onFullyLoaded = function() { height: 250, backgroundColor: { red: 255, green: 255, blue: 255}, color: { red: 0, green: 0, blue: 0}, - topMargin: 10, - leftMargin: 8, - font: {size: 28}, + topMargin: 5, + leftMargin: 0, + font: {size: textFontSize}, text: "", alpha: 0.8 }); + updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard cursor = new Cursor(); cursor.onUpdate = function(position) { From c0ba9e73c28725a6662e70d5f7a53879a318d7ea Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 5 Dec 2014 01:07:49 +0100 Subject: [PATCH 11/13] fixed font height bq --- examples/virtualKeyboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 3d00f934e2..2340bcab6e 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -85,9 +85,9 @@ function updateTextOverlay() { } } var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; - var maxFontSize = 240 / textLines.length; + var maxFontSize = 190 / textLines.length; textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; - var topMargin = (250 - (textFontSize * textLines.length)) / 2; + var topMargin = (250 - (textFontSize * textLines.length)) / 4; Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); var maxLineWidth = 0; for (textLine in textLines) { From ccdb13c951129351336296f578d7c7d3f2b937d7 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 6 Dec 2014 00:33:33 +0100 Subject: [PATCH 12/13] virtualkeyboard: moved files to hifi public bucket --- examples/virtualKeyboard.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index 2340bcab6e..e48da8a4d1 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -15,14 +15,16 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + const KBD_UPPERCASE_DEFAULT = 0; const KBD_LOWERCASE_DEFAULT = 1; const KBD_UPPERCASE_HOVER = 2; const KBD_LOWERCASE_HOVER = 3; const KBD_BACKGROUND = 4; -const KEYBOARD_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/keyboard.svg"; -const CURSOR_URL = "http://test.thoys.nl/hifi/images/virtualKeyboard/cursor.svg"; +const KEYBOARD_URL = HIFI_PUBLIC_BUCKET + "images/keyboard.svg"; +const CURSOR_URL = HIFI_PUBLIC_BUCKET + "images/cursor.svg"; const SPACEBAR_CHARCODE = 32; From 351819708bc1d9855175365b9814315650020746 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 6 Dec 2014 23:50:30 +0100 Subject: [PATCH 13/13] style fixes --- examples/virtualKeyboard.js | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index e48da8a4d1..c89dc6fb04 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -77,7 +77,6 @@ function deleteChar() { } function updateTextOverlay() { - var textwidth = Overlays.textWidth(text, textText); var textLines = textText.split("\n"); var maxLineWidth = 0; for (textLine in textLines) { @@ -182,16 +181,16 @@ keyboard.onFullyLoaded = function() { }; }; -function KeyboardKey(keyboard, key_properties) { +function KeyboardKey(keyboard, keyProperties) { var tthis = this; this._focus = false; - this._beingpressed = false; - this.event = key_properties.event != undefined ? - key_properties.event : 'keypress'; - this.bounds = key_properties.bounds; - this.states = key_properties.states; + this._beingPressed = false; + this.event = keyProperties.event != undefined ? + keyProperties.event : 'keypress'; + this.bounds = keyProperties.bounds; + this.states = keyProperties.states; this.keyboard = keyboard; - this.key_state = key_properties.key_state != undefined ? key_properties.key_state : KBD_LOWERCASE_DEFAULT; + this.keyState = keyProperties.keyState != undefined ? keyProperties.keyState : KBD_LOWERCASE_DEFAULT; // one overlay per bound vector [this.bounds] this.overlays = []; this.getKeyEvent = function() { @@ -217,7 +216,7 @@ function KeyboardKey(keyboard, key_properties) { tthis.setState(eval('KBD_' + (tthis.keyboard.shift ? 'UPPERCASE' : 'LOWERCASE') + '_' + (tthis._focus ? 'HOVER' : 'DEFAULT'))); }; this.updateColor = function() { - var colorIntensity = this._beingpressed ? 128 : 255; + var colorIntensity = this._beingPressed ? 128 : 255; for (var i = 0; i < tthis.bounds.length; i++) { Overlays.editOverlay(tthis.overlays[i], {color: {red: colorIntensity, green: colorIntensity, blue: colorIntensity}} @@ -225,11 +224,11 @@ function KeyboardKey(keyboard, key_properties) { } }; this.press = function() { - tthis._beingpressed = true; + tthis._beingPressed = true; tthis.updateColor(); }; this.release = function() { - tthis._beingpressed = false; + tthis._beingPressed = false; tthis.updateColor(); }; this.blur = function() { @@ -241,10 +240,10 @@ function KeyboardKey(keyboard, key_properties) { tthis.updateState(); }; this.setState = function(state) { - tthis.key_state = state; + tthis.keyState = state; for (var i = 0; i < tthis.bounds.length; i++) { Overlays.editOverlay(tthis.overlays[i], { - subImage: {width: tthis.bounds[i][BOUND_W], height: tthis.bounds[i][BOUND_H], x: tthis.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * tthis.key_state) + tthis.bounds[i][BOUND_Y]} + subImage: {width: tthis.bounds[i][BOUND_W], height: tthis.bounds[i][BOUND_H], x: tthis.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * tthis.keyState) + tthis.bounds[i][BOUND_Y]} }); } }; @@ -278,7 +277,7 @@ function KeyboardKey(keyboard, key_properties) { y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, width: this.bounds[i][BOUND_W] * keyboard.scale, height: this.bounds[i][BOUND_H] * keyboard.scale, - subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.key_state) + this.bounds[i][BOUND_Y]}, + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, alpha: 1 }); this.overlays.push(newOverlay); @@ -366,7 +365,7 @@ function Keyboard() { this.releaseKeys = function() { for (var i = 0; i < tthis.keys.length; i++) { - if (tthis.keys[i]._beingpressed) { + if (tthis.keys[i]._beingPressed) { if (tthis.keys[i].event != 'shift') { tthis.keys[i].release(); } @@ -504,9 +503,9 @@ function Keyboard() { {bounds: [[899, 355, 263, 67]], event: 'submit'} ]; - this.keyboardtextureloaded = function() { + this.keyboardTextureLoaded = function() { if (Overlays.isLoaded(tthis.background)) { - Script.clearInterval(tthis.keyboardtextureloaded_timer); + Script.clearInterval(tthis.keyboardTextureLoaded_timer); for (var i = 0; i < keyProperties.length; i++) { tthis.keys.push(new KeyboardKey(tthis, keyProperties[i])); } @@ -515,7 +514,7 @@ function Keyboard() { } } }; - this.keyboardtextureloaded_timer = Script.setInterval(this.keyboardtextureloaded, 250); + this.keyboardTextureLoaded_timer = Script.setInterval(this.keyboardTextureLoaded, 250); } function Cursor() {