diff --git a/index.html b/index.html
index 76666dc..db22337 100755
--- a/index.html
+++ b/index.html
@@ -6,13 +6,15 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Disconnected
@@ -59,7 +61,7 @@
|
-
+
|
diff --git a/styles.css b/styles.css
index c05cc6e..2e0b38b 100755
--- a/styles.css
+++ b/styles.css
@@ -15,10 +15,6 @@ table.blockly-table {
height: 95%;
width: 100%;
}
-/* non clickable input forms */
-.non-clickable {
- pointer-events: none;
-}
/* spans */
span.has-error {
color: #a94442 !important;
@@ -126,7 +122,7 @@ div#stream {
td#blocklyCodeArea {
display: none;
}
- textarea#blocklyCode {
+ div#blocklyCode {
display: none;
}
}
@@ -140,8 +136,7 @@ div#stream {
width: 40%;
height: 100%;
}
- textarea#blocklyCode {
- border: none;
+ div#blocklyCode {
width: 100%;
height: 100%;
font-size: 1.8em;
diff --git a/sumorobot.js b/sumorobot.js
index 8856bb0..5e8928a 100755
--- a/sumorobot.js
+++ b/sumorobot.js
@@ -6,6 +6,9 @@ var remoteControl = false;
//var robotServer = "10.42.0.1";
var robotServer = "iot.koodur.com";
+/* ace editor object */
+var pythonEditor = null;
+
/* the sumorobot code */
var sumocode = "";
/* the sumorobot object */
@@ -129,6 +132,44 @@ window.onload = function() {
/* load the control panel */
updateControlPanel();
+ /* load ace editor */
+ pythonEditor = ace.edit("blocklyCode");
+ /* set the style */
+ pythonEditor.setTheme("ace/theme/textmate");
+ pythonEditor.session.setMode("ace/mode/python");
+ pythonEditor.session.setTabSize(2);
+ pythonEditor.setReadOnly(true);
+ /* disable scrolling warning */
+ pythonEditor.$blockScrolling = Infinity;
+ /* enable autocomplete */
+ ace.require("ace/ext/language_tools");
+ pythonEditor.setOptions({
+ enableSnippets: true,
+ enableLiveAutocompletion: true,
+ enableBasicAutocompletion: true
+ });
+ /* add autocomplete keywords */
+ pythonEditor.completers.push({
+ getCompletions: function(editor, session, pos, prefix, callback) {
+ callback(null, [
+ {value: "STOP", score: 1000, meta: "sumorobot"},
+ {value: "LEFT", score: 1000, meta: "sumorobot"},
+ {value: "RIGHT", score: 1000, meta: "sumorobot"},
+ {value: "FORWARD", score: 1000, meta: "sumorobot"},
+ {value: "BACKWARD", score: 1000, meta: "sumorobot"},
+ {value: "STATUS", score: 1000, meta: "sumorobot"},
+ {value: "LEFT_LINE", score: 1000, meta: "sumorobot"},
+ {value: "RIGHT_LINE", score: 1000, meta: "sumorobot"},
+ {value: "sumorobot", score: 1000, meta: "sumorobot"},
+ {value: "move", score: 1000, meta: "sumorobot"},
+ {value: "set_led", score: 1000, meta: "sumorobot"},
+ {value: "is_line", score: 1000, meta: "sumorobot"},
+ {value: "set_servo", score: 1000, meta: "sumorobot"},
+ {value: "is_opponent", score: 1000, meta: "sumorobot"}
+ ]);
+ }
+ });
+
/* change the if block to be more cheerful */
Blockly.Msg.LOGIC_HUE = '#44CC00';
Blockly.Constants.Logic.HUE = '#44CC00';
@@ -327,7 +368,7 @@ window.onload = function() {
}
/* retrieve the blocks */
- var xml = Blockly.Xml.textToDom(getLocalStorageItem("sumorobot.currentProgram"));
+ var xml = Blockly.Xml.textToDom(getLocalStorageItem("sumorobot.blockly"));
/* resume the blocks */
Blockly.Xml.domToWorkspace(xml, workspace);
@@ -358,12 +399,13 @@ window.onload = function() {
/* generate code from the used blocks */
sumocode = Blockly.Python.workspaceToCode(workspace);
- /* show the code to the user, filter out block IDs */
- document.getElementById("blocklyCode").value = sumocode.replace(/[,]?[ ]?"(.*?)"/g, "");
+ /* show the code in the ace editor, filter out block IDs */
+ pythonEditor.setValue("\n" + sumocode.replace(/[,]?[ ]?"(.*?)"/g, ""));
+ pythonEditor.clearSelection();
/* save the code to the local storage */
var xml = Blockly.Xml.workspaceToDom(workspace);
- localStorage.setItem("sumorobot.currentProgram", Blockly.Xml.domToText(xml));
+ localStorage.setItem("sumorobot.blockly", Blockly.Xml.domToText(xml));
/* if control_if block is used */
if (controlBlockId != "") {
@@ -431,14 +473,29 @@ window.onload = function() {
$("#blocklyCode").toggle();
break;
case 80: // p
- $("#blocklyCode").blur();
$("#blocklyDiv").toggle();
$("#blocklyArea").toggle();
- $("#blocklyCode").toggleClass("non-clickable");
- var event = {type: Blockly.Events.CHANGE};
- workspace.fireChangeListener(event);
+ /* disable / enable ace editor */
+ pythonEditor.setReadOnly(pythonEnabled);
/* toggle python enabled */
pythonEnabled = !pythonEnabled;
+ if (pythonEnabled) {
+ /* get the saved Python code from local storage or set empty */
+ pythonEditor.setValue(getLocalStorageItem("sumorobot.python") || "");
+ /* add an input listener for the code editor */
+ pythonEditor.on("change", function() {
+ setLocalStorageItem("sumorobot.python", pythonEditor.getValue())
+ });
+ pythonEditor.clearSelection();
+ pythonEditor.focus();
+ } else {
+ /* remove input listener from the code editor */
+ pythonEditor.session.removeAllListeners("change");
+ /* fire CHANGE event in Blockly workspace to change the Python code */
+ var event = {type: Blockly.Events.CHANGE};
+ workspace.fireChangeListener(event);
+ pythonEditor.blur();
+ }
break;
case 82: // r
if (remoteControl)
@@ -483,7 +540,7 @@ window.onload = function() {
/* if we are in Python mode */
if (pythonEnabled) {
/* send the code from the textarea to the SumoRobot */
- sumorobot.send("start:" + $("#blocklyCode").val());
+ sumorobot.send("start:" + pythonEditor.getValue());
/* otherwise when we are in Blockly mode */
} else {
/* send the code from the blocks to the SumoRobot */