From f30eac41e92c7c0cee6173a06d55a9c6e554dbd4 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Thu, 28 Dec 2017 11:17:18 -0800 Subject: [PATCH] Persist selected state of controls across simulator restarts --- sim/state/control.ts | 1 - sim/visuals/board.ts | 30 ++++++++++++++++++++++++++-- sim/visuals/nodes/colorSensorView.ts | 1 + sim/visuals/nodes/largeMotorView.ts | 1 + sim/visuals/nodes/mediumMotorView.ts | 1 + sim/visuals/nodes/moduleView.ts | 18 +++++++++++------ sim/visuals/view.ts | 1 - 7 files changed, 43 insertions(+), 10 deletions(-) diff --git a/sim/state/control.ts b/sim/state/control.ts index dabc588b..0735c5b3 100644 --- a/sim/state/control.ts +++ b/sim/state/control.ts @@ -81,7 +81,6 @@ namespace pxsim.control { export function dmesg(s: string) { console.log("DMESG: " + s) } - } namespace pxsim.output { diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index e598839e..35b426c0 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -340,6 +340,28 @@ namespace pxsim.visuals { cancelAnimationFrame(animationId); }) } + // Save previous inputs for the next cycle + 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); + } + + private static previousSelectedInputs: number[]; + private static previousSeletedOutputs: number[]; + + private static isPreviousInputSelected(index: number, id: number) { + if (EV3View.previousSelectedInputs && EV3View.previousSelectedInputs[index] == id) { + EV3View.previousSelectedInputs[index] = undefined; + return true; + } + return false; + } + + private static isPreviousOutputSelected(index: number, id: number) { + if (EV3View.previousSeletedOutputs && EV3View.previousSeletedOutputs[index] == id) { + EV3View.previousSeletedOutputs[index] = undefined; + return true; + } + return false; } private begin() { @@ -382,7 +404,9 @@ namespace pxsim.visuals { const view = this.getDisplayViewForNode(node.id, index); if (!node.didChange() && !view.didChange()) return; if (view) { - const control = view.getSelected() ? this.getControlForNode(node.id, index) : undefined; + const isSelected = EV3View.isPreviousInputSelected(index, node.id) || view.getSelected(); + if (isSelected && !view.getSelected()) view.setSelected(true); + const control = isSelected ? this.getControlForNode(node.id, index) : undefined; const closeIcon = control ? this.getCloseIconView() : undefined; this.layoutView.setInput(index, view, control, closeIcon); view.updateState(); @@ -401,7 +425,9 @@ namespace pxsim.visuals { const view = this.getDisplayViewForNode(node.id, index); if (!node.didChange() && !view.didChange()) return; if (view) { - const control = view.getSelected() ? this.getControlForNode(node.id, index) : undefined; + const isSelected = EV3View.isPreviousOutputSelected(index, node.id) || view.getSelected(); + if (isSelected && !view.getSelected()) view.setSelected(true); + const control = isSelected ? this.getControlForNode(node.id, index) : undefined; const closeIcon = control ? this.getCloseIconView() : undefined; this.layoutView.setOutput(index, view, control, closeIcon); view.updateState(); diff --git a/sim/visuals/nodes/colorSensorView.ts b/sim/visuals/nodes/colorSensorView.ts index 62d82023..5637af6d 100644 --- a/sim/visuals/nodes/colorSensorView.ts +++ b/sim/visuals/nodes/colorSensorView.ts @@ -14,6 +14,7 @@ namespace pxsim.visuals { } public updateState() { + super.updateState(); // TODO: show different color modes } } diff --git a/sim/visuals/nodes/largeMotorView.ts b/sim/visuals/nodes/largeMotorView.ts index 62ef88c9..0e10e685 100644 --- a/sim/visuals/nodes/largeMotorView.ts +++ b/sim/visuals/nodes/largeMotorView.ts @@ -10,6 +10,7 @@ namespace pxsim.visuals { } updateState() { + super.updateState(); const motorState = ev3board().getMotors()[this.port]; if (!motorState) return; const speed = motorState.getSpeed(); diff --git a/sim/visuals/nodes/mediumMotorView.ts b/sim/visuals/nodes/mediumMotorView.ts index b1f17f3f..d980f95e 100644 --- a/sim/visuals/nodes/mediumMotorView.ts +++ b/sim/visuals/nodes/mediumMotorView.ts @@ -20,6 +20,7 @@ namespace pxsim.visuals { } updateState() { + super.updateState(); const motorState = ev3board().getMotors()[this.port]; if (!motorState) return; const speed = motorState.getSpeed(); diff --git a/sim/visuals/nodes/moduleView.ts b/sim/visuals/nodes/moduleView.ts index 051f074d..ede63633 100644 --- a/sim/visuals/nodes/moduleView.ts +++ b/sim/visuals/nodes/moduleView.ts @@ -4,7 +4,8 @@ namespace pxsim.visuals { protected content: SVGSVGElement; protected controlShown: boolean; - protected selected: boolean; + + protected opacity: number; constructor(protected xml: string, protected prefix: string, protected id: NodeType, protected port: NodeType) { super(); @@ -106,19 +107,24 @@ namespace pxsim.visuals { this.updateOpacity(); } + public updateState() { + this.updateOpacity(); + } + protected updateOpacity() { if (this.rendered) { - const opacity = this.selected ? "0.2" : "1"; - if (this.hasClick()) { - this.setOpacity(opacity); + const opacity = this.selected ? 0.2 : 1; + if (this.hasClick() && this.opacity != opacity) { + this.opacity = opacity; + this.setOpacity(this.opacity); if (this.selected) this.content.style.cursor = ""; else this.content.style.cursor = "pointer"; } } } - protected setOpacity(opacity: string) { - this.element.setAttribute("opacity", opacity); + protected setOpacity(opacity: number) { + this.element.setAttribute("opacity", `${opacity}`); } } } \ No newline at end of file diff --git a/sim/visuals/view.ts b/sim/visuals/view.ts index 7e46300c..b0d7ae9f 100644 --- a/sim/visuals/view.ts +++ b/sim/visuals/view.ts @@ -219,7 +219,6 @@ namespace pxsim.visuals { this.changed = false; return res; } - } export abstract class SimView extends View implements LayoutElement {