[web] Try StringSequence update logic and add tooltip.

This commit is contained in:
Matthew Shao 2017-07-10 20:42:24 +08:00 committed by Maximilian Hils
parent e1ee21d8bb
commit 73685da78b

View File

@ -6,12 +6,19 @@ PureBooleanOption.PropTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
} }
function PureBooleanOption({ value, onChange, help}) { function PureBooleanOption({ value, onChange, ...props}) {
let onFocus = () => { props.onFocus() },
onBlur = () => { props.onBlur() },
onMouseEnter = () => { props.onMouseEnter() },
onMouseLeave = () => { props.onMouseLeave() }
return ( return (
<input type="checkbox" <input type="checkbox"
checked={value} checked={value}
onChange={onChange} onChange={onChange}
title={help} onFocus={onFocus}
onBlur={onBlur}
onMouseOver={onMouseEnter}
onMouseLeave={onMouseLeave}
/> />
) )
} }
@ -21,14 +28,21 @@ PureStringOption.PropTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
} }
function PureStringOption( { value, onChange, help }) { function PureStringOption( { value, onChange, ...props }) {
let onKeyDown = (e) => {e.stopPropagation()} let onKeyDown = (e) => {e.stopPropagation()},
onFocus = () => { props.onFocus() },
onBlur = () => { props.onBlur() },
onMouseEnter = () => { props.onMouseEnter() },
onMouseLeave = () => { props.onMouseLeave() }
return ( return (
<input type="text" <input type="text"
value={value} value={value}
onChange={onChange} onChange={onChange}
title={help}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
onMouseOver={onMouseEnter}
onMouseLeave={onMouseLeave}
/> />
) )
} }
@ -38,14 +52,22 @@ PureNumberOption.PropTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
} }
function PureNumberOption( {value, onChange, help }) { function PureNumberOption( {value, onChange, ...props }) {
let onKeyDown = (e) => {e.stopPropagation()} let onKeyDown = (e) => {e.stopPropagation()},
onFocus = () => { props.onFocus() },
onBlur = () => { props.onBlur() },
onMouseEnter = () => { props.onMouseEnter() },
onMouseLeave = () => { props.onMouseLeave() }
return ( return (
<input type="number" <input type="number"
value={value} value={value}
onChange={onChange} onChange={onChange}
title={help}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
onMouseOver={onMouseEnter}
onMouseLeave={onMouseLeave}
/> />
) )
} }
@ -55,9 +77,21 @@ PureChoicesOption.PropTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
} }
function PureChoicesOption( { value, onChange, name, help, choices }) { function PureChoicesOption( { value, onChange, name, choices, ...props}) {
let onFocus = () => { props.onFocus() },
onBlur = () => { props.onBlur() },
onMouseEnter = () => { props.onMouseEnter() },
onMouseLeave = () => { props.onMouseLeave() }
return ( return (
<select name={name} onChange={onChange} title={help} selected={value}> <select
name={name}
onChange={onChange}
selected={value}
onFocus={onFocus}
onBlur={onBlur}
onMouseOver={onMouseEnter}
onMouseLeave={onMouseLeave}
>
{ choices.map((choice, index) => ( { choices.map((choice, index) => (
<option key={index} value={choice}> {choice} </option> <option key={index} value={choice}> {choice} </option>
))} ))}
@ -68,34 +102,42 @@ function PureChoicesOption( { value, onChange, name, help, choices }) {
class PureStringSequenceOption extends Component { class PureStringSequenceOption extends Component {
constructor(props, context) { constructor(props, context) {
super(props, context) super(props, context)
this.state = { height: 1, focus: false } this.state = { height: 1, focus: false, value: this.props.value}
this.onFocus = this.onFocus.bind(this) this.onFocus = this.onFocus.bind(this)
this.onBlur = this.onBlur.bind(this) this.onBlur = this.onBlur.bind(this)
this.onKeyDown = this.onKeyDown.bind(this) this.onKeyDown = this.onKeyDown.bind(this)
this.onChange = this.onChange.bind(this)
} }
onFocus() { onFocus() {
this.setState( {focus: true, height: 3 }) this.setState( {focus: true, height: 3 })
this.props.onFocus()
} }
onBlur() { onBlur() {
this.setState( {focus: false, height: 1}) this.setState( {focus: false, height: 1})
this.props.onBlur()
} }
onKeyDown(e) { onKeyDown(e) {
e.stopPropagation() e.stopPropagation()
} }
onChange(e) {
const value = e.target.value.split("\n")
console.log(value)
this.props.onChange(e)
this.setState({ value })
}
render() { render() {
const {value, onChange, help} = this.props const {height, value} = this.state
const {height, focus} = this.state
return ( return (
<textarea <textarea
rows={height} rows={height}
value={value} value={value}
onChange={onChange} onChange={this.onChange}
title={help}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
onFocus={this.onFocus} onFocus={this.onFocus}
onBlur={this.onBlur} onBlur={this.onBlur}
@ -112,15 +154,36 @@ const OptionTypes = {
"sequence of str": PureStringSequenceOption, "sequence of str": PureStringSequenceOption,
} }
export default function OptionMaster({option, name, updateOptions, ...props}) { export default class OptionMaster extends Component {
let WrappedComponent = null
if (option.choices) { constructor(props, context) {
WrappedComponent = PureChoicesOption super(props, context)
} else { this.state = {
WrappedComponent = OptionTypes[option.type] updateOptions: this.props.updateOptions,
option: this.props.option,
name: this.props.name,
mousefocus: false,
focus: false,
}
if (props.option.choices) {
this.WrappedComponent = PureChoicesOption
} else {
this.WrappedComponent = OptionTypes[props.option.type]
}
this.onChange = this.onChange.bind(this)
this.onMouseEnter = this.onMouseEnter.bind(this)
this.onMouseLeave = this.onMouseLeave.bind(this)
this.onFocus = this.onFocus.bind(this)
this.onBlur = this.onBlur.bind(this)
} }
let onChange = (e) => { componentWillReceiveProps(nextProps) {
this.setState({ option: nextProps.option })
}
onChange(e) {
const { updateOptions, option, name } = this.state
switch (option.type) { switch (option.type) {
case 'bool' : case 'bool' :
updateOptions({[name]: !option.value}) updateOptions({[name]: !option.value})
@ -128,25 +191,62 @@ export default function OptionMaster({option, name, updateOptions, ...props}) {
case 'int': case 'int':
updateOptions({[name]: parseInt(e.target.value)}) updateOptions({[name]: parseInt(e.target.value)})
break break
case 'sequence of str':
const value = e.target.value.split('\n')
updateOptions({[name]: value})
break
default: default:
updateOptions({[name]: e.target.value}) updateOptions({[name]: e.target.value})
} }
} }
return (
<div className="row"> onMouseEnter() {
<div className="col-sm-8"> console.log(this.state)
{name} this.setState({ mousefocus: true })
}
onMouseLeave() {
this.setState({ mousefocus: false })
}
onFocus() {
console.log(this.state)
this.setState({ focus: true })
}
onBlur() {
this.setState({ focus: false })
}
render() {
const { name, children } = this.props
const { option, focus, mousefocus } = this.state
const WrappedComponent = this.WrappedComponent
return (
<div className="row">
<div className="col-sm-8">
{name}
</div>
<div className="col-sm-4">
<WrappedComponent
children={children}
value={option.value}
onChange={this.onChange}
name={name}
choices={option.choices}
onFocus={this.onFocus}
onBlur={this.onBlur}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
/>
{(focus || mousefocus) && (
<div className="tooltip tooltip-bottom" role="tooltip" style={{opacity: 1}}>
<div className="tooltip-inner">
{option.help}
</div>
</div>)}
</div>
</div> </div>
<div className="col-sm-4"> )
<WrappedComponent }
children={props.children}
value={option.value}
onChange={onChange}
name={name}
help={option.help}
choices={option.choices}
/>
</div>
</div>
)
} }