Zoom screen (#285)

* always start with full brick layout

* adding 'on start' to template

* render entire board when selected

* zoom brick when clicking on screen

* resize when zooming

* toggle zooming of the brick

* inject close icon when selected

* fix toggling
This commit is contained in:
Peli de Halleux 2018-01-30 22:22:21 -08:00 committed by GitHub
parent 822227eb48
commit fcf91caeb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 12 deletions

View File

@ -1,3 +1,5 @@
<xml xmlns="http://www.w3.org/1999/xhtml"> <xml xmlns="http://www.w3.org/1999/xhtml">
<block type="forever"></block> <variables></variables>
<block type="pxt-on-start" x="0" y="0"></block>
<block type="forever" x="176" y="0"></block>
</xml> </xml>

View File

@ -298,7 +298,14 @@ namespace pxsim.visuals {
this.layoutView.inject(this.element); this.layoutView.inject(this.element);
// Add EV3 module element // Add EV3 module element
this.layoutView.setBrick(new BrickView(-1)); const brickCloseIcon = this.getCloseIconView();
brickCloseIcon.registerClick(ev => {
this.layoutView.unselectBrick();
this.resize();
});
const brick =new BrickView(-1);
brick.setSelected(EV3View.isPreviousBrickSelected());
this.layoutView.setBrick(brick, brickCloseIcon);
this.resize(); this.resize();
@ -329,6 +336,12 @@ namespace pxsim.visuals {
this.screenCanvas = document.createElement("canvas"); this.screenCanvas = document.createElement("canvas");
this.screenCanvas.id = "board-screen-canvas"; this.screenCanvas.id = "board-screen-canvas";
this.screenCanvas.style.position = "absolute"; this.screenCanvas.style.position = "absolute";
this.screenCanvas.addEventListener(pxsim.pointerEvents.up, ev => {
this.layoutView.selectBrick();
this.resize();
})
this.screenCanvas.style.cursor = "pointer";
/*
this.screenCanvas.style.cursor = "crosshair"; this.screenCanvas.style.cursor = "crosshair";
this.screenCanvas.onmousemove = (e: MouseEvent) => { this.screenCanvas.onmousemove = (e: MouseEvent) => {
const x = e.clientX; const x = e.clientX;
@ -340,6 +353,7 @@ namespace pxsim.visuals {
this.screenCanvas.onmouseleave = () => { this.screenCanvas.onmouseleave = () => {
this.updateXY(SCREEN_WIDTH, SCREEN_HEIGHT); this.updateXY(SCREEN_WIDTH, SCREEN_HEIGHT);
} }
*/
this.screenCanvas.width = SCREEN_WIDTH; this.screenCanvas.width = SCREEN_WIDTH;
this.screenCanvas.height = SCREEN_HEIGHT; this.screenCanvas.height = SCREEN_HEIGHT;
@ -360,10 +374,12 @@ namespace pxsim.visuals {
// Save previous inputs for the next cycle // Save previous inputs for the next cycle
EV3View.previousSelectedInputs = ev3board().getInputNodes().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1) EV3View.previousSelectedInputs = ev3board().getInputNodes().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1)
EV3View.previousSeletedOutputs = ev3board().getMotors().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1); EV3View.previousSeletedOutputs = ev3board().getMotors().map((node, index) => (this.getDisplayViewForNode(node.id, index).getSelected()) ? node.id : -1);
EV3View.previousSelectedBrick = this.layoutView.getBrick().getSelected();
} }
private static previousSelectedInputs: number[]; private static previousSelectedInputs: number[];
private static previousSeletedOutputs: number[]; private static previousSeletedOutputs: number[];
private static previousSelectedBrick: boolean;
private static isPreviousInputSelected(index: number, id: number) { private static isPreviousInputSelected(index: number, id: number) {
if (EV3View.previousSelectedInputs && EV3View.previousSelectedInputs[index] == id) { if (EV3View.previousSelectedInputs && EV3View.previousSelectedInputs[index] == id) {
@ -381,6 +397,12 @@ namespace pxsim.visuals {
return false; return false;
} }
private static isPreviousBrickSelected() {
const b = EV3View.previousSelectedBrick;
EV3View.previousSelectedBrick = false;
return !!b;
}
private begin() { private begin() {
this.running = true; this.running = true;
this.updateState(); this.updateState();

View File

@ -37,6 +37,8 @@ namespace pxsim.visuals {
private outputWires: WireView[] = []; private outputWires: WireView[] = [];
private brick: BrickView; private brick: BrickView;
private brickCloseIcon: View = undefined;
private offsets: number[]; private offsets: number[];
private contentGroup: SVGGElement; private contentGroup: SVGGElement;
private scrollGroup: SVGGElement; private scrollGroup: SVGGElement;
@ -67,9 +69,13 @@ namespace pxsim.visuals {
this.position(); this.position();
} }
public setBrick(brick: BrickView) { public setBrick(brick: BrickView, brickCloseIcon: View) {
this.brick = brick; this.brick = brick;
this.brick.inject(this.scrollGroup); this.brick.inject(this.scrollGroup);
this.brickCloseIcon = brickCloseIcon;
this.addView(this.brickCloseIcon);
this.brickCloseIcon.setVisible(this.brick.getSelected());
this.position(); this.position();
} }
@ -77,6 +83,18 @@ namespace pxsim.visuals {
return this.brick; return this.brick;
} }
public unselectBrick() {
this.brick.setSelected(false);
this.brickCloseIcon.setVisible(false);
this.position();
}
public selectBrick() {
this.brick.setSelected(true);
this.brickCloseIcon.setVisible(true);
this.position();
}
public setInput(port: number, view: LayoutElement, control?: View, closeIcon?: View) { public setInput(port: number, view: LayoutElement, control?: View, closeIcon?: View) {
if (this.inputs[port] != view || this.inputControls[port] != control) { if (this.inputs[port] != view || this.inputControls[port] != control) {
if (this.inputs[port]) { if (this.inputs[port]) {
@ -224,17 +242,23 @@ namespace pxsim.visuals {
const noConnections = this.outputs.concat(this.inputs).filter(m => m.getId() != NodeType.Port).length == 0; const noConnections = this.outputs.concat(this.inputs).filter(m => m.getId() != NodeType.Port).length == 0;
if (noConnections) { // render the full brick layout, even when there are not connection
// No connections render the entire board // otherwise, it creates flickering of the simulator.
this.brick.resize(contentWidth, contentHeight); if (this.brick.getSelected()) {
this.brick.translate(0, 0); // render output button
const closeIconWidth = this.brickCloseIcon.getWidth();
const closeIconHeight = this.brickCloseIcon.getHeight();
this.brickCloseIcon.translate(contentWidth / 2 - closeIconWidth / 2, 0);
// render the entire board
this.brick.resize(contentWidth, contentHeight - closeIconHeight * 2);
this.brick.translate(0, closeIconHeight * 2);
// Hide all other connections // Hide all other connections
this.outputs.concat(this.inputs).forEach(m => m.setVisible(false)); this.outputs.concat(this.inputs).forEach(m => m.setVisible(false));
return; return;
} else {
this.outputs.concat(this.inputs).forEach(m => m.setVisible(true));
} }
this.outputs.concat(this.inputs).forEach(m => m.setVisible(true));
const moduleHeight = this.getModuleHeight(); const moduleHeight = this.getModuleHeight();

View File

@ -206,9 +206,11 @@ namespace pxsim.visuals {
} }
public setSelected(selected: boolean) { public setSelected(selected: boolean) {
if (this.selected != selected) {
this.selected = selected; this.selected = selected;
this.setChangedState(); this.setChangedState();
} }
}
protected setChangedState() { protected setChangedState() {
this.changed = true; this.changed = true;