Skip to content

Commit

Permalink
Merge pull request #26 from Kitware/add-support-for-unsized-props
Browse files Browse the repository at this point in the history
fix(ReactProperties): Allow dynamic size for a property
  • Loading branch information
jourdain committed Feb 29, 2016
2 parents d7109d4 + 6c676bc commit be3649f
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 39 deletions.
28 changes: 14 additions & 14 deletions dist/ParaViewWeb.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/Common/Misc/ConvertProxyProperty/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const typeMapping = {
};

function extractLayout(ui) {
if(ui.size === 0) {
return '-1';
}

if(ui.size < 4) {
return ui.size.toString();
}
Expand Down
32 changes: 28 additions & 4 deletions src/React/Properties/CellProperty/InputCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,37 @@ export default React.createClass({
}

// Handle range
if (this.props.domain.hasOwnProperty('range')) {
const { min, max } = this.props.domain.range[idx];
val = (min !== undefined) ? Math.max(min, val) : val;
val = (max !== undefined) ? Math.min(max, val) : val;
if (this.props.domain.hasOwnProperty('range') && this.props.domain.range.length) {
const size = this.props.domain.range.length;
const { min, max, force } = this.props.domain.range[idx % size];
if(force) {
val = (min !== undefined) ? Math.max(min, val) : val;
val = (max !== undefined) ? Math.min(max, val) : val;
}
}
return val;
},

getTooltip() {
var tooltip = '';
const idx = this.props.idx;

if(!this.props.domain) {
return tooltip;
}

// Handle range
if (this.props.domain.hasOwnProperty('range') && this.props.domain.range.length) {
const size = this.props.domain.range.length;
const { min, max } = this.props.domain.range[idx % size] || {};

tooltip += (min !== undefined) ? `min(${min}) ` : '';
tooltip += (max !== undefined) ? `max(${max}) ` : '';
}

return tooltip;
},

endEditing(){
this.setState({editing: false});
},
Expand All @@ -69,6 +92,7 @@ export default React.createClass({
className={ style.inputCellInput }
value={this.state.editing ? this.state.valueRep : this.props.value}
onChange={this.valueChange}
title={ this.getTooltip() }
onBlur={this.endEditing}/>
</td>);
},
Expand Down
43 changes: 39 additions & 4 deletions src/React/Properties/CellProperty/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,56 @@ export default React.createClass({

valueChange(idx, newVal) {
var newData = this.state.data;
newData.value[idx] = newVal;
if(newVal === null) {
newData.value.splice(idx, 1);
} else {
newData.value[idx] = newVal;
}

this.setState({data: newData});
if (this.props.onChange) {
this.props.onChange(newData);
}
},

addValue() {
var newData = this.state.data,
values = newData.value;

switch(values.length) {
case 0:
values.push(0);
break;
case 1:
values.push(values[0]);
break;
default:
const last = Number(values[values.length - 1]);
const beforeLast = Number(values[values.length - 2]);
const newValue = last + (last - beforeLast);
if(!Number.isNaN(newValue) && Number.isFinite(newValue)) {
values.push(newValue);
} else {
values.push(values[values.length - 1]);
}

}

this.setState({data: newData});
if (this.props.onChange) {
this.props.onChange(newData);
}
},

render() {
return (
<div className={ this.props.show(this.props.viewData) ? style.container : style.hidden }>
<div className={ style.header }>
<strong>{this.props.ui.label}</strong>
<span>
<i className={ this.props.ui.layout === '-1' ? style.plusIcon : style.hidden }
onClick={ this.addValue }>
</i>
<ToggleIconButton
icon={ style.helpIcon }
value={this.state.helpOpen}
Expand All @@ -44,9 +81,7 @@ export default React.createClass({
</div>
<div className={ style.inputBlock }>
<table className={ style.inputTable }>
<tbody>
{ layouts(this.props.data, this.state.ui, this.valueChange) }
</tbody>
{ layouts(this.props.data, this.props.ui, this.valueChange) }
</table>
</div>
<div className={ this.state.helpOpen ? style.helpBox : style.hidden }
Expand Down
65 changes: 48 additions & 17 deletions src/React/Properties/CellProperty/layouts.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,85 +20,116 @@ const layouts = {
ui.componentLabels = arrayFill(ui.componentLabels, 1);
data.value = arrayFill(data.value, 1, null);
return (
<tbody>
<tr className={ style.inputRow }>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>);
</tr>
</tbody>);
},
'2': (data, ui, callback) => {
ui.componentLabels = arrayFill(ui.componentLabels, 2);
data.value = arrayFill(data.value, 2, null);
return (
<tbody>
<tr className={ style.inputRow }>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={1} label={ui.componentLabels[1]} type={ui.type} value={data.value[1]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>);
</tr>
</tbody>);
},
'3': (data, ui, callback) => {
ui.componentLabels = arrayFill(ui.componentLabels, 3);
data.value = arrayFill(data.value, 3, null);
return (
<tbody>
<tr className={ style.inputRow }>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={1} label={ui.componentLabels[1]} type={ui.type} value={data.value[1]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={2} label={ui.componentLabels[2]} type={ui.type} value={data.value[2]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>);
</tr>
</tbody>);
},
'2x3': (data, ui, callback) => {
ui.componentLabels = arrayFill(ui.componentLabels, 6);
data.value = arrayFill(data.value, 6, null);
return ([
return (
<tbody>
<tr className={ style.inputRow } key={ data.id + '_0'}>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={1} label={ui.componentLabels[1]} type={ui.type} value={data.value[1]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={2} label={ui.componentLabels[2]} type={ui.type} value={data.value[2]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>,
</tr>
<tr className={ style.inputRow } key={ data.id + '_1'}>
<InputCell idx={3} label={ui.componentLabels[3]} type={ui.type} value={data.value[3]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={4} label={ui.componentLabels[4]} type={ui.type} value={data.value[4]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={5} label={ui.componentLabels[5]} type={ui.type} value={data.value[5]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>]);
</tr>
</tbody>);
},
'3x2': (data, ui, callback) => {
ui.componentLabels = arrayFill(ui.componentLabels, 6);
data.value = arrayFill(data.value, 6, null);
return ([
return (
<tbody>
<tr className={ style.inputRow } key={ data.id + '_0'}>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={1} label={ui.componentLabels[1]} type={ui.type} value={data.value[1]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>,
</tr>
<tr className={ style.inputRow } key={ data.id + '_1'}>
<InputCell idx={2} label={ui.componentLabels[2]} type={ui.type} value={data.value[2]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={3} label={ui.componentLabels[3]} type={ui.type} value={data.value[3]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>,
</tr>
<tr className={ style.inputRow } key={ data.id + '_2'}>
<InputCell idx={4} label={ui.componentLabels[4]} type={ui.type} value={data.value[4]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={5} label={ui.componentLabels[5]} type={ui.type} value={data.value[5]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>]);
</tr>
</tbody>);
},
'm6': (data, ui, callback) => {
ui.componentLabels = arrayFill(ui.componentLabels, 6);
data.value = arrayFill(data.value, 6, null);
return ([
return (
<tbody>
<tr className={ style.inputRow } key={ data.id + '_0'}>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={1} label={ui.componentLabels[1]} type={ui.type} value={data.value[1]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={2} label={ui.componentLabels[2]} type={ui.type} value={data.value[2]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>,
</tr>
<tr className={ style.inputRow } key={ data.id + '_1'}>
<td></td>
<InputCell idx={3} label={ui.componentLabels[3]} type={ui.type} value={data.value[3]} name={data.name} domain={ui.domain} onChange={callback}/>
<InputCell idx={4} label={ui.componentLabels[4]} type={ui.type} value={data.value[4]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>,
</tr>
<tr className={ style.inputRow } key={ data.id + '_2'}>
<td></td>
<td></td>
<InputCell idx={5} label={ui.componentLabels[5]} type={ui.type} value={data.value[5]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>]);
</tr>
</tbody>);
},
'-1': (data, ui, callback) => {
return (
<tbody>
{ data.value.map((value, index) => {
return (
<tr key={[data.id,index].join('_')} className={ style.inputRow }>
<td>
<i className={ index ? style.deleteIcon : style.hidden }
onClick={ () => { callback(index, null); } }>
</i>
</td>
<InputCell idx={index} label='' type={ui.type} value={value} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>);
})}
</tbody>);
},
'NO_LAYOUT': (data, ui, callback) => {
return (<tr className={ style.inputRow }>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>);
return (
<tbody>
<tr className={ style.inputRow }>
<InputCell idx={0} label={ui.componentLabels[0]} type={ui.type} value={data.value[0]} name={data.name} domain={ui.domain} onChange={callback}/>
</tr>
</tbody>);
},
};
/* eslint-enable react/display-name */
Expand Down
15 changes: 15 additions & 0 deletions style/ReactProperties/CellProperty.mcss
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,24 @@
}

.helpIcon {
composes: fa from 'font-awesome/css/font-awesome.css';
composes: fa-question-circle from 'font-awesome/css/font-awesome.css';
}

.plusIcon {
composes: fa from 'font-awesome/css/font-awesome.css';
composes: fa-plus from 'font-awesome/css/font-awesome.css';
cursor: pointer;
}

.deleteIcon {
position: relative;
top: 10px;
composes: fa from 'font-awesome/css/font-awesome.css';
composes: fa-trash-o from 'font-awesome/css/font-awesome.css';
cursor: pointer;
}

.helpBox {
padding: 18px;
border: 1px solid #ddd;
Expand Down

0 comments on commit be3649f

Please sign in to comment.