summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.xml15
-rwxr-xr-xdesktop.sh12
-rwxr-xr-xmobile.sh21
-rw-r--r--morphic.js5
-rw-r--r--objects.js43
-rw-r--r--package.json8
-rwxr-xr-xsnap.html4
-rw-r--r--threads.js108
8 files changed, 216 insertions, 0 deletions
diff --git a/config.xml b/config.xml
new file mode 100644
index 0000000..36a7bcf
--- /dev/null
+++ b/config.xml
@@ -0,0 +1,15 @@
+<?xml version='4.0' encoding='utf-8'?>
+<widget id="edu.berkeley.snap" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+ <name>Snap!</name>
+ <description>
+ Snap! Build Your Own Blocks
+ A visual, blocks based programming language inspired by Scratch
+ </description>
+ <author email="jens@moenig.org" href="http://snap.berkeley.edu">
+ Jens Mönig and Brian Harvey
+ </author>
+ <content src="snap.html" />
+ <access origin="*" />
+ <preference name="Fullscreen" value="true" />
+ <icon src="www/snap_logo_sm.png" />
+</widget>
diff --git a/desktop.sh b/desktop.sh
new file mode 100755
index 0000000..46a7594
--- /dev/null
+++ b/desktop.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Requirements:
+# git, zip, nodejs
+# node-webkit (https://github.com/rogerwang/node-webkit), node-webkit-builder (https://github.com/mllrsohn/node-webkit-builder)
+
+# binaries are in snap/build/Snap!
+
+git clone https://github.com/Gubolin/snap.git
+cd "snap"
+git checkout mobileapp
+nwbuild -p win,osx,linux32,linux64 .
diff --git a/mobile.sh b/mobile.sh
new file mode 100755
index 0000000..656b7dc
--- /dev/null
+++ b/mobile.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Requirements:
+# git, nodejs, android SDK / other platform(s)
+# cordova (https://cordova.apache.org/)
+
+# binaries are in platform/android/ant-build/Snap-debug.apk
+
+cordova create Snap-Mobile edu.berkeley.snap "Snap\!"
+cd Snap-Mobile
+rm -rf www config.xml
+git clone https://github.com/Gubolin/snap.git www
+cd www
+git checkout mobileapp
+cordova platform add android
+cordova plugin add org.apache.cordova.plugin.softkeyboard
+cordova plugin add org.apache.cordova.vibration
+cordova plugin add org.apache.cordova.device-motion
+cordova plugin add org.apache.cordova.device-orientation
+cordova plugin add org.apache.cordova.geolocation
+cordova build android
diff --git a/morphic.js b/morphic.js
index 2a242f2..efdf139 100644
--- a/morphic.js
+++ b/morphic.js
@@ -10778,6 +10778,11 @@ WorldMorph.prototype.edit = function (aStringOrTextMorph) {
this.virtualKeyboard.style.top = this.cursor.top() + pos.y + "px";
this.virtualKeyboard.style.left = this.cursor.left() + pos.x + "px";
this.virtualKeyboard.focus();
+ if (cordova) {
+ if (cordova.plugins.SoftKeyboard) { // Android only
+ cordova.plugins.SoftKeyboard.show(); // Issue #81
+ }
+ }
}
if (MorphicPreferences.useSliderForInput) {
diff --git a/objects.js b/objects.js
index 5450a49..49fafb5 100644
--- a/objects.js
+++ b/objects.js
@@ -878,6 +878,31 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sensing',
spec: 'current %dates'
},
+ doVibrate: {
+ type: 'command',
+ category: 'sensing',
+ spec: 'vibrate %n seconds'
+ },
+ reportCompassHeading: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'current compass heading'
+ },
+ reportAccelerationX: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'current acceleration along the x axes'
+ },
+ reportAccelerationY: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'current acceleration along the y axes'
+ },
+ reportAccelerationZ: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'current acceleration along the z axes'
+ },
reportLanguage: {
type: 'reporter',
category: 'sensing',
@@ -1897,6 +1922,14 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push('-');
blocks.push(block('reportLanguage'));
blocks.push(block('reportLocation'));
+ blocks.push('-');
+ blocks.push(block('doVibrate'));
+ blocks.push('-');
+ blocks.push(block('reportCompassHeading'));
+ blocks.push('-');
+ blocks.push(block('reportAccelerationX'));
+ blocks.push(block('reportAccelerationY'));
+ blocks.push(block('reportAccelerationZ'));
// for debugging: ///////////////
@@ -4271,6 +4304,8 @@ StageMorph.prototype.init = function (globals) {
this.paletteCache = {}; // not to be serialized (!)
this.lastAnswer = ''; // last user input, do not persist
this.activeSounds = []; // do not persist
+ this.acceleration = null; // do not persist
+ this.compassHeading = null; // do not persist
this.trailsCanvas = null;
this.isThreadSafe = false;
@@ -5007,6 +5042,14 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push('-');
blocks.push(block('reportLanguage'));
blocks.push(block('reportLocation'));
+ blocks.push('-');
+ blocks.push(block('doVibrate'));
+ blocks.push('-');
+ blocks.push(block('reportCompassHeading'));
+ blocks.push('-');
+ blocks.push(block('reportAccelerationX'));
+ blocks.push(block('reportAccelerationY'));
+ blocks.push(block('reportAccelerationZ'));
// for debugging: ///////////////
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..678a69c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "Snap!",
+ "version": "4.0",
+ "main": "snap.html",
+ "window": {
+ "toolbar": false
+ }
+}
diff --git a/snap.html b/snap.html
index 904aba8..8e8e919 100755
--- a/snap.html
+++ b/snap.html
@@ -18,6 +18,10 @@
<script type="text/javascript" src="locale.js"></script>
<script type="text/javascript" src="cloud.js"></script>
<script type="text/javascript" src="sha512.js"></script>
+
+ <!-- packaged mobile app library -->
+ <script type="text/javascript" src="cordova.js"></script>
+
<script type="text/javascript">
var world;
window.onload = function () {
diff --git a/threads.js b/threads.js
index 754d502..3e50686 100644
--- a/threads.js
+++ b/threads.js
@@ -2673,6 +2673,114 @@ Process.prototype.reportDate = function (datefn) {
return result;
};
+Process.prototype.getCompassHeading = function (dest) {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ stage.compassHeading = null;
+ if (navigator.compass) {
+ navigator.compass.getCurrentHeading(
+ function (result) {
+ stage.compassHeading = result;
+ },
+ function () {
+ stage.compassHeading =
+ {'magneticHeading': 0, 'trueHeading': 0,
+ 'headingAccuracy': 0, 'timestamp': 0};
+ }
+ );
+ } else {
+ stage.compassHeading =
+ {'magneticHeading': 0, 'trueHeading': 0,
+ 'headingAccuracy': 0, 'timestamp': 0};
+ }
+};
+
+Process.prototype.reportCompassHeading = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.compassHeading !== null) {
+ return stage.compassHeading.magneticHeading;
+ }
+ } else {
+ this.context.wait = true;
+ this.getCompassHeading();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.getAcceleration = function (dest) {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ stage.acceleration = null;
+ if (navigator.accelerometer) {
+ navigator.accelerometer.getCurrentAcceleration(
+ function (result) {
+ stage.acceleration = result;
+ },
+ function () {
+ stage.acceleration =
+ {'timestamp': 0, 'z': 0, 'y': 0, 'x': 0};
+ }
+ );
+ } else {
+ stage.acceleration =
+ {'timestamp': 0, 'z': 0, 'y': 0, 'x': 0};
+ }
+};
+
+Process.prototype.reportAccelerationX = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.x;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.reportAccelerationY = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.y;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.reportAccelerationZ = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.z;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.doVibrate = function (seconds) {
+ if ("vibrate" in navigator) {
+ window.navigator.vibrate(seconds * 1000);
+ }
+};
+
// Process code mapping
/*