From cab7f8872fd2184ee4f47d4e376531d51838c9af Mon Sep 17 00:00:00 2001 From: hamed musallam Date: Thu, 2 Oct 2025 10:09:09 +0200 Subject: [PATCH 1/2] refactor: position 'move peaks' popup near cursor refactor: improve actions popover positioning relative to cursor x/y close #3717 --- .../1d/peaks/PeakAnnotationsSpreadMode.tsx | 5 ++-- .../elements/ActionsButtonsPopover.tsx | 27 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx b/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx index aa3836d7d1..4ecb885bc3 100644 --- a/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx +++ b/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx @@ -116,11 +116,12 @@ function PeakAnnotationsSpreadMode(props: PeakAnnotationsSpreadModeProps) { isSeparator(button) || button?.visible !== false, ); - const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursorY; + const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursor.y; + const offsetX = offsetXMode === 'fixed' ? externalOffsetX : cursor.x; function handleMouseEnter(event) { - const { clientY, target } = event; - if (!target || offsetYMode !== 'cursor') return; - const targetElementRect = (target as HTMLElement)?.getBoundingClientRect(); - const y = clientY - targetElementRect.y; - setCursorY(y); + const { clientX, clientY, currentTarget } = event; + if (!(currentTarget instanceof Element)) return; + const rect = currentTarget.getBoundingClientRect(); + + setCursor((prev) => ({ + x: offsetXMode === 'cursor' ? clientX - rect.left : prev.x, + y: offsetYMode === 'cursor' ? clientY - rect.top : prev.y, + })); } + return ( From 5db09cfd62168611143be7a7d79110ec4b7bb5c4 Mon Sep 17 00:00:00 2001 From: hamed musallam Date: Thu, 2 Oct 2025 10:34:25 +0200 Subject: [PATCH 2/2] fix: correctly position zone assignment popup --- src/component/2d/zones/Signal.tsx | 35 +++++++++----------- src/component/2d/zones/SignalCrosshair.tsx | 4 +-- src/component/2d/zones/Zone.tsx | 37 ++++++++++++---------- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/component/2d/zones/Signal.tsx b/src/component/2d/zones/Signal.tsx index 5ad0324819..dc44d45e06 100644 --- a/src/component/2d/zones/Signal.tsx +++ b/src/component/2d/zones/Signal.tsx @@ -7,8 +7,6 @@ import { useHighlight, useHighlightData } from '../../highlight/index.js'; import { useActiveSpectrumZonesViewState } from '../../hooks/useActiveSpectrumZonesViewState.js'; import { useScale2DX, useScale2DY } from '../utilities/scale.js'; -import SignalCrosshair from './SignalCrosshair.js'; - interface SignalProps { signal: Signal2D; } @@ -52,24 +50,21 @@ function Signal({ signal }: SignalProps) { return ( {showSignals && ( - - - { - assignment?.highlight(); - highlight.show(); - }} - onMouseLeave={() => { - assignment?.clearHighlight(); - highlight.hide(); - }} - key={signal.id} - cx={scaleX(signal.x.delta || 0)} - cy={scaleY(signal.y.delta || 0)} - r={isHighlighted ? 6 : 4} - fill={isHighlighted ? 'green' : 'darkgreen'} - /> - + { + assignment?.highlight(); + highlight.show(); + }} + onMouseLeave={() => { + assignment?.clearHighlight(); + highlight.hide(); + }} + key={signal.id} + cx={scaleX(signal.x.delta || 0)} + cy={scaleY(signal.y.delta || 0)} + r={isHighlighted ? 6 : 4} + fill={isHighlighted ? 'green' : 'darkgreen'} + /> )} {showPeaks && diff --git a/src/component/2d/zones/SignalCrosshair.tsx b/src/component/2d/zones/SignalCrosshair.tsx index d61425518e..34b6c2611d 100644 --- a/src/component/2d/zones/SignalCrosshair.tsx +++ b/src/component/2d/zones/SignalCrosshair.tsx @@ -9,7 +9,7 @@ interface SignalCrosshairProps { signal: Signal2D; } -function SignalCrosshair({ signal }: SignalCrosshairProps) { +export function SignalCrosshair({ signal }: SignalCrosshairProps) { const highlightIDsX = useMemo(() => { return [buildID(signal.id, 'Crosshair'), buildID(signal.id, 'Crosshair_X')]; }, [signal.id]); @@ -39,5 +39,3 @@ function SignalCrosshair({ signal }: SignalCrosshairProps) { ); } - -export default SignalCrosshair; diff --git a/src/component/2d/zones/Zone.tsx b/src/component/2d/zones/Zone.tsx index b08b181eb2..ccd1760b72 100644 --- a/src/component/2d/zones/Zone.tsx +++ b/src/component/2d/zones/Zone.tsx @@ -12,6 +12,7 @@ import { useActiveSpectrumZonesViewState } from '../../hooks/useActiveSpectrumZo import { useScale2DX, useScale2DY } from '../utilities/scale.js'; import Signal from './Signal.js'; +import { SignalCrosshair } from './SignalCrosshair.tsx'; interface ZoneProps { zoneData: ZoneType; @@ -54,21 +55,25 @@ function Zone({ zoneData }: ZoneProps) { ]; return ( - { + assignmentZone.highlight(); + highlightZone.show(); + }} + onMouseLeave={() => { + assignmentZone.clearHighlight(); + highlightZone.hide(); + }} > - { - assignmentZone.highlight(); - highlightZone.show(); - }} - onMouseLeave={() => { - assignmentZone.clearHighlight(); - highlightZone.hide(); - }} + {signals.map((signal) => ( + + ))} + + {showZones && ( @@ -87,8 +92,8 @@ function Zone({ zoneData }: ZoneProps) { // eslint-disable-next-line react/no-array-index-key ))} - - + + ); }