diff --git a/sim/dalboard.ts b/sim/dalboard.ts index e5101a5f..9ccbe149 100644 --- a/sim/dalboard.ts +++ b/sim/dalboard.ts @@ -19,6 +19,9 @@ namespace pxsim { brickNode: BrickNode; outputNodes: MotorNode[] = []; + highcontrastMode?: boolean; + lightMode?: boolean; + public motorMap: pxt.Map = { 0x01: 0, 0x02: 1, @@ -77,17 +80,25 @@ namespace pxsim { fnArgs: fnArgs, maxWidth: "100%", maxHeight: "100%", + highContrast: msg.highContrast, + light: msg.light }; const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({ - visual: boardDef.visual + visual: boardDef.visual, + highContrast: msg.highContrast, + light: msg.light }), opts); document.body.innerHTML = ""; // clear children + document.body.className = msg.light ? "light" : ""; document.body.appendChild(this.view = viewHost.getView() as SVGSVGElement); this.inputNodes = []; this.outputNodes = []; + this.highcontrastMode = msg.highContrast; + this.lightMode = msg.light; + return Promise.resolve(); } @@ -171,6 +182,14 @@ namespace pxsim { return runtime.board as EV3Board; } + export function inLightMode(): boolean { + return /light=1/i.test(window.location.href) || ev3board().lightMode; + } + + export function inHighcontrastMode(): boolean { + return ev3board().highcontrastMode; + } + if (!pxsim.initCurrentRuntime) { pxsim.initCurrentRuntime = initRuntimeWithDalBoard; } diff --git a/sim/public/simulator.html b/sim/public/simulator.html index 28d631bb..ae445bae 100644 --- a/sim/public/simulator.html +++ b/sim/public/simulator.html @@ -18,6 +18,10 @@ body { overflow: hidden; margin: 0; } + +.light * { + transition: none !important; +} diff --git a/sim/visuals/assets/Color Sensor.svg b/sim/visuals/assets/Color Sensor.svg index 5b5d6de7..12d13e91 100644 --- a/sim/visuals/assets/Color Sensor.svg +++ b/sim/visuals/assets/Color Sensor.svg @@ -13,7 +13,7 @@ - + diff --git a/sim/visuals/assets/ColorSensorsvg.ts b/sim/visuals/assets/ColorSensorsvg.ts index 7863b173..4a54f652 100644 --- a/sim/visuals/assets/ColorSensorsvg.ts +++ b/sim/visuals/assets/ColorSensorsvg.ts @@ -1,34 +1,3 @@ namespace pxsim { - export const COLOR_SENSOR_SVG = ` - - - - - - - Color Sensor - - - - - - - - - - - - - - - - - - - - - - - -`; + export const COLOR_SENSOR_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/assets/EV3svg.ts b/sim/visuals/assets/EV3svg.ts index 1ece658a..c4475e50 100644 --- a/sim/visuals/assets/EV3svg.ts +++ b/sim/visuals/assets/EV3svg.ts @@ -1,110 +1,4 @@ namespace pxsim.visuals { - export const EV3_SVG = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EV3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const EV3_SVG = ``; } diff --git a/sim/visuals/assets/LargeMotorsvg.ts b/sim/visuals/assets/LargeMotorsvg.ts index 22c98430..dacc990a 100644 --- a/sim/visuals/assets/LargeMotorsvg.ts +++ b/sim/visuals/assets/LargeMotorsvg.ts @@ -1,79 +1,3 @@ namespace pxsim { - export const LARGE_MOTOR_SVG = ` - - - Large Motor - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const LARGE_MOTOR_SVG = ` Large Motor Created with Sketch. `; } \ No newline at end of file diff --git a/sim/visuals/assets/MediumMotorsvg.ts b/sim/visuals/assets/MediumMotorsvg.ts index 33054802..ab5ccd1e 100644 --- a/sim/visuals/assets/MediumMotorsvg.ts +++ b/sim/visuals/assets/MediumMotorsvg.ts @@ -1,35 +1,3 @@ namespace pxsim.visuals { - export const MEDIUM_MOTOR_SVG = ` - - - - - - - MediumMotor - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const MEDIUM_MOTOR_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/assets/Portsvg.ts b/sim/visuals/assets/Portsvg.ts index bf7d03d0..c385b021 100644 --- a/sim/visuals/assets/Portsvg.ts +++ b/sim/visuals/assets/Portsvg.ts @@ -1,13 +1,4 @@ namespace pxsim.visuals { - export const PORT_SVG = ` - port - - - - - B - - -`; + export const PORT_SVG = `B`; } \ No newline at end of file diff --git a/sim/visuals/assets/RemoteSvg.ts b/sim/visuals/assets/RemoteSvg.ts index 5e61c12a..b1977a26 100644 --- a/sim/visuals/assets/RemoteSvg.ts +++ b/sim/visuals/assets/RemoteSvg.ts @@ -1,100 +1,3 @@ namespace pxsim.visuals { - export const REMOVE_SVG = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `; + export const REMOVE_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/assets/TouchSensorsvg.ts b/sim/visuals/assets/TouchSensorsvg.ts index ec82b7b2..144b1f87 100644 --- a/sim/visuals/assets/TouchSensorsvg.ts +++ b/sim/visuals/assets/TouchSensorsvg.ts @@ -1,64 +1,4 @@ namespace pxsim.visuals { - export const TOUCH_SENSOR_SVG = ` - - - - - - - - - - - - - - - - - - - - - - - - - Touch sensor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const TOUCH_SENSOR_SVG = ``; } diff --git a/sim/visuals/assets/gyro.svg b/sim/visuals/assets/gyro.svg index 0dfdd4cc..296f10bc 100644 --- a/sim/visuals/assets/gyro.svg +++ b/sim/visuals/assets/gyro.svg @@ -32,7 +32,7 @@ - + diff --git a/sim/visuals/assets/gyrosvg.ts b/sim/visuals/assets/gyrosvg.ts index f484ed2f..84bc66e8 100644 --- a/sim/visuals/assets/gyrosvg.ts +++ b/sim/visuals/assets/gyrosvg.ts @@ -1,54 +1,4 @@ namespace pxsim { - export const GYRO_SVG = ` - - - - - - - - - - - - - - gyro - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const GYRO_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/assets/infraredsvg.ts b/sim/visuals/assets/infraredsvg.ts index 7798320f..1096b9b1 100644 --- a/sim/visuals/assets/infraredsvg.ts +++ b/sim/visuals/assets/infraredsvg.ts @@ -1,64 +1,3 @@ namespace pxsim { - export const INFRARED_SVG = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `; + export const INFRARED_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/assets/ultrasonicsvg.ts b/sim/visuals/assets/ultrasonicsvg.ts index 9c9191a6..48c8aaa7 100644 --- a/sim/visuals/assets/ultrasonicsvg.ts +++ b/sim/visuals/assets/ultrasonicsvg.ts @@ -1,79 +1,3 @@ namespace pxsim { - export const ULTRASONIC_SVG = ` - - - - - - - - - ultra sonic - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; + export const ULTRASONIC_SVG = ``; } \ No newline at end of file diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index fe4f9c04..339056ea 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -109,7 +109,7 @@ namespace pxsim.visuals { } }); - export function randomTheme(): IBoardTheme { + export function randomTheme(highContrast?: boolean, light?: boolean): IBoardTheme { return themes[Math.floor(Math.random() * themes.length)]; } @@ -303,7 +303,7 @@ namespace pxsim.visuals { this.wrapper = document.createElement('div'); this.wrapper.style.display = 'inline'; - this.element = svg.elt("svg", { height: "100%", width: "100%" }) as SVGSVGElement; + this.element = svg.elt("svg", { height: "100%", width: "100%", "class": "user-select-none" }) as SVGSVGElement; this.defs = svg.child(this.element, "defs") as SVGDefsElement; @@ -391,6 +391,9 @@ namespace pxsim.visuals { cancelAnimationFrame(animationId); }) } + // Kill the brick + this.layoutView.getBrick().kill(); + // 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); diff --git a/sim/visuals/boardview.ts b/sim/visuals/boardview.ts index e7c140ba..7f89c560 100644 --- a/sim/visuals/boardview.ts +++ b/sim/visuals/boardview.ts @@ -2,7 +2,7 @@ namespace pxsim.visuals { mkBoardView = (opts: BoardViewOptions): BoardView => { return new visuals.EV3View({ runtime: runtime, - theme: visuals.randomTheme(), + theme: visuals.randomTheme(opts.highContrast, opts.light), disableTilt: false, wireframe: opts.wireframe, }); diff --git a/sim/visuals/nodes/brickView.ts b/sim/visuals/nodes/brickView.ts index c1d4e545..fa7af946 100644 --- a/sim/visuals/nodes/brickView.ts +++ b/sim/visuals/nodes/brickView.ts @@ -13,6 +13,9 @@ namespace pxsim.visuals { private currentCanvasX = 178; private currentCanvasY = 128; + private static LIGHT_BLACK_COLOR = '#6a6a6a'; + private static LIGHT_RED_COLOR = '#6a6a6a'; + constructor(port: number) { super(EV3_SVG, "board", NodeType.Brick, port); } @@ -26,9 +29,16 @@ namespace pxsim.visuals { this.light = this.content.getElementById(this.normalizeId(BrickView.EV3_LIGHT_ID)) as SVGElement; } - private setStyleFill(svgId: string, fillUrl: string) { + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('ev3_body_2')) as SVGElement).style.fill = '#f1f1f1'; + (this.content.getElementById(this.normalizeId('ev3_screen_grey')) as SVGElement).style.fill = '#a8aaa8'; + (this.content.getElementById(this.normalizeId('ev3_grey_buttom')) as SVGElement).style.fill = '#a8aaa8'; + (this.content.getElementById(this.normalizeId('btn_part_2')) as SVGElement).style.fill = '#393939'; + } + + private setStyleFill(svgId: string, fillUrl: string, lightFill?: string) { const el = (this.content.getElementById(svgId) as SVGRectElement); - if (el) el.style.fill = `url("#${fillUrl}")`; + if (el) el.style.fill = inLightMode() ? lightFill || BrickView.LIGHT_BLACK_COLOR : `url("#${fillUrl}")`; } public hasClick() { @@ -64,15 +74,15 @@ namespace pxsim.visuals { //svg.fill(this.light, "#FFF"); break; case 1: // LED_GREEN - this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-green`)); + this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-green`), 'green'); //svg.fill(this.light, "#00ff00"); break; case 2: // LED_RED - this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-red`)); + this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-red`), 'red'); //svg.fill(this.light, "#ff0000"); break; case 3: // LED_ORANGE - this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-orange`)); + this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-orange`), 'orange'); //svg.fill(this.light, "#FFA500"); break; case 4: // LED_GREEN_FLASH @@ -120,14 +130,13 @@ namespace pxsim.visuals { private flash: boolean; private flashLightAnimationStep(id: string) { if (this.flash) { - this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`)); + this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`), id); } else { this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); } this.flash = !this.flash; } - private pulseLightAnimation(id: string) { const pattern = this.lastLightPattern; let fps = 8; @@ -153,21 +162,24 @@ namespace pxsim.visuals { private pulse: number = 0; private pulseLightAnimationStep(id: string) { switch (this.pulse) { - case 0: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; case 1: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; case 2: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; case 3: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; case 4: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; - case 5: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`)); break; - case 6: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`)); break; + case 5: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`), id); break; + case 6: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`), id); break; case 7: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-black`)); break; - case 8: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`)); break; + case 8: this.setStyleFill(this.normalizeId(BrickView.EV3_LIGHT_ID), this.normalizeId(`linear-gradient-${id}`), id); break; } this.pulse++; if (this.pulse == 9) this.pulse = 0; } + public kill() { + cancelAnimationFrame(this.lastLightAnimationId); + } + public attachEvents() { let bpState = ev3board().getBrickNode().buttonState; let stateButtons = bpState.buttons; diff --git a/sim/visuals/nodes/colorSensorView.ts b/sim/visuals/nodes/colorSensorView.ts index 5637af6d..a8d605db 100644 --- a/sim/visuals/nodes/colorSensorView.ts +++ b/sim/visuals/nodes/colorSensorView.ts @@ -9,6 +9,10 @@ namespace pxsim.visuals { super(COLOR_SENSOR_SVG, "color", NodeType.ColorSensor, port); } + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('color_bigbox-2_path')) as SVGElement).style.fill = '#a8aaa8'; + } + public getPaddingRatio() { return 1 / 4; } diff --git a/sim/visuals/nodes/gyroSensorView.ts b/sim/visuals/nodes/gyroSensorView.ts index 37850463..193b0d31 100644 --- a/sim/visuals/nodes/gyroSensorView.ts +++ b/sim/visuals/nodes/gyroSensorView.ts @@ -7,6 +7,11 @@ namespace pxsim.visuals { super(GYRO_SVG, "gyro", NodeType.GyroSensor, port); } + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('gyro_white_1')) as SVGElement).style.fill = '#7B7B7B'; + (this.content.getElementById(this.normalizeId('gyro_white_small_path')) as SVGElement).style.fill = '#7B7B7B'; + } + public getPaddingRatio() { return 0.3; } diff --git a/sim/visuals/nodes/infraredview.ts b/sim/visuals/nodes/infraredview.ts index c32a838b..50ffcd51 100644 --- a/sim/visuals/nodes/infraredview.ts +++ b/sim/visuals/nodes/infraredview.ts @@ -6,5 +6,9 @@ namespace pxsim.visuals { constructor(port: number) { super(INFRARED_SVG, "infrared", NodeType.InfraredSensor, port); } + + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('path9245')) as SVGElement).style.fill = '#f2f2f2'; + } } } \ No newline at end of file diff --git a/sim/visuals/nodes/mediumMotorView.ts b/sim/visuals/nodes/mediumMotorView.ts index ab632ec0..caee2a10 100644 --- a/sim/visuals/nodes/mediumMotorView.ts +++ b/sim/visuals/nodes/mediumMotorView.ts @@ -8,6 +8,10 @@ namespace pxsim.visuals { super(MEDIUM_MOTOR_SVG, "medium-motor", NodeType.MediumMotor, port, "medmotor_Hole"); } + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('medmotor_box_wgradient')) as SVGElement).style.fill = '#a8aaa8'; + } + public getPaddingRatio() { return 1 / 5; } diff --git a/sim/visuals/nodes/moduleView.ts b/sim/visuals/nodes/moduleView.ts index 6b68034c..5ce227fe 100644 --- a/sim/visuals/nodes/moduleView.ts +++ b/sim/visuals/nodes/moduleView.ts @@ -55,6 +55,7 @@ namespace pxsim.visuals { protected buildDom(): SVGElement { this.content = svg.parseString(this.xml); this.buildDomCore(); + if (pxsim.inLightMode()) this.optimizeForLightMode(); this.attachEvents(); if (this.hasClick()) this.content.style.cursor = "pointer"; @@ -65,6 +66,10 @@ namespace pxsim.visuals { } + protected optimizeForLightMode() { + + } + public getInnerHeight() { if (!this.content) { return 0; diff --git a/sim/visuals/nodes/touchSensorView.ts b/sim/visuals/nodes/touchSensorView.ts index bce6f92a..cca656f3 100644 --- a/sim/visuals/nodes/touchSensorView.ts +++ b/sim/visuals/nodes/touchSensorView.ts @@ -12,10 +12,17 @@ namespace pxsim.visuals { private xLinkGradients: string[]; + private static LIGHT_TOUCH_BLACK_COLOR = '#000'; + private static LIGHT_TOUCH_RED_COLOR = '#d42715'; + constructor(port: number) { super(TOUCH_SENSOR_SVG, "touch", NodeType.TouchSensor, port); } + protected optimizeForLightMode() { + (this.content.getElementById(this.normalizeId('touch_box_2-2')) as SVGElement).style.fill = '#a8aaa8'; + } + public getPaddingRatio() { return 1 / 4; } @@ -29,9 +36,9 @@ namespace pxsim.visuals { if (el) el.setAttribute(attribute, value); } - private setStyleFill(svgId: string, fillUrl: string) { + private setStyleFill(svgId: string, fillUrl: string, lightFill: string) { const el = (this.content.getElementById(svgId) as SVGRectElement); - if (el) el.style.fill = `url("#${fillUrl}")`; + if (el) el.style.fill = inLightMode() ? lightFill : `url("#${fillUrl}")`; } public attachEvents() { @@ -55,11 +62,11 @@ namespace pxsim.visuals { private setPressed(pressed: boolean) { if (pressed) { for (let i = 0; i < 4; i ++) { - this.setStyleFill(`${this.normalizeId(TouchSensorView.RECT_ID[i])}`, `${this.normalizeId(TouchSensorView.TOUCH_GRADIENT_PRESSED[i])}`); + this.setStyleFill(`${this.normalizeId(TouchSensorView.RECT_ID[i])}`, `${this.normalizeId(TouchSensorView.TOUCH_GRADIENT_PRESSED[i])}`, TouchSensorView.LIGHT_TOUCH_BLACK_COLOR); } } else { for (let i = 0; i < 4; i ++) { - this.setStyleFill(`${this.normalizeId(TouchSensorView.RECT_ID[i])}`, `${this.normalizeId(TouchSensorView.TOUCH_GRADIENT_UNPRESSED[i])}`); + this.setStyleFill(`${this.normalizeId(TouchSensorView.RECT_ID[i])}`, `${this.normalizeId(TouchSensorView.TOUCH_GRADIENT_UNPRESSED[i])}`, TouchSensorView.LIGHT_TOUCH_RED_COLOR); } } } diff --git a/sim/visuals/view.ts b/sim/visuals/view.ts index cbe95623..e9d0dca3 100644 --- a/sim/visuals/view.ts +++ b/sim/visuals/view.ts @@ -249,6 +249,9 @@ namespace pxsim.visuals { protected getView() { return super.getView(); } + + public kill() { + } } export class ViewContainer extends View { diff --git a/theme/site/globals/site.variables b/theme/site/globals/site.variables index 55c4ea6c..333ddf6e 100644 --- a/theme/site/globals/site.variables +++ b/theme/site/globals/site.variables @@ -131,8 +131,6 @@ @editorToolsBackground: @legoGreyLight; /* #fff;*/ /* #fcfbfa; */ @blocklySvgColor: #f9f9f9; /*#f2f6f8;*/ /*ecf6fe;*/ -@homeScreenBackground: #F2F2F2; - /*------------------- Full screen --------------------*/ @@ -147,6 +145,13 @@ @sidedocsButtonsTop: (@mainMenuHeight + 1rem); @sidedocsButtonsRight: 4.25rem; +/*------------------- + Home screen +--------------------*/ + +@homeScreenBackground: #F2F2F2; +@homeCardBorderColor: #F2F2F2; + /*------------------- Editor --------------------*/