11import styled from '@emotion/styled' ;
22import type { BoundingBox , Spectrum , TextStyle } from '@zakodium/nmrium-core' ;
3- import { useEffect , useMemo , useState } from 'react' ;
3+ import { useCallback , useEffect , useMemo , useState } from 'react' ;
44import { BsArrowsMove } from 'react-icons/bs' ;
55import { FaEdit , FaTimes } from 'react-icons/fa' ;
66import { Rnd } from 'react-rnd' ;
@@ -43,6 +43,8 @@ function useWrapSVGText(params: UseWrapSVGTextParams) {
4343
4444 const debugCanvas = false ;
4545 const labelSize = style . fontSize ?? 12 ;
46+ // ctx used only for debug canvas purpose.
47+ // eslint-disable-next-line @typescript-eslint/no-deprecated
4648 const { getTextWidth, ctx } = useTextMetrics ( {
4749 labelSize,
4850 labelStyle : style . fontStyle ,
@@ -175,55 +177,115 @@ function PublicationText(props: PublicationTextProps) {
175177
176178interface DraggablePublicationStringProps {
177179 value : string ;
178- bonding : BoundingBox ;
180+ bounding : BoundingBox ;
179181 nucleus : string ;
180182 spectrum : Spectrum ;
181183}
182184
185+ function useBoundingBox ( externalBoundingPercent : BoundingBox ) {
186+ const { percentToPixel, pixelToPercent } = useSVGUnitConverter ( ) ;
187+
188+ const convertToPixel = useCallback (
189+ ( bounding : Partial < BoundingBox > ) => {
190+ const { x, y, height, width } = bounding ;
191+ const output : Partial < BoundingBox > = { } ;
192+
193+ if ( typeof x === 'number' ) {
194+ output . x = percentToPixel ( x , 'x' ) ;
195+ }
196+ if ( typeof y === 'number' ) {
197+ output . y = percentToPixel ( y , 'y' ) ;
198+ }
199+ if ( typeof width === 'number' ) {
200+ output . width = width ;
201+ }
202+ if ( typeof height === 'number' ) {
203+ output . height = height ;
204+ }
205+
206+ return output ;
207+ } ,
208+ [ percentToPixel ] ,
209+ ) ;
210+
211+ const convertToPercent = useCallback (
212+ ( bounding : Partial < BoundingBox > ) => {
213+ const { x, y, height, width } = bounding ;
214+ const output : Partial < BoundingBox > = { } ;
215+
216+ if ( typeof x === 'number' ) {
217+ output . x = pixelToPercent ( x , 'x' ) ;
218+ }
219+ if ( typeof y === 'number' ) {
220+ output . y = pixelToPercent ( y , 'y' ) ;
221+ }
222+ if ( typeof width === 'number' ) {
223+ output . width = width ;
224+ }
225+ if ( typeof height === 'number' ) {
226+ output . height = height ;
227+ }
228+
229+ return output ;
230+ } ,
231+ [ pixelToPercent ] ,
232+ ) ;
233+
234+ const [ bounding , setBounding ] = useState < BoundingBox > ( ( ) => {
235+ return convertToPixel ( externalBoundingPercent ) as BoundingBox ;
236+ } ) ;
237+
238+ useEffect ( ( ) => {
239+ setBounding ( convertToPixel ( externalBoundingPercent ) as BoundingBox ) ;
240+ } , [ convertToPixel , externalBoundingPercent ] ) ;
241+
242+ return {
243+ bounding,
244+ setBounding,
245+ convertToPixel,
246+ convertToPercent,
247+ } ;
248+ }
249+
183250function DraggablePublicationString ( props : DraggablePublicationStringProps ) {
184- const { value, bonding : externalBounding , nucleus, spectrum } = props ;
251+ const {
252+ value,
253+ bounding : externalBoundingInPercent ,
254+ nucleus,
255+ spectrum,
256+ } = props ;
185257 const spectrumKey = spectrum . id ;
186258
187259 const dispatch = useDispatch ( ) ;
188260 const { viewerRef } = useGlobal ( ) ;
189- const [ bounding , setBounding ] = useState < BoundingBox > ( externalBounding ) ;
190261 const [ isMoveActive , setIsMoveActive ] = useState ( false ) ;
191- const { percentToPixel, pixelToPercent } = useSVGUnitConverter ( ) ;
192262 const isExportProcessStart = useCheckExportStatus ( ) ;
193263 const acsOptions = useACSSettings ( nucleus ) ;
194264 const [ isDialogOpen , setIsDialogOpen ] = useState ( false ) ;
195265
196- useEffect ( ( ) => {
197- setBounding ( { ...externalBounding } ) ;
198- } , [ externalBounding ] ) ;
199-
200- function handleResize (
201- internalBounding : Pick < BoundingBox , 'height' | 'width' > ,
202- ) {
203- const { width = 0 , height = 0 } = convertToPixel ( externalBounding ) ;
204- internalBounding . width += width ;
205- internalBounding . height += height ;
206- setBounding ( ( prevBounding ) => ( {
207- ...prevBounding ,
208- ...convertToPercent ( internalBounding ) ,
209- } ) ) ;
266+ const { bounding, setBounding, convertToPercent } = useBoundingBox (
267+ externalBoundingInPercent ,
268+ ) ;
269+
270+ function handleResize ( bounding : Pick < BoundingBox , 'height' | 'width' > ) {
271+ setBounding ( ( prevBounding ) => {
272+ return {
273+ ...prevBounding ,
274+ width : bounding . width ,
275+ height : bounding . height ,
276+ } ;
277+ } ) ;
210278 }
211279
212- function handleDrag ( internalBounding : Pick < BoundingBox , 'x' | 'y' > ) {
280+ function handleDrag ( newPosition : Pick < BoundingBox , 'x' | 'y' > ) {
213281 setBounding ( ( prevBounding ) => ( {
214282 ...prevBounding ,
215- ...convertToPercent ( internalBounding ) ,
283+ ...newPosition ,
216284 } ) ) ;
217285 }
286+
218287 function handleChangeInsetBounding ( bounding : Partial < BoundingBox > ) {
219- if (
220- typeof bounding ?. width === 'number' &&
221- typeof bounding ?. height === 'number'
222- ) {
223- const { width, height } = externalBounding ;
224- bounding . width += width ;
225- bounding . height += height ;
226- }
288+ setBounding ( ( prev ) => ( { ...prev , ...bounding } ) ) ;
227289
228290 dispatch ( {
229291 type : 'CHANGE_RANGES_VIEW_FLOATING_BOX_BOUNDING' ,
@@ -235,45 +297,6 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
235297 } ) ;
236298 }
237299
238- function convertToPixel ( bounding : Partial < BoundingBox > ) {
239- const { x, y, height, width } = bounding ;
240- const output : Partial < BoundingBox > = { } ;
241-
242- if ( x ) {
243- output . x = percentToPixel ( x , 'x' ) ;
244- }
245- if ( y ) {
246- output . y = percentToPixel ( y , 'y' ) ;
247- }
248- if ( width ) {
249- output . width = width ;
250- }
251- if ( height ) {
252- output . height = height ;
253- }
254-
255- return output ;
256- }
257- function convertToPercent ( bounding : Partial < BoundingBox > ) {
258- const { x, y, height, width } = bounding ;
259- const output : Partial < BoundingBox > = { } ;
260-
261- if ( x ) {
262- output . x = pixelToPercent ( x , 'x' ) ;
263- }
264- if ( y ) {
265- output . y = pixelToPercent ( y , 'y' ) ;
266- }
267- if ( width ) {
268- output . width = width ;
269- }
270- if ( height ) {
271- output . height = height ;
272- }
273-
274- return output ;
275- }
276-
277300 function handleRemove ( ) {
278301 dispatch ( {
279302 type : 'TOGGLE_RANGES_VIEW_PROPERTY' ,
@@ -306,10 +329,7 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
306329 ] ;
307330 if ( ! viewerRef || ! value ) return null ;
308331
309- const { width, height, x : xInPercent , y : yInPercent } = bounding ;
310-
311- const x = percentToPixel ( xInPercent , 'x' ) ;
312- const y = percentToPixel ( yInPercent , 'y' ) ;
332+ const { width, height, x = 0 , y = 0 } = bounding ;
313333
314334 if ( isExportProcessStart ) {
315335 return (
@@ -333,18 +353,26 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
333353 dragHandleClassName = "handle"
334354 enableUserSelectHack = { false }
335355 bounds = { `#${ viewerRef . id } ` }
336- onResize = { ( e , dir , eRef , size , position ) =>
337- handleResize ( { ...size , ...position } )
338- }
339- onResizeStop = { ( e , dir , eRef , size , position ) =>
340- handleChangeInsetBounding ( { ...size , ...position } )
341- }
356+ onResize = { ( e , dir , eRef , size , position ) => {
357+ handleResize ( {
358+ ...position ,
359+ height : eRef . clientHeight ,
360+ width : eRef . clientWidth ,
361+ } ) ;
362+ } }
363+ onResizeStop = { ( e , dir , eRef , size , position ) => {
364+ handleChangeInsetBounding ( {
365+ ...position ,
366+ height : eRef . clientHeight ,
367+ width : eRef . clientWidth ,
368+ } ) ;
369+ } }
342370 onDragStart = { ( ) => setIsMoveActive ( true ) }
343- onDrag = { ( e , { x , y } ) => {
344- handleDrag ( { x, y } ) ;
371+ onDrag = { ( e , data ) => {
372+ handleDrag ( { x : data . x , y : data . y } ) ;
345373 } }
346- onDragStop = { ( e , { x , y } ) => {
347- handleChangeInsetBounding ( { x, y } ) ;
374+ onDragStop = { ( e , data ) => {
375+ handleChangeInsetBounding ( { x : data . x , y : data . y } ) ;
348376 setIsMoveActive ( false ) ;
349377 } }
350378 resizeHandleWrapperStyle = { { backgroundColor : 'white' } }
@@ -353,7 +381,6 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
353381 buttons = { actionButtons }
354382 fill
355383 positioningStrategy = "fixed"
356-
357384 direction = "row"
358385 targetProps = { { style : { width : '100%' , height : '100%' } } }
359386 space = { 2 }
@@ -365,8 +392,8 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
365392 width = { width || 'auto' }
366393 height = { height || 'auto' }
367394 xmlns = "http://www.w3.org/2000/svg"
368-
369- > < PublicationText
395+ >
396+ < PublicationText
370397 text = { value }
371398 width = { width }
372399 textStyle = { acsOptions . textStyle }
@@ -424,7 +451,7 @@ export function FloatPublicationString() {
424451 key = { id }
425452 spectrum = { spectrum }
426453 nucleus = { nucleus }
427- bonding = { publicationStringBounding }
454+ bounding = { publicationStringBounding }
428455 value = { publicationString [ id ] }
429456 />
430457 ) ;
0 commit comments