mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-24 08:29:48 +00:00
Merge branch 'develop'
This commit is contained in:
commit
540ed6c1f7
138
index.html
138
index.html
@ -91,20 +91,6 @@
|
|||||||
<block type="logic_null"></block>
|
<block type="logic_null"></block>
|
||||||
<block type="logic_ternary"></block>
|
<block type="logic_ternary"></block>
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
<!-- <category name="論理">
|
|
||||||
<block type="controls_if"></block>
|
|
||||||
<block type="logic_compare">
|
|
||||||
<field name="OP">EQ</field>
|
|
||||||
</block>
|
|
||||||
<block type="logic_operation">
|
|
||||||
<field name="OP">AND</field>
|
|
||||||
</block>
|
|
||||||
<block type="logic_negate"></block>
|
|
||||||
<block type="logic_boolean">
|
|
||||||
<field name="BOOL">TRUE</field>
|
|
||||||
</block>
|
|
||||||
</category> -->
|
|
||||||
<category name="ループ" css-icon="customIcon fas fa-redo-alt" categorystyle="loop_category">
|
<category name="ループ" css-icon="customIcon fas fa-redo-alt" categorystyle="loop_category">
|
||||||
<block type="controls_repeat_ext">
|
<block type="controls_repeat_ext">
|
||||||
<value name="TIMES">
|
<value name="TIMES">
|
||||||
@ -312,14 +298,14 @@
|
|||||||
<block type="ugj_gpio_setoutput">
|
<block type="ugj_gpio_setoutput">
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">20</field>
|
<field name="NUM">5</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_gpio_write">
|
<block type="ugj_gpio_write">
|
||||||
<value name="ugj_gpio_num">
|
<value name="ugj_gpio_num">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">20</field>
|
<field name="NUM">5</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<value name="ugj_gpio_value">
|
<value name="ugj_gpio_value">
|
||||||
@ -332,14 +318,14 @@
|
|||||||
<field name="updown">pi.PUD_DOWN</field>
|
<field name="updown">pi.PUD_DOWN</field>
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">4</field>
|
<field name="NUM">6</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_gpio_read">
|
<block type="ugj_gpio_read">
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">4</field>
|
<field name="NUM">6</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
@ -348,7 +334,7 @@
|
|||||||
<field name="pwmfreq">50</field>
|
<field name="pwmfreq">50</field>
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">20</field>
|
<field name="NUM">5</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
@ -360,14 +346,14 @@
|
|||||||
</value>
|
</value>
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">20</field>
|
<field name="NUM">5</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_gpio_servo">
|
<block type="ugj_gpio_servo">
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
<shadow type="math_number">
|
<shadow type="math_number">
|
||||||
<field name="NUM">14</field>
|
<field name="NUM">12</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<value name="pulsewidth">
|
<value name="pulsewidth">
|
||||||
@ -436,16 +422,6 @@
|
|||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<label text="センサー" web-line="4.0" web-line-width="200"></label>
|
<label text="センサー" web-line="4.0" web-line-width="200"></label>
|
||||||
<block type="ugj_dht">
|
|
||||||
<field name="type">11</field>
|
|
||||||
<field name="temperature" id="b4bG/!B(8TP1=sB,OJjw" variabletype="">気温</field>
|
|
||||||
<field name="humidity" id="yh}5iLSHLiaNg8BpL|zd" variabletype="">湿度</field>
|
|
||||||
<value name="gpio">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">4</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
<label text="Extra" web-line="4.0" web-line-width="200"></label>
|
<label text="Extra" web-line="4.0" web-line-width="200"></label>
|
||||||
<block type="ugj_gpio_sleep">
|
<block type="ugj_gpio_sleep">
|
||||||
<field name="sec">1</field>
|
<field name="sec">1</field>
|
||||||
@ -564,37 +540,11 @@
|
|||||||
<block type="ugj_sound_play">
|
<block type="ugj_sound_play">
|
||||||
<field name="sound">meow</field>
|
<field name="sound">meow</field>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_multimedia_webspeech_recognition">
|
<block type="ugj_multimedia_webspeech_recognition" disabled="true">
|
||||||
<field name="transcript" id="=3;~1sjv_R.pRhO)=wQY" variabletype="">ことば</field>
|
<field name="transcript" id="=3;~1sjv_R.pRhO)=wQY" variabletype="">ことば</field>
|
||||||
<field name="continuous">once</field>
|
<field name="continuous">once</field>
|
||||||
<field name="interim">TRUE</field>
|
<field name="interim">TRUE</field>
|
||||||
</block>
|
</block>
|
||||||
<!-- <block type="ugj_multimedia_cloudspeech_recognition">
|
|
||||||
<field name="transcript" id="=3;~1sjv_R.pRhO)=wQY" variabletype="">ことば</field>
|
|
||||||
<field name="continuous">once</field>
|
|
||||||
<field name="interim">TRUE</field>
|
|
||||||
</block> -->
|
|
||||||
<!-- <label text="顔認識" web-line="4.0" web-line-width="200"></label>
|
|
||||||
<block type="ugj_library_load">
|
|
||||||
<value name="lib">
|
|
||||||
<shadow type="ugj_face_library"></block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
<block type="ugj_face_init"></block>
|
|
||||||
<block type="ugj_face_display"></block>
|
|
||||||
<block type="ugj_face_detect">
|
|
||||||
<field name="x" id="TF-ziC[]OAJ9]r}YjUQg" variabletype="">左</field>
|
|
||||||
<field name="y" id="]G:_%S*1v4!9_+yx532d" variabletype="">上</field>
|
|
||||||
<field name="w" id="wP$LdeXDCiWzrI!/9R)G" variabletype="">幅</field>
|
|
||||||
<field name="h" id="8+E.-dP-Omt}v2~DCC]M" variabletype="">高さ</field>
|
|
||||||
</block>
|
|
||||||
<block type="ugj_face_drawrect">
|
|
||||||
<value name="color">
|
|
||||||
<shadow type="colour_picker">
|
|
||||||
<field name="COLOUR">#ff0000</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block> -->
|
|
||||||
<label text="画像認識" web-line="4.0" web-line-width="200"></label>
|
<label text="画像認識" web-line="4.0" web-line-width="200"></label>
|
||||||
<block type="ugj_library_load">
|
<block type="ugj_library_load">
|
||||||
<value name="lib">
|
<value name="lib">
|
||||||
@ -658,7 +608,7 @@
|
|||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<label text="ウェブチャット" web-line="4.0" web-line-width="200"></label>
|
<label text="ウェブチャット" web-line="4.0" web-line-width="200"></label>
|
||||||
<block type="ugj_library_load" disabled="true">
|
<block type="ugj_library_load">
|
||||||
<value name="lib">
|
<value name="lib">
|
||||||
<shadow type="ugj_library_skyway"></shadow>
|
<shadow type="ugj_library_skyway"></shadow>
|
||||||
</value>
|
</value>
|
||||||
@ -702,11 +652,6 @@
|
|||||||
<field name="TEXT">お名前は?</field>
|
<field name="TEXT">お名前は?</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<value name="sec">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">5</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_blackboard_show"></block>
|
<block type="ugj_blackboard_show"></block>
|
||||||
<block type="ugj_blackboard_write">
|
<block type="ugj_blackboard_write">
|
||||||
@ -808,9 +753,6 @@
|
|||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_child_facepy">
|
|
||||||
<field name="win"> </field>
|
|
||||||
</block>
|
|
||||||
<block type="ugj_child_gesture"></block>
|
<block type="ugj_child_gesture"></block>
|
||||||
<block type="ugj_child_irrecord">
|
<block type="ugj_child_irrecord">
|
||||||
<value name="gpio">
|
<value name="gpio">
|
||||||
@ -902,12 +844,68 @@
|
|||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="ugj_child_debug">
|
|
||||||
<value name="cmd">
|
|
||||||
</block>
|
|
||||||
<label text="_" web-line="4.0" web-line-width="200"></label>
|
<label text="_" web-line="4.0" web-line-width="200"></label>
|
||||||
</category>
|
</category>
|
||||||
<category name="スニペット" css-icon="customIcon fas fa-egg" categorystyle="snippets_category">
|
<category name="スニペット" css-icon="customIcon fas fa-egg" categorystyle="snippets_category">
|
||||||
|
<label text="入出力" web-line="4.0" web-line-width="200"></label>
|
||||||
|
<block type="ugj_event_answer">
|
||||||
|
<field name="answer" id="_m@Uj#wHnIuGJNVwdUR+" variabletype="">答え</field>
|
||||||
|
<value name="question">
|
||||||
|
<shadow type="text">
|
||||||
|
<field name="TEXT">お名前は?</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<statement name="do">
|
||||||
|
<block type="ugj_canvas_say">
|
||||||
|
<value name="say">
|
||||||
|
<shadow type="text">
|
||||||
|
<field name="TEXT">・・・</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<value name="sec">
|
||||||
|
<shadow type="math_number">
|
||||||
|
<field name="NUM">2</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<next>
|
||||||
|
<block type="ugj_sleep">
|
||||||
|
<value name="sec">
|
||||||
|
<shadow type="math_number">
|
||||||
|
<field name="NUM">2</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<next>
|
||||||
|
<block type="ugj_canvas_say">
|
||||||
|
<value name="say">
|
||||||
|
<block type="text_join">
|
||||||
|
<mutation items="2"></mutation>
|
||||||
|
<value name="ADD0">
|
||||||
|
<block type="variables_get">
|
||||||
|
<field name="VAR" id="_m@Uj#wHnIuGJNVwdUR+">答え</field>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
<value name="ADD1">
|
||||||
|
<block type="text">
|
||||||
|
<field name="TEXT">たん</field>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
</value>
|
||||||
|
<value name="sec">
|
||||||
|
<shadow type="math_number">
|
||||||
|
<field name="NUM">2</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
</next>
|
||||||
|
</block>
|
||||||
|
</next>
|
||||||
|
</block>
|
||||||
|
</statement>
|
||||||
|
|
||||||
|
</block>
|
||||||
|
|
||||||
</category>
|
</category>
|
||||||
</xml>
|
</xml>
|
||||||
|
|
||||||
|
18
package-lock.json
generated
18
package-lock.json
generated
@ -775,9 +775,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "11.2.3",
|
"version": "11.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-11.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-11.3.0.tgz",
|
||||||
"integrity": "sha512-6yxOc42nDAptHKNlUG/vcOh2GI9x2fqp2nQbZO0/3sz2CrwsJkwR3i3oMN9XhVJaqI7GK1vSCJz0verOkWlXcQ==",
|
"integrity": "sha512-MhdS0gok3wZBTscLBbYrOhLaQybCSAfkupazbK1dMP5c+84eVMxJE/QGohiWQkzs0tVFIJsAHyN19YKPbelNrQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.0.1",
|
"@electron/get": "^1.0.1",
|
||||||
@ -1249,9 +1249,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globalthis": {
|
"globalthis": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz",
|
||||||
"integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==",
|
"integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1499,9 +1499,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.20",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/ocogeclub/ocoge#readme",
|
"homepage": "https://github.com/ocogeclub/ocoge#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "11.2.3",
|
"electron": "11.3.0",
|
||||||
"electron-rebuild": "^2.3.4"
|
"electron-rebuild": "^2.3.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// ローカルプロパティ
|
// ローカルプロパティ
|
||||||
// Hard Coding!!!
|
// Hard Coding!!!
|
||||||
const appName = 'ocoge';
|
const appName = 'ocoge';
|
||||||
const defpath = '/home/pi/Documents/ocoge/';
|
const defpath = '/home/pi/Documents/ocoge_docs/';
|
||||||
const mascotDefPath = '/home/pi/Applications/ocoge/img/';
|
const mascotDefPath = '/home/pi/Applications/ocoge/img/';
|
||||||
// Require
|
// Require
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@ -18,7 +18,7 @@ const clipboard = require('electron').clipboard;
|
|||||||
|
|
||||||
var saveFilepath = null;
|
var saveFilepath = null;
|
||||||
var wsChanged = false;
|
var wsChanged = false;
|
||||||
var mascotFilePath = './img/cogechee.png';
|
var mascotFilePath = mascotDefPath + 'cogechee.png';
|
||||||
|
|
||||||
// 0で数値の桁合わせ
|
// 0で数値の桁合わせ
|
||||||
// NUM=値 LEN=桁数
|
// NUM=値 LEN=桁数
|
||||||
@ -26,10 +26,10 @@ const zeroPadding = (NUM, LEN) => (Array(LEN).join('0') + NUM).slice(-LEN);
|
|||||||
|
|
||||||
// 現在の日付時刻から workspace フォルダ内のユニークなファイルパスを作成
|
// 現在の日付時刻から workspace フォルダ内のユニークなファイルパスを作成
|
||||||
const getUniqueFilepath = () => {
|
const getUniqueFilepath = () => {
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
let filename = today.getFullYear() + '-' + zeroPadding((today.getMonth() + 1), 2) + '-' + zeroPadding(today.getDate(), 2) + '-' + zeroPadding(today.getHours(), 2) + '-' + zeroPadding(today.getMinutes(), 2) + '-' + zeroPadding(today.getSeconds(), 2);
|
let filename = today.getFullYear() + '-' + zeroPadding((today.getMonth() + 1), 2) + '-' + zeroPadding(today.getDate(), 2) + '-' + zeroPadding(today.getHours(), 2) + '-' + zeroPadding(today.getMinutes(), 2) + '-' + zeroPadding(today.getSeconds(), 2);
|
||||||
let filepath = path.join(defpath, filename);
|
let filepath = path.join(defpath, filename);
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// クリップボードにコピー
|
// クリップボードにコピー
|
||||||
@ -37,7 +37,7 @@ exports.copyText = text => clipboard.writeText(text);
|
|||||||
|
|
||||||
// リンクを外部ブラウザで開く
|
// リンクを外部ブラウザで開く
|
||||||
exports.openURL = (url) => {
|
exports.openURL = (url) => {
|
||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// タイトルバーにファイル名を表示
|
// タイトルバーにファイル名を表示
|
||||||
@ -50,23 +50,23 @@ exports.openURL = (url) => {
|
|||||||
// saveFilepath を更新
|
// saveFilepath を更新
|
||||||
// ウィンドウタイトルバーテキストを変更
|
// ウィンドウタイトルバーテキストを変更
|
||||||
const setSaveFilepath = filepath => {
|
const setSaveFilepath = filepath => {
|
||||||
let title;
|
let title;
|
||||||
saveFilepath = filepath;
|
saveFilepath = filepath;
|
||||||
// if (filepath) title = filepath + ' - ' + appName;
|
// if (filepath) title = filepath + ' - ' + appName;
|
||||||
// else title = appName;
|
// else title = appName;
|
||||||
// mainWin.setTitle(title);
|
// mainWin.setTitle(title);
|
||||||
this.setWsChanged(false);
|
this.setWsChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースが変更された・保存された
|
// ワークスペースが変更された・保存された
|
||||||
// ウィンドウタイトルバーテキストを変更
|
// ウィンドウタイトルバーテキストを変更
|
||||||
exports.setWsChanged = changed => {
|
exports.setWsChanged = changed => {
|
||||||
let title;
|
let title;
|
||||||
wsChanged = changed;
|
wsChanged = changed;
|
||||||
if (saveFilepath) title = saveFilepath + ' - ' + appName;
|
if (saveFilepath) title = saveFilepath + ' - ' + appName;
|
||||||
else title = appName;
|
else title = appName;
|
||||||
if (changed) title = '*' + title;
|
if (changed) title = '*' + title;
|
||||||
mainWin.setTitle(title);
|
mainWin.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存ファイルプロパティを更新
|
// 保存ファイルプロパティを更新
|
||||||
@ -74,159 +74,161 @@ exports.newFile = () => setSaveFilepath(null);
|
|||||||
|
|
||||||
// ワークスペースファイル読み込みの一連の動作のラッパ
|
// ワークスペースファイル読み込みの一連の動作のラッパ
|
||||||
exports.loadWsFile = () => {
|
exports.loadWsFile = () => {
|
||||||
let filepath = openFile('xml', defpath);
|
let filepath = openFile('xml', defpath);
|
||||||
if (filepath.length > 0) {
|
if (filepath.length > 0) {
|
||||||
if (saveFilepath === null) {
|
if (saveFilepath === null) {
|
||||||
setSaveFilepath(filepath);
|
setSaveFilepath(filepath);
|
||||||
} //読み込みに失敗してもsaveFilepathが更新されてしまうのはちょっと具合が悪いかも
|
} //読み込みに失敗してもsaveFilepathが更新されてしまうのはちょっと具合が悪いかも
|
||||||
return readFromFile(filepath);
|
return readFromFile(filepath);
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// その他ファイル読み込みの一連の動作のラッパ
|
// その他ファイル読み込みの一連の動作のラッパ
|
||||||
exports.loadFile = ext => {
|
exports.loadFile = ext => {
|
||||||
let filepath = openFile(ext, defpath);
|
let filepath = openFile(ext, defpath);
|
||||||
if (filepath.length > 0) {
|
if (filepath.length > 0) {
|
||||||
return readFromFile(filepath);
|
return readFromFile(filepath);
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.selectMascotFile = () => {
|
exports.selectMascotFile = () => {
|
||||||
return openFile('png', mascotDefPath);
|
return openFile('png', mascotDefPath);
|
||||||
}
|
}
|
||||||
// オープンファイルダイアログ
|
// オープンファイルダイアログ
|
||||||
const openFile = (ext, dpath) => {
|
const openFile = (ext, dpath) => {
|
||||||
let filter;
|
let filter;
|
||||||
if (ext == 'xml') {
|
if (ext == 'xml') {
|
||||||
filter = { name: 'XML - Extensible Markup Language', extensions: ['xml'] };
|
filter = { name: 'XML - Extensible Markup Language', extensions: ['xml'] };
|
||||||
} else if (ext == 'js') {
|
} else if (ext == 'js') {
|
||||||
filter = { name: 'JS - JavaScript', extensions: ['js'] };
|
filter = { name: 'JS - JavaScript', extensions: ['js'] };
|
||||||
} else if (ext == 'png') {
|
} else if (ext == 'png') {
|
||||||
filter = { name: 'PNG - Portable Network Graphics', extensions: ['png'] };
|
filter = { name: 'PNG - Portable Network Graphics', extensions: ['png'] };
|
||||||
} else {
|
} else {
|
||||||
filter = { name: 'text file', extensions: ['txt'] };
|
filter = { name: 'text file', extensions: ['txt'] };
|
||||||
}
|
}
|
||||||
let filepaths = dialog.showOpenDialogSync(mainWin, {
|
let filepaths = dialog.showOpenDialogSync(mainWin, {
|
||||||
properties: ['openFile'],
|
properties: ['openFile'],
|
||||||
title: 'Select a file',
|
title: 'Select a file',
|
||||||
defaultPath: dpath,
|
defaultPath: dpath,
|
||||||
filters: [
|
filters: [
|
||||||
filter
|
filter
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
if (filepaths == undefined) {
|
if (filepaths == undefined) {
|
||||||
return '';
|
return '';
|
||||||
} else {
|
} else {
|
||||||
return filepaths[0];
|
return filepaths[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ファイルからデータを読み込み
|
// ファイルからデータを読み込み
|
||||||
const readFromFile = filepath => {
|
const readFromFile = filepath => {
|
||||||
let data = '';
|
let data = '';
|
||||||
try {
|
try {
|
||||||
data = fs.readFileSync(filepath, 'utf-8');
|
data = fs.readFileSync(filepath, 'utf-8');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
// テキストファイル読み込み: 外部スクリプト動的読み込みに使用
|
// テキストファイル読み込み: 外部スクリプト動的読み込みに使用
|
||||||
exports.readTextFile = filepath => {
|
exports.readTextFile = filepath => {
|
||||||
return readFromFile(filepath);
|
return readFromFile(filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースファイル保存の一連の動作のラッパ
|
// ワークスペースファイル保存の一連の動作のラッパ
|
||||||
exports.saveWsFile = data => {
|
exports.saveWsFile = data => {
|
||||||
if (saveFilepath === null) {
|
if (saveFilepath === null) {
|
||||||
let filepath = selectSaveFile('xml');
|
let filepath = selectSaveFile('xml');
|
||||||
if (filepath === undefined) { //キャンセル
|
if (filepath === undefined) { //キャンセル
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
setSaveFilepath(filepath);
|
setSaveFilepath(filepath);
|
||||||
} //これも保存が成功したら変更するようにすべきかしら
|
} //これも保存が成功したら変更するようにすべきかしら
|
||||||
} else this.setWsChanged(false);
|
} else this.setWsChanged(false);
|
||||||
return writeToFile(saveFilepath, data);
|
return writeToFile(saveFilepath, data);
|
||||||
}
|
}
|
||||||
// その他ファイル保存の一連の動作のラッパ
|
// その他ファイル保存の一連の動作のラッパ
|
||||||
exports.saveFile = (data, ext) => {
|
exports.saveFile = (data, ext) => {
|
||||||
let filepath = selectSaveFile(ext);
|
let filepath = selectSaveFile(ext);
|
||||||
if (filepath === undefined) { //キャンセル
|
if (filepath === undefined) { //キャンセル
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return writeToFile(filepath, data);
|
return writeToFile(filepath, data);
|
||||||
}
|
}
|
||||||
// ファイル保存ダイアログ
|
// ファイル保存ダイアログ
|
||||||
const selectSaveFile = ext => {
|
const selectSaveFile = ext => {
|
||||||
let filter;
|
let filter;
|
||||||
let defName;
|
let defName;
|
||||||
if (ext == 'xml') {
|
if (ext == 'xml') {
|
||||||
filter = { name: 'xml file', extensions: ['xml'] };
|
filter = { name: 'xml file', extensions: ['xml'] };
|
||||||
defName = getUniqueFilepath() + '.xml';
|
defName = getUniqueFilepath() + '.xml';
|
||||||
} else if (ext == 'js') {
|
} else if (ext == 'js') {
|
||||||
filter = { name: 'javascript file', extensions: ['js'] };
|
filter = { name: 'javascript file', extensions: ['js'] };
|
||||||
// ワークスペース保存名がある場合、それをベースにファイル名の候補を決める
|
// ワークスペース保存名がある場合、それをベースにファイル名の候補を決める
|
||||||
if (saveFilepath === null) {
|
if (saveFilepath === null) {
|
||||||
defName = getUniqueFilepath() + '.js';
|
defName = getUniqueFilepath() + '.js';
|
||||||
} else {
|
|
||||||
let dirname = path.dirname(saveFilepath);
|
|
||||||
let basename = path.basename(saveFilepath, '.xml');
|
|
||||||
defName = path.join(dirname, basename) + '.js';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
filter = { name: 'text file', extensions: ['txt'] };
|
let dirname = path.dirname(saveFilepath);
|
||||||
|
let basename = path.basename(saveFilepath, '.xml');
|
||||||
|
defName = path.join(dirname, basename) + '.js';
|
||||||
}
|
}
|
||||||
let filename = dialog.showSaveDialogSync(mainWin, {
|
} else {
|
||||||
title: '保存先を決定してください',
|
filter = { name: 'text file', extensions: ['txt'] };
|
||||||
defaultPath: defName,
|
}
|
||||||
filters: [filter]
|
let filename = dialog.showSaveDialogSync(mainWin, {
|
||||||
});
|
title: '保存先を決定してください',
|
||||||
return filename;
|
defaultPath: defName,
|
||||||
|
filters: [filter]
|
||||||
|
});
|
||||||
|
return filename;
|
||||||
}
|
}
|
||||||
// ファイル書き込み
|
// ファイル書き込み
|
||||||
const writeToFile = (filepath, data) => {
|
const writeToFile = (filepath, data) => {
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(filepath, data);
|
fs.writeFileSync(filepath, data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 子プロセス関連
|
// 子プロセス関連
|
||||||
let children = [];
|
let children = [];
|
||||||
// 新しい子プロセスを作成し、配列に保存
|
// 新しい子プロセスを作成し、配列に保存
|
||||||
exports.addChild = (child) => {
|
exports.addChild = (child) => {
|
||||||
children.push(child);
|
children.push(child);
|
||||||
}
|
}
|
||||||
// 全ての子プロセスを殺し、配列をクリア
|
// 全ての子プロセスを殺し、配列をクリア
|
||||||
exports.killAllChildren = () => {
|
exports.killAllChildren = () => {
|
||||||
children.forEach(function( child ) {
|
children.forEach(function (child) {
|
||||||
child.kill();
|
child.kill();
|
||||||
});
|
});
|
||||||
children = [];
|
children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
||||||
exports.savePrefsToLS = () => {
|
exports.savePrefsToLS = () => {
|
||||||
let wc = '0';
|
let wc = '0';
|
||||||
if (wsChanged) wc = '1';
|
if (wsChanged) wc = '1';
|
||||||
let o = { 'saveFilepath': saveFilepath, 'wsChanged': wc, 'mascotFilePath': mascotFilePath };
|
let o = { 'saveFilepath': saveFilepath, 'wsChanged': wc, 'mascotFilePath': mascotFilePath };
|
||||||
let s = JSON.stringify(o);
|
let s = JSON.stringify(o);
|
||||||
localStorage.setItem("abrage.json", s);
|
localStorage.setItem("ocoge.json", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージからロード
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージからロード
|
||||||
exports.loadPrefsFromLS = () => {
|
exports.loadPrefsFromLS = () => {
|
||||||
let s = localStorage.getItem("abrage.json");
|
let s = localStorage.getItem("ocoge.json");
|
||||||
|
if (s !== null) {
|
||||||
let o = JSON.parse(s);
|
let o = JSON.parse(s);
|
||||||
setSaveFilepath(o.saveFilepath);
|
setSaveFilepath(o.saveFilepath);
|
||||||
if (o.wsChanged == '0') this.setWsChanged(false);
|
if (o.wsChanged == '0') this.setWsChanged(false);
|
||||||
else this.setWsChanged(true);
|
else this.setWsChanged(true);
|
||||||
if (o.mascotFilePath) this.setMascotFilePath(o.mascotFilePath);
|
if (o.mascotFilePath) this.setMascotFilePath(o.mascotFilePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// マスコット画像パスをプロパティにセット
|
// マスコット画像パスをプロパティにセット
|
||||||
@ -236,5 +238,5 @@ exports.getMascotFilePath = () => mascotFilePath;
|
|||||||
|
|
||||||
// ファイル名にアプリケーションのドキュメントルートまでのパスをつけて返す
|
// ファイル名にアプリケーションのドキュメントルートまでのパスをつけて返す
|
||||||
exports.getDocPath = filename => {
|
exports.getDocPath = filename => {
|
||||||
return path.join(appDocRoot, filename);
|
return path.join(appDocRoot, filename);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/** Hard Coding!!! */
|
/** Hard Coding!!! */
|
||||||
const appDocRoot = '/home/pi/Documents/ocoge/'
|
const appDocRoot = '/home/pi/Documents/ocoge_docs/'
|
||||||
|
|
||||||
/** Fix Basic Blocks ****************************************************************************************/
|
/** Fix Basic Blocks ****************************************************************************************/
|
||||||
Blockly.Blocks['ugj_control_for'] = {
|
Blockly.Blocks['ugj_control_for'] = {
|
||||||
@ -24,36 +24,10 @@ Blockly.Blocks['ugj_control_for'] = {
|
|||||||
this.setPreviousStatement(true, null);
|
this.setPreviousStatement(true, null);
|
||||||
this.setNextStatement(true, null);
|
this.setNextStatement(true, null);
|
||||||
this.setColour(Blockly.Msg.LOOPS_HUE);
|
this.setColour(Blockly.Msg.LOOPS_HUE);
|
||||||
this.setTooltip("");
|
this.setTooltip("インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。");
|
||||||
this.setHelpUrl("");
|
this.setHelpUrl("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Blockly.Blocks['ugj_controls_for'] = {
|
|
||||||
// init: function () {
|
|
||||||
// this.appendDummyInput()
|
|
||||||
// .appendField(new Blockly.FieldVariable("番号"), "index");
|
|
||||||
// this.appendValueInput("from")
|
|
||||||
// .setCheck("Number")
|
|
||||||
// .appendField("を");
|
|
||||||
// this.appendValueInput("to")
|
|
||||||
// .setCheck("Number")
|
|
||||||
// .appendField("から");
|
|
||||||
// this.appendValueInput("by")
|
|
||||||
// .setCheck("Number")
|
|
||||||
// .appendField("まで");
|
|
||||||
// this.appendDummyInput()
|
|
||||||
// .appendField("ずつ増やしながら");
|
|
||||||
// this.appendStatementInput("do")
|
|
||||||
// .setCheck(null);
|
|
||||||
// this.setInputsInline(true);
|
|
||||||
// this.setPreviousStatement(true, null);
|
|
||||||
// this.setNextStatement(true, null);
|
|
||||||
// this.setColour(Blockly.Msg.LOOPS_HUE);
|
|
||||||
// this.setTooltip("インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。");
|
|
||||||
// this.setHelpUrl("");
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
Blockly.JavaScript['ugj_control_for'] = function (block) {
|
Blockly.JavaScript['ugj_control_for'] = function (block) {
|
||||||
var variable_index = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
var variable_index = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||||||
var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
@ -72,20 +46,6 @@ Blockly.JavaScript['ugj_control_for'] = function (block) {
|
|||||||
].join('\n');
|
].join('\n');
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
// Blockly.JavaScript['ugj_controls_for'] = function (block) {
|
|
||||||
// var variable_index = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
|
||||||
// var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
// var value_to = Blockly.JavaScript.valueToCode(block, 'to', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
// var value_by = Blockly.JavaScript.valueToCode(block, 'by', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
// var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
|
||||||
// var code = [
|
|
||||||
// `for (${variable_index} = ${value_from}; ${variable_index} <= ${value_to}; ${variable_index} += ${value_by}) {`,
|
|
||||||
// statements_do,
|
|
||||||
// `}`,
|
|
||||||
// ''
|
|
||||||
// ].join('\n');
|
|
||||||
// return code;
|
|
||||||
// };
|
|
||||||
|
|
||||||
Blockly.Blocks['ugj_controls_forEach'] = {
|
Blockly.Blocks['ugj_controls_forEach'] = {
|
||||||
init: function () {
|
init: function () {
|
||||||
@ -146,16 +106,18 @@ Blockly.JavaScript['ugj_hextodec'] = function (block) {
|
|||||||
/************* */
|
/************* */
|
||||||
/** GPIO Start */
|
/** GPIO Start */
|
||||||
/************* */
|
/************* */
|
||||||
|
var ugjGpioStart = {
|
||||||
|
"type": "ugj_gpio_start",
|
||||||
|
"message0": "%{BKY_GPIO_START_TITLE}",
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_GPIO_START_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "gpio_blocks"
|
||||||
|
};
|
||||||
Blockly.Blocks['ugj_gpio_start'] = {
|
Blockly.Blocks['ugj_gpio_start'] = {
|
||||||
init: function () {
|
init: function () {
|
||||||
this.appendDummyInput()
|
this.jsonInit(ugjGpioStart);
|
||||||
.appendField("GPIO を使えるようにする");
|
|
||||||
this.setInputsInline(true);
|
|
||||||
this.setPreviousStatement(true, null);
|
|
||||||
this.setNextStatement(true, null);
|
|
||||||
this.setStyle('gpio_blocks')
|
|
||||||
this.setTooltip("GPIOを初期化して接続します。");
|
|
||||||
this.setHelpUrl("");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Blockly.JavaScript['ugj_gpio_start'] = function (block) {
|
Blockly.JavaScript['ugj_gpio_start'] = function (block) {
|
||||||
@ -187,16 +149,40 @@ Blockly.JavaScript['ugj_gpio_start_remote'] = function (block) {
|
|||||||
/************ */
|
/************ */
|
||||||
/** GPIO Stop */
|
/** GPIO Stop */
|
||||||
/************ */
|
/************ */
|
||||||
|
// var ugjGpioStart = {
|
||||||
|
// "type": "ugj_gpio_start",
|
||||||
|
// "message0": "%{BKY_GPIO_START_TITLE}",
|
||||||
|
// "previousStatement": null,
|
||||||
|
// "nextStatement": null,
|
||||||
|
// "tooltip": "%{BKY_GPIO_START_TOOLTIP}",
|
||||||
|
// "helpUrl": "",
|
||||||
|
// "style": "gpio_blocks"
|
||||||
|
// };
|
||||||
|
// Blockly.Blocks['ugj_gpio_start'] = {
|
||||||
|
// init: function () {
|
||||||
|
// this.jsonInit(ugjGpioStart);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
var ugjGpioStop = {
|
||||||
|
"type": "ugj_gpio_stop",
|
||||||
|
"message0": "%{BKY_GPIO_STOP_TITLE}",
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_GPIO_STOP_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "gpio_blocks"
|
||||||
|
};
|
||||||
Blockly.Blocks['ugj_gpio_stop'] = {
|
Blockly.Blocks['ugj_gpio_stop'] = {
|
||||||
init: function () {
|
init: function () {
|
||||||
this.appendDummyInput()
|
this.jsonInit(ugjGpioStop);
|
||||||
.appendField("GPIO の後片付けをする");
|
// this.appendDummyInput()
|
||||||
this.setInputsInline(true);
|
// .appendField("GPIO の後片付けをする");
|
||||||
this.setPreviousStatement(true, null);
|
// this.setInputsInline(true);
|
||||||
this.setNextStatement(true, null);
|
// this.setPreviousStatement(true, null);
|
||||||
this.setStyle('gpio_blocks')
|
// this.setNextStatement(true, null);
|
||||||
this.setTooltip("GPIOとの接続を終了します。");
|
// this.setStyle('gpio_blocks')
|
||||||
this.setHelpUrl("");
|
// this.setTooltip("GPIOとの接続を終了します。");
|
||||||
|
// this.setHelpUrl("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Blockly.JavaScript['ugj_gpio_stop'] = function (block) {
|
Blockly.JavaScript['ugj_gpio_stop'] = function (block) {
|
||||||
@ -584,45 +570,6 @@ Blockly.JavaScript['ugj_gpio_i2creadbyte'] = function (block) {
|
|||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********** */
|
|
||||||
/** DHT11/22 */
|
|
||||||
/*********** */
|
|
||||||
Blockly.Blocks['ugj_dht'] = {
|
|
||||||
init: function () {
|
|
||||||
this.appendValueInput("gpio")
|
|
||||||
.setCheck("Number")
|
|
||||||
.appendField("GPIO");
|
|
||||||
this.appendDummyInput()
|
|
||||||
.appendField("の温湿度センサー DHT")
|
|
||||||
.appendField(new Blockly.FieldDropdown([["11", "11"], ["22", "22"]]), "type")
|
|
||||||
.appendField("から")
|
|
||||||
.appendField(new Blockly.FieldVariable("気温"), "temperature")
|
|
||||||
.appendField(new Blockly.FieldVariable("湿度"), "humidity")
|
|
||||||
.appendField("を取得");
|
|
||||||
this.setInputsInline(true);
|
|
||||||
this.setPreviousStatement(true, null);
|
|
||||||
this.setNextStatement(true, null);
|
|
||||||
this.setStyle('gpio_blocks')
|
|
||||||
this.setTooltip("温湿度センサー DHT11/DHT22 を使用して気温と湿度を読み取ります。");
|
|
||||||
this.setHelpUrl("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_dht'] = function (block) {
|
|
||||||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var dropdown_type = block.getFieldValue('type');
|
|
||||||
var variable_temperature = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('temperature'), Blockly.Variables.NAME_TYPE);
|
|
||||||
var variable_humidity = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('humidity'), Blockly.Variables.NAME_TYPE);
|
|
||||||
let fix = dropdown_type / 11 - 1;
|
|
||||||
var code = [
|
|
||||||
`try {`,
|
|
||||||
`let res = await dht.read(${dropdown_type}, ${value_gpio});`,
|
|
||||||
`${variable_temperature} = res.temperature.toFixed(${fix});`,
|
|
||||||
`${variable_humidity} = res.humidity.toFixed(${fix});`,
|
|
||||||
`} catch (err) {console.error("Failed to read sensor data:", err);}`,
|
|
||||||
''
|
|
||||||
].join('\n');
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1223,109 +1170,6 @@ Blockly.JavaScript['ugj_sound_play'] = function (block) {
|
|||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************** */
|
|
||||||
/** Cloud Speech Recognization */
|
|
||||||
/***************************** */
|
|
||||||
Blockly.Blocks['ugj_multimedia_cloudspeech_recognition'] = {
|
|
||||||
init: function () {
|
|
||||||
this.appendDummyInput()
|
|
||||||
.appendField("音声認識で")
|
|
||||||
.appendField(new Blockly.FieldVariable("ことば"), "transcript")
|
|
||||||
.appendField("を取得する:")
|
|
||||||
.appendField(new Blockly.FieldDropdown([["一回のみ", "once"], ["継続", "continue"]]), "continuous")
|
|
||||||
.appendField(new Blockly.FieldCheckbox("TRUE"), "interim")
|
|
||||||
.appendField("未確定も取得");
|
|
||||||
this.appendStatementInput("isFinal_do")
|
|
||||||
.setCheck(null)
|
|
||||||
.appendField("確定したら");
|
|
||||||
this.appendStatementInput("isInterim_do")
|
|
||||||
.setCheck(null)
|
|
||||||
.appendField("未確定なら");
|
|
||||||
this.appendStatementInput("onStart_do")
|
|
||||||
.setCheck(null)
|
|
||||||
.appendField("開始したら");
|
|
||||||
this.appendStatementInput("onError_do")
|
|
||||||
.setCheck(null)
|
|
||||||
.appendField("停止したら");
|
|
||||||
this.setInputsInline(true);
|
|
||||||
this.setPreviousStatement(true);
|
|
||||||
this.setStyle('multimedia_blocks')
|
|
||||||
this.setTooltip("Google Cloud Speech API による音声認識を行います。言葉を検知したらステートメントが実行されます。認識途中の暫定結果を取得することもできます。");
|
|
||||||
this.setHelpUrl("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_multimedia_cloudspeech_recognition'] = function (block) {
|
|
||||||
var variable_transcript = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('transcript'), Blockly.Variables.NAME_TYPE);
|
|
||||||
var dropdown_continuous = block.getFieldValue('continuous');
|
|
||||||
var checkbox_interim = block.getFieldValue('interim') == 'TRUE';
|
|
||||||
var statements_isfinal_do = Blockly.JavaScript.statementToCode(block, 'isFinal_do');
|
|
||||||
var statements_isinterim_do = Blockly.JavaScript.statementToCode(block, 'isInterim_do');
|
|
||||||
var statements_onStart_do = Blockly.JavaScript.statementToCode(block, 'onStart_do');
|
|
||||||
var statements_onError_do = Blockly.JavaScript.statementToCode(block, 'onError_do');
|
|
||||||
var functionName = Blockly.JavaScript.provideFunction_(
|
|
||||||
'listenTimeout',
|
|
||||||
[
|
|
||||||
'const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = () => {',
|
|
||||||
'clearTimeout(tout);',
|
|
||||||
'tout = setTimeout(() => {',
|
|
||||||
`console.log('Timeout.');`,
|
|
||||||
'recording.stop();',
|
|
||||||
'}, 15000);',
|
|
||||||
'}'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
var code = [
|
|
||||||
`const client = new speech.SpeechClient({`,
|
|
||||||
`projectId: 'ugjiclass',`,
|
|
||||||
`keyFilename: './.shared/OCOGE-8a8e7ecac31c.json',`,
|
|
||||||
`});`,
|
|
||||||
`const request = {`,
|
|
||||||
`config: {`,
|
|
||||||
`encoding: 'LINEAR16',`,
|
|
||||||
`sampleRateHertz: 16000,`,
|
|
||||||
`languageCode: 'ja-JP'`,
|
|
||||||
`},`,
|
|
||||||
``].join('\n');
|
|
||||||
if (dropdown_continuous == 'once') code += 'singleUtterance: true,\n';
|
|
||||||
if (checkbox_interim == true) code += 'interimResults: true,\n';
|
|
||||||
code += [
|
|
||||||
`};`,
|
|
||||||
`var tout;`,
|
|
||||||
`${functionName}();`,
|
|
||||||
`const recognizeStream = client`,
|
|
||||||
`.streamingRecognize(request)`,
|
|
||||||
`.on('error', console.error)`,
|
|
||||||
`.on('data', data => {`,
|
|
||||||
`let result = data.results[0];`,
|
|
||||||
`if (result && result.alternatives[0]) {`,
|
|
||||||
`${variable_transcript} = result.alternatives[0].transcript;`,
|
|
||||||
`if (result.isFinal) {`,
|
|
||||||
statements_isfinal_do,
|
|
||||||
`${functionName}();`,
|
|
||||||
`} else {`,
|
|
||||||
statements_isinterim_do,
|
|
||||||
`}`,
|
|
||||||
`} else {`,
|
|
||||||
`console.log('Reached transcription time limit.');`,
|
|
||||||
`recording.stop();`,
|
|
||||||
'clearTimeout(tout);',
|
|
||||||
`}`,
|
|
||||||
`});`,
|
|
||||||
`const recording = recorder.record({`,
|
|
||||||
`sampleRate: 16000,`,
|
|
||||||
`recorder: 'sox',`,
|
|
||||||
`silence: '0.5',`,
|
|
||||||
`});`,
|
|
||||||
`recording`,
|
|
||||||
`.stream()`,
|
|
||||||
`.on('error', err => {${statements_onError_do}})`,
|
|
||||||
`.pipe(recognizeStream);`,
|
|
||||||
statements_onStart_do,
|
|
||||||
''
|
|
||||||
].join('\n');
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*************************** */
|
/*************************** */
|
||||||
/** Web Speech Recognization */
|
/** Web Speech Recognization */
|
||||||
/*************************** */
|
/*************************** */
|
||||||
@ -1353,7 +1197,7 @@ Blockly.Blocks['ugj_multimedia_webspeech_recognition'] = {
|
|||||||
this.setInputsInline(true);
|
this.setInputsInline(true);
|
||||||
this.setPreviousStatement(true);
|
this.setPreviousStatement(true);
|
||||||
this.setStyle('multimedia_blocks')
|
this.setStyle('multimedia_blocks')
|
||||||
this.setTooltip("Web Speech API による音声認識を行います。言葉を検知したらステートメントが実行されます。認識途中の暫定結果を取得することもできます。");
|
this.setTooltip("Web Speech API による音声認識を行います。言葉を検知したらステートメントが実行されます。認識途中の暫定結果を取得することもできます。※Web版のみの機能です。");
|
||||||
this.setHelpUrl("");
|
this.setHelpUrl("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1996,9 +1840,6 @@ Blockly.Blocks['ugj_event_answer'] = {
|
|||||||
init: function () {
|
init: function () {
|
||||||
this.appendValueInput("question")
|
this.appendValueInput("question")
|
||||||
.setCheck("String");
|
.setCheck("String");
|
||||||
// this.appendValueInput("sec")
|
|
||||||
// .setCheck("Number")
|
|
||||||
// .appendField("と");
|
|
||||||
this.appendDummyInput()
|
this.appendDummyInput()
|
||||||
.appendField("ときいて")
|
.appendField("ときいて")
|
||||||
.appendField(new Blockly.FieldVariable("答え"), "answer")
|
.appendField(new Blockly.FieldVariable("答え"), "answer")
|
||||||
@ -2013,7 +1854,6 @@ Blockly.Blocks['ugj_event_answer'] = {
|
|||||||
};
|
};
|
||||||
Blockly.JavaScript['ugj_event_answer'] = function (block) {
|
Blockly.JavaScript['ugj_event_answer'] = function (block) {
|
||||||
var value_question = Blockly.JavaScript.valueToCode(block, 'question', Blockly.JavaScript.ORDER_ATOMIC);
|
var value_question = Blockly.JavaScript.valueToCode(block, 'question', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
// var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var variable_answer = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('answer'), Blockly.Variables.NAME_TYPE);
|
var variable_answer = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('answer'), Blockly.Variables.NAME_TYPE);
|
||||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||||
var code = [
|
var code = [
|
||||||
@ -2126,24 +1966,7 @@ Blockly.JavaScript['ugj_child_gesture'] = function (block) {
|
|||||||
var code = `'python3', ['./scripts/gesture.py']`;
|
var code = `'python3', ['./scripts/gesture.py']`;
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
};
|
};
|
||||||
// face.py
|
|
||||||
Blockly.Blocks['ugj_child_facepy'] = {
|
|
||||||
init: function () {
|
|
||||||
this.appendDummyInput()
|
|
||||||
.appendField("face.py:カメラ画像を表示")
|
|
||||||
.appendField(new Blockly.FieldDropdown([["しない", " "], ["する", "-w"]]), "win");
|
|
||||||
this.setOutput(true, "shcmd");
|
|
||||||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
|
||||||
this.setStyle('special_blocks')
|
|
||||||
this.setTooltip("OpenCVによる顔認識 Python2スクリプト - 顔のX座標を返します。");
|
|
||||||
this.setHelpUrl("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_child_facepy'] = function (block) {
|
|
||||||
var dropdown_win = block.getFieldValue('win');
|
|
||||||
var code = `'python', ['./scripts/face.py', '${dropdown_win}']`;
|
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
|
||||||
};
|
|
||||||
// open jtalk
|
// open jtalk
|
||||||
Blockly.Blocks['ugj_child_openjtalk'] = {
|
Blockly.Blocks['ugj_child_openjtalk'] = {
|
||||||
init: function () {
|
init: function () {
|
||||||
@ -2364,29 +2187,6 @@ Blockly.JavaScript['ugj_child_testjs'] = function (block) {
|
|||||||
// TODO: Change ORDER_NONE to the correct strength.
|
// TODO: Change ORDER_NONE to the correct strength.
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
};
|
};
|
||||||
// Debug *Danger*
|
|
||||||
Blockly.Blocks['ugj_child_debug'] = {
|
|
||||||
init: function () {
|
|
||||||
this.appendValueInput("cmd")
|
|
||||||
.setCheck("String")
|
|
||||||
.appendField("cmd");
|
|
||||||
this.appendValueInput("opt")
|
|
||||||
.setCheck("Array")
|
|
||||||
.appendField("opt");
|
|
||||||
this.setInputsInline(true);
|
|
||||||
this.setOutput(true, "shcmd");
|
|
||||||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
|
||||||
this.setStyle('special_blocks')
|
|
||||||
this.setTooltip("さわるなきけん");
|
|
||||||
this.setHelpUrl("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_child_debug'] = function (block) {
|
|
||||||
var value_cmd = Blockly.JavaScript.valueToCode(block, 'cmd', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var value_opt = Blockly.JavaScript.valueToCode(block, 'opt', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var code = `${value_cmd}, ${value_opt}`;
|
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************* */
|
/******************* */
|
||||||
/** Show Blackboard ** */
|
/** Show Blackboard ** */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const testfunc = () => {
|
const testfunc = () => {
|
||||||
elec.openURL('http://ocoge.club');
|
elec.openURL('http://ocoge.club');
|
||||||
}
|
}
|
||||||
|
|
||||||
//============ User Customize Start ===============
|
//============ User Customize Start ===============
|
||||||
@ -13,55 +13,49 @@ var network_color = '340';
|
|||||||
var special_color = '20';
|
var special_color = '20';
|
||||||
var snippets_color = '90';
|
var snippets_color = '90';
|
||||||
|
|
||||||
// Blockly.Msg.UGJ_GPIO_HUE = 0;//FF7799
|
|
||||||
// Blockly.Msg.UGJ_MULTIMEDIA_HUE = 240;//CF63CF
|
|
||||||
// Blockly.Msg.UGJ_NETWORK_HUE = 340;//"#54C4EA"
|
|
||||||
// Blockly.Msg.UGJ_SPECIAL_HUE = 20;//"#0FBD8C"
|
|
||||||
// Blockly.Msg.UGJ_SNIPPETS_HUE = 90;
|
|
||||||
|
|
||||||
var theme = Blockly.Theme.defineTheme('ocoge', {
|
var theme = Blockly.Theme.defineTheme('ocoge', {
|
||||||
'base': Blockly.Themes.Classic,
|
'base': Blockly.Themes.Classic,
|
||||||
'startHats': true,
|
'startHats': true,
|
||||||
'componentStyles': {
|
'componentStyles': {
|
||||||
'toolboxBackgroundColour': 'aliceblue',
|
'toolboxBackgroundColour': 'aliceblue',
|
||||||
'flyoutBackgroundColour': 'lavender',
|
'flyoutBackgroundColour': 'lavender',
|
||||||
'toolboxForegroundColour': 'white',
|
'toolboxForegroundColour': 'white',
|
||||||
'flyoutForegroundColour': 'steelblue'
|
'flyoutForegroundColour': 'steelblue'
|
||||||
|
},
|
||||||
|
'blockStyles': {
|
||||||
|
'gpio_blocks': {
|
||||||
|
"colourPrimary": gpio_color
|
||||||
},
|
},
|
||||||
'blockStyles': {
|
'multimedia_blocks': {
|
||||||
'gpio_blocks': {
|
"colourPrimary": multimedia_color
|
||||||
"colourPrimary": gpio_color
|
|
||||||
},
|
|
||||||
'multimedia_blocks': {
|
|
||||||
"colourPrimary": multimedia_color
|
|
||||||
},
|
|
||||||
'network_blocks': {
|
|
||||||
"colourPrimary": network_color
|
|
||||||
},
|
|
||||||
'special_blocks': {
|
|
||||||
"colourPrimary": special_color
|
|
||||||
},
|
|
||||||
'snippets_blocks': {
|
|
||||||
"colourPrimary": snippets_color
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
'categoryStyles': {
|
'network_blocks': {
|
||||||
"gpio_category": {
|
"colourPrimary": network_color
|
||||||
"colour": gpio_color
|
|
||||||
},
|
|
||||||
"multimedia_category": {
|
|
||||||
"colour": multimedia_color
|
|
||||||
},
|
|
||||||
"network_category": {
|
|
||||||
"colour": network_color
|
|
||||||
},
|
|
||||||
"special_category": {
|
|
||||||
"colour": special_color
|
|
||||||
},
|
|
||||||
"snippets_category": {
|
|
||||||
"colour": snippets_color
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
'special_blocks': {
|
||||||
|
"colourPrimary": special_color
|
||||||
|
},
|
||||||
|
'snippets_blocks': {
|
||||||
|
"colourPrimary": snippets_color
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'categoryStyles': {
|
||||||
|
"gpio_category": {
|
||||||
|
"colour": gpio_color
|
||||||
|
},
|
||||||
|
"multimedia_category": {
|
||||||
|
"colour": multimedia_color
|
||||||
|
},
|
||||||
|
"network_category": {
|
||||||
|
"colour": network_color
|
||||||
|
},
|
||||||
|
"special_category": {
|
||||||
|
"colour": special_color
|
||||||
|
},
|
||||||
|
"snippets_category": {
|
||||||
|
"colour": snippets_color
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Customize messages
|
// Customize messages
|
||||||
@ -70,71 +64,76 @@ Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "";
|
|||||||
Blockly.Msg["MATH_CHANGE_TITLE"] = "変数 %1 を %2 増やす";
|
Blockly.Msg["MATH_CHANGE_TITLE"] = "変数 %1 を %2 増やす";
|
||||||
Blockly.Msg["VARIABLES_SET"] = "変数 %1 を %2 にする";
|
Blockly.Msg["VARIABLES_SET"] = "変数 %1 を %2 にする";
|
||||||
Blockly.Msg["TEXT_PRINT_TITLE"] = "ダイアログに %1 を表示";
|
Blockly.Msg["TEXT_PRINT_TITLE"] = "ダイアログに %1 を表示";
|
||||||
|
Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "偽";
|
||||||
|
Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "真 または 偽 を返します。";
|
||||||
|
Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "真";
|
||||||
|
// ローカライズ対応の準備
|
||||||
|
Blockly.Msg["GPIO_START_TITLE"] = "GPIO を使えるようにする";
|
||||||
|
Blockly.Msg["GPIO_START_TOOLTIP"] = "GPIOを初期化して接続します。";
|
||||||
|
Blockly.Msg["GPIO_STOP_TITLE"] = "GPIO の後片付けをする";
|
||||||
|
Blockly.Msg["GPIO_STOP_TOOLTIP"] = "GPIOとの接続を終了します。";
|
||||||
|
|
||||||
// Customize Toolbox
|
// Customize Toolbox
|
||||||
class CustomCategory extends Blockly.ToolboxCategory {
|
class CustomCategory extends Blockly.ToolboxCategory {
|
||||||
/** Constructor for a custom category. @override */
|
/** Constructor for a custom category. @override */
|
||||||
constructor(categoryDef, toolbox, opt_parent) {
|
constructor(categoryDef, toolbox, opt_parent) {
|
||||||
super(categoryDef, toolbox, opt_parent);
|
super(categoryDef, toolbox, opt_parent);
|
||||||
}
|
}
|
||||||
/** @override */
|
/** @override */
|
||||||
addColourBorder_(colour) {
|
addColourBorder_(colour) {
|
||||||
this.rowDiv_.style.backgroundColor = colour;
|
this.rowDiv_.style.backgroundColor = colour;
|
||||||
}
|
}
|
||||||
/** @override */
|
/** @override */
|
||||||
setSelected(isSelected) {
|
setSelected(isSelected) {
|
||||||
// We do not store the label span on the category, so use getElementsByClassName.
|
// We do not store the label span on the category, so use getElementsByClassName.
|
||||||
var labelDom = this.rowDiv_.getElementsByClassName('blocklyTreeLabel')[0];
|
var labelDom = this.rowDiv_.getElementsByClassName('blocklyTreeLabel')[0];
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// Change the background color of the div to white.
|
// Change the background color of the div to white.
|
||||||
this.rowDiv_.style.backgroundColor = 'white';
|
this.rowDiv_.style.backgroundColor = 'white';
|
||||||
// Set the colour of the text to the colour of the category.
|
// Set the colour of the text to the colour of the category.
|
||||||
labelDom.style.color = this.colour_;
|
labelDom.style.color = this.colour_;
|
||||||
this.iconDom_.style.color = this.colour_;
|
this.iconDom_.style.color = this.colour_;
|
||||||
} else {
|
} else {
|
||||||
// Set the background back to the original colour.
|
// Set the background back to the original colour.
|
||||||
this.rowDiv_.style.backgroundColor = this.colour_;
|
this.rowDiv_.style.backgroundColor = this.colour_;
|
||||||
// Set the text back to white.
|
// Set the text back to white.
|
||||||
labelDom.style.color = 'white';
|
labelDom.style.color = 'white';
|
||||||
this.iconDom_.style.color = 'white';
|
this.iconDom_.style.color = 'white';
|
||||||
}
|
|
||||||
// This is used for accessibility purposes.
|
|
||||||
Blockly.utils.aria.setState(/** @type {!Element} */(this.htmlDiv_),
|
|
||||||
Blockly.utils.aria.State.SELECTED, isSelected);
|
|
||||||
}
|
}
|
||||||
|
// This is used for accessibility purposes.
|
||||||
|
Blockly.utils.aria.setState(/** @type {!Element} */(this.htmlDiv_),
|
||||||
|
Blockly.utils.aria.State.SELECTED, isSelected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Blockly.registry.register(
|
Blockly.registry.register(
|
||||||
Blockly.registry.Type.TOOLBOX_ITEM,
|
Blockly.registry.Type.TOOLBOX_ITEM,
|
||||||
Blockly.ToolboxCategory.registrationName,
|
Blockly.ToolboxCategory.registrationName,
|
||||||
CustomCategory, true);
|
CustomCategory, true);
|
||||||
//============ User Customize End ===============
|
//============ User Customize End ===============
|
||||||
|
|
||||||
|
|
||||||
//背景canvasの準備
|
//背景canvasとマスコットの準備
|
||||||
const ugj_canvasBgImg = (imgSrc, x, y) => { //x,y == -1: center or middle
|
const ugj_canvasBgImg = (imgSrc, x, y) => { //x,y == -1: center or middle
|
||||||
let el = document.getElementById('canvas_bg');
|
let el = document.getElementById('canvas_bg');
|
||||||
let ctx = el.getContext('2d');
|
let ctx = el.getContext('2d');
|
||||||
ctx.fillStyle = 'rgb(255,255,255)';
|
ctx.fillStyle = 'rgb(255,255,255)';
|
||||||
ctx.fillRect(0,0,480,360);
|
ctx.fillRect(0, 0, 480, 360);
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = imgSrc;
|
img.src = imgSrc;
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
if (x<0) { //センタリング
|
if (x < 0) { //センタリング
|
||||||
let w = img.width;
|
let w = img.width;
|
||||||
if (w>=480) x=0;
|
if (w >= 480) x = 0;
|
||||||
else x = Math.floor((480 - w) / 2);
|
else x = Math.floor((480 - w) / 2);
|
||||||
}
|
|
||||||
if (y<0) { //縦中寄せ
|
|
||||||
let h = img.height;
|
|
||||||
if (h>=360) y=0;
|
|
||||||
else y = Math.floor((360 - h) /2);
|
|
||||||
}
|
|
||||||
ctx.drawImage(img, x, y);
|
|
||||||
}
|
}
|
||||||
|
if (y < 0) { //縦中寄せ
|
||||||
|
let h = img.height;
|
||||||
|
if (h >= 360) y = 0;
|
||||||
|
else y = Math.floor((360 - h) / 2);
|
||||||
|
}
|
||||||
|
ctx.drawImage(img, x, y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// マスコット
|
|
||||||
// ugj_canvasBgImg("./img/mimmy.png?" + new Date().getTime()); // ミミィ
|
|
||||||
// ugj_canvasBgImg("./img/cogechee.png?" + new Date().getTime(), -1,-1); // こげちー
|
|
||||||
|
|
||||||
// HTML部品のインスタンス - 画面上の必要な部品はすべてここで取得しておく
|
// HTML部品のインスタンス - 画面上の必要な部品はすべてここで取得しておく
|
||||||
ugjel_displayArea = document.getElementById('display_area'); // ディスプレイ部
|
ugjel_displayArea = document.getElementById('display_area'); // ディスプレイ部
|
||||||
@ -145,181 +144,183 @@ ugjel_inputBox = document.getElementById('inputBox'); // 入力フィールド
|
|||||||
// その他のプロパティ
|
// その他のプロパティ
|
||||||
ugj_inputEvLstnrID = 0; // 入力フォームの動的イベントリスナの最新のID
|
ugj_inputEvLstnrID = 0; // 入力フォームの動的イベントリスナの最新のID
|
||||||
ugj_sounds = (names => { // サウンドファイルのいろいろの配列の初期化
|
ugj_sounds = (names => { // サウンドファイルのいろいろの配列の初期化
|
||||||
let sounds = [];
|
let sounds = [];
|
||||||
names.forEach(value => {
|
names.forEach(value => {
|
||||||
let filepath = `./sounds/${value}.wav`;
|
let filepath = `./sounds/${value}.wav`;
|
||||||
sounds[value] = { 'file': filepath, 'audio': new Audio(filepath) };
|
sounds[value] = { 'file': filepath, 'audio': new Audio(filepath) };
|
||||||
});
|
});
|
||||||
return sounds;
|
return sounds;
|
||||||
})(['meow', 'bounce', 'type_chime', 'type_dink', 'type_tap', 'type_space', 'type_return']); // サウンドファイルのベース名のリスト
|
})(['meow', 'bounce', 'type_chime', 'type_dink', 'type_tap', 'type_space', 'type_return']); // サウンドファイルのベース名のリスト
|
||||||
|
|
||||||
// メソッド
|
// メソッド
|
||||||
|
|
||||||
// マスコット選択
|
// マスコット選択
|
||||||
const ugj_selectMascot = () => {
|
const ugj_selectMascot = () => {
|
||||||
let fname = elec.selectMascotFile();
|
let fname = elec.selectMascotFile();
|
||||||
if (fname) {
|
if (fname) {
|
||||||
ugj_canvasBgImg(fname, -1, -1);
|
ugj_canvasBgImg(fname, -1, -1);
|
||||||
elec.setMascotFilePath(fname);
|
elec.setMascotFilePath(fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// サウンド再生 - 連続再生のため、再生開始後すぐにオーディオ要素を再生成する
|
// サウンド再生 - 連続再生のため、再生開始後すぐにオーディオ要素を再生成する
|
||||||
const ugj_soundPlay = soundName => {
|
const ugj_soundPlay = soundName => {
|
||||||
ugj_sounds[soundName]['audio'].play();
|
ugj_sounds[soundName]['audio'].play();
|
||||||
ugj_sounds[soundName]['audio'] = new Audio(ugj_sounds[soundName]['file']);
|
ugj_sounds[soundName]['audio'] = new Audio(ugj_sounds[soundName]['file']);
|
||||||
};
|
};
|
||||||
|
|
||||||
// OK,Cancel 2択のダイアログを表示
|
// OK,Cancel 2択のダイアログを表示
|
||||||
const ugj_confirm = (title, message, callback) => {
|
const ugj_confirm = (title, message, callback) => {
|
||||||
CustomDialog.show(title, message, {
|
CustomDialog.show(title, message, {
|
||||||
showOkay: true,
|
showOkay: true,
|
||||||
onOkay: () => callback(true),
|
onOkay: () => callback(true),
|
||||||
showCancel: true,
|
showCancel: true,
|
||||||
onCancel: () => callback(false)
|
onCancel: () => callback(false)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const ugj_htmlEntities = str =>// HTMLエンティティのエスケープ
|
const ugj_htmlEntities = str =>// HTMLエンティティのエスケープ
|
||||||
String(str).replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');//.replace(/&/g, '&').replace(/ /g, ' ');
|
String(str).replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');//.replace(/&/g, '&').replace(/ /g, ' ');
|
||||||
|
|
||||||
// 新規ワークスペース
|
// 新規ワークスペース
|
||||||
const ugj_newWorkspace = () => {
|
const ugj_newWorkspace = () => {
|
||||||
ugj_confirm('新規ワークスペース', '保存していない内容はすべて破棄されます。よろしいですか?', okey => {
|
ugj_confirm('新規ワークスペース', '保存していない内容はすべて破棄されます。よろしいですか?', okey => {
|
||||||
if (okey) {
|
if (okey) {
|
||||||
workspace.clear();
|
workspace.clear();
|
||||||
elec.newFile();
|
elec.newFile();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースをファイルに保存・読込
|
// ワークスペースをファイルに保存・読込
|
||||||
const ugj_saveWorkspaceToFile = () => {
|
const ugj_saveWorkspaceToFile = () => {
|
||||||
let xml = Blockly.Xml.workspaceToDom(workspace);
|
let xml = Blockly.Xml.workspaceToDom(workspace);
|
||||||
let xml_text = Blockly.Xml.domToText(xml);
|
let xml_text = Blockly.Xml.domToText(xml);
|
||||||
if (elec.saveWsFile(xml_text) === false) {
|
if (elec.saveWsFile(xml_text) === false) {
|
||||||
alert('保存できませんでした。');
|
alert('保存できませんでした。');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const ugj_loadWorkspaceFromFile = () => {
|
const ugj_loadWorkspaceFromFile = () => {
|
||||||
let xml_text = elec.loadWsFile();
|
let xml_text = elec.loadWsFile();
|
||||||
if (xml_text.length > 0) {
|
if (xml_text.length > 0) {
|
||||||
let xml = Blockly.Xml.textToDom(xml_text);
|
let xml = Blockly.Xml.textToDom(xml_text);
|
||||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースを別名で保存
|
// ワークスペースを別名で保存
|
||||||
const ugj_saveWorkspaceAs = () => {
|
const ugj_saveWorkspaceAs = () => {
|
||||||
elec.newFile();
|
elec.newFile();
|
||||||
ugj_saveWorkspaceToFile();
|
ugj_saveWorkspaceToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースをローカルストレージに保存・読込
|
// ワークスペースをローカルストレージに保存・読込
|
||||||
const ugj_saveWorkspace = () => {
|
const ugj_saveWorkspace = () => {
|
||||||
// Workspace
|
// Workspace
|
||||||
let xml = Blockly.Xml.workspaceToDom(workspace);
|
let xml = Blockly.Xml.workspaceToDom(workspace);
|
||||||
let xml_text = Blockly.Xml.domToText(xml);
|
let xml_text = Blockly.Xml.domToText(xml);
|
||||||
localStorage.setItem("abrage.xml", xml_text);
|
localStorage.setItem("ocoge.xml", xml_text);
|
||||||
}
|
}
|
||||||
const ugj_loadWorkspace = () => {
|
const ugj_loadWorkspace = () => {
|
||||||
// Workspace
|
// Workspace
|
||||||
let xml_text = localStorage.getItem("abrage.xml");
|
let xml_text = localStorage.getItem("ocoge.xml");
|
||||||
|
if (xml_text !== null) {
|
||||||
if (xml_text.length != 0) {
|
if (xml_text.length != 0) {
|
||||||
let xml = Blockly.Xml.textToDom(xml_text);
|
let xml = Blockly.Xml.textToDom(xml_text);
|
||||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ワークスペースからコードを生成して必要であれば整形処理をする
|
// ワークスペースからコードを生成して必要であれば整形処理をする
|
||||||
const ugj_createCode = (args) => {
|
const ugj_createCode = (args) => {
|
||||||
addAsync = args.async || false;
|
addAsync = args.async || false;
|
||||||
beautify = args.beautify || false;
|
beautify = args.beautify || false;
|
||||||
|
|
||||||
let code = Blockly.JavaScript.workspaceToCode(workspace);
|
let code = Blockly.JavaScript.workspaceToCode(workspace);
|
||||||
|
|
||||||
// 追加モジュールのrequire
|
// 追加モジュールのrequire
|
||||||
let requires = [
|
let requires = [
|
||||||
['_gpio_', false, `const pi = require('ocoge_pigpiod');\n`],
|
['_gpio_', false, `const pi = require('ocoge_pigpiod');\n`],
|
||||||
['_axios_', false, `const axios = require('axios');\n`],
|
['_axios_', false, `const axios = require('axios');\n`],
|
||||||
['_sendmail', false, `const nodemailer = require('nodemailer');\n`],
|
['_sendmail', false, `const nodemailer = require('nodemailer');\n`],
|
||||||
['_cloudspeech_', false, `const speech = require('@google-cloud/speech');\nconst recorder = require('node-record-lpcm16');\n`],
|
['_cloudspeech_', false, `const speech = require('@google-cloud/speech');\nconst recorder = require('node-record-lpcm16');\n`],
|
||||||
['_httpserver', false, `const http = require('http');\n`],
|
['_httpserver', false, `const http = require('http');\n`],
|
||||||
['_file_', false, `const fs = require('fs');\n`],
|
['_file_', false, `const fs = require('fs');\n`],
|
||||||
// ['_bme280', false, `const BME280 = require('bme280-sensor');`],
|
// ['_bme280', false, `const BME280 = require('bme280-sensor');`],
|
||||||
['_dht', false, `const dht = require("node-dht-sensor").promises;`],
|
['_dht', false, `const dht = require("node-dht-sensor").promises;`],
|
||||||
['_socket_', false, `const net = require('net');`]
|
['_socket_', false, `const net = require('net');`]
|
||||||
];
|
];
|
||||||
let blockArray = workspace.getAllBlocks();
|
let blockArray = workspace.getAllBlocks();
|
||||||
blockArray.forEach(value => {
|
blockArray.forEach(value => {
|
||||||
for (var i = 0, l = requires.length; i < l; i++) {
|
|
||||||
if (value.type.indexOf(requires[i][0]) >= 0) requires[i][1] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (var i = 0, l = requires.length; i < l; i++) {
|
for (var i = 0, l = requires.length; i < l; i++) {
|
||||||
if (requires[i][1]) code = requires[i][2] + code;
|
if (value.type.indexOf(requires[i][0]) >= 0) requires[i][1] = true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
for (var i = 0, l = requires.length; i < l; i++) {
|
||||||
|
if (requires[i][1]) code = requires[i][2] + code;
|
||||||
|
}
|
||||||
|
|
||||||
// await使用のため、必要に応じてコード全体をasync付き即時関数でラップ
|
// await使用のため、必要に応じてコード全体をasync付き即時関数でラップ
|
||||||
if (addAsync) {
|
if (addAsync) {
|
||||||
code = [
|
code = [
|
||||||
'(async () => {',
|
'(async () => {',
|
||||||
code,
|
code,
|
||||||
'})();'
|
'})();'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// コードを綺麗に
|
// コードを綺麗に
|
||||||
if (beautify) code = js_beautify(code, { indent_size: 2 });
|
if (beautify) code = js_beautify(code, { indent_size: 2 });
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ブロックスクリプト実行
|
// ブロックスクリプト実行
|
||||||
const ugj_runCode = () => {
|
const ugj_runCode = () => {
|
||||||
document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
||||||
let code = ugj_createCode({ 'async': true });
|
let code = ugj_createCode({ 'async': true });
|
||||||
try {
|
try {
|
||||||
eval(code);
|
eval(code);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JavaScriptコードをダイアログで表示・保存
|
// JavaScriptコードをダイアログで表示・保存
|
||||||
// エレメントのオブジェクトとかコールバックとか
|
// エレメントのオブジェクトとかコールバックとか
|
||||||
// 色々この中で完結させてみる
|
// 色々この中で完結させてみる
|
||||||
const ugj_showCode = () => {
|
const ugj_showCode = () => {
|
||||||
const dialog = document.getElementById('codeDlg');
|
const dialog = document.getElementById('codeDlg');
|
||||||
const content = document.getElementById('dlgContent');
|
const content = document.getElementById('dlgContent');
|
||||||
const btn_close = document.getElementById('dlgClose');
|
const btn_close = document.getElementById('dlgClose');
|
||||||
const btn_export = document.getElementById('dlgExport');
|
const btn_export = document.getElementById('dlgExport');
|
||||||
const chkbox_cli = document.getElementById('dlgCli');
|
const chkbox_cli = document.getElementById('dlgCli');
|
||||||
|
|
||||||
let code = ugj_createCode({ 'beautify': true });
|
let code = ugj_createCode({ 'beautify': true });
|
||||||
code = ugj_htmlEntities(code);
|
code = ugj_htmlEntities(code);
|
||||||
content.innerHTML = PR.prettyPrintOne(code, 'js', true);
|
content.innerHTML = PR.prettyPrintOne(code, 'js', true);
|
||||||
|
|
||||||
dialog.showModal();
|
dialog.showModal();
|
||||||
|
|
||||||
const close_cb = () => {
|
const close_cb = () => {
|
||||||
dialog.close();
|
dialog.close();
|
||||||
btn_close.removeEventListener('click', close_cb);
|
btn_close.removeEventListener('click', close_cb);
|
||||||
btn_export.removeEventListener('click', export_cb);
|
btn_export.removeEventListener('click', export_cb);
|
||||||
|
}
|
||||||
|
const export_cb = () => {
|
||||||
|
code = ugj_createCode({ 'async': true, 'beautify': true });
|
||||||
|
// blackboardWrite()をconsole.log()に書き換え、
|
||||||
|
// document... と ugj_... と elec... をコメントアウト(ブラウザ関連部分の追放という意味では不完全なので注意)
|
||||||
|
if (chkbox_cli.checked)
|
||||||
|
code = code.replace(/const appendDiv[^#]*\/\/#/gm, 'const blackboardWrite = text => console.log(text);').replace(/(^(?=.*document.)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*ugj_)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*elec.)[^;]*;)/gm, '/* $1 */');
|
||||||
|
if (elec.saveFile(code, 'js') === false) {
|
||||||
|
alert('保存できませんでした。');
|
||||||
}
|
}
|
||||||
const export_cb = () => {
|
close_cb();
|
||||||
code = ugj_createCode({ 'async': true, 'beautify': true });
|
}
|
||||||
// blackboardWrite()をconsole.log()に書き換え、
|
btn_close.addEventListener('click', close_cb);
|
||||||
// document... と ugj_... と elec... をコメントアウト(ブラウザ関連部分の追放という意味では不完全なので注意)
|
btn_export.addEventListener('click', export_cb);
|
||||||
if (chkbox_cli.checked)
|
|
||||||
code = code.replace(/const appendDiv[^#]*\/\/#/gm, 'const blackboardWrite = text => console.log(text);').replace(/(^(?=.*document.)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*ugj_)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*elec.)[^;]*;)/gm, '/* $1 */');
|
|
||||||
if (elec.saveFile(code, 'js') === false) {
|
|
||||||
alert('保存できませんでした。');
|
|
||||||
}
|
|
||||||
close_cb();
|
|
||||||
}
|
|
||||||
btn_close.addEventListener('click', close_cb);
|
|
||||||
btn_export.addEventListener('click', export_cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -327,102 +328,102 @@ const ugj_showCode = () => {
|
|||||||
ugj_fdTimeoutID = null;
|
ugj_fdTimeoutID = null;
|
||||||
ugj_fdRecentBox = null;
|
ugj_fdRecentBox = null;
|
||||||
const ugj_fukidashi = (text, sec) => {
|
const ugj_fukidashi = (text, sec) => {
|
||||||
// Canvas Context
|
// Canvas Context
|
||||||
const context = document.getElementById('canvas').getContext('2d');
|
const context = document.getElementById('canvas').getContext('2d');
|
||||||
// 吹き出しを消去する関数
|
// 吹き出しを消去する関数
|
||||||
const clearFd = (x, y, w, h) => context.clearRect(x, y, w, h);
|
const clearFd = (x, y, w, h) => context.clearRect(x, y, w, h);
|
||||||
// 前回の思い出を忘れる
|
// 前回の思い出を忘れる
|
||||||
if (ugj_fdRecentBox !== null) {
|
if (ugj_fdRecentBox !== null) {
|
||||||
clearFd(ugj_fdRecentBox.x, ugj_fdRecentBox.y, ugj_fdRecentBox.w, ugj_fdRecentBox.h);
|
clearFd(ugj_fdRecentBox.x, ugj_fdRecentBox.y, ugj_fdRecentBox.w, ugj_fdRecentBox.h);
|
||||||
clearTimeout(ugj_fdTimeoutID);
|
clearTimeout(ugj_fdTimeoutID);
|
||||||
ugj_fdRecentBox = null;
|
ugj_fdRecentBox = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 基本設定
|
// 基本設定
|
||||||
let rtopX = 170; // フキダシ右上 X座標
|
let rtopX = 170; // フキダシ右上 X座標
|
||||||
let rtopY = 40; // フキダシ右上 Y座標
|
let rtopY = 40; // フキダシ右上 Y座標
|
||||||
let boxWidth = 140;
|
let boxWidth = 140;
|
||||||
let padding = 5;
|
let padding = 5;
|
||||||
let radius = 5;// 円弧の半径
|
let radius = 5;// 円弧の半径
|
||||||
|
|
||||||
// 吹き出しの背景色
|
// 吹き出しの背景色
|
||||||
context.fillStyle = "#b7e6ff";
|
context.fillStyle = "#b7e6ff";
|
||||||
|
|
||||||
// テキスト設定
|
// テキスト設定
|
||||||
let limitedWidth = boxWidth - (padding * 2);
|
let limitedWidth = boxWidth - (padding * 2);
|
||||||
let size = 14;
|
let size = 14;
|
||||||
context.font = size + "px ''";
|
context.font = size + "px ''";
|
||||||
|
|
||||||
// テキスト調整 行に分解
|
// テキスト調整 行に分解
|
||||||
let lineTextList = text.split("\n");
|
let lineTextList = text.split("\n");
|
||||||
let newLineTextList = [];
|
let newLineTextList = [];
|
||||||
lineTextList.forEach((lineText) => {
|
lineTextList.forEach((lineText) => {
|
||||||
|
if (context.measureText(lineText).width > limitedWidth) {
|
||||||
|
characterList = lineText.split("");// 1文字ずつ分割
|
||||||
|
let preLineText = "";
|
||||||
|
lineText = "";
|
||||||
|
characterList.forEach((character) => {
|
||||||
|
lineText += character;
|
||||||
if (context.measureText(lineText).width > limitedWidth) {
|
if (context.measureText(lineText).width > limitedWidth) {
|
||||||
characterList = lineText.split("");// 1文字ずつ分割
|
newLineTextList.push(preLineText);
|
||||||
let preLineText = "";
|
lineText = character;
|
||||||
lineText = "";
|
|
||||||
characterList.forEach((character) => {
|
|
||||||
lineText += character;
|
|
||||||
if (context.measureText(lineText).width > limitedWidth) {
|
|
||||||
newLineTextList.push(preLineText);
|
|
||||||
lineText = character;
|
|
||||||
}
|
|
||||||
preLineText = lineText;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
newLineTextList.push(lineText);
|
preLineText = lineText;
|
||||||
});
|
});
|
||||||
let lineLength = newLineTextList.length;
|
|
||||||
|
|
||||||
// 角丸
|
|
||||||
let width = boxWidth;// 枠の幅
|
|
||||||
let height = (size * lineLength) + (padding * 3); // 枠の高さ
|
|
||||||
let toRadianCoefficient = Math.PI / 180; // 角度からラジアンへの変換係数
|
|
||||||
// 角丸原点(左上座標)
|
|
||||||
let boxOrigin = {
|
|
||||||
"x": rtopX - width,
|
|
||||||
"y": rtopY,
|
|
||||||
}
|
}
|
||||||
// 円弧から円弧までの直線は自動で引かれます、角度は回り方によって変わります。
|
newLineTextList.push(lineText);
|
||||||
// arc(中心x, 中心y, 半径, 開始角度, 終了角度, 反時計回り)
|
});
|
||||||
context.beginPath();
|
let lineLength = newLineTextList.length;
|
||||||
context.arc(boxOrigin.x + radius, boxOrigin.y + radius, radius, 180 * toRadianCoefficient, 270 * toRadianCoefficient, false);// 左上
|
|
||||||
context.arc(boxOrigin.x + width - radius, boxOrigin.y + radius, radius, 270 * toRadianCoefficient, 0, false);// 右上
|
|
||||||
context.arc(boxOrigin.x + width - radius, boxOrigin.y + height - radius, radius, 0, 90 * toRadianCoefficient, false);// 右下
|
|
||||||
context.arc(boxOrigin.x + radius, boxOrigin.y + height - radius, radius, 90 * toRadianCoefficient, 180 * toRadianCoefficient, false);// 左下
|
|
||||||
context.closePath();
|
|
||||||
context.fill();
|
|
||||||
|
|
||||||
// 矢印(ヒゲ)
|
// 角丸
|
||||||
let arrow = {
|
let width = boxWidth;// 枠の幅
|
||||||
"x": rtopX - width / 2 + 40,
|
let height = (size * lineLength) + (padding * 3); // 枠の高さ
|
||||||
"y": rtopY + height + 10,
|
let toRadianCoefficient = Math.PI / 180; // 角度からラジアンへの変換係数
|
||||||
"width": 10,
|
// 角丸原点(左上座標)
|
||||||
"height": 10,
|
let boxOrigin = {
|
||||||
}
|
"x": rtopX - width,
|
||||||
context.beginPath();
|
"y": rtopY,
|
||||||
context.moveTo(arrow.x, arrow.y);
|
}
|
||||||
context.lineTo(arrow.x, arrow.y - arrow.height);
|
// 円弧から円弧までの直線は自動で引かれます、角度は回り方によって変わります。
|
||||||
context.lineTo(arrow.x - arrow.width, arrow.y - arrow.height);
|
// arc(中心x, 中心y, 半径, 開始角度, 終了角度, 反時計回り)
|
||||||
context.fill();
|
context.beginPath();
|
||||||
|
context.arc(boxOrigin.x + radius, boxOrigin.y + radius, radius, 180 * toRadianCoefficient, 270 * toRadianCoefficient, false);// 左上
|
||||||
|
context.arc(boxOrigin.x + width - radius, boxOrigin.y + radius, radius, 270 * toRadianCoefficient, 0, false);// 右上
|
||||||
|
context.arc(boxOrigin.x + width - radius, boxOrigin.y + height - radius, radius, 0, 90 * toRadianCoefficient, false);// 右下
|
||||||
|
context.arc(boxOrigin.x + radius, boxOrigin.y + height - radius, radius, 90 * toRadianCoefficient, 180 * toRadianCoefficient, false);// 左下
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
|
||||||
// テキスト描画
|
// 矢印(ヒゲ)
|
||||||
context.fillStyle = "#000000";
|
let arrow = {
|
||||||
newLineTextList.forEach((lineText, index) => {
|
"x": rtopX - width / 2 + 40,
|
||||||
context.fillText(lineText, boxOrigin.x + padding, boxOrigin.y + padding + (size * (index + 1)));
|
"y": rtopY + height + 10,
|
||||||
});
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
}
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(arrow.x, arrow.y);
|
||||||
|
context.lineTo(arrow.x, arrow.y - arrow.height);
|
||||||
|
context.lineTo(arrow.x - arrow.width, arrow.y - arrow.height);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
// 描画した吹き出しの位置情報を保存
|
// テキスト描画
|
||||||
ugj_fdRecentBox = { x: boxOrigin.x, y: boxOrigin.y, w: width, h: height + arrow.height };
|
context.fillStyle = "#000000";
|
||||||
// 指定時間後に消去(0以下で自動消去なし)
|
newLineTextList.forEach((lineText, index) => {
|
||||||
if (sec > 0) {
|
context.fillText(lineText, boxOrigin.x + padding, boxOrigin.y + padding + (size * (index + 1)));
|
||||||
ugj_fdTimeoutID = setTimeout(() => {
|
});
|
||||||
clearFd(boxOrigin.x, boxOrigin.y, width, height + arrow.height);
|
|
||||||
}, sec * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return [boxOrigin.x, boxOrigin.y, width, height+arrow.height];
|
// 描画した吹き出しの位置情報を保存
|
||||||
// https://qiita.com/horikeso/items/95595f379a8dfa63c34a
|
ugj_fdRecentBox = { x: boxOrigin.x, y: boxOrigin.y, w: width, h: height + arrow.height };
|
||||||
|
// 指定時間後に消去(0以下で自動消去なし)
|
||||||
|
if (sec > 0) {
|
||||||
|
ugj_fdTimeoutID = setTimeout(() => {
|
||||||
|
clearFd(boxOrigin.x, boxOrigin.y, width, height + arrow.height);
|
||||||
|
}, sec * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return [boxOrigin.x, boxOrigin.y, width, height+arrow.height];
|
||||||
|
// https://qiita.com/horikeso/items/95595f379a8dfa63c34a
|
||||||
}
|
}
|
||||||
|
|
||||||
//=====================================
|
//=====================================
|
||||||
@ -435,37 +436,37 @@ var blocklyDiv = document.getElementById('blocklyDiv');
|
|||||||
// var workspace = Blockly.inject(blocklyDiv,
|
// var workspace = Blockly.inject(blocklyDiv,
|
||||||
// {toolbox: document.getElementById('toolbox')});
|
// {toolbox: document.getElementById('toolbox')});
|
||||||
var workspace = Blockly.inject(blocklyDiv,
|
var workspace = Blockly.inject(blocklyDiv,
|
||||||
{
|
{
|
||||||
toolbox: document.getElementById('toolbox'),
|
toolbox: document.getElementById('toolbox'),
|
||||||
theme: theme,
|
theme: theme,
|
||||||
|
|
||||||
scrollbars: true,
|
scrollbars: true,
|
||||||
grid: {
|
grid: {
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
length: 1,
|
length: 1,
|
||||||
colour: '#888',//888
|
colour: '#888',//888
|
||||||
snap: true
|
snap: true
|
||||||
},
|
},
|
||||||
zoom: { startScale: 1.0, controls: true },
|
zoom: { startScale: 1.0, controls: true },
|
||||||
trashcan: true,
|
trashcan: true,
|
||||||
media: './google-blockly/media/'
|
media: './google-blockly/media/'
|
||||||
});
|
});
|
||||||
var onresize = function (e) {
|
var onresize = function (e) {
|
||||||
// Compute the absolute coordinates and dimensions of blocklyArea.
|
// Compute the absolute coordinates and dimensions of blocklyArea.
|
||||||
var element = blocklyArea;
|
var element = blocklyArea;
|
||||||
var x = 0;
|
var x = 0;
|
||||||
var y = 0;
|
var y = 0;
|
||||||
do {
|
do {
|
||||||
x += element.offsetLeft;
|
x += element.offsetLeft;
|
||||||
y += element.offsetTop;
|
y += element.offsetTop;
|
||||||
element = element.offsetParent;
|
element = element.offsetParent;
|
||||||
} while (element);
|
} while (element);
|
||||||
// Position blocklyDiv over blocklyArea.
|
// Position blocklyDiv over blocklyArea.
|
||||||
blocklyDiv.style.left = x + 'px';
|
blocklyDiv.style.left = x + 'px';
|
||||||
blocklyDiv.style.top = y + 'px';
|
blocklyDiv.style.top = y + 'px';
|
||||||
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
|
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
|
||||||
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
|
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
|
||||||
Blockly.svgResize(workspace);
|
Blockly.svgResize(workspace);
|
||||||
};
|
};
|
||||||
window.addEventListener('resize', onresize, false);
|
window.addEventListener('resize', onresize, false);
|
||||||
onresize();
|
onresize();
|
||||||
@ -476,95 +477,95 @@ Blockly.svgResize(workspace);
|
|||||||
|
|
||||||
// ワークスペースの未保存の変更のフラグ
|
// ワークスペースの未保存の変更のフラグ
|
||||||
const ugj_wsUpdateCB = event => {
|
const ugj_wsUpdateCB = event => {
|
||||||
if (event.type != Blockly.Events.UI) {
|
if (event.type != Blockly.Events.UI) {
|
||||||
elec.setWsChanged(true);
|
elec.setWsChanged(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ウィンドウロード・アンロード時
|
// ウィンドウロード・アンロード時
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
var menu = document.getElementById('conmenu'); //独自コンテキストメニュー
|
var menu = document.getElementById('conmenu'); //独自コンテキストメニュー
|
||||||
var area = document.getElementById('dlgContent'); //対象エリア
|
var area = document.getElementById('dlgContent'); //対象エリア
|
||||||
var body = document.body; //bodyエリア
|
var body = document.body; //bodyエリア
|
||||||
body.oncontextmenu = () => false;
|
body.oncontextmenu = () => false;
|
||||||
//右クリック時に独自コンテキストメニューを表示する
|
//右クリック時に独自コンテキストメニューを表示する
|
||||||
area.addEventListener('contextmenu', function (e) {
|
area.addEventListener('contextmenu', function (e) {
|
||||||
menu.style.left = e.pageX + 'px';
|
menu.style.left = e.pageX + 'px';
|
||||||
menu.style.top = e.pageY + 'px';
|
menu.style.top = e.pageY + 'px';
|
||||||
menu.classList.add('on');
|
menu.classList.add('on');
|
||||||
});
|
});
|
||||||
//左クリック時に独自コンテキストメニューを非表示にする
|
//左クリック時に独自コンテキストメニューを非表示にする
|
||||||
body.addEventListener('click', function () {
|
body.addEventListener('click', function () {
|
||||||
if (menu.classList.contains('on')) {
|
if (menu.classList.contains('on')) {
|
||||||
menu.classList.remove('on');
|
menu.classList.remove('on');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ワークスペースといくつかの環境のオートリストア
|
// ワークスペースといくつかの環境のオートリストア
|
||||||
ugj_loadWorkspace();
|
ugj_loadWorkspace();
|
||||||
elec.loadPrefsFromLS();
|
elec.loadPrefsFromLS();
|
||||||
setTimeout(() => { // 環境設定のロードが終わってからイベントリスナを作成
|
setTimeout(() => { // 環境設定のロードが終わってからイベントリスナを作成
|
||||||
workspace.addChangeListener(ugj_wsUpdateCB);
|
workspace.addChangeListener(ugj_wsUpdateCB);
|
||||||
}, 100);
|
}, 100);
|
||||||
// 背景canvas
|
// 背景canvas
|
||||||
ugj_canvasBgImg(elec.getMascotFilePath(), -1,-1);
|
ugj_canvasBgImg(elec.getMascotFilePath(), -1, -1);
|
||||||
}
|
}
|
||||||
window.onbeforeunload = () => {
|
window.onbeforeunload = () => {
|
||||||
ugj_saveWorkspace();
|
ugj_saveWorkspace();
|
||||||
elec.savePrefsToLS();
|
elec.savePrefsToLS();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Electron動作とブラウザ動作を自動で仕分け
|
// Electron動作とブラウザ動作を自動で仕分け
|
||||||
if (typeof require == 'function') {
|
if (typeof require == 'function') {
|
||||||
// requireが使える = Electron
|
// requireが使える = Electron
|
||||||
var elec = require('./scripts/eleclib');
|
var elec = require('./scripts/eleclib');
|
||||||
console.log('elec loaded.');
|
console.log('elec loaded.');
|
||||||
} else {
|
} else {
|
||||||
//ブラウザ動作
|
//ブラウザ動作
|
||||||
//requireのダミー
|
//requireのダミー
|
||||||
var require = (e) => {
|
var require = (e) => {
|
||||||
alert(`この機能またはブロック [${e}] は web 版ではご利用になれません。\n詳しくはお問い合わせください。`);
|
alert(`この機能またはブロック [${e}] は web 版ではご利用になれません。\n詳しくはお問い合わせください。`);
|
||||||
// if (e=='elec' || e=='ocoge' || e=='child_process' || e=='@google-cloud/speech' || e=='nodemailer' || e=='fs' )
|
// if (e=='elec' || e=='ocoge' || e=='child_process' || e=='@google-cloud/speech' || e=='nodemailer' || e=='fs' )
|
||||||
// alert(`この機能またはブロックは web 版ではご利用になれません。\n詳しくはお問い合わせください。`);
|
// alert(`この機能またはブロックは web 版ではご利用になれません。\n詳しくはお問い合わせください。`);
|
||||||
// else return;
|
// else return;
|
||||||
}
|
}
|
||||||
//elecを名前空間で置き換え
|
//elecを名前空間で置き換え
|
||||||
var elec = {};
|
var elec = {};
|
||||||
elec.saveFile = () => require('elec');
|
elec.saveFile = () => require('elec');
|
||||||
elec.savePrefsToLS = () => { ; }
|
elec.savePrefsToLS = () => { ; }
|
||||||
elec.loadPrefsFromLS = () => { ; }
|
elec.loadPrefsFromLS = () => { ; }
|
||||||
elec.newFile = () => { ; }
|
elec.newFile = () => { ; }
|
||||||
elec.setWsChanged = () => { ; }
|
elec.setWsChanged = () => { ; }
|
||||||
|
|
||||||
// マスコット
|
// マスコット
|
||||||
elec.getMascotFilePath = () => './img/cogechee.png';
|
elec.getMascotFilePath = () => './img/cogechee.png';
|
||||||
|
|
||||||
//ワークスペースのダウンロード
|
//ワークスペースのダウンロード
|
||||||
elec.saveWsFile = xml_text => {
|
elec.saveWsFile = xml_text => {
|
||||||
let blob = new Blob([xml_text], { "type": "text/xml" });
|
let blob = new Blob([xml_text], { "type": "text/xml" });
|
||||||
const downLoadLink = document.createElement("a");
|
const downLoadLink = document.createElement("a");
|
||||||
document.body.appendChild(downLoadLink);
|
document.body.appendChild(downLoadLink);
|
||||||
downLoadLink.download = 'workspace.xml';
|
downLoadLink.download = 'workspace.xml';
|
||||||
downLoadLink.href = URL.createObjectURL(blob);
|
downLoadLink.href = URL.createObjectURL(blob);
|
||||||
downLoadLink.click();
|
downLoadLink.click();
|
||||||
downLoadLink.parentElement.removeChild(downLoadLink);
|
downLoadLink.parentElement.removeChild(downLoadLink);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//ワークスペースのインポート
|
//ワークスペースのインポート
|
||||||
elec.loadWsFile = () => {
|
elec.loadWsFile = () => {
|
||||||
const fileInputEl = document.createElement('input');
|
const fileInputEl = document.createElement('input');
|
||||||
document.body.appendChild(fileInputEl);
|
document.body.appendChild(fileInputEl);
|
||||||
fileInputEl.type = 'file';
|
fileInputEl.type = 'file';
|
||||||
fileInputEl.addEventListener('change', ev => {
|
fileInputEl.addEventListener('change', ev => {
|
||||||
let reader = new FileReader();
|
let reader = new FileReader();
|
||||||
reader.readAsText(ev.target.files[0]);
|
reader.readAsText(ev.target.files[0]);
|
||||||
reader.addEventListener('load', () => {
|
reader.addEventListener('load', () => {
|
||||||
let xml = Blockly.Xml.textToDom(reader.result);
|
let xml = Blockly.Xml.textToDom(reader.result);
|
||||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fileInputEl.click();
|
fileInputEl.click();
|
||||||
fileInputEl.parentElement.removeChild(fileInputEl);
|
fileInputEl.parentElement.removeChild(fileInputEl);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user