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

wip, improved marking and picking

parent 1ff5d508
Branches
Tags
No related merge requests found
Showing
with 69 additions and 55 deletions
......@@ -52,7 +52,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR
await repr.createOrUpdate(props).run()
this.props.viewer.add(repr)
this.props.viewer.requestDraw()
this.props.viewer.requestDraw(true)
console.log(this.props.viewer.stats)
const newState = {
......
......@@ -7,7 +7,7 @@
import * as React from 'react'
import { App } from '../app';
import { MarkerAction } from 'mol-geo/util/marker-data';
import { EveryLoci } from 'mol-model/loci';
import { EveryLoci, EmptyLoci, Loci, areLociEqual } from 'mol-model/loci';
import { labelFirst } from 'mol-view/label';
interface ViewportProps {
......@@ -42,17 +42,23 @@ export class Viewport extends React.Component<ViewportProps, ViewportState> {
viewer.input.resize.subscribe(() => this.handleResize())
let prevLoci: Loci = EmptyLoci
viewer.input.move.subscribe(({x, y, inside, buttons}) => {
if (!inside || buttons) return
const p = viewer.identify(x, y)
const loci = viewer.getLoci(p)
viewer.mark(EveryLoci, MarkerAction.RemoveHighlight)
viewer.mark(loci, MarkerAction.Highlight)
const label = labelFirst(loci)
const info = `${label}`
this.setState({ info })
if (p) {
const loci = viewer.getLoci(p)
if (!areLociEqual(loci, prevLoci)) {
viewer.mark(prevLoci, MarkerAction.RemoveHighlight)
viewer.mark(loci, MarkerAction.Highlight)
prevLoci = loci
const label = labelFirst(loci)
const info = `${label}`
this.setState({ info })
}
}
})
}
......
......@@ -243,7 +243,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
viewer.add(polymerSphere)
updated.next(null)
viewer.requestDraw()
viewer.requestDraw(true)
console.log(viewer.stats)
}
......@@ -276,7 +276,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
viewer.remove(symmetryAxes)
}
updated.next(null)
viewer.requestDraw()
viewer.requestDraw(true)
}
await setModel(0, props.assemblyId, props.symmetryFeatureId)
......@@ -315,7 +315,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
}
viewer.remove(polymerSphere)
viewer.remove(symmetryAxes)
viewer.requestDraw()
viewer.requestDraw(true)
polymerSphere.destroy()
symmetryAxes.destroy()
......
......@@ -104,10 +104,4 @@ ctx.dispatcher.getStream(InteractivityEvents.HighlightLoci).subscribe(event => {
}
})
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);
......@@ -163,19 +163,24 @@ export class Viewport extends View<ViewportController, ViewportState, { noWebGl?
viewer.input.move.subscribe(({x, y, inside, buttons}) => {
if (!inside || buttons) 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}, Group: ${p.groupId}, Label: ${label}`
this.setState({ info })
if (p) {
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}, Group: ${p.groupId}, Label: ${label}`
this.setState({ info })
}
})
// TODO filter only for left button/single finger touch?
viewer.input.click.subscribe(({x, y}) => {
const loci = viewer.getLoci(viewer.identify(x, y))
InteractivityEvents.SelectLoci.dispatch(this.controller.context, loci);
const p = viewer.identify(x, y)
if (p) {
const loci = viewer.getLoci(p)
InteractivityEvents.SelectLoci.dispatch(this.controller.context, loci);
}
})
}
......
......@@ -18,7 +18,7 @@ export interface Representation<D, P extends RepresentationProps = {}> {
readonly props: Readonly<P>
createOrUpdate: (props?: Partial<P>, data?: D) => Task<void>
getLoci: (pickingId: PickingId) => Loci
mark: (loci: Loci, action: MarkerAction) => void
mark: (loci: Loci, action: MarkerAction) => boolean
destroy: () => void
}
......@@ -26,6 +26,6 @@ export interface Visual<D, P extends RepresentationProps = {}> {
readonly renderObject: RenderObject | undefined
createOrUpdate: (ctx: RuntimeContext, props?: Partial<P>, data?: D) => Promise<void>
getLoci: (pickingId: PickingId) => Loci
mark: (loci: Loci, action: MarkerAction) => void
mark: (loci: Loci, action: MarkerAction) => boolean
destroy: () => void
}
\ No newline at end of file
......@@ -86,7 +86,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
return EmptyLoci
},
mark(loci: Loci, action: MarkerAction) {
if (!_renderObject) return
if (!_renderObject) return false
const { tMarker } = _renderObject.values
let changed = false
if (isEveryLoci(loci)) {
......@@ -108,6 +108,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
if (changed) {
ValueCell.update(tMarker, tMarker.ref.value)
}
return changed
},
destroy() {
// TODO
......
......@@ -31,7 +31,7 @@ export function ComplexRepresentation<P extends StructureProps>(label: string, v
}
function mark(loci: Loci, action: MarkerAction) {
if (visual) visual.mark(loci, action)
return visual ? visual.mark(loci, action) : false
}
function destroy() {
......
......@@ -117,7 +117,7 @@ export function ComplexMeshVisual<P extends ComplexMeshProps>(builder: ComplexMe
return renderObject ? getLoci(pickingId, currentStructure, renderObject.id) : EmptyLoci
},
mark(loci: Loci, action: MarkerAction) {
if (!renderObject) return
if (!renderObject) return false
const { tMarker } = renderObject.values
const { groupCount, instanceCount } = locationIt
......@@ -129,14 +129,14 @@ export function ComplexMeshVisual<P extends ComplexMeshProps>(builder: ComplexMe
let changed = false
if (isEveryLoci(loci)) {
apply(Interval.ofBounds(0, groupCount * instanceCount))
changed = true
changed = apply(Interval.ofBounds(0, groupCount * instanceCount))
} else {
changed = mark(loci, currentStructure, apply)
}
if (changed) {
ValueCell.update(tMarker, tMarker.ref.value)
}
return changed
},
destroy() {
// TODO
......
......@@ -43,7 +43,7 @@ export function BackboneRepresentation(): BackboneRepresentation {
return traceRepr.getLoci(pickingId)
},
mark: (loci: Loci, action: MarkerAction) => {
traceRepr.mark(loci, action)
return traceRepr.mark(loci, action)
},
destroy() {
traceRepr.destroy()
......
......@@ -65,9 +65,10 @@ export function BallAndStickRepresentation(): BallAndStickRepresentation {
}
},
mark: (loci: Loci, action: MarkerAction) => {
elmementRepr.mark(loci, action)
intraLinkRepr.mark(loci, action)
interLinkRepr.mark(loci, action)
const markElement = elmementRepr.mark(loci, action)
const markIntraLink = intraLinkRepr.mark(loci, action)
const markInterLink = interLinkRepr.mark(loci, action)
return markElement || markIntraLink || markInterLink
},
destroy() {
elmementRepr.destroy()
......
......@@ -53,8 +53,9 @@ export function CarbohydrateRepresentation(): CarbohydrateRepresentation {
: carbohydrateLinkLoci
},
mark: (loci: Loci, action: MarkerAction) => {
carbohydrateSymbolRepr.mark(loci, action)
carbohydrateLinkRepr.mark(loci, action)
const markSymbol = carbohydrateSymbolRepr.mark(loci, action)
const markLink = carbohydrateLinkRepr.mark(loci, action)
return markSymbol || markLink
},
destroy() {
carbohydrateSymbolRepr.destroy()
......
......@@ -68,10 +68,11 @@ export function CartoonRepresentation(): CartoonRepresentation {
// : directionLoci
},
mark: (loci: Loci, action: MarkerAction) => {
traceRepr.mark(loci, action)
gapRepr.mark(loci, action)
blockRepr.mark(loci, action)
// directionRepr.mark(loci, action)
const markTrace = traceRepr.mark(loci, action)
const markGap = gapRepr.mark(loci, action)
const markBlock = blockRepr.mark(loci, action)
// const markDirection = directionRepr.mark(loci, action)
return markTrace || markGap || markBlock // \\ markDirection
},
destroy() {
traceRepr.destroy()
......
......@@ -45,7 +45,7 @@ export function DistanceRestraintRepresentation(): DistanceRestraintRepresentati
return crossLinkRepr.getLoci(pickingId)
},
mark: (loci: Loci, action: MarkerAction) => {
crossLinkRepr.mark(loci, action)
return crossLinkRepr.mark(loci, action)
},
destroy() {
crossLinkRepr.destroy()
......
......@@ -38,7 +38,7 @@ export function PointRepresentation(): PointRepresentation {
return pointRepr.getLoci(pickingId)
},
mark: (loci: Loci, action: MarkerAction) => {
pointRepr.mark(loci, action)
return pointRepr.mark(loci, action)
},
destroy() {
pointRepr.destroy()
......
......@@ -40,7 +40,7 @@ export function SpacefillRepresentation(): SpacefillRepresentation {
return sphereRepr.getLoci(pickingId)
},
mark: (loci: Loci, action: MarkerAction) => {
sphereRepr.mark(loci, action)
return sphereRepr.mark(loci, action)
},
destroy() {
sphereRepr.destroy()
......
......@@ -115,7 +115,11 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
}
function mark(loci: Loci, action: MarkerAction) {
visuals.forEach(({ visual }) => visual.mark(loci, action))
let changed = false
visuals.forEach(({ visual }) => {
changed = visual.mark(loci, action) || changed
})
return changed
}
function destroy() {
......
......@@ -140,7 +140,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
return renderObject ? getLoci(pickingId, currentGroup, renderObject.id) : EmptyLoci
},
mark(loci: Loci, action: MarkerAction) {
if (!renderObject) return
if (!renderObject) return false
const { tMarker } = renderObject.values
const { groupCount, instanceCount } = locationIt
......@@ -152,14 +152,14 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
let changed = false
if (isEveryLoci(loci)) {
apply(Interval.ofBounds(0, groupCount * instanceCount))
changed = true
changed = apply(Interval.ofBounds(0, groupCount * instanceCount))
} else {
changed = mark(loci, currentGroup, apply)
}
if (changed) {
ValueCell.update(tMarker, tMarker.ref.value)
}
return changed
},
destroy() {
// TODO
......
......@@ -139,7 +139,7 @@ export function ElementPointVisual(): UnitsVisual<ElementPointProps> {
return renderObject ? getElementLoci(pickingId, currentGroup, renderObject.id) : EmptyLoci
},
mark(loci: Loci, action: MarkerAction) {
if (!renderObject) return
if (!renderObject) return false
const { tMarker } = renderObject.values
const { groupCount, instanceCount } = locationIt
......@@ -159,6 +159,7 @@ export function ElementPointVisual(): UnitsVisual<ElementPointProps> {
if (changed) {
ValueCell.update(tMarker, tMarker.ref.value)
}
return changed
},
destroy() {
// TODO
......
......@@ -52,8 +52,8 @@ export function markNucleotideElement(loci: Loci, group: Unit.SymmetryGroup, app
const unitIdx = group.unitIndexMap.get(e.unit.id)
if (unitIdx !== undefined && Unit.isAtomic(e.unit)) {
if (Interval.is(e.indices)) {
const min = unitIdx * groupCount + OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.min(e.indices)])
const max = unitIdx * groupCount + OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.max(e.indices)])
const min = OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.min(e.indices)])
const max = OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.max(e.indices)])
if (min !== -1 && max !== -1) {
if (apply(Interval.ofRange(unitIdx * groupCount + min, unitIdx * groupCount + max))) changed = true
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment