Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/component/2d/BrushTracker2D.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { useChartData } from '../context/ChartContext.js';
import { useDispatch } from '../context/DispatchContext.js';
import { useMapKeyModifiers } from '../context/KeyModifierContext.js';
import { usePreferences } from '../context/PreferencesContext.js';
import { options } from '../toolbar/ToolTypes.js';

import {
Expand All @@ -23,7 +24,6 @@ import {
} from './utilities/DimensionLayout.js';
import type { Layout } from './utilities/DimensionLayout.js';
import { useScale2DX, useScale2DY } from './utilities/scale.js';
import { usePreferences } from '../context/PreferencesContext.js';

function usePixelToPPMConverter() {
const scaleX = useScale2DX();
Expand Down
109 changes: 81 additions & 28 deletions src/component/EventsTrackers/BrushTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ export type OnClick = (element: ClickOptions) => void;
export type { OnClick as OnDoubleClick };
export type ZoomOptions = Pick<
React.WheelEvent,
'deltaY' | 'shiftKey' | 'deltaMode' | 'altKey'
'deltaY' | 'shiftKey' | 'deltaMode' | 'altKey' | 'deltaX' | 'ctrlKey'
> &
Position & { invertScroll?: boolean };
Position & { invertScroll?: boolean; isBidirectionalZoom: boolean };
export type OnZoom = (options: ZoomOptions) => void;
export type OnBrush = (state: BrushTrackerData) => void;

Expand Down Expand Up @@ -127,6 +127,9 @@ export function BrushTracker({
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const lastPointRef = useRef<number>(0);
const isDraggingRef = useRef(false);
const boundingRectRef = useRef<DOMRect | null>(null);
const startPositionRef = useRef<Position>({ x: 0, y: 0 });
const lastRef = useRef<Position>({ x: 0, y: 0 });

const clickHandler = useCallback(
(event: React.MouseEvent, targetElement: Element) => {
Expand Down Expand Up @@ -168,33 +171,68 @@ export function BrushTracker({
if (noPropagation) {
event.stopPropagation();
}
dispatch({
type: 'DOWN',
payload: {
mouseButton: MouseButtons[event.button],
shiftKey: event.shiftKey,
altKey: event.altKey,
screenX: event.screenX,
screenY: event.screenY,
clientX: event.clientX,
clientY: event.clientY,
boundingRect: event.currentTarget.getBoundingClientRect(),
},
});

const boundingRect = event.currentTarget.getBoundingClientRect();
boundingRectRef.current = boundingRect;
startPositionRef.current = {
x: event.clientX - boundingRect.x,
y: event.clientY - boundingRect.y,
};

if (!event.ctrlKey) {
dispatch({
type: 'DOWN',
payload: {
mouseButton: MouseButtons[event.button],
shiftKey: event.shiftKey,
altKey: event.altKey,
screenX: event.screenX,
screenY: event.screenY,
clientX: event.clientX,
clientY: event.clientY,
boundingRect,
},
});
}
}

function moveCallback(event: PointerEvent) {
isDraggingRef.current = true; // set flag to true to skip click event if the user dragged the mouse

dispatch({
type: 'MOVE',
payload: {
screenX: event.screenX,
screenY: event.screenY,
clientX: event.clientX,
clientY: event.clientY,
},
});
const { clientX, clientY, shiftKey, altKey, ctrlKey } = event;

if (event.ctrlKey) {
if (boundingRectRef.current) {
const boundingRect = boundingRectRef.current;
const x = clientX - boundingRect.x;
const y = clientY - boundingRect.y;

const deltaX = clientX - boundingRect.x - lastRef.current.x;
const deltaY = clientY - boundingRect.y - lastRef.current.y;

lastRef.current = { x, y };
onZoom({
deltaY,
deltaX,
shiftKey,
altKey,
x: startPositionRef.current.x,
y: startPositionRef.current.y,
ctrlKey,
deltaMode: 0,
isBidirectionalZoom: true,
});
}
} else {
dispatch({
type: 'MOVE',
payload: {
screenX: event.screenX,
screenY: event.screenY,
clientX: event.clientX,
clientY: event.clientY,
},
});
}
}

function upCallback() {
Expand All @@ -218,7 +256,7 @@ export function BrushTracker({

return false;
},
[clickHandler, noPropagation],
[clickHandler, noPropagation, onZoom],
);

const handleMouseWheel = useCallback(
Expand All @@ -227,8 +265,18 @@ export function BrushTracker({
const x = event.clientX - boundingRect.x;
const y = event.clientY - boundingRect.y;

const { deltaY, deltaX, shiftKey, altKey, deltaMode } = event;
onZoom({ deltaY: deltaY || deltaX, shiftKey, altKey, deltaMode, x, y });
const { deltaY, deltaX, shiftKey, altKey, ctrlKey, deltaMode } = event;
onZoom({
deltaY,
deltaX,
shiftKey,
altKey,
ctrlKey,
deltaMode,
x,
y,
isBidirectionalZoom: false,
});
},
[onZoom],
);
Expand All @@ -255,6 +303,11 @@ export function BrushTracker({
return (
<BrushContext.Provider value={state}>
<div
onContextMenu={(e) => {
if (e.ctrlKey && e.button === 0) {
e.preventDefault();
}
}}
className={className}
style={{ ...style, touchAction: 'none' }}
onPointerDown={pointerDownHandler}
Expand Down
7 changes: 4 additions & 3 deletions src/component/reducer/actions/InsetActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,9 @@ function zoomWithScroll(draft: Draft<State>, options: ZoomWithScroll1DOptions) {

const { originDomain, mode } = draft;
const scaleX = getXScale(inset, { baseSize, mode });
const { invertScroll, deltaX, deltaY } = zoomOptions;

const scaleRatio = toScaleRatio(zoomOptions);
const scaleRatio = toScaleRatio({ delta: deltaY || deltaX, invertScroll });

const { x } = zoomOptions;
const domain = zoomIdentity
Expand All @@ -280,7 +281,7 @@ function handleInsetZoom(draft: Draft<State>, action: ZoomInsetAction) {
const {
toolOptions: { selectedTool },
} = draft;
const { altKey, shiftKey } = options;
const { altKey, shiftKey, deltaX, deltaY, invertScroll } = options;
const inset = getInset(draft, insetKey);

if (!inset) return;
Expand All @@ -294,7 +295,7 @@ function handleInsetZoom(draft: Draft<State>, action: ZoomInsetAction) {
if (altKey) {
// rescale the integral in ranges and integrals
const { view } = inset;
const scaleRatio = toScaleRatio(options);
const scaleRatio = toScaleRatio({ delta: deltaY | deltaX, invertScroll });

if (selectedTool === 'rangePicking') {
view.ranges.integralsScaleRatio *= scaleRatio;
Expand Down
18 changes: 11 additions & 7 deletions src/component/reducer/actions/ToolsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ function zoomWithScroll(
options: ZoomWithScroll1DOptions | ZoomWithScroll2DOptions,
) {
const { zoomOptions, direction = 'Horizontal', dimension } = options;
const { x, deltaX, invertScroll } = zoomOptions;

let scaleX;
let scaleY;
Expand All @@ -328,10 +329,9 @@ function zoomWithScroll(
scaleX = get2DXScale(draft);
scaleY = get2DYScale(draft);
}
const scaleRatio = toScaleRatio(zoomOptions);
const scaleRatio = toScaleRatio({ delta: deltaX, invertScroll });

if (direction === 'Both' || direction === 'Horizontal') {
const { x } = zoomOptions;
const domain = zoomIdentity
.translate(x, 0)
.scale(scaleRatio)
Expand Down Expand Up @@ -373,8 +373,10 @@ function handleZoom(draft: Draft<State>, action: ZoomAction) {
yDomains,
toolOptions: { selectedTool },
} = draft;
const scaleRatio = toScaleRatio(options);
const { altKey, shiftKey } = options;
const { altKey, shiftKey, invertScroll, deltaY, isBidirectionalZoom } =
options;

const scaleRatio = toScaleRatio({ delta: deltaY, invertScroll });

switch (displayerMode) {
case '2D': {
Expand All @@ -387,7 +389,7 @@ function handleZoom(draft: Draft<State>, action: ZoomAction) {
}

//zoom in/out in 2d
if (shiftKey) {
if (shiftKey || isBidirectionalZoom) {
zoomWithScroll(draft, {
zoomOptions: options,
dimension: '2D',
Expand All @@ -414,9 +416,11 @@ function handleZoom(draft: Draft<State>, action: ZoomAction) {
const activeSpectra = getActiveSpectra(draft);

// Horizontal zoom in/out 1d spectra by mouse wheel
if (shiftKey) {
if (shiftKey || isBidirectionalZoom) {
zoomWithScroll(draft, { zoomOptions: options, dimension: '1D' });
return;
if (!isBidirectionalZoom) {
return;
}
}

// rescale the integral in ranges and integrals
Expand Down
11 changes: 6 additions & 5 deletions src/component/reducer/helper/Zoom1DManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ export const ZOOM_TYPES = {
export type ZoomType = keyof typeof ZOOM_TYPES;

function toScaleRatio(
options: ZoomOptions,
options: { invertScroll?: boolean; delta: number },
zoomOptions: ScaleRationOptions = {},
) {
const { invertScroll = false } = options;
const { factor = 1 } = zoomOptions;

const deltaY =
Math.abs(options.deltaY) < 100 ? options.deltaY * 100 : options.deltaY;
const delta = deltaY * (invertScroll ? -0.001 : 0.001) * factor;
const normalizeDelta =
Math.abs(options.delta) < 100 ? options.delta * 100 : options.delta;
const delta = normalizeDelta * (invertScroll ? -0.001 : 0.001) * factor;
const ratio = delta < 0 ? -1 / (delta - 1) : 1 + delta;

return ratio;
Expand All @@ -38,7 +38,8 @@ function wheelZoom(
domain: number[],
scaleOptions: ScaleRationOptions = {},
): number[] {
const ratio = toScaleRatio(options, scaleOptions);
const { deltaY, invertScroll } = options;
const ratio = toScaleRatio({ delta: deltaY, invertScroll }, scaleOptions);
const [min, max] = domain;
return [min * ratio, max * ratio];
}
Expand Down
4 changes: 2 additions & 2 deletions src/component/reducer/preferences/actions/matrixGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ function changeMatrixGenerationScale(
const matrixGeneration = getMatrixGenerationPanelOptions(draft, nucleus);

if (!matrixGeneration) return;

const scaleRatio = toScaleRatio(zoomOptions);
const { deltaY, invertScroll } = zoomOptions;
const scaleRatio = toScaleRatio({ delta: deltaY, invertScroll });

matrixGeneration.scaleRatio *= scaleRatio;
}
Expand Down
2 changes: 2 additions & 0 deletions src/component/toolbar/ToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,10 @@ export default function ToolBar() {
subTitles: [
{ title: 'Vertical', shortcuts: ['Scroll wheel'] },
{ title: 'Horizontal', shortcuts: ['⇧', 'Scroll wheel'] },
{ title: 'Horizontal and Vertical', shortcuts: ['CTRL', 'drag'] },
{ title: 'Pan', shortcuts: ['Right button'] },
],
style: { minWidth: '300px' },
},
icon: <FaSearchPlus />,
},
Expand Down
Loading