Skip to content

Commit 3123906

Browse files
committed
fix centering behavior for blocks (#10482)
1 parent ba20dcb commit 3123906

File tree

6 files changed

+75
-23
lines changed

6 files changed

+75
-23
lines changed

pxtblocks/builtins/functions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ export function initFunctions() {
292292
let newBlock = workspace.getBlockById(newBlockIds[0]) as Blockly.BlockSvg;
293293
newBlock.select();
294294
// Center on the new block so we know where it is
295-
workspace.centerOnBlock(newBlock.id);
295+
workspace.centerOnBlock(newBlock.id, true);
296296
}
297297

298298
workspace.registerButtonCallback('CREATE_FUNCTION', function (button) {

pxtblocks/plugins/functions/blocks/functionDeclarationBlock.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ const FUNCTION_DECLARATION_MIXIN: FunctionDeclarationMixin = {
104104
const workspace = this.workspace;
105105

106106
if (workspace instanceof Blockly.WorkspaceSvg) {
107-
workspace.centerOnBlock(this.id);
107+
workspace.centerOnBlock(this.id, true);
108108
}
109109
newInput.fieldRow[0].showEditor();
110110
} else if (newInput.type == Blockly.inputs.inputTypes.VALUE) {
111111
// Inspect the argument editor.
112112
const target = newInput.connection!.targetBlock()!;
113113
const workspace = target.workspace;
114114
if (workspace instanceof Blockly.WorkspaceSvg) {
115-
workspace.centerOnBlock(target.id);
115+
workspace.centerOnBlock(target.id, true);
116116
}
117117
target.getField("TEXT")!.showEditor();
118118
}

pxtblocks/plugins/functions/extensions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ const contextMenuEditMixin = {
5757
callback: () => {
5858
const functionName = this.getField("function_name")!.getText();
5959
const definition = getDefinition(functionName, this.workspace);
60-
if (definition && this.workspace instanceof Blockly.WorkspaceSvg)
61-
this.workspace.centerOnBlock(definition.id);
60+
if (definition && this.workspace instanceof Blockly.WorkspaceSvg) {
61+
this.workspace.centerOnBlock(definition.id, true);
62+
}
6263
},
6364
};
6465
menuOptions.push(gtdOption);

pxtblocks/plugins/functions/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ function createFunctionCallbackFactory_(workspace: Blockly.WorkspaceSvg) {
435435
block.scheduleSnapAndBump();
436436
}
437437

438-
workspace.centerOnBlock(block.id);
438+
workspace.centerOnBlock(block.id, true);
439439
Blockly.Events.setGroup(false);
440440

441441
setTimeout(() => {

webapp/src/blocks.tsx

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,22 +1181,73 @@ export class Editor extends toolboxeditor.ToolboxEditor {
11811181
if (brk) {
11821182
const b = this.editor.getBlockById(bid) as Blockly.BlockSvg;
11831183
b.setWarningText(brk ? brk.exceptionMessage : undefined, pxtblockly.PXT_WARNING_ID);
1184-
// ensure highlight is in the screen when a breakpoint info is available
1185-
// TODO: make warning mode look good
1186-
// b.setHighlightWarning(brk && !!brk.exceptionMessage);
1187-
const p = b.getRelativeToSurfaceXY();
1188-
const c = b.getHeightWidth();
1189-
const s = this.editor.scale;
1190-
const m = this.editor.getMetrics();
1191-
// don't center if block is still on the screen
1192-
const marginx = 4;
1193-
const marginy = 4;
1194-
if (p.x * s < m.viewLeft + marginx
1195-
|| (p.x + c.width) * s > m.viewLeft + m.viewWidth - marginx
1196-
|| p.y * s < m.viewTop + marginy
1197-
|| (p.y + c.height) * s > m.viewTop + m.viewHeight - marginy) {
1198-
// move the block towards the center
1199-
this.editor.centerOnBlock(bid);
1184+
1185+
// scroll the workspace so that the block is visible. if the block is too tall or too wide
1186+
// to fit in the workspace view, then try to align it with the left/top edge of the block
1187+
const xy = b.getRelativeToSurfaceXY();
1188+
const scale = this.editor.scale;
1189+
const metrics = this.editor.getMetrics();
1190+
1191+
// this margin is in screen pixels
1192+
const margin = 20;
1193+
1194+
let scrollX = metrics.viewLeft;
1195+
let scrollY = metrics.viewTop;
1196+
1197+
const blockWidth = b.width * scale + margin * 2;
1198+
const blockHeight = b.height * scale + margin * 2;
1199+
1200+
// in RTL workspaces, the x coordinate for the block is the right side
1201+
const blockLeftEdge = this.editor.RTL ? (xy.x - b.width) * scale - margin : xy.x * scale - margin;
1202+
const blockRightEdge = blockLeftEdge + blockWidth;
1203+
1204+
const blockTopEdge = xy.y * scale - margin;
1205+
const blockBottomEdge = blockTopEdge + blockHeight;
1206+
1207+
const viewBottom = metrics.viewTop + metrics.viewHeight;
1208+
const viewRight = metrics.viewLeft + metrics.viewWidth;
1209+
1210+
if (metrics.viewTop > blockTopEdge) {
1211+
scrollY = blockTopEdge;
1212+
}
1213+
else if (viewBottom < blockBottomEdge) {
1214+
if (blockHeight > metrics.viewHeight) {
1215+
scrollY = blockTopEdge;
1216+
}
1217+
else {
1218+
scrollY = blockBottomEdge - metrics.viewHeight;
1219+
}
1220+
}
1221+
1222+
if (this.editor.RTL) {
1223+
// for RTL, we want to align to the right edge
1224+
if (viewRight < blockRightEdge) {
1225+
scrollX = blockRightEdge - metrics.viewWidth;
1226+
}
1227+
else if (metrics.viewLeft > blockLeftEdge) {
1228+
if (blockWidth > metrics.viewWidth) {
1229+
scrollX = blockRightEdge - metrics.viewWidth;
1230+
}
1231+
else {
1232+
scrollX = blockLeftEdge;
1233+
}
1234+
}
1235+
}
1236+
else if (metrics.viewLeft > blockLeftEdge) {
1237+
scrollX = blockLeftEdge;
1238+
}
1239+
else if (viewRight < blockRightEdge) {
1240+
if (blockWidth > metrics.viewWidth) {
1241+
scrollX = blockLeftEdge;
1242+
}
1243+
else {
1244+
scrollX = blockRightEdge - metrics.viewWidth;
1245+
}
1246+
}
1247+
1248+
if (scrollX !== metrics.viewLeft || scrollY !== metrics.scrollTop) {
1249+
// scroll coordinates are negative
1250+
this.editor.scroll(-scrollX, -scrollY);
12001251
}
12011252
}
12021253
return true;

webapp/src/createFunction.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class CreateFunctionDialog extends data.Component<ISettingsProps, CreateF
8787
functionBeingEdited.domToMutation(initialMutation);
8888
functionBeingEdited.initSvg();
8989
functionBeingEdited.render();
90-
functionEditorWorkspace.centerOnBlock(functionBeingEdited.id);
90+
functionEditorWorkspace.centerOnBlock(functionBeingEdited.id, true);
9191

9292
functionEditorWorkspace.addChangeListener(() => {
9393
const { functionBeingEdited } = this.state;

0 commit comments

Comments
 (0)