From 5cd64622f14ede408d3baca4a10d155b60392e46 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 13 Apr 2023 22:22:07 -0400 Subject: lots of changes to get rid of ContainingCollectionDoc and ContainingCollectionView props. --- src/client/views/nodes/trails/PresBox.tsx | 1 - src/client/views/nodes/trails/PresElementBox.tsx | 27 +++++++++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'src/client/views/nodes/trails') diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 3589a9065..807a19771 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -2457,7 +2457,6 @@ export class PresBox extends ViewBoxBaseComponent() { {mode !== CollectionViewType.Invalid ? ( () { // Idea: this boolean will determine whether to automatically show the video when this preselement is selected. // @observable static showVideo: boolean = false; @computed get indexInPres() { - return DocListCast(this.presBox[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc); + return DocListCast(this.presBox?.[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) @computed get expandViewHeight() { return 100; @@ -51,11 +51,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { return this.presBoxView?.selectedArray; } @computed get presBoxView() { - const vpath = this.props.docViewPath(); - return vpath.length > 1 ? (vpath[vpath.length - 2].ComponentView as PresBox) : undefined; + return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as PresBox; } @computed get presBox() { - return this.props.ContainingCollectionDoc!; + return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc; } @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; @@ -110,14 +109,12 @@ export class PresElementBox extends ViewBoxBaseComponent() { docFilters={this.props.docFilters} docRangeFilters={this.props.docRangeFilters} searchFilterDocs={this.props.searchFilterDocs} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} rootSelected={returnTrue} addDocument={returnFalse} removeDocument={returnFalse} fitContentsToBox={returnTrue} moveDocument={this.props.moveDocument!} - focus={DocUtils.DefaultFocus} + focus={emptyFunction} whenChildContentsActiveChanged={returnFalse} addDocTab={returnFalse} pinToPres={returnFalse} @@ -195,7 +192,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []); if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.rootDoc); dragData.dropAction = 'move'; - dragData.treeViewDoc = this.presBox._viewType === CollectionViewType.Tree ? this.props.ContainingCollectionDoc : undefined; // this.props.DocumentView?.()?.props.treeViewDoc; + dragData.treeViewDoc = this.presBox?._viewType === CollectionViewType.Tree ? this.presBox : undefined; // this.props.DocumentView?.()?.props.treeViewDoc; dragData.moveDocument = this.props.moveDocument; const dragItem: HTMLElement[] = []; if (dragArray.length === 1) { @@ -269,7 +266,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch removeItem = action((e: React.MouseEvent) => { e.stopPropagation(); - if (this.indexInPres < (this.presBoxView?.itemIndex || 0)) { + if (this.presBox && this.indexInPres < (this.presBoxView?.itemIndex || 0)) { this.presBox.itemIndex = (this.presBoxView?.itemIndex || 0) - 1; } this.props.removeDocument?.(this.rootDoc); @@ -406,15 +403,15 @@ export class PresElementBox extends ViewBoxBaseComponent() { @computed get toolbarWidth(): number { const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox); - let width: number = NumCast(this.presBox._width); + let width: number = NumCast(this.presBox?._width); if (presBoxDocView) width = presBoxDocView.props.PanelWidth(); if (width === 0) width = 300; return width; } @computed get presButtons() { - const presBox: Doc = this.presBox; //presBox - const presBoxColor: string = StrCast(presBox._backgroundColor); + const presBox = this.presBox; //presBox + const presBoxColor: string = StrCast(presBox?._backgroundColor); const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; const targetDoc: Doc = this.targetDoc; const activeItem: Doc = this.rootDoc; @@ -494,10 +491,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { @computed get mainItem() { const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false; - const isCurrent: boolean = this.presBox._itemIndex === this.indexInPres; + const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres; const miniView: boolean = this.toolbarWidth <= 110; - const presBox: Doc = this.presBox; //presBox - const presBoxColor: string = StrCast(presBox._backgroundColor); + const presBox = this.presBox; //presBox + const presBoxColor: string = StrCast(presBox?._backgroundColor); const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; const activeItem: Doc = this.rootDoc; -- cgit v1.2.3-70-g09d2 From 0a66b0f369a13d5f399bf125727aff73cd6fd1b4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 19 Apr 2023 13:01:37 -0400 Subject: fixed image importing metadata for gpt. fixed showTitle UI to be able to turn off titles on templates (like icon views). added ui for choosing primary/alternate image and a drop target for setting alternate. --- src/client/documents/Documents.ts | 2 + src/client/views/MainView.tsx | 2 + src/client/views/PropertiesButtons.tsx | 6 ++- src/client/views/nodes/ImageBox.scss | 8 +++ src/client/views/nodes/ImageBox.tsx | 58 +++++++++++++++++++--- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 ++- src/client/views/nodes/trails/PresBox.tsx | 4 +- 7 files changed, 73 insertions(+), 13 deletions(-) (limited to 'src/client/views/nodes/trails') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 09b45a481..a0149eadf 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -147,6 +147,8 @@ export class DocumentOptions { _panY?: NUMt = new NumInfo('vertical pan location of a freeform view'); _width?: NUMt = new NumInfo('displayed width of a document'); _height?: NUMt = new NumInfo('displayed height of document'); + 'data-nativeWidth'?: NUMt = new NumInfo('native width of data field contents (e.g., the pixel width of an image)'); + 'data-nativeHeight'?: NUMt = new NumInfo('native height of data field contents (e.g., the pixel height of an image)'); _nativeWidth?: NUMt = new NumInfo('native width of document contents (e.g., the pixel width of an image)'); _nativeHeight?: NUMt = new NumInfo('native height of document contents (e.g., the pixel height of an image)'); _nativeDimModifiable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers'); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index acbe0cbc3..4cbf8a811 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -314,6 +314,8 @@ export class MainView extends React.Component { fa.faArrowUp, fa.faBolt, fa.faBullseye, + fa.faTurnUp, + fa.faTurnDown, fa.faCaretUp, fa.faCat, fa.faCheck, diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 031d501ad..98dcf4f21 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -177,7 +177,11 @@ export class PropertiesButtons extends React.Component<{}, {}> { '_showTitle', on => 'Switch between title styles', on => 'text-width', - (dv, doc) => ((dv?.rootDoc || doc)._showTitle = !(dv?.rootDoc || doc)._showTitle ? 'title' : (dv?.rootDoc || doc)._showTitle === 'title' ? 'title:hover' : undefined) + (dv, doc) => { + const tdoc = dv?.rootDoc || doc; + const newtitle = !tdoc._showTitle ? 'title' : tdoc._showTitle === 'title' ? 'title:hover' : ''; + tdoc._showTitle = newtitle; + } ); } @computed get autoHeightButton() { diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 6359a9491..22dbc1e80 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -119,6 +119,14 @@ } } } +.imageBox-alternateDropTarget { + position: absolute; + color: white; + background: black; + right: 0; + bottom: 0; + z-index: 2; +} .imageBox-fader img { position: absolute; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index e8d4be1fd..98df777cb 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,3 +1,5 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@material-ui/core'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; @@ -8,7 +10,7 @@ import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { createSchema } from '../../../fields/Schema'; import { ComputedField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; +import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; import { DashColor, emptyFunction, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils'; @@ -19,6 +21,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { Networking } from '../../Network'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../../views/ContextMenu'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; @@ -57,6 +60,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent>, addAsAnnotation: boolean) => Opt = () => undefined; + private _overlayIconRef = React.createRef(); @observable _curSuffix = ''; @observable _uploadIcon = uploadIcons.idle; @@ -131,10 +135,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent { if (de.complete.docDragData) { - if (de.metaKey) { + const targetIsBullseye = (ele: HTMLElement): boolean => { + if (!ele) return false; + if (ele === this._overlayIconRef.current) return true; + return targetIsBullseye(ele.parentElement as HTMLElement); + }; + if (de.metaKey || targetIsBullseye(e.target as HTMLElement)) { de.complete.docDragData.droppedDocuments.forEach( action((drop: Doc) => { Doc.AddDocToList(this.dataDoc, this.fieldKey + '-alternates', drop); + this.rootDoc[this.fieldKey + '-usePath'] = 'alternate:hover'; e.stopPropagation(); }) ); @@ -154,8 +164,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent (this.layoutDoc._showFullRes = !this.layoutDoc._showFullRes); - @undoBatch - setUseAlt = () => (this.layoutDoc[this.fieldKey + '-useAlt'] = !this.layoutDoc[this.fieldKey + '-useAlt']); @undoBatch setNativeSize = action(() => { @@ -239,7 +247,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent Utils.CopyText(this.choosePath(field.url)), icon: 'copy' }); if (!Doc.noviceMode) { funcs.push({ description: 'Export to Google Photos', event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: 'caret-square-right' }); @@ -356,6 +363,41 @@ export class ImageBox extends ViewBoxAnnotatableComponent + toggle between + + primary, + + + alternate, + + and show + + alternate on hover + + + }> +
setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => (this.rootDoc[`_${this.fieldKey}-usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined))} + style={{ + display: (SnappingManager.GetIsDragging() && DragManager.DocDragData?.canEmbed) || DocListCast(this.dataDoc[this.fieldKey + '-alternates']).length ? 'block' : 'none', + width: 'min(10%, 25px)', + height: 'min(10%, 25px)', + background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray', + color: usePath === undefined ? 'black' : 'white', + }}> + +
+ + ); + } @computed get paths() { const field = Cast(this.dataDoc[this.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc @@ -389,15 +431,14 @@ export class ImageBox extends ViewBoxAnnotatableComponent (this._isHovering = true))} onPointerLeave={action(() => (this._isHovering = false))} key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}>
{fadepath === srcpath ? null : ( -
+
)} @@ -405,6 +446,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent + {this.overlayImageIcon}
); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 3e60441aa..bbe38cf99 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -885,13 +885,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent() { bestTarget._dataTransition = `all ${transTime}ms`; const fkey = Doc.LayoutFieldKey(bestTarget); Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData; - bestTarget[fkey + '-useAlt'] = activeItem.presUseAlt; + bestTarget[fkey + '-usePath'] = activeItem.presUsePath; setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); } if ((pinDataTypes?.textview && activeItem.presData !== undefined) || (!pinDataTypes && activeItem.presData !== undefined)) { @@ -613,7 +613,7 @@ export class PresBox extends ViewBoxBaseComponent() { pinProps?.activeFrame !== undefined; const fkey = Doc.LayoutFieldKey(targetDoc); if (pinProps.pinData.dataview) { - pinDoc.presUseAlt = targetDoc[fkey + '-useAlt']; + pinDoc.presUsePath = targetDoc[fkey + '-usePath']; pinDoc.presData = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data; } if (pinProps.pinData.dataannos) { -- cgit v1.2.3-70-g09d2