|
@@ -35,7 +35,7 @@ import { Representation } from '../mol-repr/representation';
|
|
|
import { StructureRepresentationRegistry } from '../mol-repr/structure/registry';
|
|
|
import { VolumeRepresentationRegistry } from '../mol-repr/volume/registry';
|
|
|
import { StateTransform } from '../mol-state';
|
|
|
-import { RuntimeContext, Task } from '../mol-task';
|
|
|
+import { RuntimeContext, Scheduler, Task } from '../mol-task';
|
|
|
import { ColorTheme } from '../mol-theme/color';
|
|
|
import { SizeTheme } from '../mol-theme/size';
|
|
|
import { ThemeRegistryContext } from '../mol-theme/theme';
|
|
@@ -71,6 +71,7 @@ export class PluginContext {
|
|
|
};
|
|
|
|
|
|
protected subs: Subscription[] = [];
|
|
|
+ private initCanvas3dPromiseCallbacks: [res: () => void, rej: (err: any) => void] = [() => {}, () => {}];
|
|
|
|
|
|
private disposed = false;
|
|
|
private canvasContainer: HTMLDivElement | undefined = void 0;
|
|
@@ -103,10 +104,15 @@ export class PluginContext {
|
|
|
leftPanelTabName: this.ev.behavior<LeftPanelTabName>('root')
|
|
|
},
|
|
|
canvas3d: {
|
|
|
+ // TODO: remove in 4.0?
|
|
|
initialized: this.canvas3dInit.pipe(filter(v => !!v), take(1))
|
|
|
}
|
|
|
} as const;
|
|
|
|
|
|
+ readonly canvas3dInitialized = new Promise<void>((res, rej) => {
|
|
|
+ this.initCanvas3dPromiseCallbacks = [res, rej];
|
|
|
+ });
|
|
|
+
|
|
|
readonly canvas3dContext: Canvas3DContext | undefined;
|
|
|
readonly canvas3d: Canvas3D | undefined;
|
|
|
readonly layout = new PluginLayout(this);
|
|
@@ -187,44 +193,49 @@ export class PluginContext {
|
|
|
*/
|
|
|
readonly customState: unknown = Object.create(null);
|
|
|
|
|
|
- mount(target: HTMLElement, canvas3dContext?: Canvas3DContext) {
|
|
|
- if (this.disposed) throw new Error('Cannot mount a disposed context');
|
|
|
-
|
|
|
- if (!this.canvasContainer) {
|
|
|
- const container = document.createElement('div');
|
|
|
- Object.assign(container.style, {
|
|
|
- position: 'absolute',
|
|
|
- left: 0,
|
|
|
- top: 0,
|
|
|
- right: 0,
|
|
|
- bottom: 0,
|
|
|
- '-webkit-user-select': 'none',
|
|
|
- 'user-select': 'none',
|
|
|
- '-webkit-tap-highlight-color': 'rgba(0,0,0,0)',
|
|
|
- '-webkit-touch-callout': 'none',
|
|
|
- 'touch-action': 'manipulation',
|
|
|
+ initContainer(canvas3dContext?: Canvas3DContext) {
|
|
|
+ if (this.canvasContainer) return true;
|
|
|
+
|
|
|
+ const container = document.createElement('div');
|
|
|
+ Object.assign(container.style, {
|
|
|
+ position: 'absolute',
|
|
|
+ left: 0,
|
|
|
+ top: 0,
|
|
|
+ right: 0,
|
|
|
+ bottom: 0,
|
|
|
+ '-webkit-user-select': 'none',
|
|
|
+ 'user-select': 'none',
|
|
|
+ '-webkit-tap-highlight-color': 'rgba(0,0,0,0)',
|
|
|
+ '-webkit-touch-callout': 'none',
|
|
|
+ 'touch-action': 'manipulation',
|
|
|
+ });
|
|
|
+ let canvas = canvas3dContext?.canvas;
|
|
|
+ if (!canvas) {
|
|
|
+ canvas = document.createElement('canvas');
|
|
|
+ Object.assign(canvas.style, {
|
|
|
+ 'background-image': 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey), linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey)',
|
|
|
+ 'background-size': '60px 60px',
|
|
|
+ 'background-position': '0 0, 30px 30px'
|
|
|
});
|
|
|
- let canvas = canvas3dContext?.canvas;
|
|
|
- if (!canvas) {
|
|
|
- canvas = document.createElement('canvas');
|
|
|
- Object.assign(canvas.style, {
|
|
|
- 'background-image': 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey), linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey)',
|
|
|
- 'background-size': '60px 60px',
|
|
|
- 'background-position': '0 0, 30px 30px'
|
|
|
- });
|
|
|
- container.appendChild(canvas);
|
|
|
- }
|
|
|
- if (!this.initViewer(canvas, container, canvas3dContext)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- this.canvasContainer = container;
|
|
|
+ container.appendChild(canvas);
|
|
|
+ }
|
|
|
+ if (!this.initViewer(canvas, container, canvas3dContext)) {
|
|
|
+ return false;
|
|
|
}
|
|
|
+ this.canvasContainer = container;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ mount(target: HTMLElement) {
|
|
|
+ if (this.disposed) throw new Error('Cannot mount a disposed context');
|
|
|
+
|
|
|
+ if (!this.initContainer()) return false;
|
|
|
|
|
|
- if (this.canvasContainer.parentElement !== target) {
|
|
|
- this.canvasContainer.parentElement?.removeChild(this.canvasContainer);
|
|
|
+ if (this.canvasContainer!.parentElement !== target) {
|
|
|
+ this.canvasContainer!.parentElement?.removeChild(this.canvasContainer!);
|
|
|
}
|
|
|
|
|
|
- target.appendChild(this.canvasContainer);
|
|
|
+ target.appendChild(this.canvasContainer!);
|
|
|
this.handleResize();
|
|
|
return true;
|
|
|
}
|
|
@@ -279,10 +290,12 @@ export class PluginContext {
|
|
|
|
|
|
this.handleResize();
|
|
|
|
|
|
+ Scheduler.setImmediate(() => this.initCanvas3dPromiseCallbacks[0]());
|
|
|
return true;
|
|
|
} catch (e) {
|
|
|
this.log.error('' + e);
|
|
|
console.error(e);
|
|
|
+ Scheduler.setImmediate(() => this.initCanvas3dPromiseCallbacks[1](e));
|
|
|
return false;
|
|
|
}
|
|
|
}
|