update tabs

This commit is contained in:
casperlamboo 2017-12-04 17:44:08 +01:00
parent 65d44db405
commit 9d14e40c21
3 changed files with 128 additions and 85 deletions

View File

@ -5,7 +5,7 @@ import { Tabs, Tab } from 'material-ui/Tabs';
import MenuItem from 'material-ui/MenuItem'; import MenuItem from 'material-ui/MenuItem';
import injectSheet from 'react-jss'; import injectSheet from 'react-jss';
import { SelectField, TextField, Checkbox } from './FormComponents.js'; import { SelectField, TextField, Checkbox } from './FormComponents.js';
import { grey900 } from 'material-ui/styles/colors'; import { grey800, cyan500 } from 'material-ui/styles/colors';
const styles = { const styles = {
textFieldRow: { textFieldRow: {
@ -13,7 +13,7 @@ const styles = {
}, },
text: { text: {
fontWeight: 'bold', fontWeight: 'bold',
color: grey900 color: grey800
}, },
container: { container: {
width: '100%', width: '100%',
@ -91,8 +91,8 @@ class Settings extends React.Component {
))} ))}
</SelectField> </SelectField>
<h3 className={classes.text}>Printer Setup</h3> <h3 className={classes.text}>Printer Setup</h3>
<Tabs> <Tabs inkBarStyle={{ backgroundColor: cyan500 }}>
<Tab label="basic"> <Tab buttonStyle={{ color: grey800, backgroundColor: 'white' }} label="Basic">
<div> <div>
<SelectField name="quality" floatingLabelText="Quality" fullWidth> <SelectField name="quality" floatingLabelText="Quality" fullWidth>
{Object.entries(quality).map(([value, { title }]) => ( {Object.entries(quality).map(([value, { title }]) => (
@ -101,7 +101,7 @@ class Settings extends React.Component {
</SelectField> </SelectField>
</div> </div>
</Tab> </Tab>
<Tab label="advanced"> <Tab buttonStyle={{ color: grey800, backgroundColor: 'white' }} label="Advanced">
<div> <div>
<p className={classes.text}>Printer dimensions</p> <p className={classes.text}>Printer dimensions</p>
<div className={classes.textFieldRow}> <div className={classes.textFieldRow}>

View File

@ -2,12 +2,13 @@ import _ from 'lodash';
import React from 'react'; import React from 'react';
import * as THREE from 'three'; import * as THREE from 'three';
import PropTypes from 'proptypes'; 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 injectSheet from 'react-jss';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
import Slider from 'material-ui/Slider'; import Slider from 'material-ui/Slider';
import LinearProgress from 'material-ui/LinearProgress'; import LinearProgress from 'material-ui/LinearProgress';
import { grey100, grey300, red500 } from 'material-ui/styles/colors'; import { grey100, grey300, red500 } from 'material-ui/styles/colors';
import { Tabs, Tab } from 'material-ui/Tabs';
import Settings from './Settings.js'; import Settings from './Settings.js';
import baseSettings from '../settings/default.yml'; import baseSettings from '../settings/default.yml';
import printerSettings from '../settings/printer.yml'; import printerSettings from '../settings/printer.yml';
@ -38,7 +39,7 @@ const styles = {
canvas: { canvas: {
position: 'absolute' position: 'absolute'
}, },
sliceBar: { settingsBar: {
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
maxWidth: '380px', maxWidth: '380px',
@ -104,10 +105,7 @@ class Interface extends React.Component {
const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props; const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props;
this.state = { this.state = {
controlMode: 'translate', controlMode: 'translate',
showFullScreen: { showFullScreen: false,
active: false,
settings: true
},
isSlicing: false, isSlicing: false,
error: null, error: null,
printers: defaultPrinter, printers: defaultPrinter,
@ -206,6 +204,12 @@ class Interface extends React.Component {
if (changed) render(); if (changed) render();
} }
componentDidUpdate() {
const { updateCanvas } = this.state;
const { canvas } = this.refs;
if (updateCanvas && canvas) updateCanvas(canvas);
}
onResize3dView = (width, height) => { onResize3dView = (width, height) => {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
const { setSize } = this.state; const { setSize } = this.state;
@ -215,86 +219,89 @@ class Interface extends React.Component {
}; };
onResizeContainer = (width) => { onResizeContainer = (width) => {
this.setState({ this.setState({ showFullScreen: width > MAX_FULLSCREEN_WIDTH });
showFullScreen: {
active: width > MAX_FULLSCREEN_WIDTH,
settings: this.state.showFullScreen.settings
}
});
}; };
render() { render() {
const { classes, onCompleteActions, defaultPrinter, defaultQuality, defaultMaterial } = this.props; const { classes, onCompleteActions, defaultPrinter, defaultQuality, defaultMaterial } = this.props;
const { isSlicing, progress, gcode, settings, printers, quality, material, showFullScreen, error } = this.state; 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 percentage = progress ? (progress.uploading + progress.slicing) / 2.0 * 100.0 : 0.0;
const toggleFullScreen = () => { const settingsPanel = (
this.setState({ <div className={classes.settingsBar} style={{ ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) }}>
showFullScreen: { <Settings
...this.state.showFullScreen, disabled={isSlicing}
settings: !this.state.showFullScreen.settings printers={printerSettings}
} defaultPrinter={defaultPrinter}
}); quality={qualitySettings}
}; defaultQuality={defaultQuality}
material={materialSettings}
return ( defaultMaterial={defaultMaterial}
<div className={classes.container}> initialSettings={settings}
<ReactResizeDetector handleWidth handleHeight onResize={this.onResizeContainer} /> onChange={this.onChangeSettings}
{<div style={{ display: showPreview ? 'inherit' : 'none' }} className={classes.d3View}> />
<ReactResizeDetector handleWidth handleHeight onResize={this.onResize3dView} /> <div className={classes.sliceActions}>
<canvas className={classes.canvas} ref="canvas" /> {error && <p className={classes.error}>{error}</p>}
{!showFullScreen.active && <div className={classes.buttonContainer}> {isSlicing && <p>{progress.action}</p>}
<RaisedButton fullWidth label="Edit settings" onTouchTap={toggleFullScreen}/> {isSlicing && <LinearProgress mode="determinate" value={percentage} />}
</div>} <div className={classes.sliceButtons}>
{!isSlicing && <div className={classes.controlBar}> <RaisedButton
<RaisedButton className={classes.controlButton} onTouchTap={this.resetMesh} label="reset" /> label="Print"
<RaisedButton className={classes.controlButton} onTouchTap={this.scaleUp} label="scale down" /> primary
<RaisedButton className={classes.controlButton} onTouchTap={this.scaleDown} label="scale up" /> className={`${classes.button}`}
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateX} label="rotate x" /> onTouchTap={this.slice}
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateY} label="rotate y" /> disabled={isSlicing}
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateZ} label="rotate z" /> />
</div>}
</div>}
<div
className={classes.sliceBar}
style={{
display: showSettings ? 'inherit' : 'none',
...showPreview ? {} : { maxWidth: 'inherit', width: '100%' }
}}
>
{!showFullScreen.active && <RaisedButton label="Edit model" onTouchTap={toggleFullScreen}/>}
<Settings
disabled={isSlicing}
printers={printerSettings}
defaultPrinter={defaultPrinter}
quality={qualitySettings}
defaultQuality={defaultQuality}
material={materialSettings}
defaultMaterial={defaultMaterial}
initialSettings={settings}
onChange={this.onChangeSettings}
/>
<div className={classes.sliceActions}>
{error && <p className={classes.error}>{error}</p>}
{isSlicing && <p>{progress.action}</p>}
{isSlicing && <LinearProgress mode="determinate" value={percentage} />}
<div className={classes.sliceButtons}>
<RaisedButton
label="Print"
primary
className={`${classes.button}`}
onTouchTap={this.slice}
disabled={isSlicing}
/>
</div>
</div> </div>
</div> </div>
</div> </div>
); );
const d3Panel = (
<div className={classes.d3View}>
<ReactResizeDetector handleWidth handleHeight onResize={this.onResize3dView} />
<canvas className={classes.canvas} ref="canvas" />
{!isSlicing && <div className={classes.controlBar}>
<RaisedButton className={classes.controlButton} onTouchTap={this.resetMesh} label="reset" />
<RaisedButton className={classes.controlButton} onTouchTap={this.scaleUp} label="scale down" />
<RaisedButton className={classes.controlButton} onTouchTap={this.scaleDown} label="scale up" />
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateX} label="rotate x" />
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateY} label="rotate y" />
<RaisedButton className={classes.controlButton} onTouchTap={this.rotateZ} label="rotate z" />
</div>}
</div>
);
if (showFullScreen) {
return (
<div className={classes.container}>
<ReactResizeDetector handleWidth handleHeight onResize={this.onResizeContainer} />
{d3Panel}
{settingsPanel}
</div>
);
} else {
return (
<div className={classes.container}>
<ReactResizeDetector handleWidth handleHeight onResize={this.onResizeContainer} />
<Tabs
style={{ width: '100%', display: 'flex', flexDirection: 'column' }}
tabItemContainerStyle={{ flexShrink: 0 }}
contentContainerStyle={{ flexGrow: 1, display: 'flex' }}
tabTemplateStyle={{ display: 'flex' }}
tabTemplate={TabTemplate}
>
<Tab label="Settings">
{settingsPanel}
</Tab>
<Tab label="Preview">
{d3Panel}
</Tab>
</Tabs>
</div>
);
}
} }
} }

View File

@ -4,6 +4,8 @@ import printerSettings from '../settings/printer.yml';
import materialSettings from '../settings/material.yml'; import materialSettings from '../settings/material.yml';
import qualitySettings from '../settings/quality.yml'; import qualitySettings from '../settings/quality.yml';
import { sliceGeometry } from '../slicer.js'; import { sliceGeometry } from '../slicer.js';
import React from 'react';
import PropTypes from 'prop-types';
export function placeOnGround(mesh) { export function placeOnGround(mesh) {
const boundingBox = new THREE.Box3().setFromObject(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.scale.set(dimensions.y, dimensions.z, dimensions.x);
box.updateMatrix(); box.updateMatrix();
const editorControls = new THREE.EditorControls(camera, canvas);
editorControls.focus(mesh);
const render = () => renderer.render(scene, camera); const render = () => renderer.render(scene, camera);
editorControls.addEventListener('change', render);
const setSize = (width, height, pixelRatio = 1) => { const setSize = (width, height, pixelRatio = 1) => {
renderer.setSize(width, height); renderer.setSize(width, height);
@ -58,10 +56,21 @@ export function createScene(canvas, props, state) {
render(); render();
}; };
let editorControls;
let renderer; let renderer;
const updateCanvas = (canvas) => { const updateCanvas = (canvas) => {
renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true }); if (!renderer || renderer.domElement !== canvas) {
renderer.setClearColor(0xffffff, 0); 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(); render();
}; };
updateCanvas(canvas); 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'); const popup = window.open(`${CONNECT_URL}?uuid=${id}`, '_blank');
if (!popup) throw new Error('popup was blocked by browser'); 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 (
<div style={templateStyle}>
{children}
</div>
);
};
TabTemplate.propTypes = {
children: PropTypes.node,
selected: PropTypes.bool,
style: PropTypes.object,
};