/*************** */ /** SSD1306 OLED */ /*************** */ Blockly.Blocks['oc_oled_init'] = { init: function () { this.appendDummyInput() .appendField("有機ELディスプレイ") .appendField(new Blockly.FieldVariable("oled"), "i2c_device") .appendField("に接続"); this.appendDummyInput() .setAlign(Blockly.ALIGN_RIGHT) .appendField("I2Cアドレス") .appendField(new Blockly.FieldDropdown([["0x3c", "0x3c"], ["0x3d", "0x3d"]]), "i2c_addr"); this.appendDummyInput() .setAlign(Blockly.ALIGN_RIGHT) .appendField("画面サイズ(幅x高さ)") .appendField(new Blockly.FieldDropdown([["128x64", "128x64"], ["128x32", "128x32"], ["96x16", "96x16"]]), "disp_size"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setStyle('sensor_blocks'); this.setTooltip("I2C 接続の SSD1306 有機ELディスプレイを使えるようにします。"); this.setHelpUrl(""); } }; javascript.javascriptGenerator.forBlock['oc_oled_init'] = function (block, generator) { var variable_i2c_device = generator.nameDB_.getName(block.getFieldValue('i2c_device'), Blockly.Names.NameType.VARIABLE); var dropdown_i2c_addr = block.getFieldValue('i2c_addr'); var dropdown_disp_size = block.getFieldValue('disp_size'); Blockly.JavaScript.provideFunction_( 'require_oled', [`const _oled = require('@ocoge/ssd1306');`] ); let size_x, size_y; if (dropdown_disp_size == '128x64') { size_x = 128; size_y = 64; } var code = `var _opts = { width: ${size_x}, height: ${size_y}, address: ${dropdown_i2c_addr}, bus: ${apptool.i2c_bus} }; ${variable_i2c_device} = new _oled(_rg, _opts); ${variable_i2c_device}.clearDisplay(); ${variable_i2c_device}.turnOnDisplay(); `; return code; }; /** Draw Line */ Blockly.Blocks['oc_oled_drawline'] = { init: function () { this.appendValueInput("start_x") .setCheck("Number") .appendField(new Blockly.FieldVariable("oled"), "oled_hand") .appendField("に線を描く:始点 ("); this.appendValueInput("start_y") .setCheck("Number") .appendField(","); this.appendValueInput("end_x") .setCheck("Number") .appendField(") 終点 ("); this.appendValueInput("end_y") .setCheck("Number") .appendField(","); this.appendDummyInput() .appendField(") 色") .appendField(new Blockly.FieldDropdown([["白", "1"], ["黒", "0"]]), "color"); this.setInputsInline(true); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setStyle('sensor_blocks'); this.setTooltip("OLED に線を描きます。"); this.setHelpUrl(""); } }; javascript.javascriptGenerator.forBlock['oc_oled_drawline'] = function (block, generator) { var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE); var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC); var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC); var value_end_x = generator.valueToCode(block, 'end_x', javascript.Order.ATOMIC); var value_end_y = generator.valueToCode(block, 'end_y', javascript.Order.ATOMIC); var dropdown_color = block.getFieldValue('color'); var code = `${variable_oled_hand}.drawLine(${value_start_x}, ${value_start_y}, ${value_end_x}, ${value_end_y}, ${dropdown_color});`; return code; }; /** 矩形塗りつぶし */ Blockly.defineBlocksWithJsonArray([{ "type": "oc_oled_fillrect", "message0": "%1 に四角形を描画して塗りつぶす:左上座標 ( %2 , %3 ) 幅 %4 高さ %5 色 %6", "args0": [ { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, { "type": "input_value", "name": "left", "check": "Number" }, { "type": "input_value", "name": "top", "check": "Number" }, { "type": "input_value", "name": "width", "check": "Number" }, { "type": "input_value", "name": "height", "check": "Number" }, { "type": "field_dropdown", "name": "color", "options": [ [ "白", "1" ], [ "黒", "0" ] ] } ], "inputsInline": true, "previousStatement": null, "nextStatement": null, "tooltip": "OLED に四角形を描画して塗りつぶします。", "helpUrl": "", "style": "sensor_blocks" }]); javascript.javascriptGenerator.forBlock['oc_oled_fillrect'] = function (block, generator) { var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE); var value_left = generator.valueToCode(block, 'left', javascript.Order.ATOMIC); var value_top = generator.valueToCode(block, 'top', javascript.Order.ATOMIC); var value_width = generator.valueToCode(block, 'width', javascript.Order.ATOMIC); var value_height = generator.valueToCode(block, 'height', javascript.Order.ATOMIC); var dropdown_color = block.getFieldValue('color'); var code = `${variable_oled_hand}.fillRect(${value_left}, ${value_top}, ${value_width}, ${value_height}, ${dropdown_color});\n`; return code; }; /** 文字を描画(node-canvas) */ Blockly.defineBlocksWithJsonArray([{ "type": "oc_oled_canvastext", "message0": "%1 にテキストを表示 %2 フォント %3 %4 色 %5 %6 始点 x座標 %7 y座標 %8", "args0": [ { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, { "type": "input_value", "name": "text", "check": "String" }, { "type": "field_dropdown", "name": "font", "options": [ [ "美咲ゴシック(8x8)", "8px MisakiGothic" ], [ "PixelMplus(10x10)", "10px PixelMplus10" ], [ "PixelMplus(12x12)", "12px PixelMplus12" ] ] }, { "type": "input_dummy", "align": "RIGHT" }, { "type": "field_dropdown", "name": "color", "options": [ [ "白", "white" ], [ "黒", "black" ] ] }, { "type": "input_dummy", "align": "RIGHT" }, { "type": "input_value", "name": "start_x", "check": "Number", "align": "RIGHT" }, { "type": "input_value", "name": "start_y", "check": "Number", "align": "RIGHT" } ], "inputsInline": false, "previousStatement": null, "nextStatement": null, "style": "sensor_blocks", "tooltip": "OLEDに指定のフォントで文字を描画します(node-canvas利用)。始点は1文字目の左下の座標です。", "helpUrl": "" }]); javascript.javascriptGenerator.forBlock['oc_oled_canvastext'] = function (block, generator) { var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE); var value_text = generator.valueToCode(block, 'text', javascript.Order.ATOMIC); var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC); var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC); var dropdown_font = block.getFieldValue('font'); var dropdown_color = block.getFieldValue('color'); var code = `${variable_oled_hand}.drawRGBAImage(await apptool.textToRGBA(${value_text}, '${dropdown_font}', '${dropdown_color}', ${value_start_x}, ${value_start_y}), 0, 0);`; return code; }; Blockly.defineBlocksWithJsonArray([{ "type": "oc_oled_writestring", "message0": "%1 に英数字を表示 %2 フォント %3 %4 色 %5 %6 始点 x座標 %7 y座標 %8", "args0": [ { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, { "type": "input_value", "name": "text", "check": "String" }, { "type": "field_dropdown", "name": "font", "options": [ ["oled_3x5", "oled_3x5"], ["tiny_4x6", "tiny_4x6"], ["oled_5x7", "oled_5x7"], ["small_6x8", "small_6x8"], ["sinclair_8x8", "sinclair_8x8"], ["sinclair_inverted_8x8", "sinclair_inverted_8x8"], ["tiny_8x8", "tiny_8x8"], ["cp437_8x8", "cp437_8x8"], ["myke2_8x9", "myke2_8x9"], ["small_8x12", "small_8x12"], ["tron_8x12", "tron_8x12"], ["retro_8x16", "retro_8x16"], ["medium_numbers_12x16", "medium_numbers_12x16"], ["big_numbers_14x24", "big_numbers_14x24"], ["arial_bold_16x16", "arial_bold_16x16"], ["arial_italic_16x16", "arial_italic_16x16"], ["arial_normal_16x16", "arial_normal_16x16"], ["big_16x16", "big_16x16"], ["franklin_gothic_normal_16x16", "franklin_gothic_normal_16x16"], ["hallfetica_normal_16x16", "hallfetica_normal_16x16"], ["nadianne_16x16", "nadianne_16x16"], ["sinclair_medium_16x16", "sinclair_medium_16x16"], ["sinclair_medium_inverted_16x16", "sinclair_medium_inverted_16x16"], ["swiss_721_outline_16x16", "swiss_721_outline_16x16"], ["various_symbols_16x16", "various_symbols_16x16"], ["dot_matrix_medium_16x22", "dot_matrix_medium_16x22"], ["dot_matrix_medium_zero_slash_16x22", "dot_matrix_medium_zero_slash_16x22"], ["dot_matrix_medium_numbers_only_16x22", "dot_matrix_medium_numbers_only_16x22"], ["arial_round_16x24", "arial_round_16x24"], ["ocr_a_extended_medium_16x24", "ocr_a_extended_medium_16x24"], ["sixteen_segment_16x24", "sixteen_segment_16x24"], ["grotesk_16x32", "grotesk_16x32"], ["grotesk_bold_16x32", "grotesk_bold_16x32"], ["retro_16x32", "retro_16x32"], ["various_symbols_16x32", "various_symbols_16x32"], ["various_symbols_v2_16x32", "various_symbols_v2_16x32"], ["dot_matrix_large_numbers_only_24x29", "dot_matrix_large_numbers_only_24x29"], ["inconsola_24x32", "inconsola_24x32"], ["ubuntu_24x32", "ubuntu_24x32"], ["ubuntu_bold_24x32", "ubuntu_bold_24x32"], ["dingbats1_extra_large_32x24", "dingbats1_extra_large_32x24"], ["various_symbols_32x32", "various_symbols_32x32"] ] }, { "type": "input_dummy", "align": "RIGHT" }, { "type": "field_dropdown", "name": "color", "options": [ [ "白", "1" ], [ "黒", "0" ] ] }, { "type": "input_dummy", "align": "RIGHT" }, { "type": "input_value", "name": "start_x", "check": "Number", "align": "RIGHT" }, { "type": "input_value", "name": "start_y", "check": "Number", "align": "RIGHT" } ], "inputsInline": false, "previousStatement": null, "nextStatement": null, "tooltip": "OLEDに指定の英字(数字)フォントで文字を描画します。始点は1文字目の左上の座標です。", "helpUrl": "", "style": "sensor_blocks" }]); javascript.javascriptGenerator.forBlock['oc_oled_writestring'] = function (block, generator) { var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE); var value_text = generator.valueToCode(block, 'text', javascript.Order.ATOMIC); var dropdown_font = block.getFieldValue('font'); var dropdown_color = block.getFieldValue('color'); var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC); var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC); Blockly.JavaScript.provideFunction_( 'require_fontpack', [`const _fontpack = require('oled-font-pack');`] ); var code = `${variable_oled_hand}.setCursor(${value_start_x}, ${value_start_y}); ${variable_oled_hand}.writeString(_fontpack.${dropdown_font}, 1, ${value_text}, ${dropdown_color}, false); `; return code; }; /** 点を描画 */ Blockly.defineBlocksWithJsonArray([{ "type": "oc_oled_drawpixel", "message0": "%1 に点を描画:座標 ( %2 , %3 ) 色 %4", "args0": [ { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, { "type": "input_value", "name": "x", "check": "Number" }, { "type": "input_value", "name": "y", "check": "Number" }, { "type": "field_dropdown", "name": "color", "options": [ [ "白", "1" ], [ "黒", "0" ] ] } ], "inputsInline": true, "previousStatement": null, "nextStatement": null, "tooltip": "OLED に点を描きます。", "helpUrl": "", "style": "sensor_blocks" }]); javascript.javascriptGenerator.forBlock['oc_oled_drawpixel'] = function (block, generator) { var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE); var value_x = generator.valueToCode(block, 'x', javascript.Order.ATOMIC); var value_y = generator.valueToCode(block, 'y', javascript.Order.ATOMIC); var dropdown_color = block.getFieldValue('color'); var code = `${variable_oled_hand}.drawPixel([[${value_x}, ${value_y}, ${dropdown_color}]]);\n`; return code; }; /********* */ /** Flyout */ /********* */ flyout_contents = flyout_contents.concat([ { "kind": "label", "text": "有機ELディスプレイ(SSD1306)", "web-line": "4.0", "web-line-width": "200" }, { "kind": "block", "type": "oc_oled_init", "fields": { "type": "field_variable", "name": "i2c_device", "variable": "oled" }, "fields": { "i2c_addr": "0x3c", "disp_size": "128x64" } }, { "kind": "block", "type": "oc_oled_drawpixel", "fields": { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, "inputs": { "x": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, "y": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, }, "fields": { "color": "1", } }, { "kind": "block", "type": "oc_oled_drawline", "fields": { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, "inputs": { "start_x": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, "start_y": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, "end_x": { "shadow": { "type": "math_number", "fields": { "NUM": "128" } } }, "end_y": { "shadow": { "type": "math_number", "fields": { "NUM": "64" } } }, }, "fields": { "color": "1", } }, { "kind": "block", "type": "oc_oled_fillrect", "fields": { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, "inputs": { "left": { "shadow": { "type": "math_number", "fields": { "NUM": "24" } } }, "top": { "shadow": { "type": "math_number", "fields": { "NUM": "12" } } }, "width": { "shadow": { "type": "math_number", "fields": { "NUM": "80" } } }, "height": { "shadow": { "type": "math_number", "fields": { "NUM": "40" } } }, }, "fields": { "color": "1", } }, { "kind": "block", "type": "oc_oled_canvastext", "fields": { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, "inputs": { "text": { "shadow": { "type": "text", "fields": { "TEXT": "我輩は猫である。" } } }, "start_x": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, "start_y": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, }, "fields": { "font": '8px MisakiGothic', "color": "white" } }, { "kind": "block", "type": "oc_oled_writestring", "fields": { "type": "field_variable", "name": "oled_hand", "variable": "oled" }, "inputs": { "text": { "shadow": { "type": "text", "fields": { "TEXT": "I am a cat." } } }, "start_x": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, "start_y": { "shadow": { "type": "math_number", "fields": { "NUM": "0" } } }, }, "fields": { "font": 'oled_5x7', "color": "1" } } ]);