diff --git a/src/interface/Settings.js b/src/interface/Settings.js index 5a67ca6..e553773 100644 --- a/src/interface/Settings.js +++ b/src/interface/Settings.js @@ -5,7 +5,7 @@ import { Tabs, Tab } from 'material-ui/Tabs'; import MenuItem from 'material-ui/MenuItem'; import injectSheet from 'react-jss'; import { SelectField, TextField, Checkbox } from './FormComponents.js'; -import { grey900 } from 'material-ui/styles/colors'; +import { grey800, cyan500 } from 'material-ui/styles/colors'; const styles = { textFieldRow: { @@ -13,7 +13,7 @@ const styles = { }, text: { fontWeight: 'bold', - color: grey900 + color: grey800 }, container: { width: '100%', @@ -91,8 +91,8 @@ class Settings extends React.Component { ))}

Printer Setup

- - + +
{Object.entries(quality).map(([value, { title }]) => ( @@ -101,7 +101,7 @@ class Settings extends React.Component {
- +

Printer dimensions

diff --git a/src/interface/index.js b/src/interface/index.js index be82411..b70dff6 100644 --- a/src/interface/index.js +++ b/src/interface/index.js @@ -2,12 +2,13 @@ import _ from 'lodash'; import React from 'react'; import * as THREE from 'three'; import PropTypes from 'proptypes'; -import { placeOnGround, createScene, fetchProgress, slice } from './utils.js'; +import { placeOnGround, createScene, fetchProgress, slice, TabTemplate } from './utils.js'; import injectSheet from 'react-jss'; import RaisedButton from 'material-ui/RaisedButton'; import Slider from 'material-ui/Slider'; import LinearProgress from 'material-ui/LinearProgress'; import { grey100, grey300, red500 } from 'material-ui/styles/colors'; +import { Tabs, Tab } from 'material-ui/Tabs'; import Settings from './Settings.js'; import baseSettings from '../settings/default.yml'; import printerSettings from '../settings/printer.yml'; @@ -38,7 +39,7 @@ const styles = { canvas: { position: 'absolute' }, - sliceBar: { + settingsBar: { display: 'flex', flexDirection: 'column', maxWidth: '380px', @@ -104,10 +105,7 @@ class Interface extends React.Component { const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props; this.state = { controlMode: 'translate', - showFullScreen: { - active: false, - settings: true - }, + showFullScreen: false, isSlicing: false, error: null, printers: defaultPrinter, @@ -206,6 +204,12 @@ class Interface extends React.Component { if (changed) render(); } + componentDidUpdate() { + const { updateCanvas } = this.state; + const { canvas } = this.refs; + if (updateCanvas && canvas) updateCanvas(canvas); + } + onResize3dView = (width, height) => { window.requestAnimationFrame(() => { const { setSize } = this.state; @@ -215,86 +219,89 @@ class Interface extends React.Component { }; onResizeContainer = (width) => { - this.setState({ - showFullScreen: { - active: width > MAX_FULLSCREEN_WIDTH, - settings: this.state.showFullScreen.settings - } - }); + this.setState({ showFullScreen: width > MAX_FULLSCREEN_WIDTH }); }; render() { const { classes, onCompleteActions, defaultPrinter, defaultQuality, defaultMaterial } = this.props; const { isSlicing, progress, gcode, settings, printers, quality, material, showFullScreen, error } = this.state; - const showSettings = showFullScreen.active || showFullScreen.settings; - const showPreview = showFullScreen.active || !showFullScreen.settings; - const percentage = progress ? (progress.uploading + progress.slicing) / 2.0 * 100.0 : 0.0; - const toggleFullScreen = () => { - this.setState({ - showFullScreen: { - ...this.state.showFullScreen, - settings: !this.state.showFullScreen.settings - } - }); - }; - - return ( -
- - {
- - - {!showFullScreen.active &&
- -
} - {!isSlicing &&
- - - - - - -
} -
} -
- {!showFullScreen.active && } - -
- {error &&

{error}

} - {isSlicing &&

{progress.action}

} - {isSlicing && } -
- -
+ const settingsPanel = ( +
+ +
+ {error &&

{error}

} + {isSlicing &&

{progress.action}

} + {isSlicing && } +
+
); + + const d3Panel = ( +
+ + + {!isSlicing &&
+ + + + + + +
} +
+ ); + + if (showFullScreen) { + return ( +
+ + {d3Panel} + {settingsPanel} +
+ ); + } else { + return ( +
+ + + + {settingsPanel} + + + {d3Panel} + + +
+ ); + } } } diff --git a/src/interface/utils.js b/src/interface/utils.js index bc91f35..1d75da4 100644 --- a/src/interface/utils.js +++ b/src/interface/utils.js @@ -4,6 +4,8 @@ import printerSettings from '../settings/printer.yml'; import materialSettings from '../settings/material.yml'; import qualitySettings from '../settings/quality.yml'; import { sliceGeometry } from '../slicer.js'; +import React from 'react'; +import PropTypes from 'prop-types'; export function placeOnGround(mesh) { const boundingBox = new THREE.Box3().setFromObject(mesh); @@ -44,11 +46,7 @@ export function createScene(canvas, props, state) { box.scale.set(dimensions.y, dimensions.z, dimensions.x); box.updateMatrix(); - const editorControls = new THREE.EditorControls(camera, canvas); - editorControls.focus(mesh); - const render = () => renderer.render(scene, camera); - editorControls.addEventListener('change', render); const setSize = (width, height, pixelRatio = 1) => { renderer.setSize(width, height); @@ -58,10 +56,21 @@ export function createScene(canvas, props, state) { render(); }; + let editorControls; let renderer; const updateCanvas = (canvas) => { - renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true }); - renderer.setClearColor(0xffffff, 0); + if (!renderer || renderer.domElement !== canvas) { + if (renderer) renderer.dispose(); + renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true }); + renderer.setClearColor(0xffffff, 0); + } + if (!editorControls || editorControls.domElement !== canvas) { + if (editorControls) editorControls.dispose(); + editorControls = new THREE.EditorControls(camera, canvas); + editorControls.focus(mesh); + editorControls.addEventListener('change', render); + } + render(); }; updateCanvas(canvas); @@ -143,3 +152,30 @@ export async function slice(mesh, settings, printers, quality, material, updateP const popup = window.open(`${CONNECT_URL}?uuid=${id}`, '_blank'); if (!popup) throw new Error('popup was blocked by browser'); } + +const styles = { + width: '100%', + position: 'relative', + textAlign: 'initial', +}; + +export const TabTemplate = ({children, selected, style}) => { + const templateStyle = Object.assign({}, styles, style); + if (!selected) { + templateStyle.height = 0; + templateStyle.width = 0; + templateStyle.overflow = 'hidden'; + } + + return ( +
+ {children} +
+ ); +}; + +TabTemplate.propTypes = { + children: PropTypes.node, + selected: PropTypes.bool, + style: PropTypes.object, +};