Skip to content

Commit

Permalink
Adds "Enable Drag-to-Select" toggle-button to the toolbar -- #265
Browse files Browse the repository at this point in the history
  • Loading branch information
chrtannus committed Mar 12, 2024
1 parent abfa22f commit d5a481c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
51 changes: 47 additions & 4 deletions src/client/components/network-editor/header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState, useEffect, Fragment } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import _ from 'lodash';

import { HEADER_HEIGHT, LEFT_DRAWER_WIDTH, MIN_DESKTOP_TOOLBAR_WIDTH } from '../defaults';
import useElementSize from '../../use-element-size';
Expand All @@ -11,6 +12,7 @@ import PopoverMenu from './popover-menu';
import { makeStyles } from '@material-ui/core/styles';

import { AppBar, Box, IconButton, Divider, Tooltip, Toolbar } from '@material-ui/core';
import { ToggleButton } from '@material-ui/lab';

import { AppLogoIcon } from '../svg-icons';
import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight';
Expand Down Expand Up @@ -121,13 +123,15 @@ export function Header({
<ToolbarDivider classes={classes} unrelated />
<TitleEditor controller={controller} disabled={!networkLoaded} />
<ToolbarDivider classes={classes} unrelated />
{menuDef.map(({title, icon, onClick, unrelated, isEnabled, alwaysShow, subMenu }, idx) =>
{menuDef.map(({title, icon, description, onClick, unrelated, isEnabled, isSelected, alwaysShow, subMenu }, idx) =>
(!showMobileMenu || (alwaysShow && !isMobile)) && (
<Fragment key={idx}>
<ToolbarButton
title={title}
icon={icon}
description={description}
disabled={!networkLoaded || (isEnabled && !isEnabled())}
selected={isSelected?.()}
subMenu={subMenu}
onClick={onClick}
onOpenSubMenu={handleOpenSubMenu}
Expand Down Expand Up @@ -169,26 +173,62 @@ Header.propTypes = {

//==[ ToolbarButton ]=================================================================================================

function ToolbarButton({ title, icon, color, className, disabled, subMenu, onClick, onOpenSubMenu }) {
const useToolbarButtonStyles = makeStyles((theme) => ({
toggle: {
border: 'none',
color: 'inherit',
},
}));

function ToolbarButton({ title, icon, description, color, className, disabled, selected:defaultSelected, subMenu, onClick, onOpenSubMenu }) {
const [ selected, setSelected ] = React.useState(defaultSelected);
const [ showTooltip, setShowTooltip ] = React.useState(false);

const classes = useToolbarButtonStyles();

const isToggleButton = defaultSelected != null;

const handleClick = (evt) => {
if (subMenu) {
if (isToggleButton) {
setSelected(!selected);
onClick?.(evt);
} else if (subMenu) {
onOpenSubMenu?.(evt, subMenu);
} else {
onClick?.(evt);
}
};

const tooltipText =
<>
<span style={{fontSize: '0.85rem'}}>{ title }</span>
{!_.isEmpty(description) && (
<><br />{ description }</>
)}
</>;

return (
<Tooltip
title={title}
title={tooltipText}
disableHoverListener
open={showTooltip && !disabled}
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
<span> {/* span needed to prevent issues with tooltips on disabled buttons */}
{isToggleButton ?
<ToggleButton
value="selected"
disabled={disabled}
selected={selected}
size="small"
color={color || 'inherit'}
className={clsx(classes.toggle, className)}
onClick={handleClick}
>
{ icon }
</ToggleButton>
:
<IconButton
disabled={disabled}
component={disabled ? "div" : undefined} // To prevent error: 'Material-UI: You are providing a disabled `button` child to the Tooltip component.'
Expand All @@ -199,16 +239,19 @@ function ToolbarButton({ title, icon, color, className, disabled, subMenu, onCli
>
{ icon }
</IconButton>
}
</span>
</Tooltip>
);
}
ToolbarButton.propTypes = {
title: PropTypes.string.isRequired,
icon: PropTypes.element.isRequired,
description: PropTypes.string,
color: PropTypes.string,
className: PropTypes.string,
disabled: PropTypes.bool,
selected: PropTypes.bool,
subMenu: PropTypes.array,
onClick: PropTypes.func,
onOpenSubMenu: PropTypes.func,
Expand Down
11 changes: 10 additions & 1 deletion src/client/components/network-editor/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import RemoveIcon from '@material-ui/icons/Remove';
import UndoIcon from '@material-ui/icons/Undo';
import RestoreIcon from '@material-ui/icons/SettingsBackupRestore';
import KeyboardReturnIcon from '@material-ui/icons/KeyboardReturn';
import { DownloadIcon, ShareIcon } from '../svg-icons';
import { DragSelectIcon, DownloadIcon, ShareIcon } from '../svg-icons';


const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -291,6 +291,7 @@ const Main = ({

const classes = useStyles();

const cy = controller.cy;
const snack = snackBarOps(setSnackBarState);

const shiftXCy = openLeftDrawer && !isMobile && !isTablet;
Expand Down Expand Up @@ -350,6 +351,14 @@ const Main = ({
icon: <FitScreenIcon />,
onClick: panner.fit,
unrelated: true,
}, {
title: "Enable Drag-to-Select",
description: "(or use SHIFT-select)",
icon: <DragSelectIcon />,
onClick: ()=> cy.userPanningEnabled(!cy.userPanningEnabled()),
isSelected: () => !cy.userPanningEnabled(),
alwaysShow: true, // always show on desktop/tablet, but still hides on mobile
unrelated: true,
}, {
title: "Download Data and Images",
icon: <DownloadIcon />,
Expand Down
8 changes: 8 additions & 0 deletions src/client/components/svg-icons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d5a481c

Please sign in to comment.