Skip to content

Commit

Permalink
Set focused view on any view click
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Oct 19, 2023
1 parent f5f66bd commit 9f91a49
Show file tree
Hide file tree
Showing 5 changed files with 336 additions and 297 deletions.
48 changes: 6 additions & 42 deletions packages/app-core/src/ui/App/ViewContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
import React, { useEffect, useRef } from 'react'
import { IconButton, Paper, useTheme } from '@mui/material'
import React, { useEffect } from 'react'
import { Paper, useTheme } from '@mui/material'
import { makeStyles } from 'tss-react/mui'
import { observer } from 'mobx-react'
import { getSession, useWidthSetter } from '@jbrowse/core/util'
import clsx from 'clsx'
import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'
import { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util'

// icons
import CloseIcon from '@mui/icons-material/Close'
import MinimizeIcon from '@mui/icons-material/Minimize'
import AddIcon from '@mui/icons-material/Add'

// locals
import ViewMenu from './ViewMenu'
import ViewContainerTitle from './ViewContainerTitle'
import ViewHeader from './ViewHeader'

const useStyles = makeStyles()(theme => ({
viewContainer: {
overflow: 'hidden',
margin: theme.spacing(0.5),
padding: `0 ${theme.spacing(1)} ${theme.spacing(1)}`,
},
icon: {
color: theme.palette.secondary.contrastText,
},
grow: {
flexGrow: 1,
},
focusedView: {
background: theme.palette.secondary.main,
},
Expand All @@ -47,18 +33,11 @@ const ViewContainer = observer(function ({
onMinimize: () => void
children: React.ReactNode
}) {
const { classes } = useStyles()
const theme = useTheme()
const ref = useWidthSetter(view, theme.spacing(1))
const scrollRef = useRef<HTMLDivElement>(null)
const { classes } = useStyles()
const session = getSession(view) as SessionWithFocusedViewAndDrawerWidgets

// scroll the view into view when first mounted. note: this effect will run
// only once, because of the empty array second param
useEffect(() => {
scrollRef.current?.scrollIntoView?.({ block: 'center' })
}, [])

useEffect(() => {
function handleSelectView(e: Event) {
if (e.target instanceof Element) {
Expand All @@ -79,6 +58,7 @@ const ViewContainer = observer(function ({
return (
<Paper
ref={ref}
onClick={() => session.setFocusedViewId(view.id)}
elevation={12}
className={clsx(
classes.viewContainer,
Expand All @@ -87,23 +67,7 @@ const ViewContainer = observer(function ({
: classes.unfocusedView,
)}
>
<div ref={scrollRef} style={{ display: 'flex' }}>
<ViewMenu model={view} IconProps={{ className: classes.icon }} />
<div className={classes.grow} />

<ViewContainerTitle view={view} />
<div className={classes.grow} />
<IconButton data-testid="minimize_view" onClick={onMinimize}>
{view.minimized ? (
<AddIcon className={classes.icon} fontSize="small" />
) : (
<MinimizeIcon className={classes.icon} fontSize="small" />
)}
</IconButton>
<IconButton data-testid="close_view" onClick={onClose}>
<CloseIcon className={classes.icon} fontSize="small" />
</IconButton>
</div>
<ViewHeader view={view} onClose={onClose} onMinimize={onMinimize} />
<Paper>{children}</Paper>
</Paper>
)
Expand Down
66 changes: 66 additions & 0 deletions packages/app-core/src/ui/App/ViewHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useEffect, useRef } from 'react'
import { IconButton } from '@mui/material'
import { makeStyles } from 'tss-react/mui'
import { observer } from 'mobx-react'
import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'

// icons
import CloseIcon from '@mui/icons-material/Close'
import MinimizeIcon from '@mui/icons-material/Minimize'
import AddIcon from '@mui/icons-material/Add'

// locals
import ViewMenu from './ViewMenu'
import ViewContainerTitle from './ViewContainerTitle'

const useStyles = makeStyles()(theme => ({
icon: {
color: theme.palette.secondary.contrastText,
},
grow: {
flexGrow: 1,
},
viewHeader: {
display: 'flex',
},
}))

const ViewHeader = observer(function ({
view,
onClose,
onMinimize,
}: {
view: IBaseViewModel
onClose: () => void
onMinimize: () => void
}) {
const { classes } = useStyles()
const scrollRef = useRef<HTMLDivElement>(null)

// scroll the view into view when first mounted. note: this effect will run
// only once, because of the empty array second param
useEffect(() => {
scrollRef.current?.scrollIntoView?.({ block: 'center' })
}, [])
return (
<div ref={scrollRef} className={classes.viewHeader}>
<ViewMenu model={view} IconProps={{ className: classes.icon }} />
<div className={classes.grow} />

<ViewContainerTitle view={view} />
<div className={classes.grow} />
<IconButton data-testid="minimize_view" onClick={onMinimize}>
{view.minimized ? (
<AddIcon className={classes.icon} fontSize="small" />
) : (
<MinimizeIcon className={classes.icon} fontSize="small" />
)}
</IconButton>
<IconButton data-testid="close_view" onClick={onClose}>
<CloseIcon className={classes.icon} fontSize="small" />
</IconButton>
</div>
)
})

export default ViewHeader
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { lazy, useEffect, useRef } from 'react'
import { Button, Paper, Typography } from '@mui/material'
import { makeStyles } from 'tss-react/mui'
import { LoadingEllipses } from '@jbrowse/core/ui'
import { getSession } from '@jbrowse/core/util'
import { observer } from 'mobx-react'

// icons
Expand All @@ -11,7 +12,6 @@ import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons'
import { LinearGenomeViewModel } from '..'
import TrackContainer from './TrackContainer'
import TracksContainer from './TracksContainer'
import { getSession } from '@jbrowse/core/util'

const ImportForm = lazy(() => import('./ImportForm'))

Expand All @@ -25,14 +25,39 @@ const useStyles = makeStyles()(theme => ({
},
}))

function NoTracksActive({ model }: { model: LinearGenomeViewModel }) {
const { classes } = useStyles()
const { hideNoTracksActive } = model
return (
<Paper className={classes.note}>
{!hideNoTracksActive ? (
<>
<Typography>No tracks active.</Typography>
<Button
variant="contained"
color="primary"
onClick={() => model.activateTrackSelector()}
style={{ zIndex: 1000 }}
startIcon={<TrackSelectorIcon />}
>
Open track selector
</Button>
</>
) : (
<div style={{ height: '48px' }}></div>
)}
</Paper>
)
}

const LinearGenomeView = observer(({ model }: { model: LGV }) => {
const { tracks, error, initialized, hasDisplayedRegions } = model
const { classes } = useStyles()
const ref = useRef<HTMLDivElement>(null)
const session = getSession(model)

useEffect(() => {
// sets the focused view id based on a click within the LGV; necessary for subviews to be focused properly
// sets the focused view id based on a click within the LGV;
// necessary for subviews to be focused properly
function handleSelectView(e: Event) {
if (e.target instanceof Element && ref?.current?.contains(e.target)) {
session.setFocusedViewId?.(model.id)
Expand All @@ -58,29 +83,12 @@ const LinearGenomeView = observer(({ model }: { model: LGV }) => {
const HeaderComponent = model.HeaderComponent()

return (
<div style={{ position: 'relative' }} ref={ref}>
<div ref={ref}>
<HeaderComponent model={model} />
<MiniControlsComponent model={model} />
<TracksContainer model={model}>
{!tracks.length ? (
<Paper variant="outlined" className={classes.note}>
{!model.hideNoTracksActive ? (
<>
<Typography>No tracks active.</Typography>
<Button
variant="contained"
color="primary"
onClick={model.activateTrackSelector}
style={{ zIndex: 1000 }}
startIcon={<TrackSelectorIcon />}
>
Open track selector
</Button>
</>
) : (
<div style={{ height: '48px' }}></div>
)}
</Paper>
<NoTracksActive model={model} />
) : (
tracks.map(track => (
<TrackContainer key={track.id} model={model} track={track} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const MiniControls = observer(function ({
const { classes, cx } = useStyles()
const { id, bpPerPx, maxBpPerPx, minBpPerPx, scaleFactor, hideHeader } = model
const { focusedViewId } = getSession(model)
console.log({ focusedViewId, id })
return hideHeader ? (
<Paper
className={cx(
Expand Down
Loading

0 comments on commit 9f91a49

Please sign in to comment.