diff --git a/src/extensions/cellpack/model.ts b/src/extensions/cellpack/model.ts index 2043f93f62e4f6b18f6edb8f54cf4a25a240129a..e04eb5c23c7865a2f78f2956cb3f4cfee38ce89a 100644 --- a/src/extensions/cellpack/model.ts +++ b/src/extensions/cellpack/model.ts @@ -442,9 +442,9 @@ async function handleHivRna(plugin: PluginContext, packings: CellPacking[], base async function loadMembrane(plugin: PluginContext, name: string, state: State, params: LoadCellPackModelParams) { let file: Asset.File | undefined = undefined; - if (params.ingredients.files !== null) { + if (params.ingredients !== null) { const fileName = `${name}.bcif`; - for (const f of params.ingredients.files) { + for (const f of params.ingredients) { if (fileName === f.name) { file = f; break; @@ -453,7 +453,7 @@ async function loadMembrane(plugin: PluginContext, name: string, state: State, p if (!file){ // check for cif directly const cifileName = `${name}.cif`; - for (const f of params.ingredients.files) { + for (const f of params.ingredients) { if (cifileName === f.name) { file = f; break; @@ -488,7 +488,7 @@ async function loadMembrane(plugin: PluginContext, name: string, state: State, p } async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) { - const ingredientFiles = params.ingredients.files || []; + const ingredientFiles = params.ingredients || []; let cellPackJson: StateBuilder.To<PSO.Format.Json, StateTransformer<PSO.Data.String, PSO.Format.Json>>; if (params.source.name === 'id') { @@ -563,9 +563,7 @@ const LoadCellPackModelParams = { }, { options: [['id', 'Id'], ['file', 'File']] }), baseUrl: PD.Text(DefaultCellPackBaseUrl), membrane: PD.Boolean(true), - ingredients : PD.Group({ - files: PD.FileList({ accept: '.cif,.bcif,.pdb' }) - }, { isExpanded: true }), + ingredients: PD.FileList({ accept: '.cif,.bcif,.pdb', label: 'Ingredients' }), preset: PD.Group({ traceOnly: PD.Boolean(false), representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'orientation'])) diff --git a/src/mol-plugin-ui/controls.tsx b/src/mol-plugin-ui/controls.tsx index 94b105c256babcb817080879a4313ee0b0549d4b..b4c0a5a255590de6ce1b814912824c4a80a91aa7 100644 --- a/src/mol-plugin-ui/controls.tsx +++ b/src/mol-plugin-ui/controls.tsx @@ -118,18 +118,18 @@ export class StateSnapshotViewportControls extends PluginUIComponent<{}, { isBus keyUp = (e: KeyboardEvent) => { if (!e.ctrlKey || this.state.isBusy || e.target !== document.body) return; const snapshots = this.plugin.managers.snapshot; - if (e.keyCode === 37) { // left + if (e.keyCode === 37 || e.key === 'ArrowLeft') { if (snapshots.state.isPlaying) snapshots.stop(); this.prev(); - } else if (e.keyCode === 38) { // up + } else if (e.keyCode === 38 || e.key === 'ArrowUp') { if (snapshots.state.isPlaying) snapshots.stop(); if (snapshots.state.entries.size === 0) return; const e = snapshots.state.entries.get(0); this.update(e.snapshot.id); - } else if (e.keyCode === 39) { // right + } else if (e.keyCode === 39 || e.key === 'ArrowRight') { if (snapshots.state.isPlaying) snapshots.stop(); this.next(); - } else if (e.keyCode === 40) { // down + } else if (e.keyCode === 40 || e.key === 'ArrowDown') { if (snapshots.state.isPlaying) snapshots.stop(); if (snapshots.state.entries.size === 0) return; const e = snapshots.state.entries.get(snapshots.state.entries.size - 1); diff --git a/src/mol-plugin-ui/controls/common.tsx b/src/mol-plugin-ui/controls/common.tsx index e89af928aa3702b18a1ff80b90c954d1a3b80cba..3bd9951df294535b580278f06d603fa9aa0fd6e4 100644 --- a/src/mol-plugin-ui/controls/common.tsx +++ b/src/mol-plugin-ui/controls/common.tsx @@ -141,7 +141,7 @@ export class TextInput<T = string> extends React.PureComponent<TextInputProps<T> } onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => { - if (e.charCode === 27 || e.keyCode === 27 /* esc */) { + if (e.charCode === 27 || e.keyCode === 27 || e.key === 'Escape') { if (this.props.blurOnEscape && this.input.current) { this.input.current.blur(); } @@ -149,7 +149,7 @@ export class TextInput<T = string> extends React.PureComponent<TextInputProps<T> } onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { - if (e.keyCode === 13 || e.charCode === 13 /* enter */) { + if (e.keyCode === 13 || e.charCode === 13 || e.key === 'Enter') { if (this.isPending) { this.clearTimeout(); this.raiseOnChange(); diff --git a/src/mol-plugin-ui/controls/parameters.tsx b/src/mol-plugin-ui/controls/parameters.tsx index 0b682a9b57c87997034b3921e28ac0bfd2a7ebbc..1fd2e31cda2b861e78280fddd08ddfc36023f0d1 100644 --- a/src/mol-plugin-ui/controls/parameters.tsx +++ b/src/mol-plugin-ui/controls/parameters.tsx @@ -379,7 +379,7 @@ export class TextControl extends SimpleParam<PD.Text> { } onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { - if ((e.keyCode === 13 || e.charCode === 13)) { + if ((e.keyCode === 13 || e.charCode === 13 || e.key === 'Enter')) { if (this.props.onEnter) this.props.onEnter(); } e.stopPropagation(); @@ -794,7 +794,7 @@ export class UrlControl extends SimpleParam<PD.UrlParam> { } onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { - if ((e.keyCode === 13 || e.charCode === 13)) { + if ((e.keyCode === 13 || e.charCode === 13 || e.key === 'Enter')) { if (this.props.onEnter) this.props.onEnter(); } e.stopPropagation(); @@ -813,6 +813,8 @@ export class UrlControl extends SimpleParam<PD.UrlParam> { } export class FileControl extends React.PureComponent<ParamProps<PD.FileParam>> { + state = { showHelp: false }; + change(value: File) { this.props.onChange({ name: this.props.name, param: this.props.param, value: Asset.File(value) }); } @@ -821,16 +823,34 @@ export class FileControl extends React.PureComponent<ParamProps<PD.FileParam>> { this.change(e.target.files![0]); } - render() { + toggleHelp = () => this.setState({ showHelp: !this.state.showHelp }); + + renderControl() { const value = this.props.value; return <div className='msp-btn msp-btn-block msp-btn-action msp-loader-msp-btn-file' style={{ marginTop: '1px' }}> {value ? value.name : 'Select a file...'} <input disabled={this.props.isDisabled} onChange={this.onChangeFile} type='file' multiple={false} accept={this.props.param.accept} /> </div>; } + + render() { + if (this.props.param.label) { + return renderSimple({ + props: this.props, + state: this.state, + control: this.renderControl(), + toggleHelp: this.toggleHelp, + addOn: null + }); + } else { + return this.renderControl(); + } + } } export class FileListControl extends React.PureComponent<ParamProps<PD.FileListParam>> { + state = { showHelp: false }; + change(value: FileList) { const files: Asset.File[] = []; if (value) { @@ -845,7 +865,9 @@ export class FileListControl extends React.PureComponent<ParamProps<PD.FileListP this.change(e.target.files!); } - render() { + toggleHelp = () => this.setState({ showHelp: !this.state.showHelp }); + + renderControl() { const value = this.props.value; const names: string[] = []; @@ -862,6 +884,20 @@ export class FileListControl extends React.PureComponent<ParamProps<PD.FileListP {label} <input disabled={this.props.isDisabled} onChange={this.onChangeFileList} type='file' multiple={true} accept={this.props.param.accept} /> </div>; } + + render() { + if (this.props.param.label) { + return renderSimple({ + props: this.props, + state: this.state, + control: this.renderControl(), + toggleHelp: this.toggleHelp, + addOn: null + }); + } else { + return this.renderControl(); + } + } } export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiSelect<any>>, { isExpanded: boolean }> { @@ -1258,7 +1294,7 @@ export class ScriptControl extends SimpleParam<PD.Script> { } onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { - if ((e.keyCode === 13 || e.charCode === 13)) { + if ((e.keyCode === 13 || e.charCode === 13 || e.key === 'Enter')) { if (this.props.onEnter) this.props.onEnter(); } e.stopPropagation();