Skip to content

Commit

Permalink
feat: fill chemical shift input by using the cursor on the spectrum (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
hamed-musallam authored Jan 17, 2025
1 parent f0c1a9f commit 02ee2f8
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 14 deletions.
30 changes: 29 additions & 1 deletion src/component/modal/editRange/forms/components/DeltaInput.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { translateMultiplet } from 'nmr-processing';
import { useFormContext } from 'react-hook-form';
import { useFormContext, useWatch } from 'react-hook-form';

import { NumberInput2Controller } from '../../../../elements/NumberInput2Controller.js';
import { useEvent } from '../../../../utility/Events.js';

import { useEventFocusInput } from './SignalsContent.js';

interface DeltaInputProps {
signal: any;
Expand All @@ -16,8 +19,30 @@ export function DeltaInput({ signal, index }: DeltaInputProps) {
const {
control,
formState: { errors },
setValue,
} = useFormContext();
const isNotValid = hasError(errors, index);
const { signalIndex } = useWatch();
const { focusSource, setFocusSource } = useEventFocusInput();

useEvent({
onClick: ({ xPPM, shiftKey }) => {
if (index === signalIndex && shiftKey && focusSource === 'delta') {
setValue(`signals.${index}.delta`, xPPM);
}
},
onBrushEnd: (options) => {
const {
range: [from, to],
shiftKey,
} = options;
if (index === signalIndex && shiftKey && focusSource === 'delta') {
const delta = (to - from) / 2 + from;
setValue(`signals.${index}.delta`, delta);
}
},
});

return (
<div
style={{
Expand All @@ -42,6 +67,9 @@ export function DeltaInput({ signal, index }: DeltaInputProps) {
noShadowBox
buttonPosition="none"
debounceTime={250}
onClick={() => {
setFocusSource('delta');
}}
/>
<span>
{signal.js
Expand Down
60 changes: 51 additions & 9 deletions src/component/modal/editRange/forms/components/SignalsContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
/** @jsxImportSource @emotion/react */
import { Tab, Tabs } from '@blueprintjs/core';
import type { Range } from 'nmr-processing';
import { memo, useCallback, useEffect, useMemo } from 'react';
import {
createContext,
memo,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { FaPlus } from 'react-icons/fa';

Expand All @@ -16,6 +24,38 @@ interface SignalsFormProps {
range: Range;
}

type FocusSource = 'peak' | 'coupling' | 'delta' | null;
interface FocusInputContextState {
focusSource: 'peak' | 'coupling' | 'delta' | null;
setFocusSource: (source: FocusSource) => void;
}

const FocusInputContext = createContext<FocusInputContextState | null>(null);

export function useEventFocusInput() {
const context = useContext(FocusInputContext);

if (!context) {
throw new Error('FocusInputContext was not found.');
}

return context;
}

function FocusInputProvider({ children }) {
const [focusSource, setFocusSource] = useState<FocusSource>(null);

const state = useMemo(() => {
return { focusSource, setFocusSource };
}, [focusSource]);

return (
<FocusInputContext.Provider value={state}>
{children}
</FocusInputContext.Provider>
);
}

function SignalsContent({ range }: SignalsFormProps) {
const { setValue } = useFormContext();
const { signals, signalIndex } = useWatch();
Expand Down Expand Up @@ -78,14 +118,16 @@ function SignalsContent({ range }: SignalsFormProps) {
return (
<div>
<InfoBlock />
<Tabs
renderActiveTabPanelOnly
selectedTabId={signalIndex}
onChange={(id) => tapClickHandler(id)}
animate={false}
>
{signalFormTabs}
</Tabs>
<FocusInputProvider>
<Tabs
renderActiveTabPanelOnly
selectedTabId={signalIndex}
onChange={(id) => tapClickHandler(id)}
animate={false}
>
{signalFormTabs}
</Tabs>
</FocusInputProvider>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Select2Controller } from '../../../../../elements/Select2Controller.js'
import useSpectrum from '../../../../../hooks/useSpectrum.js';
import { hasCouplingConstant } from '../../../../../panels/extra/utilities/MultiplicityUtilities.js';
import { useEvent } from '../../../../../utility/Events.js';
import { useEventFocusInput } from '../SignalsContent.js';

const styles: Record<'input' | 'select' | 'column', CSSProperties> = {
input: {
Expand Down Expand Up @@ -49,6 +50,8 @@ function getCouplingMinErrorMessage(errors, index) {
}

export function SignalJCouplingsTable(props: SignalJCouplingsTableProps) {
const { focusSource, setFocusSource } = useEventFocusInput();

const {
setValue,
control,
Expand All @@ -67,7 +70,8 @@ export function SignalJCouplingsTable(props: SignalJCouplingsTableProps) {
if (
props.index === signalIndex &&
typeof lastSelectedCouplingIndexRef.current === 'number' &&
shiftKey
shiftKey &&
focusSource === 'coupling'
) {
setValue(
getJCouplingKey(
Expand All @@ -89,7 +93,8 @@ export function SignalJCouplingsTable(props: SignalJCouplingsTableProps) {
props.index === signalIndex &&
typeof lastSelectedCouplingIndexRef.current === 'number' &&
shiftKey &&
isSpectrum1D(spectrum)
isSpectrum1D(spectrum) &&
focusSource === 'coupling'
) {
const value = Math.abs(to - from) * spectrum.info.originFrequency;

Expand Down Expand Up @@ -218,6 +223,7 @@ export function SignalJCouplingsTable(props: SignalJCouplingsTableProps) {
);

function selectRowHandler(index) {
setFocusSource('coupling');
lastSelectedCouplingIndexRef.current = index;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { Column } from '../../../../../elements/ReactTable/ReactTable.js';
import ReactTable from '../../../../../elements/ReactTable/ReactTable.js';
import useSpectrum from '../../../../../hooks/useSpectrum.js';
import { useEvent } from '../../../../../utility/Events.js';
import { useEventFocusInput } from '../SignalsContent.js';

const styles: Record<'input' | 'column', CSSProperties> = {
input: {
Expand All @@ -41,6 +42,8 @@ function getPeakKey(signalIndex: number, peakIndex, key?: keyof Peak1D) {
}

export function SignalPeaksTable(props: SignalPeaksTableProps) {
const { focusSource, setFocusSource } = useEventFocusInput();

const { setValue, control, setFocus } = useFormContext();
const { signals, signalIndex } = useWatch();
const signal = signals?.[signalIndex] || {};
Expand All @@ -57,7 +60,8 @@ export function SignalPeaksTable(props: SignalPeaksTableProps) {
if (
props.index === signalIndex &&
typeof lastSelectedPeakIndexRef.current === 'number' &&
shiftKey
shiftKey &&
focusSource === 'peak'
) {
const delta = xPPM;
const xIndex = xFindClosestIndex(xArray, delta, { sorted: false });
Expand All @@ -77,7 +81,8 @@ export function SignalPeaksTable(props: SignalPeaksTableProps) {
if (
props.index === signalIndex &&
typeof lastSelectedPeakIndexRef.current === 'number' &&
shiftKey
shiftKey &&
focusSource === 'peak'
) {
const delta = (to - from) / 2 + from;

Expand Down Expand Up @@ -206,6 +211,7 @@ export function SignalPeaksTable(props: SignalPeaksTableProps) {
);

function selectRowHandler(index) {
setFocusSource('peak');
lastSelectedPeakIndexRef.current = index;
setFocus(`signals.${signalIndex}.peaks.${index}.x`, { shouldSelect: true });
}
Expand Down

0 comments on commit 02ee2f8

Please sign in to comment.