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
51 changes: 49 additions & 2 deletions src/blocks/mrc_call_python_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,13 +597,57 @@ const CALL_PYTHON_FUNCTION = {
mrcOnLoad: function(this: CallPythonFunctionBlock, editor: Editor): void {
this.checkFunction(editor);
},
/**
* mrcOnCreate is called for each CallPythonFunctionBlock when it is created.
*/
mrcOnCreate: function(this: CallPythonFunctionBlock, editor: Editor): void {
this.checkFunction(editor);
},
/**
* checkFunction checks the block, updates it, and/or adds a warning balloon if necessary.
* It is called from mrcOnModuleCurrent and mrcOnLoad above.
* It is called from mrcOnModuleCurrent, mrcOnLoad, and mrcOnCreate above.
*/
checkFunction: function(this: CallPythonFunctionBlock, editor: Editor): void {
const warnings: string[] = [];

// If this block is calling a method defined in this module, check whether the method still
// exists and whether it has been changed.
// If the method doesn't exist, put a visible warning on this block.
// If the robot method has changed, update the block if possible or put a
// visible warning on it.
if (this.mrcFunctionKind === FunctionKind.INSTANCE_WITHIN) {
let foundMethod = false;
const methodsFromWorkspace = editor.getMethodsForWithinFromWorkspace();
for (const method of methodsFromWorkspace) {
if (method.methodId === this.mrcMethodId) {
foundMethod = true;
if (this.mrcActualFunctionName !== method.pythonName) {
this.mrcActualFunctionName = method.pythonName;
}
if (this.getFieldValue(FIELD_FUNCTION_NAME) !== method.visibleName) {
this.setFieldValue(method.visibleName, FIELD_FUNCTION_NAME);
}

this.mrcReturnType = method.returnType;
this.mrcArgs = [];
// We don't include the arg for the self argument because we don't need a socket for it.
for (let i = 1; i < method.args.length; i++) {
this.mrcArgs.push({
name: method.args[i].name,
type: method.args[i].type,
});
}
this.updateBlock_();

// Since we found the method, we can break out of the loop.
break;
}
}
if (!foundMethod) {
warnings.push(Blockly.Msg.WARNING_CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD);
}
}

// If this block is calling a component method, check whether the component
// still exists and whether it has been changed.
// If the component doesn't exist, put a visible warning on this block.
Expand Down Expand Up @@ -823,7 +867,10 @@ const CALL_PYTHON_FUNCTION = {
// Add a warnings to the block.
const warningText = warnings.join('\n\n');
this.setWarningText(warningText, WARNING_ID_FUNCTION_CHANGED);
this.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
if (icon) {
icon.setBubbleVisible(true);
}
this.bringToFront();
} else {
// Clear the existing warning on the block.
Expand Down
6 changes: 6 additions & 0 deletions src/blocks/mrc_component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ const COMPONENT = {
mrcOnLoad: function(this: ComponentBlock, _editor: Editor): void {
this.checkBlockIsInHolder();
},
/**
* mrcOnCreate is called for each ComponentBlock when it is created.
*/
mrcOnCreate: function(this: ComponentBlock, _editor: Editor): void {
this.checkBlockIsInHolder();
},
/**
* mrcOnMove is called when a ComponentBlock is moved.
*/
Expand Down
6 changes: 6 additions & 0 deletions src/blocks/mrc_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ const EVENT = {
mrcOnLoad: function(this: EventBlock, _editor: Editor): void {
this.checkBlockIsInHolder();
},
/**
* mrcOnCreate is called for each EventBlock when it is created.
*/
mrcOnCreate: function(this: EventBlock, _editor: Editor): void {
this.checkBlockIsInHolder();
},
/**
* mrcOnMove is called when an EventBlock is moved.
*/
Expand Down
13 changes: 11 additions & 2 deletions src/blocks/mrc_event_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,15 @@ const EVENT_HANDLER = {
mrcOnLoad: function(this: EventHandlerBlock, editor: Editor): void {
this.checkEvent(editor);
},
/**
* mrcOnCreate is called for each EventHandlerBlock when it is created.
*/
mrcOnCreate: function(this: EventHandlerBlock, editor: Editor): void {
this.checkEvent(editor);
},
/**
* checkEvent checks the block, updates it, and/or adds a warning balloon if necessary.
* It is called from mrcOnModuleCurrent and mrcOnLoad above.
* It is called from mrcOnModuleCurrent, mrcOnLoad, and mrcCreate above.
*/
checkEvent: function(this: EventHandlerBlock, editor: Editor): void {
const warnings: string[] = [];
Expand Down Expand Up @@ -282,7 +288,10 @@ const EVENT_HANDLER = {
// Add a warnings to the block.
const warningText = warnings.join('\n\n');
this.setWarningText(warningText, WARNING_ID_EVENT_CHANGED);
this.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
if (icon) {
icon.setBubbleVisible(true);
}
this.bringToFront();
} else {
// Clear the existing warning on the block.
Expand Down
5 changes: 4 additions & 1 deletion src/blocks/mrc_jump_to_step.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ const JUMP_TO_STEP_BLOCK = {
// Otherwise, add a warning to this block.
if (!this.mrcHasWarning) {
this.setWarningText(Blockly.Msg.JUMP_CAN_ONLY_GO_IN_THEIR_STEPS_BLOCK, WARNING_ID_NOT_IN_STEP);
this.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
if (icon) {
icon.setBubbleVisible(true);
}
this.mrcHasWarning = true;
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/blocks/mrc_mechanism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ const MECHANISM = {
this.checkBlockIsInHolder();
this.checkMechanism(editor);
},
/**
* mrcOnCreate is called for each MechanismBlock when it is created.
*/
mrcOnCreate: function(this: MechanismBlock, editor: Editor): void {
this.checkBlockIsInHolder();
this.checkMechanism(editor);
},
/**
* mrcOnMove is called when a MechanismBlock is moved.
*/
Expand Down Expand Up @@ -299,7 +306,10 @@ const MECHANISM = {
// Add a warnings to the block.
const warningText = warnings.join('\n\n');
this.setWarningText(warningText, WARNING_ID_MECHANISM_CHANGED);
this.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
if (icon) {
icon.setBubbleVisible(true);
}
this.bringToFront();
} else {
// Clear the existing warning on the block.
Expand Down
1 change: 1 addition & 0 deletions src/blocks/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg {
SET_INSTANCE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_INSTANCE_VARIABLE'),
VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE: t('BLOCKLY.ERROR.VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE'),
MECHANISM_NOT_FOUND_WARNING: t('BLOCKLY.WARNING.MECHANISM_NOT_FOUND'),
WARNING_CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD: t('BLOCKLY.WARNING.CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD'),
WARNING_CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT'),
WARNING_CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT'),
WARNING_CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM: t('BLOCKLY.WARNING.CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM'),
Expand Down
46 changes: 46 additions & 0 deletions src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const EMPTY_TOOLBOX: Blockly.utils.toolbox.ToolboxInfo = {
};

const MRC_ON_LOAD = 'mrcOnLoad';
const MRC_ON_CREATE = 'mrcOnCreate';
const MRC_ON_MOVE = 'mrcOnMove';
const MRC_ON_DESCENDANT_DISCONNECT = 'mrcOnDescendantDisconnect';
const MRC_ON_ANCESTOR_MOVE = 'mrcOnAncestorMove';
Expand Down Expand Up @@ -134,6 +135,24 @@ export class Editor {
return;
}

if (event.type === Blockly.Events.VIEWPORT_CHANGE) {
this.setPasteLocation();
}

if (event.type === Blockly.Events.BLOCK_CREATE) {
const blockCreateEvent = event as Blockly.Events.BlockCreate;
if (blockCreateEvent.ids) {
blockCreateEvent.ids.forEach(id => {
const block = this.blocklyWorkspace.getBlockById(id);
if (block) {
if (MRC_ON_CREATE in block && typeof block[MRC_ON_CREATE] === 'function') {
block[MRC_ON_CREATE](this);
}
}
});
}
}

if (event.type === Blockly.Events.BLOCK_MOVE) {
const blockMoveEvent = event as Blockly.Events.BlockMove;
const reason: string[] = blockMoveEvent.reason ?? [];
Expand Down Expand Up @@ -165,6 +184,7 @@ export class Editor {
}
});
}

if (event.type === Blockly.Events.BUBBLE_OPEN) {
const bubbleOpenEvent = event as Blockly.Events.BubbleOpen;
if (bubbleOpenEvent.bubbleType === 'mutator' && bubbleOpenEvent.isOpen) {
Expand Down Expand Up @@ -199,6 +219,16 @@ export class Editor {
block[MRC_ON_MODULE_CURRENT](this);
}
});

if (Blockly.clipboard.getLastCopiedWorkspace()) {
Blockly.clipboard.setLastCopiedWorkspace(this.blocklyWorkspace);

setTimeout(() => {
this.blocklyWorkspace.markFocused();
Blockly.getFocusManager().focusNode(this.blocklyWorkspace);
this.setPasteLocation();
});
}
}

public abandon(): void {
Expand Down Expand Up @@ -618,4 +648,20 @@ export class Editor {
public static getCurrentEditor(): Editor | null {
return Editor.currentEditor;
}

private setPasteLocation(): void {
const copyData = Blockly.clipboard.getLastCopiedData();
if (copyData && copyData.paster === 'block') {
const blockCopyData = copyData as Blockly.clipboard.BlockCopyData;
if (blockCopyData.blockState) {
const metrics = this.blocklyWorkspace.getMetrics();
const center = new Blockly.utils.Coordinate(
metrics.viewLeft + metrics.viewWidth / 2,
metrics.viewTop + metrics.viewHeight / 2);
blockCopyData.blockState.x = center.x;
blockCopyData.blockState.y = center.y;
Blockly.clipboard.setLastCopiedLocation(center);
}
}
}
}
1 change: 1 addition & 0 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
"PAGINATION_TOTAL": "{{start}}-{{end}} of {{total}} items"
},
"WARNING":{
"CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD": "This block calls a method that does not exist in this module.",
"CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT": "This blocks calls a method on a private component in the {{mechanismClassName}} mechanism.",
"CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT": "This block calls a method on a component that no longer exists.",
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM": "This block calls a method on a component that belongs to a mechanism that no longer exists.",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
"PAGINATION_TOTAL": "{{start}}-{{end}} de {{total}} elementos"
},
"WARNING":{
"CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD": "Este bloque llama a un método que no existe en este módulo.",
"CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT": "Este bloque llama a un método en un componente privado en el mecanismo {{mechanismClassName}}.",
"CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT": "Este bloque llama a un método en un componente que ya no existe.",
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM": "Este bloque llama a un método de un componente que pertenece a un mecanismo que ya no existe.",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/he/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
"PAGINATION_TOTAL": "{{start}}-{{end}} מתוך {{total}} פריטים"
},
"WARNING": {
"CALL_INSTANCE_WITHIN_METHOD_MISSING_METHOD": "בלוק זה קורא למתודה שאינה קיימת במודול זה.",
"CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT": "בלוק זה קורא למתודה על רכיב פרטי במנגנון {{mechanismClassName}}.",
"CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT": "בלוק זה קורא למתודה על רכיב שכבר לא קיים.",
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM": "בלוק זה קורא למתודה על רכיב ששייך למנגנון שכבר לא קיים.",
Expand Down