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

use events for highlight & select

parent bfec0476
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,9 @@ import { EntityTreeController } from 'mol-app/controller/entity/tree';
import { TransformListController } from 'mol-app/controller/transform/list';
import { TransformList } from 'mol-app/ui/transform/list';
import { SequenceView } from 'mol-app/ui/visualization/sequence-view';
import { InteractivityEvents } from 'mol-app/event/basic';
import { MarkerAction } from 'mol-geo/util/marker-data';
import { EveryLoci } from 'mol-model/loci';
const elm = document.getElementById('app')
if (!elm) throw new Error('Can not find element with id "app".')
......@@ -94,4 +97,17 @@ ctx.layout.setState({
})
// ctx.viewport.setState()
ctx.dispatcher.getStream(InteractivityEvents.HighlightLoci).subscribe(event => {
ctx.stage.viewer.mark(EveryLoci, MarkerAction.RemoveHighlight)
if (event && event.data) {
ctx.stage.viewer.mark(event.data, MarkerAction.Highlight)
}
})
ctx.dispatcher.getStream(InteractivityEvents.SelectLoci).subscribe(event => {
if (event && event.data) {
ctx.stage.viewer.mark(event.data, MarkerAction.ToggleSelect)
}
})
ReactDOM.render(React.createElement(Layout, { controller: ctx.layout }), elm);
......@@ -11,7 +11,7 @@ import { Dispatcher } from '../service/dispatcher'
import { LayoutState } from '../controller/layout';
import { ViewportOptions } from '../controller/visualization/viewport';
import { Job } from '../service/job';
import { Element } from 'mol-model/structure'
import { Loci } from 'mol-model/loci';
const Lane = Dispatcher.Lane;
......@@ -34,5 +34,7 @@ export namespace LayoutEvents {
}
export namespace InteractivityEvents {
export const HighlightElementLoci = Event.create<Element.Loci | undefined>('bs.Interactivity.HighlightElementLoci', Lane.Slow);
export const HighlightLoci = Event.create<Loci>('bs.Interactivity.HighlightLoci', Lane.Slow);
export const SelectLoci = Event.create<Loci>('bs.Interactivity.SelectLoci', Lane.Slow);
export const LabelLoci = Event.create<Loci>('bs.Interactivity.LabelLoci', Lane.Slow);
}
......@@ -11,6 +11,7 @@ import { Structure, StructureSequence, Queries, Selection } from 'mol-model/stru
import { Context } from '../../context/context';
import { InteractivityEvents } from '../../event/basic';
import { SyncRuntimeContext } from 'mol-task/execution/synchronous';
import { EmptyLoci } from 'mol-model/loci';
export class SequenceView extends View<SequenceViewController, {}, {}> {
render() {
......@@ -36,14 +37,14 @@ class EntitySequence extends React.Component<{ ctx: Context, seq: StructureSeque
async raiseInteractityEvent(seqId?: number) {
if (typeof seqId === 'undefined') {
InteractivityEvents.HighlightElementLoci.dispatch(this.props.ctx, void 0);
InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
return;
}
const query = createQuery(this.props.seq.entityId, seqId);
const loci = Selection.toLoci(await query(this.props.structure, SyncRuntimeContext));
if (loci.elements.length === 0) InteractivityEvents.HighlightElementLoci.dispatch(this.props.ctx, void 0);
else InteractivityEvents.HighlightElementLoci.dispatch(this.props.ctx, loci);
if (loci.elements.length === 0) InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
else InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, loci);
}
......
......@@ -14,6 +14,8 @@ import { View } from '../view';
import { HelpBox, Toggle, Button } from '../controls/common'
import { Slider } from '../controls/slider'
import { ImageCanvas } from './image-canvas';
import { InteractivityEvents } from '../../event/basic';
import { labelFirst } from 'mol-view/label';
export class ViewportControls extends View<ViewportController, { showSceneOptions?: boolean, showHelp?: boolean }, {}> {
state = { showSceneOptions: false, showHelp: false };
......@@ -142,10 +144,6 @@ export class Viewport extends View<ViewportController, ViewportState, { noWebGl?
})
})
viewer.identified.subscribe(info => {
this.setState({ info })
})
viewer.didDraw.subscribe(() => {
// this.setState({ imageData: viewer.getImageData() })
this.setState({
......@@ -158,7 +156,23 @@ export class Viewport extends View<ViewportController, ViewportState, { noWebGl?
})
viewer.input.resize.subscribe(() => this.handleResize())
this.handleResize()
viewer.input.move.subscribe(({x, y, inside}) => {
if (!inside) return
const p = viewer.identify(x, y)
const loci = viewer.getLoci(p)
InteractivityEvents.HighlightLoci.dispatch(this.controller.context, loci);
// TODO use LabelLoci event and make configurable
const label = labelFirst(loci)
const info = `Object: ${p.objectId}, Instance: ${p.instanceId}, Element: ${p.elementId}, Label: ${label}`
this.setState({ info })
})
viewer.input.click.subscribe(({x, y}) => {
const loci = viewer.getLoci(viewer.identify(x, y))
InteractivityEvents.SelectLoci.dispatch(this.controller.context, loci);
})
}
componentWillUnmount() {
......
......@@ -98,6 +98,7 @@ export type MoveInput = {
y: number,
pageX: number,
pageY: number,
inside: boolean,
} & BaseInput
export type PinchInput = {
......@@ -355,7 +356,8 @@ namespace InputObserver {
eventOffset(pointerEnd, ev)
const { pageX, pageY } = ev
const [ x, y ] = pointerEnd
move.next({ x, y, pageX, pageY, buttons, modifiers })
const inside = insideBounds(pointerEnd)
move.next({ x, y, pageX, pageY, buttons, modifiers, inside })
if (dragging === DraggingState.Stopped) return
......
......@@ -22,9 +22,8 @@ import { createRenderTarget } from 'mol-gl/webgl/render-target';
import Scene from 'mol-gl/scene';
import { RenderVariant } from 'mol-gl/webgl/render-item';
import { PickingId, decodeIdRGBA } from 'mol-geo/util/picking';
import { labelFirst } from './label';
import { MarkerAction } from 'mol-geo/util/marker-data';
import { EveryLoci } from 'mol-model/loci';
import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
interface Viewer {
center: (p: Vec3) => void
......@@ -41,7 +40,9 @@ interface Viewer {
requestDraw: () => void
animate: () => void
pick: () => void
identify: (x: number, y: number) => void
identify: (x: number, y: number) => PickingId
mark: (loci: Loci, action: MarkerAction) => void
getLoci: (pickingId: PickingId) => Loci
reprCount: BehaviorSubject<number>
identified: BehaviorSubject<string>
......@@ -76,35 +77,7 @@ namespace Viewer {
const startTime = performance.now()
const didDraw = new BehaviorSubject(0)
const input = InputObserver.create(canvas)
input.resize.subscribe(handleResize)
input.move.subscribe(({x, y}) => {
const p = identify(x, y)
let label = ''
reprMap.forEach((roSet, repr) => {
repr.mark(EveryLoci, MarkerAction.RemoveHighlight)
const loci = repr.getLoci(p)
if (loci) {
label = labelFirst(loci)
repr.mark(loci, MarkerAction.Highlight)
}
scene.update()
requestDraw()
})
identified.next(`Object: ${p.objectId}, Instance: ${p.instanceId}, Element: ${p.elementId}, Label: ${label}`)
})
input.click.subscribe(({x, y}) => {
const p = identify(x, y)
reprMap.forEach((roSet, repr) => {
const loci = repr.getLoci(p)
if (loci) {
repr.mark(loci, MarkerAction.ToggleSelect)
scene.update()
requestDraw()
}
})
})
const camera = PerspectiveCamera.create({
near: 0.1,
......@@ -141,6 +114,24 @@ namespace Viewer {
const prevProjectionView = Mat4.zero()
const prevSceneView = Mat4.zero()
function getLoci(pickingId: PickingId) {
let loci: Loci = EmptyLoci
reprMap.forEach((_, repr) => {
const _loci = repr.getLoci(pickingId)
if (!isEmptyLoci(_loci)) {
if (!isEmptyLoci(loci)) console.warn('found another loci')
loci = _loci
}
})
return loci
}
function mark(loci: Loci, action: MarkerAction) {
reprMap.forEach((roSet, repr) => repr.mark(loci, action))
scene.update()
requestDraw()
}
let nearPlaneDelta = 0
function computeNearDistance() {
const focusRadius = scene.boundingSphere.radius
......@@ -295,6 +286,8 @@ namespace Viewer {
animate,
pick,
identify,
mark,
getLoci,
handleResize,
resetCamera: () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment