import React, { useRef } from 'react' import { Menu } from '@jbrowse/core/ui' import { getContainingView, getEnv, getSession, isSessionModelWithWidgets, } from '@jbrowse/core/util' import { useTheme } from '@mui/material' import { observer } from 'mobx-react' import Crosshairs from './Crosshairs' import MAFTooltip from './MAFTooltip' import MsaHighlightOverlay from './MsaHighlightOverlay' import YScaleBars from './Sidebar/YScaleBars' import { useDragSelection } from './useDragSelection' import type { LinearMafDisplayModel } from '../stateModel' import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view' const LinearMafDisplay = observer(function (props: { model: LinearMafDisplayModel }) { const { model } = props const { pluginManager } = getEnv(model) const { height, scrollTop, rowHeight, sidebarWidth, samples: sources } = model const ref = useRef(null) const theme = useTheme() const session = getSession(model) const LinearGenomePlugin = pluginManager.getPlugin( 'LinearGenomeViewPlugin', ) as import('@jbrowse/plugin-linear-genome-view').default const { BaseLinearDisplayComponent } = LinearGenomePlugin.exports const { isDragging, dragStartX, dragEndX, dragStartY, dragEndY, showSelectionBox, mouseX, mouseY, contextCoord, setContextCoord, handleMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, clearSelectionBox, } = useDragSelection(ref) const view = getContainingView(model) as LinearGenomeViewModel const { width } = view return (
{ if (showSelectionBox) { clearSelectionBox() } }} onMouseLeave={handleMouseLeave} > {model.showSidebar ? : null} {mouseY !== undefined && mouseX !== undefined && mouseX > sidebarWidth && sources && !contextCoord ? (
) : null} {(isDragging || showSelectionBox) && dragStartX !== undefined && dragEndX !== undefined && dragStartY !== undefined && dragEndY !== undefined ? (
) : null} { callback() setContextCoord(undefined) }} onClose={() => { setContextCoord(undefined) }} slotProps={{ transition: { onExit: () => { setContextCoord(undefined) }, }, }} anchorReference="anchorPosition" anchorPosition={ contextCoord ? { top: contextCoord.coord[1], left: contextCoord.coord[0] } : undefined } style={{ zIndex: theme.zIndex.tooltip, }} menuItems={[ { label: 'View subsequences (all rows)', onClick: () => { if (!contextCoord) { return } const { refName, assemblyName } = view.displayedRegions[0]! const [s, e] = [ Math.min(contextCoord.dragStartX, contextCoord.dragEndX), Math.max(contextCoord.dragStartX, contextCoord.dragEndX), ] if (isSessionModelWithWidgets(session)) { const widget = session.addWidget( 'MafSequenceWidget', 'mafSequence', { adapterConfig: model.adapterConfig, samples: model.samples, regions: [ { refName, start: view.pxToBp(s).coord - 1, end: view.pxToBp(e).coord, assemblyName, }, ], connectedViewId: view.id, }, ) session.showWidget(widget) } setContextCoord(undefined) }, }, { label: 'View subsequences (selected rows)', onClick: () => { if (!contextCoord || !sources) { return } const { refName, assemblyName } = view.displayedRegions[0]! const [s, e] = [ Math.min(contextCoord.dragStartX, contextCoord.dragEndX), Math.max(contextCoord.dragStartX, contextCoord.dragEndX), ] const minY = Math.min( contextCoord.dragStartY, contextCoord.dragEndY, ) const maxY = Math.max( contextCoord.dragStartY, contextCoord.dragEndY, ) const startRowIdx = Math.floor((minY + scrollTop) / rowHeight) const endRowIdx = Math.ceil((maxY + scrollTop) / rowHeight) const selectedSamples = sources.slice(startRowIdx, endRowIdx) if ( isSessionModelWithWidgets(session) && selectedSamples.length > 0 ) { const widget = session.addWidget( 'MafSequenceWidget', 'mafSequence', { adapterConfig: model.adapterConfig, samples: selectedSamples, regions: [ { refName, start: view.pxToBp(s).coord - 1, end: view.pxToBp(e).coord, assemblyName, }, ], connectedViewId: view.id, }, ) session.showWidget(widget) } setContextCoord(undefined) }, }, ]} />
) }) export default LinearMafDisplay