Skip to content

Commit

Permalink
Merge pull request #18 from CASL/rodeditor
Browse files Browse the repository at this point in the history
Rod editor
  • Loading branch information
floryst authored Apr 30, 2018
2 parents 16d8439 + 5f9a8a9 commit 46eec0f
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 7 deletions.
150 changes: 150 additions & 0 deletions src/simput/RodEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React from 'react';
import PropTypes from 'prop-types';

import Rod2DPreview from '../widgets/Rod2DPreview';
import EditableList from '../widgets/EditableList';

import style from './RodEditor.mcss';

export default class RodEditor extends React.Component {
constructor(props) {
super(props);
this.state = {};

this.onCellChange = this.onCellChange.bind(this);
this.onLengthChange = this.onLengthChange.bind(this);
this.addLayer = this.addLayer.bind(this);
this.delLayer = this.delLayer.bind(this);
}

onCellChange(layer, value) {
const data = this.props.data;
const cells = this.props.ui.domain;
if (data.value && data.value.length) {
const stack = data.value[0].stack;
if (value in cells) {
stack[layer.key].label = value;
this.props.onChange(data);
}
}
}

onLengthChange(layer, value) {
const data = this.props.data;
if (data.value && data.value.length) {
const stack = data.value[0].stack;
const newValue = Number(value);
const totalLength = Number(this.props.viewData.rodInfo.height.value[0]);
const currentLength = stack.reduce((t, l) => t + l.length, 0);
const newLength = currentLength - stack[layer.key].length + newValue;

if (newLength <= totalLength) {
stack[layer.key].length = newValue;
this.props.onChange(data);
}
}
}

addLayer(idx) {
const data = this.props.data;
const cells = Object.keys(this.props.ui.domain);
if (data.value && data.value.length && cells.length) {
const stack = data.value[0].stack;
const afterIdx = idx + 1;
stack.splice(afterIdx, 0, {
color: 'blue',
label: cells[0],
length: 0,
});

this.props.onChange(data);
}
}

delLayer(idx) {
const data = this.props.data;
if (data.value && data.value.length) {
const stack = data.value[0].stack;
stack.splice(idx, 1);

this.props.onChange(data);
}
}

render() {
const cells = Object.keys(this.props.ui.domain);

const columns = [
{
key: 'color',
dataKey: 'color',
label: 'Color',
},
{
key: 'cell',
dataKey: 'cell',
label: 'Cell/Layer Type',
classes: style.centeredCell,
render: (cellName, layer) => (
<select
className={style.cellSelect}
onChange={(e) => this.onCellChange(layer, e.target.value)}
>
{cells.map((name) => <option key={name}>{name}</option>)}
</select>
),
},
{
key: 'length',
dataKey: 'length',
label: 'Length',
classes: style.centeredCell,
render: (value, layer) => (
<input
type="number"
min="0"
step="1"
value={layer.length}
onChange={(e) => this.onLengthChange(layer, e.target.value)}
/>
),
},
];

let items = [];
if (this.props.data.value && this.props.data.value.length) {
items = this.props.data.value[0].stack.map((layer, idx) =>
Object.assign({ key: idx }, layer)
);
}

const totalLength = Number(this.props.viewData.rodInfo.height.value[0]);

return (
<div>
<Rod2DPreview stack={items} totalLength={totalLength} />
<EditableList
columns={columns}
data={items}
onAdd={this.addLayer}
onDelete={this.delLayer}
/>
</div>
);
}
}

RodEditor.propTypes = {
data: PropTypes.object.isRequired,
// help: PropTypes.string,
// name: PropTypes.string,
onChange: PropTypes.func.isRequired,
// show: PropTypes.func.isRequired,
ui: PropTypes.object.isRequired,
viewData: PropTypes.object.isRequired,
};

RodEditor.defaultProps = {
// name: '',
// help: '',
};
7 changes: 7 additions & 0 deletions src/simput/RodEditor.mcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.centeredCell {
text-align: center;
}

.cellSelect {
width: 100%;
}
15 changes: 11 additions & 4 deletions src/simput/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import CellEditor from './CellEditor';
import Rod2DPreview from '../widgets/Rod2DPreview';
import RodEditor from './RodEditor';

function registerLocalEditors(Simput) {
if (Simput && Simput.updateWidgetMapping) {
Simput.updateWidgetMapping('RodCellEditor', (prop, viewData, onChange) => (
Simput.updateWidgetMapping('CellEditor', (prop, viewData, onChange) => (
<CellEditor
key={prop.data.id}
data={prop.data}
Expand All @@ -14,8 +14,15 @@ function registerLocalEditors(Simput) {
onChange={onChange || prop.onChange}
/>
));
Simput.updateWidgetMapping('RodPreview', (prop, viewData, onChange) => (
<Rod2DPreview key={prop.data.id} />
Simput.updateWidgetMapping('RodEditor', (prop, viewData, onChange) => (
<RodEditor
key={prop.data.id}
data={prop.data}
ui={prop.ui}
viewData={viewData}
show={prop.show}
onChange={onChange || prop.onChange}
/>
));
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/widgets/EditableList.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ function EditableList(props) {

const cellKey = `${col.dataKey}::${datum.key}`;

return <td key={cellKey}>{content}</td>;
return (
<td className={col.classes} key={cellKey}>
{content}
</td>
);
});

return (
Expand Down
5 changes: 4 additions & 1 deletion src/widgets/Rod2DPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export default function Rod2DPreview(props) {
}}
/>
))}
<td className={style.last} />
<td
className={style.last}
style={{ width: `${100 * remaining / props.totalLength}%` }}
/>
</tr>
<tr className={style.labels}>
{props.stack.map(({ label }, i) => (
Expand Down
2 changes: 1 addition & 1 deletion src/widgets/Rod3DPreview.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Rod3DPreview.js
Rod3DPreview.js;

0 comments on commit 46eec0f

Please sign in to comment.