Browse Source

provide some feedback for users in canvas app

Alexander Rose 6 years ago
parent
commit
50cdc8daea

+ 27 - 4
src/apps/canvas/app.ts

@@ -32,23 +32,46 @@ export class App {
         }
     }
 
+    setStatus(msg: string) {
+
+    }
+
+    private taskCount = 0
+    taskCountChanged = new BehaviorSubject({ count: 0, info: '' })
+
+    private changeTaskCount(delta: number, info = '') {
+        this.taskCount += delta
+        this.taskCountChanged.next({ count: this.taskCount, info })
+    }
+
+    async runTask<T>(promise: Promise<T>, info: string) {
+        this.changeTaskCount(1, info)
+        let result: T
+        try {
+            result = await promise
+        } finally {
+            this.changeTaskCount(-1)
+        }
+        return result
+    }
+
     async loadCif(cif: CifBlock, assemblyId?: string) {
-        const models = await getModelsFromMmcif(cif)
-        this.structureView = await StructureView(this.viewer, models, { assemblyId })
+        const models = await this.runTask(getModelsFromMmcif(cif), 'Build models')
+        this.structureView = await this.runTask(StructureView(this, this.viewer, models, { assemblyId }), 'Init structure view')
         this.pdbIdLoaded.next(this.structureView)
     }
 
     async loadPdbIdOrUrl(idOrUrl: string, options?: { assemblyId?: string, binary?: boolean }) {
         if (this.structureView) this.structureView.destroy();
         const url = idOrUrl.length <= 4 ? `https://files.rcsb.org/download/${idOrUrl}.cif` : idOrUrl;
-        const cif = await getCifFromUrl(url, options ? !!options.binary : false)
+        const cif = await this.runTask(getCifFromUrl(url, options ? !!options.binary : false), 'Load mmCIF from URL')
         this.loadCif(cif, options ? options.assemblyId : void 0)
     }
 
     async loadCifFile(file: File) {
         if (this.structureView) this.structureView.destroy();
         const binary = /\.bcif$/.test(file.name);
-        const cif = await getCifFromFile(file, binary)
+        const cif = await this.runTask(getCifFromFile(file, binary), 'Load mmCIF from file')
         this.loadCif(cif)
     }
 }

+ 4 - 2
src/apps/canvas/component/structure-representation.tsx

@@ -12,8 +12,10 @@ import { Color } from 'mol-util/color';
 import { Progress } from 'mol-task';
 import { VisualQuality, VisualQualityNames } from 'mol-geo/geometry/geometry';
 import { SizeThemeProps } from 'mol-view/theme/size';
+import { App } from '../app';
 
 export interface StructureRepresentationComponentProps {
+    app: App
     viewer: Viewer
     representation: StructureRepresentation<StructureProps>
 }
@@ -82,9 +84,9 @@ export class StructureRepresentationComponent extends React.Component<StructureR
         if (state.pointFilledCircle !== undefined) (props as any).pointFilledCircle = state.pointFilledCircle
         if (state.pointEdgeBleach !== undefined) (props as any).pointEdgeBleach = state.pointEdgeBleach
 
-        await repr.createOrUpdate(props).run(
+        await this.props.app.runTask(repr.createOrUpdate(props).run(
             progress => console.log(Progress.format(progress))
-        )
+        ), 'Create/update representation')
         this.props.viewer.add(repr)
         this.props.viewer.draw(true)
         console.log(this.props.viewer.stats)

+ 1 - 0
src/apps/canvas/component/structure-view.tsx

@@ -185,6 +185,7 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
                                 <StructureRepresentationComponent
                                     representation={structureRepresentations[k]}
                                     viewer={structureView.viewer}
+                                    app={structureView.app}
                                 />
                             </div>
                         } else {

+ 26 - 6
src/apps/canvas/component/viewport.tsx

@@ -15,8 +15,9 @@ interface ViewportProps {
 }
 
 interface ViewportState {
-    noWebGl: boolean,
-    info: string
+    noWebGl: boolean
+    pickingInfo: string
+    taskInfo: string
 }
 
 export class Viewport extends React.Component<ViewportProps, ViewportState> {
@@ -25,7 +26,8 @@ export class Viewport extends React.Component<ViewportProps, ViewportState> {
 
     state: ViewportState = {
         noWebGl: false,
-        info: ''
+        pickingInfo: '',
+        taskInfo: ''
     };
 
     handleResize() {
@@ -55,11 +57,15 @@ export class Viewport extends React.Component<ViewportProps, ViewportState> {
                     prevLoci = loci
 
                     const label = labelFirst(loci)
-                    const info = `${label}`
-                    this.setState({ info })
+                    const pickingInfo = `${label}`
+                    this.setState({ pickingInfo })
                 }
             }
         })
+
+        this.props.app.taskCountChanged.subscribe(({ count, info }) => {
+            this.setState({ taskInfo: count > 0 ? info : '' })
+        })
     }
 
     componentWillUnmount() {
@@ -94,8 +100,22 @@ export class Viewport extends React.Component<ViewportProps, ViewportState> {
                     background: 'rgba(0, 0, 0, 0.2)'
                 }}
             >
-                {this.state.info}
+                {this.state.pickingInfo}
             </div>
+            { this.state.taskInfo ?
+                <div
+                    style={{
+                        position: 'absolute',
+                        top: 10,
+                        right: 10,
+                        padding: 10,
+                        color: 'lightgrey',
+                        background: 'rgba(0, 0, 0, 0.2)'
+                    }}
+                >
+                    {this.state.taskInfo}
+                </div>
+            : '' }
         </div>;
     }
 }

+ 11 - 8
src/apps/canvas/structure-view.ts

@@ -25,9 +25,11 @@ import { BehaviorSubject } from 'rxjs';
 import { SpacefillRepresentation } from 'mol-geo/representation/structure/representation/spacefill';
 import { DistanceRestraintRepresentation } from 'mol-geo/representation/structure/representation/distance-restraint';
 import { SurfaceRepresentation } from 'mol-geo/representation/structure/representation/surface';
-// import { Progress } from 'mol-task';
+import { App } from './app';
+import { Progress } from 'mol-task';
 
 export interface StructureView {
+    readonly app: App
     readonly viewer: Viewer
 
     readonly label: string
@@ -64,11 +66,11 @@ interface StructureViewProps {
 
 
 
-export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> {
+export async function StructureView(app: App, viewer: Viewer, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> {
     const active: { [k: string]: boolean } = {
         cartoon: true,
         point: false,
-        surface: true,
+        surface: false,
         ballAndStick: false,
         carbohydrate: false,
         spacefill: false,
@@ -105,7 +107,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
         if (!value) {
             assemblySymmetry = undefined
         } else {
-            await AssemblySymmetry.attachFromCifOrAPI(models[modelId])
+            await app.runTask(AssemblySymmetry.attachFromCifOrAPI(models[modelId]), 'Load symmetry annotation')
             assemblySymmetry = AssemblySymmetry.get(models[modelId])
         }
         active.symmetryAxes = value
@@ -195,7 +197,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
     }
 
     async function getStructure() {
-        if (model) structure = await getStructureFromModel(model, assemblyId)
+        if (model) structure = await app.runTask(getStructureFromModel(model, assemblyId), 'Build structure')
         if (model && structure) {
             label = `${model.label} - Assembly ${assemblyId}`
         } else {
@@ -209,9 +211,9 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
             console.log('createStructureRepr')
             for (const k in structureRepresentations) {
                 if (active[k]) {
-                    await structureRepresentations[k].createOrUpdate({ colorTheme: { name: 'element-index' } }, structure).run(
-                        // progress => console.log(Progress.format(progress))
-                    )
+                    await app.runTask(structureRepresentations[k].createOrUpdate({}, structure).run(
+                        progress => console.log(Progress.format(progress))
+                    ), 'Create/update representation')
                     viewer.add(structureRepresentations[k])
                 } else {
                     viewer.remove(structureRepresentations[k])
@@ -288,6 +290,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
     await setModel(0, props.assemblyId, props.symmetryFeatureId)
 
     return {
+        app,
         viewer,
 
         get label() { return label },