Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ 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 * as toolboxOpmode from '../toolbox/toolbox_opmode';
import * as toolboxMechanism from '../toolbox/toolbox_mechanism';
import * as toolboxRobot from '../toolbox/toolbox_robot';

//import { testAllBlocksInToolbox } from '../toolbox/toolbox_tests';
import { MethodsCategory} from '../toolbox/methods_category';

Expand Down Expand Up @@ -166,7 +169,7 @@ export class Editor {
if (toolbox != this.toolbox) {
this.toolbox = toolbox;
this.blocklyWorkspace.updateToolbox(toolbox);
//testAllBlocksInToolbox();
// testAllBlocksInToolbox(toolbox);
}
}

Expand All @@ -182,23 +185,30 @@ export class Editor {

public updateToolbox(shownPythonToolboxCategories: Set<string>): void {
if (this.currentModule) {
if (this.currentModule.moduleType === commonStorage.MODULE_TYPE_PROJECT) {
// If we are editing a Project, we don't add any additional blocks to
// the toolbox.
this.setToolbox(getToolboxJSON([], shownPythonToolboxCategories));
return;
}
// Otherwise, we add the exported blocks from the Project.
if (!this.projectContent) {
// The Project content hasn't been fetched yet. Try again in a bit.
setTimeout(() => {
this.updateToolbox(shownPythonToolboxCategories)
}, 50);
return;
}
const robotBlocks = commonStorage.extractExportedBlocks(
this.currentModule.projectName, this.projectContent);
this.setToolbox(getToolboxJSON(robotBlocks, shownPythonToolboxCategories));
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;
}
}
}

Expand Down
56 changes: 2 additions & 54 deletions src/toolbox/hardware_category.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const category_robot =
export const category =
{
kind: 'category',
name: 'Hardware',
Expand Down Expand Up @@ -169,56 +169,4 @@ const category_robot =
}
},
],
}

const category_mechanism =
{
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
},
},
],
}
export const category = category_mechanism;
}
50 changes: 50 additions & 0 deletions src/toolbox/hardware_component_category.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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
},
},
],
}
74 changes: 73 additions & 1 deletion src/toolbox/robotpy_toolbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
import * as toolboxItems from './items';


export function getToolboxCategories(): toolboxItems.Category[] {
export function getToolboxCategories(shownPythonToolboxCategories: Set<string> | null): toolboxItems.Category[] {
const contents: toolboxItems.Category[] = [];

const allCategories: {[key: string]: toolboxItems.Category} = {};
Expand Down Expand Up @@ -87,6 +87,9 @@ export function getToolboxCategories(): toolboxItems.Category[] {

recursivelyRemoveEmptyCategories(contents);

// TODO: Maybe later there is a better way to do this...
filterRobotPyCategories(contents, shownPythonToolboxCategories);

return contents;
}

Expand Down Expand Up @@ -175,3 +178,72 @@ function recursivelyRemoveEmptyCategories(contents: toolboxItems.ContentsType[])
}
}
}

function filterRobotPyCategories(
contents: toolboxItems.ContentsType[], shownPythonToolboxCategories: Set<string> | null) {
contents.forEach((item) => {
if (item.kind === 'category') {
const category = item as toolboxItems.Category;
// Traverse the tree depth-first so we can easily identify and remove empty categories.
if (category.contents) {
filterRobotPyCategories(category.contents, shownPythonToolboxCategories);
}
if ((category as toolboxItems.PythonModuleCategory).moduleName) {
const moduleName = (item as toolboxItems.PythonModuleCategory).moduleName;
if (shownPythonToolboxCategories != null && !shownPythonToolboxCategories.has(moduleName)) {
if (category.contents) {
removeBlocksAndSeparators(category.contents);
}
}
}
if ((category as toolboxItems.PythonClassCategory).className) {
const className = (item as toolboxItems.PythonClassCategory).className;
if (shownPythonToolboxCategories != null && !shownPythonToolboxCategories.has(className)) {
if (category.contents) {
removeBlocksAndSeparators(category.contents);
}
}
}
}
});
removeEmptyCategories(contents, shownPythonToolboxCategories);
}

function removeBlocksAndSeparators(contents: toolboxItems.ContentsType[]) {
let i = 0;
while (i < contents.length) {
const remove = (contents[i].kind === 'block' || contents[i].kind === 'sep');
if (remove) {
contents.splice(i, 1);
continue;
}
i++;
}
}

function removeEmptyCategories(
contents: toolboxItems.ContentsType[], shownPythonToolboxCategories: Set<string> | null) {
let i = 0;
while (i < contents.length) {
let remove = false;
if (contents[i].kind === 'category') {
const category = contents[i] as toolboxItems.Category;
let fullCategoryName = '';
if ((category as toolboxItems.PythonModuleCategory).moduleName) {
fullCategoryName = (category as toolboxItems.PythonModuleCategory).moduleName
} else if ((category as toolboxItems.PythonClassCategory).className) {
fullCategoryName = (category as toolboxItems.PythonClassCategory).className;
}
if (category.contents &&
category.contents.length == 0 &&
shownPythonToolboxCategories != null && !shownPythonToolboxCategories.has(fullCategoryName)) {
remove = true;
}
}
if (remove) {
contents.splice(i, 1);
continue;
}
i++;
}
}
Loading