From dc2af387afc84a8ff2e9808ba492b43f6ae043dc Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 16:48:03 -0400 Subject: [PATCH 1/7] Prepare fake toolbox items to be done for real --- src/editor/editor.ts | 23 +- .../add_hardware_component_category.ts | 50 --- src/toolbox/blocks_components.ts | 39 ++ src/toolbox/blocks_mechanisms.ts | 123 ++++++ src/toolbox/component_samples_category.ts | 228 +--------- src/toolbox/components_category.ts | 2 + src/toolbox/hardware_category.ts | 401 +++++++++++------- .../hardware_components/color_sensor.ts | 96 +++++ src/toolbox/hardware_components/servo.ts | 104 +++++ .../hardware_components/smart_motor.ts | 175 ++++++++ .../hardware_components/touch_sensor.ts | 104 +++++ src/toolbox/robot_category.ts | 134 ------ src/toolbox/toolbox.ts | 38 ++ src/toolbox/toolbox_mechanism.ts | 19 - src/toolbox/toolbox_opmode.ts | 34 -- src/toolbox/toolbox_robot.ts | 18 - 16 files changed, 934 insertions(+), 654 deletions(-) delete mode 100644 src/toolbox/add_hardware_component_category.ts create mode 100644 src/toolbox/blocks_components.ts create mode 100644 src/toolbox/blocks_mechanisms.ts create mode 100644 src/toolbox/hardware_components/color_sensor.ts create mode 100644 src/toolbox/hardware_components/servo.ts create mode 100644 src/toolbox/hardware_components/smart_motor.ts create mode 100644 src/toolbox/hardware_components/touch_sensor.ts delete mode 100644 src/toolbox/robot_category.ts create mode 100644 src/toolbox/toolbox.ts delete mode 100644 src/toolbox/toolbox_mechanism.ts delete mode 100644 src/toolbox/toolbox_opmode.ts delete mode 100644 src/toolbox/toolbox_robot.ts diff --git a/src/editor/editor.ts b/src/editor/editor.ts index a3938082..231fe799 100644 --- a/src/editor/editor.ts +++ b/src/editor/editor.ts @@ -24,9 +24,7 @@ import * as Blockly from 'blockly/core'; import { extendedPythonGenerator } from './extended_python_generator'; import { GeneratorContext } from './generator_context'; import * as commonStorage from '../storage/common_storage'; -import * as toolboxOpmode from '../toolbox/toolbox_opmode'; -import * as toolboxMechanism from '../toolbox/toolbox_mechanism'; -import * as toolboxRobot from '../toolbox/toolbox_robot'; +import { getToolboxJSON } from '../toolbox/toolbox'; //import { testAllBlocksInToolbox } from '../toolbox/toolbox_tests'; import { MethodsCategory} from '../toolbox/methods_category'; @@ -201,23 +199,8 @@ export class Editor { }, 50); return; } - switch(this.currentModule.moduleType){ - case commonStorage.MODULE_TYPE_PROJECT: - this.setToolbox(toolboxRobot.getToolboxJSON(shownPythonToolboxCategories)); - break; - case commonStorage.MODULE_TYPE_MECHANISM: - this.setToolbox(toolboxMechanism.getToolboxJSON(shownPythonToolboxCategories)); - break; - case commonStorage.MODULE_TYPE_OPMODE: -/* - * TODO: When editing an opmode, we'll need to have blocks for all the methods that a robot has. - * Not sure what this will be replaced with, but it will need something. - * const robotBlocks = commonStorage.extractExportedBlocks( - * this.currentModule.projectName, this.projectContent); -*/ - this.setToolbox(toolboxOpmode.getToolboxJSON(shownPythonToolboxCategories)); - break; - } + this.setToolbox(getToolboxJSON( + shownPythonToolboxCategories, this.currentModule)); } } diff --git a/src/toolbox/add_hardware_component_category.ts b/src/toolbox/add_hardware_component_category.ts deleted file mode 100644 index b7c580d4..00000000 --- a/src/toolbox/add_hardware_component_category.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const category = -{ - kind: 'category', - name: 'Hardware', - contents: [ - { - kind: 'label', - text: 'Components', - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_motor', - TYPE: 'SmartMotor' - }, - extraState: { - importModule: 'smart_motor', - params: [{ name: 'motor_port', type: 'int' }], - hideParams: true - }, - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_color_range_sensor', - TYPE: 'ColorRangeSensor' - }, - extraState: { - importModule: 'color_range_sensor', - params: [{ name: 'i2c_port', type: 'int' }], - hideParams: true - }, - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_touch_sensor', - TYPE: 'RevTouchSensor' - }, - extraState: { - importModule: 'rev_touch_sensor', - params: [{ name: 'smartIO_port', type: 'int' }], - hideParams: true - }, - }, - ], -} \ No newline at end of file diff --git a/src/toolbox/blocks_components.ts b/src/toolbox/blocks_components.ts new file mode 100644 index 00000000..9093552c --- /dev/null +++ b/src/toolbox/blocks_components.ts @@ -0,0 +1,39 @@ +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author alan@porpoiseful.com (Alan Smith) + */ +import * as Blockly from 'blockly/core'; + +import * as ToolboxItems from './items'; +import * as ColorSensor from './hardware_components/color_sensor'; +import * as SmartMotor from './hardware_components/smart_motor'; +import * as TouchSensor from './hardware_components/touch_sensor'; +import * as Servo from './hardware_components/servo'; + +import { Color } from 'antd/es/color-picker'; + + +export function getAllPossibleComponents(hideParams : boolean): ToolboxItems.ContentsType[] { + return [ + SmartMotor.getDefinitionBlock(hideParams), + TouchSensor.getDefinitionBlock(hideParams), + ColorSensor.getDefinitionBlock(hideParams), + Servo.getDefinitionBlock(hideParams), + ]; +} diff --git a/src/toolbox/blocks_mechanisms.ts b/src/toolbox/blocks_mechanisms.ts new file mode 100644 index 00000000..8ddc61b2 --- /dev/null +++ b/src/toolbox/blocks_mechanisms.ts @@ -0,0 +1,123 @@ +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author alan@porpoiseful.com (Alan Smith) + */ +import * as Blockly from 'blockly/core'; + +import * as ToolboxItems from './items'; + +/** + * TODO: This is all fake right now, it will be generated dynamically + * based on reading things from mechanisms. + */ + +export function getAllPossibleMechanisms(): ToolboxItems.ContentsType[] { + return [ + + { + kind: 'block', + type: 'mrc_mechanism', + fields: { + NAME: 'claw', + TYPE: 'Claw' + }, + extraState: { + importModule: 'claw', + params: [{ name: 'gripper_port', type: 'int' }, + { name: 'piece_sensor_port', type: 'int' }, + ] + }, + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 1 + }, + }, + }, + ARG1: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1 + }, + }, + }, + } + }, + { + kind: 'block', + type: 'mrc_mechanism', + fields: { + NAME: 'drive', + TYPE: 'DriveMecanum' + }, + extraState: { + importModule: 'DriveMecanum', + params: [{ name: 'front_left_drive_port', type: 'int' }, + { name: 'front_right_drive_port', type: 'int' }, + { name: 'back_left_drive_port', type: 'int' }, + { name: 'back_right_drive_port', type: 'int' }, + ] + }, + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 1 + }, + }, + }, + ARG1: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 2 + }, + }, + }, + ARG2: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 3 + }, + }, + }, + ARG3: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 4 + }, + }, + }, + } + }, + ]; +} + diff --git a/src/toolbox/component_samples_category.ts b/src/toolbox/component_samples_category.ts index 68008610..1f1662a8 100644 --- a/src/toolbox/component_samples_category.ts +++ b/src/toolbox/component_samples_category.ts @@ -66,232 +66,8 @@ export const category = }, ], }, - { - kind: 'category', - name: 'REV Servo', - contents: [ - // def set_position(self, pos: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'pos', - type: 'float', - }, - ], - tooltip: 'Set the servo to a position between 0 and 1.', - importModule: '', - componentClassName: 'rev.Servo', - componentName: 'clawServo', - }, - fields: { - COMPONENT_NAME: 'clawServo', - FUNC: 'set_position', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 0.5, - }, - }, - }, - }, - }, - // def set_angle_degrees(self, angle: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'angle', - type: 'float', - }, - ], - tooltip: 'Set the servo to an angle between 0 and 270.', - importModule: '', - componentClassName: 'rev.Servo', - componentName: 'clawServo', - }, - fields: { - COMPONENT_NAME: 'clawServo', - FUNC: 'set_angle_degrees', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 180, - }, - }, - }, - }, - }, - ], - }, - { - kind: 'category', - name: 'REV Smart Motor', - contents: [ - // def set_speed(self, speed: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'speed', - type: 'float', - }, - ], - tooltip: 'Set the motor to a speed between -1 and 1.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'leftMotor', - }, - fields: { - COMPONENT_NAME: 'leftMotor', - FUNC: 'set_speed', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 0.8, - }, - }, - }, - }, - }, - // def set_angle_degrees(self, angle: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'angle', - type: 'float', - }, - ], - tooltip: 'Set the motor to an angle between 0 and 360.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'leftMotor', - }, - fields: { - COMPONENT_NAME: 'leftMotor', - FUNC: 'set_angle_degrees', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 180, - }, - }, - }, - }, - }, - // def get_num_relative_encoder_ticks(self) -> int: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'int', - args: [], - tooltip: 'Get the number of relative motor ticks since reset of encoder.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'leftMotor', - }, - fields: { - COMPONENT_NAME: 'leftMotor', - FUNC: 'get_num_relative_encoder_ticks', - }, - inputs: {}, - }, - // def get_angle_degrees(self) -> float: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'float', - args: [], - tooltip: 'Get the angle position of the motor.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'leftMotor', - }, - fields: { - COMPONENT_NAME: 'leftMotor', - FUNC: 'get_angle_degrees', - }, - inputs: {}, - }, - // def reset_relative_encoder(self) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [], - tooltip: 'Reset the relative encoder value to 0.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'leftMotor', - }, - fields: { - COMPONENT_NAME: 'leftMotor', - FUNC: 'reset_relative_encoder', - }, - inputs: {}, - }, - ] - }, - { - kind: 'category', - name: 'REV Touch Sensor', - contents: [ - // def is_pressed(self) -> bool: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'bool', - args: [], - tooltip: 'Return whether the touch sensor is pressed.', - importModule: '', - componentClassName: 'rev.TouchSensor', - componentName: 'frontTouch', - }, - fields: { - COMPONENT_NAME: 'frontTouch', - FUNC: 'is_pressed', - }, - inputs: {}, - }, - ], - }, + + { kind: 'category', name: 'SparkFun LED Stick', diff --git a/src/toolbox/components_category.ts b/src/toolbox/components_category.ts index b312cadc..34f934c4 100644 --- a/src/toolbox/components_category.ts +++ b/src/toolbox/components_category.ts @@ -30,6 +30,8 @@ import * as toolboxItems from './items'; import * as commonStorage from '../storage/common_storage'; import { MRC_CATEGORY_STYLE_COMPONENTS } from '../themes/styles'; + + const CUSTOM_CATEGORY_COMPONENTS = 'COMPONENTS'; export const category = { diff --git a/src/toolbox/hardware_category.ts b/src/toolbox/hardware_category.ts index cffc7ef5..f5b9d8c2 100644 --- a/src/toolbox/hardware_category.ts +++ b/src/toolbox/hardware_category.ts @@ -1,172 +1,267 @@ -export const category = -{ - kind: 'category', - name: 'Hardware', - contents: [ +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author alan@porpoiseful.com (Alan Smith) + */ + +/** + * TODO: This is all fake right now, it will be generated dynamically + * based on the components that are available in the current module. + */ + +import * as Blockly from 'blockly/core'; + +import * as toolboxItems from './items'; +import * as commonStorage from '../storage/common_storage'; +import { getAllPossibleMechanisms } from './blocks_mechanisms'; +import { getAllPossibleComponents } from './blocks_components'; +import * as SmartMotor from './hardware_components/smart_motor'; +import * as TouchSensor from './hardware_components/touch_sensor'; + +export function getHardwareCategory(currentModule: commonStorage.Module) { + if (currentModule.moduleType === commonStorage.MODULE_TYPE_OPMODE) { + return { + kind: 'category', + name: 'Robot', + contents: [ + getRobotMechanismsBlocks(currentModule), + getRobotComponentsBlocks(currentModule), + getRobotMethodsBlocks(currentModule), + ] + }; + } + if (currentModule.moduleType === commonStorage.MODULE_TYPE_PROJECT) { + return { + kind: 'category', + name: 'Hardware', + contents: [ + getRobotMechanismsBlocks(currentModule), + getRobotComponentsBlocks(currentModule), + ] + }; + } + if (currentModule.moduleType === commonStorage.MODULE_TYPE_MECHANISM) { + return getComponentsBlocks(currentModule); + } + // Return default empty category if module type doesn't match + return { + kind: 'category', + name: 'Hardware', + contents: [] + }; +} + +// TODO: This needs to load the robot file and get the list of mechanisms +function getRobotMechanismsBlocks(currentModule: commonStorage.Module) { + const includeAdd = currentModule.moduleType !== commonStorage.MODULE_TYPE_OPMODE; + + const contents = []; + + // Only include the "+ Mechanism" category if includeAdd is true + if (includeAdd) { + contents.push({ + kind: 'category', + name: '+ Mechanism', + contents: getAllPossibleMechanisms(), + }); + } + + // Add the existing mechanisms + contents.push( { - kind: 'label', - text: 'Mechanisms', - }, - { - kind: 'block', - type: 'mrc_mechanism', - fields: { - NAME: 'claw', - TYPE: 'Claw' - }, - extraState: { - importModule: 'claw', - params: [{ name: 'gripper_port', type: 'int' }, - { name: 'piece_sensor_port', type: 'int' }, - ] - }, - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 1 - }, + kind: 'category', + name: 'drive', + contents: [ + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: '', + args: [ + { + name: 'forward_speed', + type: 'float', + }, + { + name: 'strafe_right_speed', + type: 'float', + }, + { + name: 'rotate_cw_speed', + type: 'float', + }, + ], + tooltip: 'Drive (robot relative)', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: 'robot.drive', }, - }, - ARG1: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartIO', - PORT_NUM: 1 - }, + fields: { + COMPONENT_NAME: 'robot.drive', + FUNC: 'drive_field_relative', }, + inputs: {}, }, - } + ] }, { - kind: 'block', - type: 'mrc_mechanism', - fields: { - NAME: 'drive', - TYPE: 'DriveMecanum' - }, - extraState: { - importModule: 'DriveMecanum', - params: [{ name: 'front_left_drive_port', type: 'int' }, - { name: 'front_right_drive_port', type: 'int' }, - { name: 'back_left_drive_port', type: 'int' }, - { name: 'back_right_drive_port', type: 'int' }, - ] - }, - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 1 - }, - }, + kind: 'category', + name: 'claw', + contents: [ + { + kind: 'category', + name: 'gripper', + contents: [], }, - ARG1: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 2 + { + kind: 'category', + name: 'piece_sensor', + contents: [ + // def get_color_rgb(self) -> tuple[int, int, int]: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in rgb (red, green, blue).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: 'colorSensor', + }, + fields: { + COMPONENT_NAME: 'robot.claw.piece_sensor', + FUNC: 'get_color_rgb', + }, + inputs: {}, }, - }, - }, - ARG2: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 3 + // def get_color_hsv(self) -> tuple[int, int, int]: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in hsv (hue, saturation, value).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: 'colorSensor', + }, + fields: { + COMPONENT_NAME: 'robot.claw.piece_sensor', + FUNC: 'get_color_hsv', + }, + inputs: {}, }, - }, - }, - ARG3: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 4 + // def get_distance_mm(self) -> float: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'float', + args: [], + tooltip: 'Get the distance of the object seen.', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: 'colorSensor', + }, + fields: { + COMPONENT_NAME: 'robot.claw.piece_sensor', + FUNC: 'get_distance_mm', + }, + inputs: {}, }, - }, + ], }, - } + ] }, { - kind: 'label', - text: 'Components', + kind: 'category', + name: 'flywheel', + contents: [], }, { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_motor', - TYPE: 'SmartMotor' - }, - extraState: { - importModule: 'smart_motor', - params: [{ name: 'motor_port', type: 'int' }] - }, - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 1 - }, - }, - }, - } + kind: 'category', + name: 'shooter', + contents: [], + } + ); + + return { + kind: 'category', + name: 'Mechanisms', + contents, + }; +} + +// TODO: This needs to load the robot file and get the list of components +function getRobotComponentsBlocks(currentModule: commonStorage.Module) { + const includeAdd = currentModule.moduleType !== commonStorage.MODULE_TYPE_OPMODE; + const contents = []; + + if (includeAdd) { + contents.push({ + kind: 'category', + name: '+ Component', + contents: getAllPossibleComponents(false) + }); + } + + return { + kind: 'category', + name: 'Components', + contents, + }; +} + +function getRobotMethodsBlocks(currentModule: commonStorage.Module) { + return { + kind: 'category', + name: 'Methods', + contents: [] + }; +} + +function getComponentsBlocks(currentModule: commonStorage.Module) { + const contents = []; + contents.push({ + kind: 'category', + name: '+ Component', + contents: getAllPossibleComponents(true) + }); + contents.push({ + kind: 'category', + name: 'my_motor', + contents: SmartMotor.getBlocks('my_motor') }, { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_color_range_sensor', - TYPE: 'ColorRangeSensor' - }, - extraState: { - importModule: 'color_range_sensor', - params: [{ name: 'i2c_port', type: 'int' }] - }, - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'I2C', - PORT_NUM: 1 - }, - }, - }, - } - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_touch_sensor', - TYPE: 'RevTouchSensor' - }, - extraState: { - importModule: 'rev_touch_sensor', - params: [{ name: 'smartIO_port', type: 'int' }] - }, - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartIO', - PORT_NUM: 1 - }, - }, - }, - } + kind: 'category', + name: 'my_touch_sensor', + contents: TouchSensor.getBlocks('my_touch_sensor') }, - ], + ); + return { + kind: 'category', + name: 'Components', + contents, + }; } \ No newline at end of file diff --git a/src/toolbox/hardware_components/color_sensor.ts b/src/toolbox/hardware_components/color_sensor.ts new file mode 100644 index 00000000..525b4488 --- /dev/null +++ b/src/toolbox/hardware_components/color_sensor.ts @@ -0,0 +1,96 @@ +import * as Blockly from 'blockly/core'; +import * as ToolboxItems from '../items'; + +export const TYPE_NAME = 'ColorRangeSensor'; + +export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_color_range_sensor', + TYPE: 'ColorRangeSensor' + }, + extraState: { + importModule: 'rev_color_range_sensor', + params: [{ name: 'smartIO_port', type: 'int' }], + hideParams: hideParams + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1 + }, + }, + }, + } + }) + }; +} + +export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { + return [ + // def get_color_rgb(self) -> tuple[int, int, int]: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in rgb (red, green, blue).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_color_rgb', + }, + inputs: {}, + }, + // def get_color_hsv(self) -> tuple[int, int, int]: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in hsv (hue, saturation, value).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_color_hsv', + }, + inputs: {}, + }, + // def get_distance_mm(self) -> float: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'float', + args: [], + tooltip: 'Get the distance of the object seen.', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_distance_mm', + }, + inputs: {}, + }, + + ]; +} \ No newline at end of file diff --git a/src/toolbox/hardware_components/servo.ts b/src/toolbox/hardware_components/servo.ts new file mode 100644 index 00000000..25238480 --- /dev/null +++ b/src/toolbox/hardware_components/servo.ts @@ -0,0 +1,104 @@ +import * as Blockly from 'blockly/core'; +import * as ToolboxItems from '../items'; + +export const TYPE_NAME = 'Servo'; + +export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_servo', + TYPE: 'RevServo' + }, + extraState: { + importModule: 'rev_servo', + params: [{ name: 'servo_port', type: 'int' }], + hideParams: hideParams + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1 + }, + }, + }, + } + }) + }; +} + +export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { + return [ + // def set_position(self, pos: float) -> None: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'pos', + type: 'float', + }, + ], + tooltip: 'Set the servo to a position between 0 and 1.', + importModule: '', + componentClassName: 'rev.Servo', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_position', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', + fields: { + NUM: 0.5, + }, + }, + }, + }, + }, + // def set_angle_degrees(self, angle: float) -> None: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'angle', + type: 'float', + }, + ], + tooltip: 'Set the servo to an angle between 0 and 270.', + importModule: '', + componentClassName: 'rev.Servo', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_angle_degrees', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', + fields: { + NUM: 180, + }, + }, + }, + }, + }, + ]; +} diff --git a/src/toolbox/hardware_components/smart_motor.ts b/src/toolbox/hardware_components/smart_motor.ts new file mode 100644 index 00000000..4e2d489e --- /dev/null +++ b/src/toolbox/hardware_components/smart_motor.ts @@ -0,0 +1,175 @@ +import * as Blockly from 'blockly/core'; +import * as ToolboxItems from '../items'; + +export const TYPE_NAME = 'SmartMotor'; + +export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_motor', + TYPE: 'SmartMotor' + }, + extraState: { + importModule: 'smart_motor', + params: [{ name: 'motor_port', type: 'int' }], + hideParams: hideParams + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 1 + }, + }, + }, + } + }) + } +} + +export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { + return [ + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: componentName, + EVENT_NAME: 'on_stall', + }, + }, + // def set_speed(self, speed: float) -> None: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'speed', + type: 'float', + }, + ], + tooltip: 'Set the motor to a speed between -1 and 1.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_speed', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', + fields: { + NUM: 0.8, + }, + }, + }, + }, + }, + // def set_angle_degrees(self, angle: float) -> None: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'angle', + type: 'float', + }, + ], + tooltip: 'Set the motor to an angle between 0 and 360.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_angle_degrees', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', + fields: { + NUM: 180, + }, + }, + }, + }, + }, + // def get_num_relative_encoder_ticks(self) -> int: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'int', + args: [], + tooltip: 'Get the number of relative motor ticks since reset of encoder.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_num_relative_encoder_ticks', + }, + inputs: {}, + }, + // def get_angle_degrees(self) -> float: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'float', + args: [], + tooltip: 'Get the angle position of the motor.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_angle_degrees', + }, + inputs: {}, + }, + // def reset_relative_encoder(self) -> None: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [], + tooltip: 'Reset the relative encoder value to 0.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'reset_relative_encoder', + }, + inputs: {}, + }, + ]; +} \ No newline at end of file diff --git a/src/toolbox/hardware_components/touch_sensor.ts b/src/toolbox/hardware_components/touch_sensor.ts new file mode 100644 index 00000000..1a5f78dc --- /dev/null +++ b/src/toolbox/hardware_components/touch_sensor.ts @@ -0,0 +1,104 @@ +import * as Blockly from 'blockly/core'; +import * as ToolboxItems from '../items'; + +export const TYPE_NAME = 'TouchSensor'; + +export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_touch_sensor', + TYPE: 'RevTouchSensor' + }, + extraState: { + importModule: 'rev_touch_sensor', + params: [{ name: 'smartIO_port', type: 'int' }], + hideParams: hideParams + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1 + }, + }, + }, + } + }) + }; +} + +export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { + return [ + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'pressed', + }, + }, + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'released', + }, + }, + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [ + { + name: 'new_state', + type: 'boolean', + }, + ], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'changed', + }, + }, + // def is_pressed(self) -> bool: + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'bool', + args: [], + tooltip: 'Return whether the touch sensor is pressed.', + importModule: '', + componentClassName: 'rev.TouchSensor', + componentName: componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'is_pressed', + }, + inputs: {}, + }, + ]; +} diff --git a/src/toolbox/robot_category.ts b/src/toolbox/robot_category.ts deleted file mode 100644 index e7bd2768..00000000 --- a/src/toolbox/robot_category.ts +++ /dev/null @@ -1,134 +0,0 @@ -export const category = -{ - kind: 'category', - name: 'Robot', - contents: [ - { - kind: 'category', - name: 'drive', - contents: [ - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: '', - args: [ - { - name: 'forward_speed', - type: 'float', - }, - { - name: 'strafe_right_speed', - type: 'float', - }, - { - name: 'rotate_cw_speed', - type: 'float', - }, - ], - tooltip: 'Drive (robot relative)', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'robot.drive', - }, - fields: { - COMPONENT_NAME: 'robot.drive', - FUNC: 'drive_field_relative', - }, - inputs: {}, - }, - ] - }, - { - kind: 'category', - name: 'claw', - contents: [ - { - kind: 'category', - name: 'gripper', - contents: [ - - ], - }, - { - kind: 'category', - name: 'piece_sensor', - contents: [ - // def get_color_rgb(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in rgb (red, green, blue).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'robot.claw.piece_sensor', - FUNC: 'get_color_rgb', - }, - inputs: {}, - }, - // def get_color_hsv(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in hsv (hue, saturation, value).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'robot.claw.piece_sensor', - FUNC: 'get_color_hsv', - }, - inputs: {}, - }, - // def get_distance_mm(self) -> float: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'float', - args: [], - tooltip: 'Get the distance of the object seen.', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'robot.claw.piece_sensor', - FUNC: 'get_distance_mm', - }, - inputs: {}, - }, - ], - }, - ] - }, - { - kind: 'category', - name: 'flywheel', - contents: [ - - ], - }, - { - kind: 'category', - name: 'shooter', - contents: [ - - ], - }, - ], -} \ No newline at end of file diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts new file mode 100644 index 00000000..e7308354 --- /dev/null +++ b/src/toolbox/toolbox.ts @@ -0,0 +1,38 @@ +import * as Blockly from 'blockly/core'; +import * as commonStorage from '../storage/common_storage'; +import * as common from './toolbox_common' +import { getHardwareCategory } from './hardware_category'; +import { category as eventCategory } from './event_category'; + +export function getToolboxJSON( + shownPythonToolboxCategories: Set | null, + currentModule: commonStorage.Module): Blockly.utils.toolbox.ToolboxDefinition { + switch (currentModule.moduleType) { + case commonStorage.MODULE_TYPE_PROJECT: + case commonStorage.MODULE_TYPE_MECHANISM: + return { + kind: 'categoryToolbox', + contents: [ + getHardwareCategory(currentModule), + { kind: 'sep' }, + ...common.getToolboxItems(shownPythonToolboxCategories), + eventCategory, + + ] + }; break; + case commonStorage.MODULE_TYPE_OPMODE: + return { + kind: 'categoryToolbox', + contents: [ + getHardwareCategory(currentModule), + { kind: 'sep' }, + ...common.getToolboxItems(shownPythonToolboxCategories) + ] + }; + default: + return { + kind: 'categoryToolbox', + contents: [] + }; + } +} \ No newline at end of file diff --git a/src/toolbox/toolbox_mechanism.ts b/src/toolbox/toolbox_mechanism.ts deleted file mode 100644 index ce841212..00000000 --- a/src/toolbox/toolbox_mechanism.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as common from './toolbox_common' -import { category as hardwareComponentCategory } from './add_hardware_component_category'; -import { category as eventCategory } from './event_category'; -import { category as componentsCategory } from './components_category'; - -export function getToolboxJSON( - shownPythonToolboxCategories: Set | null) { - - return { - kind: 'categoryToolbox', - contents: [ - hardwareComponentCategory, - componentsCategory, - eventCategory, - { kind: 'sep' }, - ...common.getToolboxItems(shownPythonToolboxCategories) - ] - }; -} diff --git a/src/toolbox/toolbox_opmode.ts b/src/toolbox/toolbox_opmode.ts deleted file mode 100644 index 2b2e3139..00000000 --- a/src/toolbox/toolbox_opmode.ts +++ /dev/null @@ -1,34 +0,0 @@ - import * as common from './toolbox_common' - import {category as robotCategory} from './/robot_category'; - - export function getToolboxJSON( - shownPythonToolboxCategories: Set | null) { - - return { - kind: 'categoryToolbox', - contents: [ - robotCategory, - { kind: 'sep' }, - ...common.getToolboxItems(shownPythonToolboxCategories) - ] - }; - } - /** TODO: - * The opmode will need to have blocks for all the methods that are in the - * robot. This commented out code will have to be reworked in the future to - * do this. - */ - /*if (opt_robotBlocks.length) { - contents.push.apply( - contents, - [ - { - kind: 'sep', - }, - { - kind: 'category', - name: 'Project', - contents: opt_robotBlocks, - }, - ]); - }*/ \ No newline at end of file diff --git a/src/toolbox/toolbox_robot.ts b/src/toolbox/toolbox_robot.ts deleted file mode 100644 index c61acc72..00000000 --- a/src/toolbox/toolbox_robot.ts +++ /dev/null @@ -1,18 +0,0 @@ - import * as common from './toolbox_common' - import {category as hardwareCategory} from './hardware_category'; - import {category as eventCategory} from './event_category'; - - export function getToolboxJSON( - shownPythonToolboxCategories: Set | null) { - - return { - kind: 'categoryToolbox', - contents: [ - hardwareCategory, - eventCategory, - { kind: 'sep' }, - ...common.getToolboxItems(shownPythonToolboxCategories) - ] - }; - } - \ No newline at end of file From ef4338e74a127bd3f4f73a2b1a7c449f9d11545b Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:06:41 -0400 Subject: [PATCH 2/7] Use copilot to match Google coding standards for Typescript --- .../hardware_components/color_sensor.ts | 198 +++++----- src/toolbox/hardware_components/servo.ts | 203 +++++----- .../hardware_components/smart_motor.ts | 346 ++++++++++-------- .../hardware_components/touch_sensor.ts | 218 ++++++----- 4 files changed, 539 insertions(+), 426 deletions(-) diff --git a/src/toolbox/hardware_components/color_sensor.ts b/src/toolbox/hardware_components/color_sensor.ts index 525b4488..cf659ff1 100644 --- a/src/toolbox/hardware_components/color_sensor.ts +++ b/src/toolbox/hardware_components/color_sensor.ts @@ -1,96 +1,122 @@ -import * as Blockly from 'blockly/core'; +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Color range sensor hardware component definitions. + * @author alan@porpoiseful.com (Alan Smith) + */ + import * as ToolboxItems from '../items'; export const TYPE_NAME = 'ColorRangeSensor'; +/** + * Returns a component definition block for a color range sensor. + */ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { - return { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_color_range_sensor', - TYPE: 'ColorRangeSensor' - }, - extraState: { - importModule: 'rev_color_range_sensor', - params: [{ name: 'smartIO_port', type: 'int' }], - hideParams: hideParams - }, - ...(hideParams ? {} : { - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartIO', - PORT_NUM: 1 - }, - }, - }, - } - }) - }; -} - -export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { - return [ - // def get_color_rgb(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in rgb (red, green, blue).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'get_color_rgb', - }, - inputs: {}, - }, - // def get_color_hsv(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in hsv (hue, saturation, value).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: componentName, - }, + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_color_range_sensor', + TYPE: 'ColorRangeSensor', + }, + extraState: { + importModule: 'rev_color_range_sensor', + params: [{name: 'smartIO_port', type: 'int'}], + hideParams, + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', fields: { - COMPONENT_NAME: componentName, - FUNC: 'get_color_hsv', + TYPE: 'SmartIO', + PORT_NUM: 1, }, - inputs: {}, - }, - // def get_distance_mm(self) -> float: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'float', - args: [], - tooltip: 'Get the distance of the object seen.', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'get_distance_mm', - }, - inputs: {}, + }, }, + }, + }), + }; +} - ]; +/** + * Returns the blocks available for a color range sensor component. + */ +export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { + return [ + // Method: get_color_rgb() -> tuple[int, int, int] + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in rgb (red, green, blue).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_color_rgb', + }, + inputs: {}, + }, + // Method: get_color_hsv() -> tuple[int, int, int] + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'tuple[int, int, int]', + args: [], + tooltip: 'Get the color in hsv (hue, saturation, value).', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_color_hsv', + }, + inputs: {}, + }, + // Method: get_distance_mm() -> float + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'float', + args: [], + tooltip: 'Get the distance of the object seen.', + importModule: '', + componentClassName: 'rev.ColorRangeSensor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_distance_mm', + }, + inputs: {}, + }, + ]; } \ No newline at end of file diff --git a/src/toolbox/hardware_components/servo.ts b/src/toolbox/hardware_components/servo.ts index 25238480..32a62cbf 100644 --- a/src/toolbox/hardware_components/servo.ts +++ b/src/toolbox/hardware_components/servo.ts @@ -1,104 +1,133 @@ +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Servo hardware component definitions. + * @author alan@porpoiseful.com (Alan Smith) + */ + import * as Blockly from 'blockly/core'; + import * as ToolboxItems from '../items'; export const TYPE_NAME = 'Servo'; +/** + * Returns a component definition block for a servo. + */ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { - return { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_servo', - TYPE: 'RevServo' - }, - extraState: { - importModule: 'rev_servo', - params: [{ name: 'servo_port', type: 'int' }], - hideParams: hideParams + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_servo', + TYPE: 'RevServo', + }, + extraState: { + importModule: 'rev_servo', + params: [{name: 'servo_port', type: 'int'}], + hideParams, + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1, + }, + }, }, - ...(hideParams ? {} : { - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartIO', - PORT_NUM: 1 - }, - }, - }, - } - }) - }; + }, + }), + }; } +/** + * Returns the blocks available for a servo component. + */ export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { - return [ - // def set_position(self, pos: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'pos', - type: 'float', - }, - ], - tooltip: 'Set the servo to a position between 0 and 1.', - importModule: '', - componentClassName: 'rev.Servo', - componentName: componentName, - }, + return [ + // Method: set_position(pos: float) -> None + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'pos', + type: 'float', + }, + ], + tooltip: 'Set the servo to a position between 0 and 1.', + importModule: '', + componentClassName: 'rev.Servo', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_position', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', fields: { - COMPONENT_NAME: componentName, - FUNC: 'set_position', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 0.5, - }, - }, - }, + NUM: 0.5, }, + }, }, - // def set_angle_degrees(self, angle: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'angle', - type: 'float', - }, - ], - tooltip: 'Set the servo to an angle between 0 and 270.', - importModule: '', - componentClassName: 'rev.Servo', - componentName: componentName, - }, + }, + }, + // Method: set_angle_degrees(angle: float) -> None + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'angle', + type: 'float', + }, + ], + tooltip: 'Set the servo to an angle between 0 and 270.', + importModule: '', + componentClassName: 'rev.Servo', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_angle_degrees', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', fields: { - COMPONENT_NAME: componentName, - FUNC: 'set_angle_degrees', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 180, - }, - }, - }, + NUM: 180, }, + }, }, - ]; + }, + }, + ]; } diff --git a/src/toolbox/hardware_components/smart_motor.ts b/src/toolbox/hardware_components/smart_motor.ts index 4e2d489e..b1fa5de7 100644 --- a/src/toolbox/hardware_components/smart_motor.ts +++ b/src/toolbox/hardware_components/smart_motor.ts @@ -1,175 +1,203 @@ -import * as Blockly from 'blockly/core'; +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview SmartMotor hardware component definitions. + * @author alan@porpoiseful.com (Alan Smith) + */ + import * as ToolboxItems from '../items'; export const TYPE_NAME = 'SmartMotor'; +/** + * Returns a component definition block for a smart motor. + */ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { - return { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_motor', - TYPE: 'SmartMotor' - }, - extraState: { - importModule: 'smart_motor', - params: [{ name: 'motor_port', type: 'int' }], - hideParams: hideParams + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_motor', + TYPE: 'SmartMotor', + }, + extraState: { + importModule: 'smart_motor', + params: [{name: 'motor_port', type: 'int'}], + hideParams, + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartMotor', + PORT_NUM: 1, + }, + }, }, - ...(hideParams ? {} : { - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartMotor', - PORT_NUM: 1 - }, - }, - }, - } - }) - } + }, + }), + }; } +/** + * Returns the blocks available for a smart motor component. + */ export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { - return [ - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: componentName, - EVENT_NAME: 'on_stall', - }, - }, - // def set_speed(self, speed: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'speed', - type: 'float', - }, - ], - tooltip: 'Set the motor to a speed between -1 and 1.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'set_speed', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 0.8, - }, - }, - }, - }, - }, - // def set_angle_degrees(self, angle: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'angle', - type: 'float', - }, - ], - tooltip: 'Set the motor to an angle between 0 and 360.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'set_angle_degrees', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 180, - }, - }, - }, - }, - }, - // def get_num_relative_encoder_ticks(self) -> int: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'int', - args: [], - tooltip: 'Get the number of relative motor ticks since reset of encoder.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'get_num_relative_encoder_ticks', - }, - inputs: {}, - }, - // def get_angle_degrees(self) -> float: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'float', - args: [], - tooltip: 'Get the angle position of the motor.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: componentName, - }, + return [ + // Event: on_stall + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: componentName, + EVENT_NAME: 'on_stall', + }, + }, + // Method: set_speed(speed: float) -> None + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'speed', + type: 'float', + }, + ], + tooltip: 'Set the motor to a speed between -1 and 1.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_speed', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', fields: { - COMPONENT_NAME: componentName, - FUNC: 'get_angle_degrees', + NUM: 0.8, }, - inputs: {}, + }, }, - // def reset_relative_encoder(self) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [], - tooltip: 'Reset the relative encoder value to 0.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: componentName, - }, + }, + }, + // Method: set_angle_degrees(angle: float) -> None + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [ + { + name: 'angle', + type: 'float', + }, + ], + tooltip: 'Set the motor to an angle between 0 and 360.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'set_angle_degrees', + }, + inputs: { + ARG0: { + block: { + type: 'math_number', fields: { - COMPONENT_NAME: componentName, - FUNC: 'reset_relative_encoder', + NUM: 180, }, - inputs: {}, + }, }, - ]; + }, + }, + // Method: get_num_relative_encoder_ticks() -> int + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'int', + args: [], + tooltip: 'Get the number of relative motor ticks since reset of encoder.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_num_relative_encoder_ticks', + }, + inputs: {}, + }, + // Method: get_angle_degrees() -> float + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'float', + args: [], + tooltip: 'Get the angle position of the motor.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'get_angle_degrees', + }, + inputs: {}, + }, + // Method: reset_relative_encoder() -> None + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'None', + args: [], + tooltip: 'Reset the relative encoder value to 0.', + importModule: '', + componentClassName: 'rev.SmartMotor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'reset_relative_encoder', + }, + inputs: {}, + }, + ]; } \ No newline at end of file diff --git a/src/toolbox/hardware_components/touch_sensor.ts b/src/toolbox/hardware_components/touch_sensor.ts index 1a5f78dc..9546b188 100644 --- a/src/toolbox/hardware_components/touch_sensor.ts +++ b/src/toolbox/hardware_components/touch_sensor.ts @@ -1,104 +1,134 @@ -import * as Blockly from 'blockly/core'; +/** + * @license + * Copyright 2025 Porpoiseful LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Touch Sensor hardware component definitions. + * @author alan@porpoiseful.com (Alan Smith) + */ + import * as ToolboxItems from '../items'; export const TYPE_NAME = 'TouchSensor'; +/** + * Returns a component definition block for a touch sensor. + */ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsType { - return { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_touch_sensor', - TYPE: 'RevTouchSensor' - }, - extraState: { - importModule: 'rev_touch_sensor', - params: [{ name: 'smartIO_port', type: 'int' }], - hideParams: hideParams + return { + kind: 'block', + type: 'mrc_component', + fields: { + NAME: 'my_touch_sensor', + TYPE: 'RevTouchSensor', + }, + extraState: { + importModule: 'rev_touch_sensor', + params: [{name: 'smartIO_port', type: 'int'}], + hideParams, + }, + ...(hideParams ? {} : { + inputs: { + ARG0: { + shadow: { + type: 'mrc_port', + fields: { + TYPE: 'SmartIO', + PORT_NUM: 1, + }, + }, }, - ...(hideParams ? {} : { - inputs: { - ARG0: { - shadow: { - type: 'mrc_port', - fields: { - TYPE: 'SmartIO', - PORT_NUM: 1 - }, - }, - }, - } - }) - }; + }, + }), + }; } +/** + * Returns the blocks available for a touch sensor component. + */ export function getBlocks(componentName: string): ToolboxItems.ContentsType[] { - return [ - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'pressed', - }, - }, - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'released', - }, - }, - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [ - { - name: 'new_state', - type: 'boolean', - }, - ], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'changed', - }, - }, - // def is_pressed(self) -> bool: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'bool', - args: [], - tooltip: 'Return whether the touch sensor is pressed.', - importModule: '', - componentClassName: 'rev.TouchSensor', - componentName: componentName, - }, - fields: { - COMPONENT_NAME: componentName, - FUNC: 'is_pressed', - }, - inputs: {}, - }, - ]; + return [ + // Event: pressed + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'pressed', + }, + }, + // Event: released + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'released', + }, + }, + // Event: changed with new_state parameter + { + kind: 'block', + type: 'mrc_event_handler', + extraState: { + tooltip: '', + pathOfSender: '', + typeOfSender: 'component', + params: [ + { + name: 'new_state', + type: 'boolean', + }, + ], + }, + fields: { + SENDER: 'my_touch_sensor', + EVENT_NAME: 'changed', + }, + }, + // Method: is_pressed() -> bool + { + kind: 'block', + type: 'mrc_call_python_function', + extraState: { + functionKind: 'instance_component', + returnType: 'bool', + args: [], + tooltip: 'Return whether the touch sensor is pressed.', + importModule: '', + componentClassName: 'rev.TouchSensor', + componentName, + }, + fields: { + COMPONENT_NAME: componentName, + FUNC: 'is_pressed', + }, + inputs: {}, + }, + ]; } From 8cc13436630d5f807d159f2fb03056e395249c67 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:06:57 -0400 Subject: [PATCH 3/7] remove components category --- src/editor/editor.ts | 10 +- src/toolbox/components_category.ts | 248 ----------------------------- 2 files changed, 3 insertions(+), 255 deletions(-) delete mode 100644 src/toolbox/components_category.ts diff --git a/src/editor/editor.ts b/src/editor/editor.ts index 231fe799..48358810 100644 --- a/src/editor/editor.ts +++ b/src/editor/editor.ts @@ -24,13 +24,11 @@ import * as Blockly from 'blockly/core'; import { extendedPythonGenerator } from './extended_python_generator'; import { GeneratorContext } from './generator_context'; import * as commonStorage from '../storage/common_storage'; -import { getToolboxJSON } from '../toolbox/toolbox'; //import { testAllBlocksInToolbox } from '../toolbox/toolbox_tests'; import { MethodsCategory} from '../toolbox/methods_category'; import { EventsCategory} from '../toolbox/event_category'; -import { ComponentsCategory } from '../toolbox/components_category'; - +import { getToolboxJSON } from '../toolbox/toolbox'; const EMPTY_TOOLBOX: Blockly.utils.toolbox.ToolboxDefinition = { kind: 'categoryToolbox', @@ -45,7 +43,6 @@ export class Editor { private storage: commonStorage.Storage; private methodsCategory: MethodsCategory; private eventsCategory: EventsCategory; - private componentsCategory: ComponentsCategory; private currentModule: commonStorage.Module | null = null; private modulePath: string = ''; private projectPath: string = ''; @@ -61,7 +58,6 @@ export class Editor { this.storage = storage; this.methodsCategory = new MethodsCategory(blocklyWorkspace); this.eventsCategory = new EventsCategory(blocklyWorkspace); - this.componentsCategory = new ComponentsCategory(blocklyWorkspace); } private onChangeWhileLoading(event: Blockly.Events.Abstract) { @@ -125,7 +121,6 @@ export class Editor { this.currentModule = currentModule; this.methodsCategory.setCurrentModule(currentModule); this.eventsCategory.setCurrentModule(currentModule); - this.componentsCategory.setCurrentModule(currentModule); if (currentModule) { this.modulePath = currentModule.modulePath; @@ -199,7 +194,8 @@ export class Editor { }, 50); return; } - this.setToolbox(getToolboxJSON( + this.setToolbox( + getToolboxJSON( shownPythonToolboxCategories, this.currentModule)); } } diff --git a/src/toolbox/components_category.ts b/src/toolbox/components_category.ts deleted file mode 100644 index 34f934c4..00000000 --- a/src/toolbox/components_category.ts +++ /dev/null @@ -1,248 +0,0 @@ -/** - * @license - * Copyright 2025 Porpoiseful LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author alan@porpoiseful.com (Alan Smith) - */ - -/** - * TODO: This is all fake right now, it will be generated dynamically - * based on the components that are available in the current module. - */ - -import * as Blockly from 'blockly/core'; - -import * as toolboxItems from './items'; -import * as commonStorage from '../storage/common_storage'; -import { MRC_CATEGORY_STYLE_COMPONENTS } from '../themes/styles'; - - - -const CUSTOM_CATEGORY_COMPONENTS = 'COMPONENTS'; - -export const category = { - kind: 'category', - categorystyle: MRC_CATEGORY_STYLE_COMPONENTS, - name: 'Hardware', - contents: [ - { - kind: 'category', - name: 'my_motor', - custom: CUSTOM_CATEGORY_COMPONENTS, - componentConfig: { - name: 'my_motor', - type: 'rev.SmartMotor', - } - }, - { - kind: 'category', - name: 'my_touch_sensor', - custom: CUSTOM_CATEGORY_COMPONENTS, - componentConfig: { - name: 'my_touch_sensor', - type: 'rev.TouchSensor', - } - }, - { - kind: 'category', - name: 'New', - contents: [ - { - kind: 'label', - text: 'Components', - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_motor', - TYPE: 'SmartMotor' - }, - extraState: { - importModule: 'smart_motor', - params: [{ name: 'motor_port', type: 'int' }], - hideParams: true - }, - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_color_range_sensor', - TYPE: 'ColorRangeSensor' - }, - extraState: { - importModule: 'color_range_sensor', - params: [{ name: 'i2c_port', type: 'int' }], - hideParams: true - }, - }, - { - kind: 'block', - type: 'mrc_component', - fields: { - NAME: 'my_touch_sensor', - TYPE: 'RevTouchSensor' - }, - extraState: { - importModule: 'rev_touch_sensor', - params: [{ name: 'smartIO_port', type: 'int' }], - hideParams: true - }, - }, - ] - },] -}; - - -export class ComponentsCategory { - private currentModule: commonStorage.Module | null = null; - - - constructor(blocklyWorkspace: Blockly.WorkspaceSvg) { - blocklyWorkspace.registerToolboxCategoryCallback(CUSTOM_CATEGORY_COMPONENTS, this.componentsFlyout.bind(this)); - } - - public setCurrentModule(currentModule: commonStorage.Module | null) { - this.currentModule = currentModule; - } - - public componentsFlyout(workspace: Blockly.WorkspaceSvg) { - const contents: toolboxItems.ContentsType[] = []; - - contents.push( - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: 'my_motor', - EVENT_NAME: 'on_stall', - }, - }, - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [ - { - name: 'new_state', - type: 'boolean', - }, - ], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'on_change', - }, - }, - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'on_pressed', - }, - }, - { - kind: 'block', - type: 'mrc_event_handler', - extraState: { - tooltip: '', - pathOfSender: '', - typeOfSender: 'component', - params: [], - }, - fields: { - SENDER: 'my_touch_sensor', - EVENT_NAME: 'on_released', - }, - }, - // def set_speed(self, speed: float) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'speed', - type: 'float', - }, - ], - tooltip: 'Set the motor to a speed between -1 and 1.', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'my_motor', - }, - fields: { - COMPONENT_NAME: 'my_motor', - FUNC: 'set_speed', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 0.8, - }, - }, - }, - }, - }, - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - ], - tooltip: 'Stop the motor', - importModule: '', - componentClassName: 'rev.SmartMotor', - componentName: 'my_motor', - }, - fields: { - COMPONENT_NAME: 'my_motor', - FUNC: 'stop', - }, - }, - ); - - const toolboxInfo = { - contents: contents, - }; - - return toolboxInfo; - } -} \ No newline at end of file From fe7fd42f83784d92cecac3d15587917ff87bf0c2 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:07:06 -0400 Subject: [PATCH 4/7] remove samples --- src/toolbox/component_samples_category.ts | 302 ---------------------- 1 file changed, 302 deletions(-) delete mode 100644 src/toolbox/component_samples_category.ts diff --git a/src/toolbox/component_samples_category.ts b/src/toolbox/component_samples_category.ts deleted file mode 100644 index 1f1662a8..00000000 --- a/src/toolbox/component_samples_category.ts +++ /dev/null @@ -1,302 +0,0 @@ -export const category = -{ - kind: 'category', - name: 'Components', - contents: [ - { - kind: 'category', - name: 'REV Color Range Sensor', - contents: [ - // def get_color_rgb(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in rgb (red, green, blue).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'colorSensor', - FUNC: 'get_color_rgb', - }, - inputs: {}, - }, - // def get_color_hsv(self) -> tuple[int, int, int]: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'tuple[int, int, int]', - args: [], - tooltip: 'Get the color in hsv (hue, saturation, value).', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'colorSensor', - FUNC: 'get_color_hsv', - }, - inputs: {}, - }, - // def get_distance_mm(self) -> float: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'float', - args: [], - tooltip: 'Get the distance of the object seen.', - importModule: '', - componentClassName: 'rev.ColorRangeSensor', - componentName: 'colorSensor', - }, - fields: { - COMPONENT_NAME: 'colorSensor', - FUNC: 'get_distance_mm', - }, - inputs: {}, - }, - ], - }, - - - { - kind: 'category', - name: 'SparkFun LED Stick', - contents: [ - // def set_color(self, position: int, color: wpilib.Color) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'position', - type: 'int', - }, - { - name: 'color', - type: 'wpilib.Color', - }, - ], - tooltip: 'Change the color of an individual LED.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'set_color', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 1, - }, - }, - }, - ARG1: { - block: { - type: 'mrc_get_python_variable', - extraState: { - varKind: 'class', - moduleOrClassName: 'wpilib.Color', - varType: 'wpilib.Color', - importModule: 'wpilib', - }, - fields: { - MODULE_OR_CLASS: 'wpilib.Color', - VAR: 'kWhite', - }, - }, - }, - }, - }, - // def set_color(self, color: wpilib.Color) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'color', - type: 'wpilib.Color', - }, - ], - tooltip: 'Change the color of all LEDs to a single color.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'set_color', - }, - inputs: { - ARG0: { - block: { - type: 'mrc_get_python_variable', - extraState: { - varKind: 'class', - moduleOrClassName: 'wpilib.Color', - varType: 'wpilib.Color', - importModule: 'wpilib', - }, - fields: { - MODULE_OR_CLASS: 'wpilib.Color', - VAR: 'kWhite', - }, - }, - }, - }, - }, - // def set_colors(self, colors: list[int]) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'colors', - type: 'list[int]', - }, - ], - tooltip: 'Change the color of all LEDs using a list.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'set_colors', - }, - inputs: { - ARG0: { - block: { - type: 'variables_get', - fields: { - VAR: { - name: 'myListOfColors', - }, - }, - }, - }, - }, - }, - // def set_brightness(self, position: int, brightness: int) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'position', - type: 'int', - }, - { - name: 'brightness', - type: 'int', - }, - ], - tooltip: 'Set the brightness of an individual LED.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'set_brightness', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 1, - }, - }, - }, - ARG1: { - block: { - type: 'math_number', - fields: { - NUM: 16, - }, - }, - }, - }, - }, - // def set_brightness(self, brightness: int) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [ - { - name: 'brightness', - type: 'int', - } - ], - tooltip: 'Set the brightness of all LEDs.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'set_brightness', - }, - inputs: { - ARG0: { - block: { - type: 'math_number', - fields: { - NUM: 16, - }, - }, - }, - }, - }, - // def turn_all_off(self) -> None: - { - kind: 'block', - type: 'mrc_call_python_function', - extraState: { - functionKind: 'instance_component', - returnType: 'None', - args: [], - tooltip: 'Turn all LEDs off.', - importModule: '', - componentClassName: 'sparkfun.LEDStick', - componentName: 'ledStick', - }, - fields: { - COMPONENT_NAME: 'ledStick', - FUNC: 'turn_all_off', - }, - inputs: {}, - }, - ], - } - ], -} \ No newline at end of file From 85de2f6ee9ca16a0d3d1388782a1b3e896b249d1 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:07:23 -0400 Subject: [PATCH 5/7] remove unneeded imports --- src/toolbox/blocks_components.ts | 5 ----- src/toolbox/blocks_mechanisms.ts | 2 -- 2 files changed, 7 deletions(-) diff --git a/src/toolbox/blocks_components.ts b/src/toolbox/blocks_components.ts index 9093552c..84372a5a 100644 --- a/src/toolbox/blocks_components.ts +++ b/src/toolbox/blocks_components.ts @@ -18,17 +18,12 @@ /** * @author alan@porpoiseful.com (Alan Smith) */ -import * as Blockly from 'blockly/core'; - import * as ToolboxItems from './items'; import * as ColorSensor from './hardware_components/color_sensor'; import * as SmartMotor from './hardware_components/smart_motor'; import * as TouchSensor from './hardware_components/touch_sensor'; import * as Servo from './hardware_components/servo'; -import { Color } from 'antd/es/color-picker'; - - export function getAllPossibleComponents(hideParams : boolean): ToolboxItems.ContentsType[] { return [ SmartMotor.getDefinitionBlock(hideParams), diff --git a/src/toolbox/blocks_mechanisms.ts b/src/toolbox/blocks_mechanisms.ts index 8ddc61b2..249dc454 100644 --- a/src/toolbox/blocks_mechanisms.ts +++ b/src/toolbox/blocks_mechanisms.ts @@ -18,8 +18,6 @@ /** * @author alan@porpoiseful.com (Alan Smith) */ -import * as Blockly from 'blockly/core'; - import * as ToolboxItems from './items'; /** From 0583616d06ba2bc889eadb7b949f9c8ec98fe6ec Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:07:32 -0400 Subject: [PATCH 6/7] remove dead break --- src/toolbox/toolbox.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index e7308354..1509966a 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -17,9 +17,8 @@ export function getToolboxJSON( { kind: 'sep' }, ...common.getToolboxItems(shownPythonToolboxCategories), eventCategory, - ] - }; break; + }; case commonStorage.MODULE_TYPE_OPMODE: return { kind: 'categoryToolbox', From 8c22933908efcfa40fc99c9cf4a7bc329befebe9 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 27 Jun 2025 17:23:05 -0400 Subject: [PATCH 7/7] Changed TYPE to use constant TYPE_NAME --- src/toolbox/hardware_components/color_sensor.ts | 2 +- src/toolbox/hardware_components/servo.ts | 5 +---- src/toolbox/hardware_components/smart_motor.ts | 2 +- src/toolbox/hardware_components/touch_sensor.ts | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/toolbox/hardware_components/color_sensor.ts b/src/toolbox/hardware_components/color_sensor.ts index cf659ff1..6cd689fb 100644 --- a/src/toolbox/hardware_components/color_sensor.ts +++ b/src/toolbox/hardware_components/color_sensor.ts @@ -33,7 +33,7 @@ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsTy type: 'mrc_component', fields: { NAME: 'my_color_range_sensor', - TYPE: 'ColorRangeSensor', + TYPE: TYPE_NAME, }, extraState: { importModule: 'rev_color_range_sensor', diff --git a/src/toolbox/hardware_components/servo.ts b/src/toolbox/hardware_components/servo.ts index 32a62cbf..4274c4b5 100644 --- a/src/toolbox/hardware_components/servo.ts +++ b/src/toolbox/hardware_components/servo.ts @@ -19,9 +19,6 @@ * @fileoverview Servo hardware component definitions. * @author alan@porpoiseful.com (Alan Smith) */ - -import * as Blockly from 'blockly/core'; - import * as ToolboxItems from '../items'; export const TYPE_NAME = 'Servo'; @@ -35,7 +32,7 @@ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsTy type: 'mrc_component', fields: { NAME: 'my_servo', - TYPE: 'RevServo', + TYPE: TYPE_NAME, }, extraState: { importModule: 'rev_servo', diff --git a/src/toolbox/hardware_components/smart_motor.ts b/src/toolbox/hardware_components/smart_motor.ts index b1fa5de7..abbe1deb 100644 --- a/src/toolbox/hardware_components/smart_motor.ts +++ b/src/toolbox/hardware_components/smart_motor.ts @@ -33,7 +33,7 @@ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsTy type: 'mrc_component', fields: { NAME: 'my_motor', - TYPE: 'SmartMotor', + TYPE: TYPE_NAME, }, extraState: { importModule: 'smart_motor', diff --git a/src/toolbox/hardware_components/touch_sensor.ts b/src/toolbox/hardware_components/touch_sensor.ts index 9546b188..5b95a8f5 100644 --- a/src/toolbox/hardware_components/touch_sensor.ts +++ b/src/toolbox/hardware_components/touch_sensor.ts @@ -33,7 +33,7 @@ export function getDefinitionBlock(hideParams: boolean): ToolboxItems.ContentsTy type: 'mrc_component', fields: { NAME: 'my_touch_sensor', - TYPE: 'RevTouchSensor', + TYPE: TYPE_NAME, }, extraState: { importModule: 'rev_touch_sensor',