From e8f1d494d36a5e1f1ee33d59faa4be2559cd752e Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 22 Apr 2025 10:54:38 -0400 Subject: adding drop handling code for scrapbookBox --- src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- src/client/views/nodes/ImageBox.tsx | 5 +- src/client/views/nodes/scrapbook/ScrapbookBox.tsx | 87 ++++++++++++---------- 4 files changed, 52 insertions(+), 46 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index de49f502f..b4473d9dc 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -68,7 +68,7 @@ export interface FieldViewSharedProps { isGroupActive?: () => string | undefined; // is this document part of a group that is active // eslint-disable-next-line no-use-before-define setContentViewBox?: (view: ViewBoxInterface) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox - + rejectDrop?: (draggedDoc: Doc[] | undefined, subView?: DocumentView) => boolean; // whether a document drop is rejected PanelWidth: () => number; PanelHeight: () => number; isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 3190757e2..5941e1669 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -117,10 +117,10 @@ export class FontIconBox extends ViewBoxBaseComponent() { default: type = 'slider'; break; } // prettier-ignore - const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, value, _readOnly_: value === undefined }); + const numScript = (value?: number) => ScriptCast(this.Document.script)?.script.run({ this: this.Document, value, _readOnly_: value === undefined }); const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; // Script for checking the outcome of the toggle - const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3))); + const checkResult = Number(Number(numScript()?.result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3))); return ( () { drop = undoable( action((e: Event, de: DragManager.DropEvent) => { - if (de.complete.docDragData) { + if (de.complete.docDragData && this._props.rejectDrop?.(de.complete.docDragData?.draggedDocuments, this.DocumentView?.())) { let added: boolean | undefined; const hitDropTarget = (ele: HTMLElement, dropTarget: HTMLDivElement | null): boolean => { if (!ele) return false; @@ -938,6 +938,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { ScreenToLocalTransform={this.screenToLocalTransform} select={emptyFunction} focus={this.focus} + rejectDrop={this._props.rejectDrop} getScrollHeight={this.getScrollHeight} NativeDimScaling={returnOne} isAnyChildContentActive={returnFalse} diff --git a/src/client/views/nodes/scrapbook/ScrapbookBox.tsx b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx index 56cfcda70..b02976067 100644 --- a/src/client/views/nodes/scrapbook/ScrapbookBox.tsx +++ b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx @@ -1,24 +1,25 @@ -import { makeObservable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import * as React from 'react'; -import { ViewBoxAnnotatableComponent } from '../../DocComponent'; -import { FieldView, FieldViewProps } from '../FieldView'; +import { Doc } from '../../../../fields/Doc'; +import { List } from '../../../../fields/List'; +import { emptyFunction } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; -import { action, observable } from 'mobx'; -import { DocListCast } from '../../../../fields/Doc'; -import { Doc } from '../../../../fields/Doc'; +import { CollectionView } from '../../collections/CollectionView'; +import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { DocumentView } from '../DocumentView'; -import { FormattedTextBox } from '../formattedText/FormattedTextBox'; -import { List } from '../../../../fields/List'; +import { FieldView, FieldViewProps } from '../FieldView'; +import { DragManager } from '../../../util/DragManager'; // Scrapbook view: a container that lays out its child items in a grid/template export class ScrapbookBox extends ViewBoxAnnotatableComponent() { @observable createdDate: string; + private _dropDisposer?: DragManager.DragDropDisposer; constructor(props: FieldViewProps) { super(props); makeObservable(this); this.createdDate = this.getFormattedDate(); - + // ensure we always have a List in dataDoc['items'] if (!this.dataDoc[this.fieldKey]) { this.dataDoc[this.fieldKey] = new List(); @@ -31,12 +32,6 @@ export class ScrapbookBox extends ViewBoxAnnotatableComponent() return FieldView.LayoutString(ScrapbookBox, fieldStr); } - - - - - - getFormattedDate(): string { return new Date().toLocaleDateString(undefined, { year: 'numeric', @@ -55,40 +50,50 @@ export class ScrapbookBox extends ViewBoxAnnotatableComponent() componentDidMount() { this.setTitle(); - if (!this.dataDoc[this.fieldKey]) { - this.dataDoc[this.fieldKey] = new List(); - } } + childRejectDrop = (draggedDoc: Doc[] | undefined, subView?: DocumentView) => { + if (draggedDoc?.length === 1 && subView) { + if (subView.Document.type === DocumentType.IMG && draggedDoc[0].$type !== DocumentType.IMG) { + return true; + } + } + return false; + }; + rejectDrop = (draggedDoc: Doc[] | undefined, subView?: DocumentView) => { + if (draggedDoc?.length === 1 && draggedDoc[0].$type !== DocumentType.IMG) { + return true; + } + return false; + }; + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { + if (de.complete.docDragData?.draggedDocuments[0]?.$type === DocumentType.IMG) { + return true; + } + return false; + }; + + protected createDashEventsTarget = (ele: HTMLDivElement | null) => { + this._dropDisposer?.(); + if (ele) { + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); + } + }; + render() { - // cast into an array even if empty - const items: Doc[] = DocListCast(this.dataDoc[this.fieldKey]); - return ( -
- +
r && this.createDashEventsTarget(r)}> +
- - //
- // {items.length === 0 - // ?
Drop docs here
- // : items.map((childDoc, idx) => ( - // - // )) - // } - //
); - } + } } - // Register scrapbook Docs.Prototypes.TemplateMap.set(DocumentType.SCRAPBOOK, { layout: { view: ScrapbookBox, dataField: 'items' }, -- cgit v1.2.3-70-g09d2