Skip to content
Snippets Groups Projects
Commit 50cdc8da authored by Alexander Rose's avatar Alexander Rose
Browse files

provide some feedback for users in canvas app

parent af192a3b
No related branches found
No related tags found
No related merge requests found
......@@ -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)
}
}
\ No newline at end of file
......@@ -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)
......
......@@ -185,6 +185,7 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
<StructureRepresentationComponent
representation={structureRepresentations[k]}
viewer={structureView.viewer}
app={structureView.app}
/>
</div>
} else {
......
......@@ -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>;
}
}
\ No newline at end of file
......@@ -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 },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment