aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts43
-rw-r--r--src/client/util/CurrentUserUtils.ts4
-rw-r--r--src/client/views/DocumentDecorations.tsx312
-rw-r--r--src/client/views/InkControlPtHandles.tsx7
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx2
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx2
-rw-r--r--src/client/views/global/globalScripts.ts14
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/PDFBox.tsx2
-rw-r--r--src/client/views/nodes/WebBox.tsx13
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx6
-rw-r--r--src/fields/Doc.ts6
15 files changed, 191 insertions, 237 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1ea9b1dcc..bd5fa5d78 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -186,8 +186,6 @@ export class DocumentOptions {
linearBtnWidth?: NUMt = new NumInfo('unexpanded width of a linear menu button (button "width" changes when it expands)', false);
_nativeWidth?: NUMt = new NumInfo('native width of document contents (e.g., the pixel width of an image)', false);
_nativeHeight?: NUMt = new NumInfo('native height of document contents (e.g., the pixel height of an image)', false);
- _nativeDimModifiable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false);
- _nativeHeightUnfrozen?: BOOLt = new BoolInfo('native height can be changed independent of width by dragging decoration resizers');
'acl-Guest'?: STRt = new StrInfo("permissions granted to users logged in as 'guest' (either view, or private)"); // public permissions
'_acl-Guest'?: string; // public permissions
@@ -229,12 +227,16 @@ export class DocumentOptions {
layout_hideLinkButton?: BOOLt = new BoolInfo('whether the blue link counter button should be hidden');
layout_hideDecorationTitle?: BOOLt = new BoolInfo('whether to suppress the document decortations title when selected');
layout_borderRounding?: string;
+ _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false);
+ _layout_reflowVertical?: BOOLt = new BoolInfo('native height can be changed independent of width by dragging decoration resizers');
+ _layout_reflowHorizontal?: BOOLt = new BoolInfo('whether a doc with a native size can be horizonally resized, causing some form of reflow');
layout_boxShadow?: string; // box-shadow css string OR "standard" to use dash standard box shadow
layout_maxAutoHeight?: NUMt = new NumInfo('maximum height for newly created (eg, from pasting) text documents', false);
_layout_autoHeight?: BOOLt = new BoolInfo('whether document automatically resizes vertically to display contents');
_layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false);
_layout_currentTimecode?: NUMt = new NumInfo('the current timecode of a time-based document (e.g., current time of a video) value is in seconds', false);
_layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown');
+ _layout_centered?: BOOLt = new BoolInfo('whether text should be vertically centered in Doc');
_layout_fitWidth?: BOOLt = new BoolInfo('whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)');
_layout_fitContentsToBox?: BOOLt = new BoolInfo('whether a freeformview should zoom/scale to create a shrinkwrapped view of its content');
_layout_fieldKey?: STRt = new StrInfo('the field key containing the current layout definition', false);
@@ -472,9 +474,9 @@ export namespace Docs {
_height: 35,
_xMargin: 10,
_yMargin: 10,
- nativeDimModifiable: true,
- nativeHeightUnfrozen: true,
- layout_forceReflow: true,
+ layout_nativeDimEditable: true,
+ layout_reflowVertical: true,
+ layout_reflowHorizontal: true,
defaultDoubleClick: 'ignore',
systemIcon: 'BsFileEarmarkTextFill',
},
@@ -505,7 +507,7 @@ export namespace Docs {
DocumentType.WEB,
{
layout: { view: WebBox, dataField: defaultDataKey },
- options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
+ options: { _height: 300, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
},
],
[
@@ -533,7 +535,7 @@ export namespace Docs {
DocumentType.AUDIO,
{
layout: { view: AudioBox, dataField: defaultDataKey },
- options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true, systemIcon: 'BsFillVolumeUpFill' },
+ options: { _height: 100, layout_fitWidth: true, layout_reflowHorizontal: true, layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' },
},
],
[
@@ -547,14 +549,14 @@ export namespace Docs {
DocumentType.PDF,
{
layout: { view: PDFBox, dataField: defaultDataKey },
- options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsFileEarmarkPdfFill' },
+ options: { _layout_curPage: 1, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, systemIcon: 'BsFileEarmarkPdfFill' },
},
],
[
DocumentType.MAP,
{
layout: { view: MapBox, dataField: defaultDataKey },
- options: { map: '', _height: 600, _width: 800, nativeDimModifiable: true, systemIcon: 'BsFillPinMapFill' },
+ options: { map: '', _height: 600, _width: 800, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillPinMapFill' },
},
],
[
@@ -613,14 +615,14 @@ export namespace Docs {
DocumentType.EQUATION,
{
layout: { view: EquationBox, dataField: 'text' },
- options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript
+ options: { layout_nativeDimEditable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript
},
],
[
DocumentType.FUNCPLOT,
{
layout: { view: FunctionPlotBox, dataField: defaultDataKey },
- options: { nativeDimModifiable: true },
+ options: { layout_nativeDimEditable: true },
},
],
[
@@ -672,12 +674,12 @@ export namespace Docs {
layout: { view: InkingStroke, dataField: 'stroke' },
options: {
systemIcon: 'BsFillPencilFill', //
- nativeDimModifiable: true,
- nativeHeightUnfrozen: true,
+ layout_nativeDimEditable: true,
+ layout_reflowVertical: true,
+ layout_reflowHorizontal: true,
layout_hideDecorationTitle: true, // don't show title when selected
fitWidth: false,
layout_isSvg: true,
- layout_forceReflow: true,
},
},
],
@@ -685,7 +687,7 @@ export namespace Docs {
DocumentType.SCREENSHOT,
{
layout: { view: ScreenshotBox, dataField: defaultDataKey },
- options: { nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsCameraFill' },
+ options: { layout_nativeDimEditable: true, systemIcon: 'BsCameraFill' },
},
],
[
@@ -714,14 +716,14 @@ export namespace Docs {
DocumentType.DATAVIZ,
{
layout: { view: DataVizBox, dataField: defaultDataKey },
- options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, nativeDimModifiable: true },
+ options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true },
},
],
[
DocumentType.LOADING,
{
layout: { view: LoadingBox, dataField: '' },
- options: { _layout_fitWidth: true, _fitHeight: true, nativeDimModifiable: true },
+ options: { _layout_fitWidth: true, _fitHeight: true, layout_nativeDimEditable: true },
},
],
[
@@ -731,11 +733,9 @@ export namespace Docs {
layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 },
options: {
_height: 100,
- layout_forceReflow: true,
- nativeHeightUnfrozen: true,
mass1: '',
mass2: '',
- nativeDimModifiable: true,
+ layout_nativeDimEditable: true,
position: '',
acceleration: '',
pendulum: '',
@@ -948,7 +948,7 @@ export namespace Docs {
export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) {
const imgField = url instanceof ImageField ? url : new ImageField(url);
- return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { _nativeDimModifiable: false, _nativeHeightUnfrozen: false, title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
+ return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
}
export function PresDocument(options: DocumentOptions = {}) {
@@ -1864,6 +1864,7 @@ export namespace DocUtils {
_height: 35,
x: x,
y: y,
+ _layout_centered: BoolCast(Doc.UserDoc().layout_centered),
_layout_fitWidth: true,
_layout_autoHeight: true,
_layout_enableAltContentUI: BoolCast(Doc.UserDoc().defaultToFlashcards),
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index cd19daee5..ac506e2d6 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -655,13 +655,13 @@ export class CurrentUserUtils {
{ title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", toolType:"underline",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "Bullets", toolTip: "Bullet List", btnType: ButtonType.ToggleButton, icon: "list", toolType:"bullet", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "#", toolTip: "Number List", btnType: ButtonType.ToggleButton, icon: "list-ol", toolType:"decimal", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+ { title: "Vcenter", toolTip: "Vertical center", btnType: ButtonType.ToggleButton, icon: "pallet", toolType:"vcent", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "Align", toolTip: "Alignment", btnType: ButtonType.MultiToggleButton, toolType:"alignment", ignoreClick: true,
subMenu: [
{ title: "Left", toolTip: "Left align (Cmd-[)", btnType: ButtonType.ToggleButton, icon: "align-left", toolType:"left", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}' }},
{ title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
- ]
- },
+ ]},
{ title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}},
{ title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink", expertMode:true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
// { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 33886e791..8df5740fa 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -2,18 +2,17 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { IconButton } from 'browndash-components';
-import { action, computed, observable, reaction } from 'mobx';
+import { action, computed, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
-import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
import { InkField } from '../../fields/InkField';
import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
-import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
-import { aggregateBounds, emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
+import { emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
import { Docs } from '../documents/Documents';
import { DocumentType } from '../documents/DocumentTypes';
import { DocumentManager } from '../util/DocumentManager';
@@ -36,6 +35,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { ImageBox } from './nodes/ImageBox';
import React = require('react');
import _ = require('lodash');
+import { DateField } from '../../fields/DateField';
@observer
export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
@@ -46,11 +46,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
private _linkBoxHeight = 20 + 3; // link button height + margin
private _titleHeight = 20;
private _resizeUndo?: UndoManager.Batch;
- private _offX = 0;
- private _offY = 0; // offset from click pt to inner edge of resize border
- private _snapX = 0;
- private _snapY = 0; // last snapped location of resize border
- private _dragHeights = new Map<Doc, { start: number; lowest: number }>();
+ private _offset = { x: 0, y: 0 }; // offset from click pt to inner edge of resize border
+ private _snapPt = { x: 0, y: 0 }; // last snapped location of resize border
private _inkDragDocs: { doc: Doc; x: number; y: number; width: number; height: number }[] = [];
@observable private _accumulatedTitle = '';
@@ -479,29 +476,24 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
DocumentView.Interacting = true; // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
this._resizeHdlId = e.currentTarget.className;
const bounds = e.currentTarget.getBoundingClientRect();
- this._offX = this._resizeHdlId.toLowerCase().includes('left') ? bounds.right - e.clientX : bounds.left - e.clientX;
- this._offY = this._resizeHdlId.toLowerCase().includes('top') ? bounds.bottom - e.clientY : bounds.top - e.clientY;
+ this._offset = { x: this._resizeHdlId.toLowerCase().includes('left') ? bounds.right - e.clientX : bounds.left - e.clientX, y: this._resizeHdlId.toLowerCase().includes('top') ? bounds.bottom - e.clientY : bounds.top - e.clientY };
this._resizeUndo = UndoManager.StartBatch('drag resizing');
- this._snapX = e.pageX;
- this._snapY = e.pageY;
- const ffviewSet = new Set<CollectionFreeFormView>();
- SelectionManager.Views().forEach(docView => {
- docView.CollectionFreeFormView && ffviewSet.add(docView.CollectionFreeFormView);
- this._dragHeights.set(docView.layoutDoc, { start: NumCast(docView.rootDoc._height), lowest: NumCast(docView.rootDoc._height) });
- });
- Array.from(ffviewSet).map(ffview => ffview.dragStarting(false, false));
+ this._snapPt = { x: e.pageX, y: e.pageY };
+ SelectionManager.Views().forEach(docView => docView.CollectionFreeFormView?.dragStarting(false, false));
};
+ _lock: any;
onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
const first = SelectionManager.Views()[0];
const effectiveAcl = GetEffectiveAcl(first.rootDoc);
if (!(effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment)) return false;
if (!first) return false;
- let thisPt = { x: e.clientX - this._offX, y: e.clientY - this._offY };
+ let thisPt = { x: e.clientX - this._offset.x, y: e.clientY - this._offset.y };
var fixedAspect = Doc.NativeAspect(first.layoutDoc);
+ const dragHdl = this._resizeHdlId.split(' ')[0].replace('documentDecorations-', '').replace('Resizer', '');
- const resizeHdl = this._resizeHdlId.split(' ')[0];
- if (fixedAspect && (resizeHdl === 'documentDecorations-bottomRightResizer' || resizeHdl === 'documentDecorations-topLeftResizer')) {
+ // do snapping of drag point
+ if (fixedAspect && (dragHdl === 'bottomRight' || dragHdl === 'topLeft')) {
// need to generalize for bl and tr drag handles
const project = (p: number[], a: number[], b: number[]) => {
const atob = [b[0] - a[0], b[1] - a[1]];
@@ -513,173 +505,124 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
return [a[0] + atob[0] * t, a[1] + atob[1] * t];
};
const tl = first.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
- const drag = project([e.clientX + this._offX, e.clientY + this._offY], tl, [tl[0] + fixedAspect, tl[1] + 1]);
+ const drag = project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]);
thisPt = DragManager.snapDragAspect(drag, fixedAspect);
} else {
- thisPt = DragManager.snapDrag(e, -this._offX, -this._offY, this._offX, this._offY);
+ thisPt = DragManager.snapDrag(e, -this._offset.x, -this._offset.y, this._offset.x, this._offset.y);
}
- move[0] = thisPt.x - this._snapX;
- move[1] = thisPt.y - this._snapY;
- this._snapX = thisPt.x;
- this._snapY = thisPt.y;
- let dragBottom = false,
- dragRight = false,
- dragBotRight = false,
- dragTop = false;
- let dXin = 0,
- dYin = 0,
- dWin = 0,
- dHin = 0;
- switch (this._resizeHdlId.split(' ')[0]) {
- case '':
- break;
- case 'documentDecorations-topLeftResizer':
- dXin = -1;
- dYin = -1;
- dWin = -move[0];
- dHin = -move[1];
- break;
- case 'documentDecorations-topRightResizer':
- dWin = move[0];
- dYin = -1;
- dHin = -move[1];
- break;
- case 'documentDecorations-topResizer':
- dYin = -1;
- dHin = -move[1];
- dragTop = true;
- break;
- case 'documentDecorations-bottomLeftResizer':
- dXin = -1;
- dWin = -move[0];
- dHin = move[1];
- break;
- case 'documentDecorations-bottomRightResizer':
- dWin = move[0];
- dHin = move[1];
- dragBotRight = true;
- break;
- case 'documentDecorations-bottomResizer':
- dHin = move[1];
- dragBottom = true;
- break;
- case 'documentDecorations-leftResizer':
- dXin = -1;
- dWin = -move[0];
- break;
- case 'documentDecorations-rightResizer':
- dWin = move[0];
- dragRight = true;
- break;
- }
+ const { scale, refPt } = this.getResizeVals(thisPt, dragHdl);
+ // resize selected docs
+ !this._lock && runInAction(async () => {
+ this._lock = true;
+ this._snapPt = thisPt;
+ e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.props.Document) && docView.toggleNativeDimensions()));
+ const fixedAspect = SelectionManager.Docs().some(this.hasFixedAspect);
+ SelectionManager.Views().forEach(docView =>
+ this.resizeView(docView, refPt, scale.x === 1 && fixedAspect ? scale.y : scale.x,
+ scale.x !== 1 && fixedAspect ? scale.x : scale.y, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore
+ await new Promise<any>(res => setTimeout(() => res(this._lock = undefined)));
+ }); // prettier-ignore
- const isGroup = first.rootDoc._isGroup ? first.rootDoc : undefined;
- const scaleViews = isGroup ? DocListCast(isGroup.data).map(doc => DocumentManager.Instance.getFirstDocumentView(doc)!) : SelectionManager.Views();
- const aggBounds = aggregateBounds(scaleViews.map(view => view.rootDoc) as any, 0, 0);
- const refWidth = aggBounds.r - aggBounds.x;
- const refHeight = aggBounds.b - aggBounds.y;
- const scaleRefPt = first.props
- .ScreenToLocalTransform()
- .inverse()
- .transformPoint(
- NumCast(isGroup?._xPadding) + (dXin ? refWidth : 0), //
- NumCast(isGroup?._yPadding) + (dYin ? refHeight : 0)
- );
- scaleViews.forEach(
- action((docView: DocumentView) => {
- if (e.ctrlKey && !Doc.NativeHeight(docView.props.Document)) docView.toggleNativeDimensions();
- if (dXin !== 0 || dYin !== 0 || dWin !== 0 || dHin !== 0) {
- const doc = docView.rootDoc;
- const refCent = docView.props.ScreenToLocalTransform().transformPoint(scaleRefPt[0], scaleRefPt[1]);
-
- if (doc.nativeHeightUnfrozen && !NumCast(doc.nativeHeight) && doc._nativeWidth !== undefined) {
- doc._nativeHeight = (NumCast(doc._height) / NumCast(doc._width, 1)) * docView.nativeWidth;
- }
- const nwidth = docView.nativeWidth;
- const nheight = docView.nativeHeight;
- const docwidth = NumCast(doc._width);
- let docheight = (hgt => (!hgt || isNaN(hgt) ? 20 : hgt))(NumCast(doc._height) || (nheight / nwidth) * docwidth);
- let dW = docwidth * (dWin / refWidth);
- let dH = docheight * (dHin / refHeight);
- const scale = docView.props.ScreenToLocalTransform().Scale;
- const modifyNativeDim = (e.ctrlKey && doc.nativeDimModifiable) || (doc.layout_forceReflow && !dragBottom && !dragTop) || (doc.nativeHeightUnfrozen && (dragBottom || dragTop || e.ctrlKey));
- if (nwidth && nheight) {
- if (nwidth / nheight !== docwidth / docheight && !dragBottom && !dragTop) {
- docheight = (nheight / nwidth) * docwidth;
- }
- if (modifyNativeDim && !dragBottom && !dragTop) {
- // ctrl key enables modification of the nativeWidth or nativeHeight durin the interaction
- if (Math.abs(dW) > Math.abs(dH)) dH = (dW * nheight) / nwidth;
- else dW = (dH * nwidth) / nheight;
- }
- }
- let actualdW = Math.max(docwidth + dW * scale, 20);
- let actualdH = Math.max(docheight + dH * scale, 20);
- let dX = !dWin ? 0 : (scale * refCent[0] * -dWin) / refWidth;
- let dY = !dHin ? 0 : (scale * refCent[1] * -dHin) / refHeight;
- const preserveNativeDim = !doc._nativeHeightUnfrozen && !doc._nativeDimModifiable;
- const fixedAspect = nwidth && nheight && (!doc._layout_fitWidth || preserveNativeDim || e.ctrlKey || doc.nativeHeightUnfrozen || doc.nativeDimModifiable);
- if (fixedAspect) {
- if ((Math.abs(dW) > Math.abs(dH) && ((!dragBottom && !dragTop) || !modifyNativeDim)) || dragRight) {
- if (dragRight && modifyNativeDim) {
- if (Doc.NativeWidth(doc)) {
- doc._nativeWidth = (actualdW / (docwidth || 1)) * Doc.NativeWidth(doc);
- }
- } else {
- if (!doc._layout_fitWidth || preserveNativeDim) {
- actualdH = (nheight / nwidth) * actualdW;
- dYin && (dY = -dW * scale * (nheight / nwidth));
- doc._height = actualdH;
- } else if (!modifyNativeDim || dragBotRight) {
- doc._height = actualdH;
- }
- }
- doc._width = actualdW;
- } else {
- if ((dragBottom || dragTop) && (modifyNativeDim || (docView.layoutDoc.nativeHeightUnfrozen && docView.layoutDoc._layout_fitWidth))) {
- // frozen web pages, PDFs, and some RTFS have frozen nativewidth/height. But they are marked to allow their nativeHeight
- // to be explicitly modified with fitWidth and vertical resizing. (ie, with fitWidth they can't grow horizontally to match
- // a vertical resize so it makes more sense to change their nativeheight even if the ctrl key isn't used)
- doc._nativeHeight = (actualdH / (docheight || 1)) * Doc.NativeHeight(doc);
- doc._layout_autoHeight = false;
- } else {
- if (!doc._layout_fitWidth || preserveNativeDim) {
- actualdW = (nwidth / nheight) * actualdH;
- dXin && (dX = -dH * scale * (nwidth / nheight));
- doc._width = actualdW;
- } else if (!modifyNativeDim || dragBotRight) {
- doc._width = actualdW;
- }
- }
- if (!modifyNativeDim) {
- actualdH = (nheight / nwidth) * NumCast(doc._width); //, actualdH);
- }
- doc._height = actualdH;
- }
- } else {
- const rotCtr = [docwidth / 2, docheight / 2];
- const tlRotated = Utils.rotPt(-rotCtr[0], -rotCtr[1], (NumCast(doc._rotation) / 180) * Math.PI);
-
- const maxHeight = doc.nativeHeightUnfrozen || !nheight ? 0 : Math.max(nheight, NumCast(doc.scrollHeight, NumCast(doc[docView.LayoutFieldKey + '_scrollHeight']))) * docView.NativeDimScaling();
- dH && (doc._height = actualdH > maxHeight && maxHeight ? maxHeight : actualdH);
- dW && (doc._width = actualdW);
- dH && (doc._layout_autoHeight = false);
-
- const rotCtr2 = [NumCast(doc._width) / 2, NumCast(doc._height) / 2];
- const tlRotated2 = Utils.rotPt(-rotCtr2[0], -rotCtr2[1], (NumCast(doc._rotation) / 180) * Math.PI);
- doc.x = NumCast(doc.x) + tlRotated.x + rotCtr[0] - (tlRotated2.x + rotCtr2[0]); // doc shifts by amount topleft moves because rotation is about center of doc
- doc.y = NumCast(doc.y) + tlRotated.y + rotCtr[1] - (tlRotated2.y + rotCtr2[1]);
- }
- doc.x = NumCast(doc.x) + dX;
- doc.y = NumCast(doc.y) + dY;
- doc._layout_modificationDate = new DateField();
+ return false;
+ };
+
+ //
+ // determines how much to resize, and determines the resize reference point
+ //
+ getResizeVals = (thisPt: { x: number; y: number }, dragHdl: string) => {
+ const [w, h] = [this.Bounds.r - this.Bounds.x, this.Bounds.b - this.Bounds.y];
+ const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y];
+ switch (dragHdl) {
+ case 'topLeft': return { scale: { x: 1 - moveX / w, y: 1 -moveY / h }, refPt: [this.Bounds.r, this.Bounds.b] };
+ case 'topRight': return { scale: { x: 1 + moveX / w, y: 1 -moveY / h }, refPt: [this.Bounds.x, this.Bounds.b] };
+ case 'top': return { scale: { x: 1, y: 1 -moveY / h }, refPt: [this.Bounds.x, this.Bounds.b] };
+ case 'left': return { scale: { x: 1 - moveX / w, y: 1 }, refPt: [this.Bounds.r, this.Bounds.y] };
+ case 'bottomLeft': return { scale: { x: 1 - moveX / w, y: 1 + moveY / h }, refPt: [this.Bounds.r, this.Bounds.y] };
+ case 'right': return { scale: { x: 1 + moveX / w, y: 1 }, refPt: [this.Bounds.x, this.Bounds.y] };
+ case 'bottomRight':return { scale: { x: 1 + moveX / w, y: 1 + moveY / h }, refPt: [this.Bounds.x, this.Bounds.y] };
+ case 'bottom': return { scale: { x: 1, y: 1 + moveY / h }, refPt: [this.Bounds.x, this.Bounds.y] };
+ default: return { scale: { x: 1, y: 1 }, refPt: [this.Bounds.x, this.Bounds.y] };
+ } // prettier-ignore
+ };
+
+ //
+ // determines if anything being dragged directly or via a group has a fixed aspect ratio (in which case we resize uniformly)
+ //
+ hasFixedAspect = (doc: Doc): boolean => (doc.isGroup ? DocListCast(doc.data).some(this.hasFixedAspect) : !BoolCast(doc.layout_nativeDimEditable));
+
+ //
+ // resize a single DocumentView about the specified reference point, possibly setting/updating the native dimensions of the Doc
+ //
+ resizeView = (docView: DocumentView, refPt: number[], scaleX: number, scaleY: number, opts: { dragHdl: string; ctrlKey: boolean }) => {
+ const doc = docView.rootDoc;
+ if (doc.isGroup) {
+ DocListCast(doc.data)
+ .map(member => DocumentManager.Instance.getDocumentView(member, docView)!)
+ .forEach(member => this.resizeView(member, refPt, scaleX, scaleY, opts));
+ doc.xPadding = NumCast(doc.xPadding) * scaleX;
+ doc.yPadding = NumCast(doc.yPadding) * scaleY;
+ } else {
+ const doc = docView.rootDoc;
+ const refCent = docView.props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
+ const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight];
+ const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)];
+
+ const modifyNativeDim =
+ (opts.ctrlKey && doc.layout_nativeDimEditable) || // e.g., PDF or web page
+ (doc.layout_reflowHorizontal && opts.dragHdl !== 'bottom' && opts.dragHdl !== 'top') || // eg rtf or some web pages
+ (doc.layout_reflowVertical && (opts.dragHdl === 'bottom' || opts.dragHdl === 'top' || opts.ctrlKey)); // eg rtf, web, pdf
+ if (nwidth && nheight && !modifyNativeDim) {
+ // eg., dragging right resizer on PDF -- enforce native dimensions because not expliclty overridden with ctrl or bottom resize drag
+ scaleX === 1 ? (scaleX = scaleY) : (scaleY = scaleX);
+ }
+
+ if (['right', 'left'].includes(opts.dragHdl) && modifyNativeDim && Doc.NativeWidth(doc)) {
+ const setData = Doc.NativeWidth(Doc.GetProto(doc)) === doc.nativeWidth;
+ doc.nativeWidth = scaleX * Doc.NativeWidth(doc);
+ if (setData) Doc.SetNativeWidth(Doc.GetProto(doc), NumCast(doc.nativeWidth));
+ if (doc.layout_reflowVertical && !NumCast(doc.nativeHeight)) {
+ doc._nativeHeight = (initHeight / initWidth) * nwidth; // initializes the nativeHeight for a PDF
}
- const val = this._dragHeights.get(docView.layoutDoc);
- if (val) this._dragHeights.set(docView.layoutDoc, { start: val.start, lowest: Math.min(val.lowest, NumCast(docView.layoutDoc._height)) });
- })
+ }
+ if (['bottom', 'top'].includes(opts.dragHdl) && modifyNativeDim && Doc.NativeHeight(doc)) {
+ const setData = Doc.NativeHeight(Doc.GetProto(doc)) === doc.nativeHeight;
+ doc._nativeHeight = scaleY * Doc.NativeHeight(doc);
+ if (setData) Doc.SetNativeHeight(Doc.GetProto(doc), NumCast(doc._nativeHeight));
+ }
+
+ doc._width = NumCast(doc._width) * scaleX;
+ doc._height = NumCast(doc._height) * scaleY;
+ const { deltaX, deltaY } = this.realignRefPt(doc, refCent, initWidth, initHeight);
+ doc.x = NumCast(doc.x) + deltaX;
+ doc.y = NumCast(doc.y) + deltaY;
+
+ doc._layout_modificationDate = new DateField();
+ scaleY !== 1 && (doc._layout_autoHeight = undefined);
+ }
+ };
+
+ // This realigns the doc's resize reference point with where it was before resizing it.
+ // This is needed, because the transformation for doc's with a rotation is screwy:
+ // the top left of the doc is the 'origin', but the rotation happens about the center of the Doc.
+ // So resizing a rotated doc will cause it to shift -- this counteracts that shift by determine how
+ // the reference points shifted, and returning a translation to restore the reference point.
+ realignRefPt = (doc: Doc, refCent: number[], initWidth: number, initHeight: number) => {
+ const refCentPct = [refCent[0] / initWidth, refCent[1] / initHeight];
+ const rotRefStart = Utils.rotPt(
+ refCent[0] - initWidth / 2, // rotate reference pointe before scaling
+ refCent[1] - initHeight / 2,
+ (NumCast(doc._rotation) / 180) * Math.PI
);
- return false;
+ const rotRefEnd = Utils.rotPt(
+ refCentPct[0] * NumCast(doc._width) - NumCast(doc._width) / 2, // rotate reference point after scaling
+ refCentPct[1] * NumCast(doc._height) - NumCast(doc._height) / 2,
+ (NumCast(doc._rotation) / 180) * Math.PI
+ );
+ return {
+ deltaX: rotRefStart.x + initWidth / 2 - (rotRefEnd.x + NumCast(doc._width) / 2), //
+ deltaY: rotRefStart.y + initHeight / 2 - (rotRefEnd.y + NumCast(doc._height) / 2),
+ };
};
@action
@@ -691,10 +634,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
SnappingManager.clearSnapLines();
// detect layout_autoHeight gesture and apply
- SelectionManager.Views()
- .map(docView => ({ doc: docView.layoutDoc, hgts: this._dragHeights.get(docView.layoutDoc) }))
- .filter(pair => pair.hgts && pair.hgts.lowest < pair.hgts.start && pair.hgts.lowest <= 20)
- .forEach(pair => (pair.doc._layout_autoHeight = true));
+ SelectionManager.Docs().forEach(doc => NumCast(doc._height) < 20 && (doc._layout_autoHeight = true));
//need to change points for resize, or else rotation/control points will fail.
this._inkDragDocs
.map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] }))
diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx
index 0d7f7ebd8..e5141b7f4 100644
--- a/src/client/views/InkControlPtHandles.tsx
+++ b/src/client/views/InkControlPtHandles.tsx
@@ -12,6 +12,7 @@ import { UndoManager } from '../util/UndoManager';
import { Colors } from './global/globalEnums';
import { InkingStroke } from './InkingStroke';
import { InkStrokeProperties } from './InkStrokeProperties';
+import { SnappingManager } from '../util/SnappingManager';
export interface InkControlProps {
inkDoc: Doc;
@@ -190,6 +191,7 @@ export class InkEndPtHandles extends React.Component<InkEndProps> {
@action
dragRotate = (e: React.PointerEvent, pt1: () => { X: number; Y: number }, pt2: () => { X: number; Y: number }) => {
+ SnappingManager.SetIsDragging(true);
setupMoveUpEvents(
this,
e,
@@ -211,6 +213,7 @@ export class InkEndPtHandles extends React.Component<InkEndProps> {
return false;
}),
action(() => {
+ SnappingManager.SetIsDragging(false);
this.props.inkView.controlUndo?.end();
this.props.inkView.controlUndo = undefined;
UndoManager.FilterBatches(['stroke', 'x', 'y', 'width', 'height']);
@@ -237,8 +240,8 @@ export class InkEndPtHandles extends React.Component<InkEndProps> {
);
return (
<svg>
- {hdl('start', this.props.startPt(), (e: React.PointerEvent) => this.dragRotate(e, this.props.startPt, this.props.endPt))}
- {hdl('end', this.props.endPt(), (e: React.PointerEvent) => this.dragRotate(e, this.props.endPt, this.props.startPt))}
+ {hdl('start', this.props.startPt(), e => this.dragRotate(e, this.props.startPt, this.props.endPt))}
+ {hdl('end', this.props.endPt(), e => this.dragRotate(e, this.props.endPt, this.props.startPt))}
</svg>
);
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a6f0b9e84..5bed0f923 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -252,6 +252,7 @@ export class MainView extends React.Component {
fa.faShare,
fa.faTaxi,
fa.faDownload,
+ fa.faPallet,
fa.faExpandArrowsAlt,
fa.faAmbulance,
fa.faLayerGroup,
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 81453c0b8..c2586fb4b 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -295,7 +295,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
const aspect = Doc.NativeAspect(layout, undefined, true);
const width = () => this.lookupPixels(layout);
const height = () => PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
- const docwidth = () => (layout._layout_forceReflow ? width() : Math.min(height() * aspect, width()));
+ const docwidth = () => (layout._layout_reflowHorizontal ? width() : Math.min(height() * aspect, width()));
const docheight = () => Math.min(docwidth() / aspect, height());
const dxf = () =>
this.lookupIndividualTransform(layout)
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 04cfc5456..249c3551b 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -292,7 +292,7 @@ export class CollectionMultirowView extends CollectionSubView() {
const height = () => this.lookupPixels(layout);
const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
const docheight = () => Math.min(width() / aspect, height());
- const docwidth = () => (layout._layout_forceReflow ? width() : Math.min(width(), docheight() * aspect));
+ const docwidth = () => (layout._layout_reflowHorizontal ? width() : Math.min(width(), docheight() * aspect));
const dxf = () =>
this.lookupIndividualTransform(layout)
.translate(-NumCast(Document._xMargin) - (width() - docwidth()) / 2, -NumCast(Document._yMargin) - (height() - docheight()) / 2)
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index c690b8623..3af523d73 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -181,16 +181,22 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
map.get(attr)?.setDoc?.();
});
-type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'bullet' | 'decimal';
+type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'vcent' | 'bullet' | 'decimal';
type attrfuncs = [attrname, { checkResult: () => boolean; toggle: () => any }];
ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: boolean) {
const textView = RichTextMenu.Instance?.TextView;
const editorView = textView?.EditorView;
// prettier-ignore
- const alignments:attrfuncs[] = (['left','right','center'] as ("left"|"center"|"right")[]).map((where) =>
- [ where, { checkResult: () =>(editorView ? (RichTextMenu.Instance.textAlign ===where): (Doc.UserDoc().textAlign ===where) ? true:false),
- toggle: () => (editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, where):(Doc.UserDoc().textAlign = where))}]);
+ const alignments:attrfuncs[] = (['left','right','center','vcent'] as ("left"|"center"|"right"|"vcent")[]).map((where) =>
+ [ where, { checkResult: () =>(editorView ? (where === 'vcent' ? SelectionManager.Docs().some(doc => doc.layout_centered):
+ (RichTextMenu.Instance.textAlign === where)):
+ where === 'vcent' ? BoolCast(Doc.UserDoc().layout_centered):
+ (Doc.UserDoc().textAlign ===where) ? true:false),
+ toggle: () => (editorView?.state ? (where === 'vcent' ? SelectionManager.Docs().forEach(doc => doc.layout_centered = !doc.layout_centered):
+ RichTextMenu.Instance.align(editorView, editorView.dispatch, where)):
+ where === 'vcent' ? Doc.UserDoc().layout_centered = !Doc.UserDoc().layout_centered:
+ (Doc.UserDoc().textAlign = where))}]); // prettier-ignore
// prettier-ignore
const listings:attrfuncs[] = (['bullet','decimal'] as attrname[]).map(list =>
[ list, { checkResult: () => (editorView ? RichTextMenu.Instance.getActiveListStyle() === list:false),
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index a05d6c904..582a5518a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -62,7 +62,7 @@ export class CollectionFreeFormDocumentViewWrapper extends DocComponent<Collecti
w_Y = () => this.Y; // prettier-ignore
w_Z = () => this.Z; // prettier-ignore
w_ZIndex = () => this.ZIndex ?? NumCast(this.props.Document.zIndex); // prettier-ignore
- w_Rot = () => this.Rotation ?? NumCast(this.props.Document._rotation); // prettier-ignore
+ w_Rotation = () => this.Rotation ?? NumCast(this.props.Document._rotation); // prettier-ignore
w_Opacity = () => this.Opacity; // prettier-ignore
w_BackgroundColor = () => this.BackgroundColor ?? Cast(this.props.Document._backgroundColor, 'string', null); // prettier-ignore
w_Color = () => this.Color ?? Cast(this.props.Document._color, 'string', null); // prettier-ignore
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 299494c83..b3f813eda 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -115,8 +115,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
layoutDoc: this.layoutDoc,
records: this.records,
axes: this.axes,
- height: (this.props.PanelHeight() - 32) /* height of 'change view' button */ * 0.9,
- width: this.props.PanelWidth() * 0.9,
+ height: (this.props.PanelHeight() * (this.props.NativeDimScaling?.() || 1) - 32) /* height of 'change view' button */ * 0.9,
+ width: this.props.PanelWidth() * (this.props.NativeDimScaling?.() || 1) * 0.9,
margin: { top: 10, right: 25, bottom: 75, left: 45 },
};
if (!this.records.length) return 'no data/visualization';
@@ -133,6 +133,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
render() {
+ const scale = this.props.NativeDimScaling?.() || 1;
+
return !this.records.length ? (
// displays how to get data into the DataVizBox if its empty
<div className="start-message">To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command 'ctrl + p' to bring the data table to your canvas.</div>
@@ -141,6 +143,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
className="dataViz"
style={{
pointerEvents: this.props.isContentActive() === true ? 'all' : 'none',
+ width: `${100 / scale}%`,
+ height: `${100 / scale}%`,
+ transform: `scale(${scale})`,
+ position: 'absolute',
}}
onWheel={e => e.stopPropagation()}
ref={r =>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d1caf0acf..e3d6c3fdf 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1495,7 +1495,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.effectiveNativeWidth ? this.effectiveNativeWidth * this.nativeScaling : this.props.PanelWidth();
}
@computed get panelHeight() {
- if (this.effectiveNativeHeight && (!this.layout_fitWidth || !this.layoutDoc.nativeHeightUnfrozen)) {
+ if (this.effectiveNativeHeight && (!this.layout_fitWidth || !this.layoutDoc.layout_reflowVertical)) {
return Math.min(this.props.PanelHeight(), this.effectiveNativeHeight * this.nativeScaling);
}
return this.props.PanelHeight();
@@ -1507,7 +1507,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.effectiveNativeWidth &&
this.effectiveNativeHeight &&
Math.abs(this.Xshift) < 0.001 &&
- (!this.layoutDoc.nativeHeightUnfrozen || (!this.layout_fitWidth && this.effectiveNativeHeight * this.nativeScaling <= this.props.PanelHeight()))
+ (!this.layoutDoc.layout_reflowVertical || (!this.layout_fitWidth && this.effectiveNativeHeight * this.nativeScaling <= this.props.PanelHeight()))
? Math.max(0, (this.props.PanelHeight() - this.effectiveNativeHeight * this.nativeScaling) / 2)
: 0;
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index bde1d5fa4..185c6553a 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -347,7 +347,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = action((preview: boolean = false) => {
const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
- const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth + PDFBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth;
+ const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth + PDFBox.sidebarResizerWidth : 0) + NumCast(this.layoutDoc._width)) / NumCast(this.layoutDoc._width);
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
if (preview) {
this._previewNativeWidth = nativeWidth * sideratio;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index a452b1cdd..d9ea48c3b 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -707,10 +707,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
icon: 'snowflake',
});
funcs.push({
- description: (!this.layoutDoc.layout_forceReflow ? 'Force' : 'Prevent') + ' Reflow',
+ description: (!this.layoutDoc.layout_reflowHorizontal ? 'Force' : 'Prevent') + ' Reflow',
event: () => {
- const nw = !this.layoutDoc.layout_forceReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.NativeDimScaling?.() || 1);
- this.layoutDoc.layout_forceReflow = !nw;
+ const nw = !this.layoutDoc.layout_reflowHorizontal ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.NativeDimScaling?.() || 1);
+ this.layoutDoc.layout_reflowHorizontal = !nw;
if (nw) {
Doc.SetInPlace(this.layoutDoc, this.fieldKey + '_nativeWidth', nw, true);
}
@@ -872,13 +872,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = action((preview: boolean = false) => {
var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
if (!nativeWidth) {
- const defaultNativeWidth = this.rootDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width);
+ const defaultNativeWidth = NumCast(this.rootDoc.nativeWidth, this.rootDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width));
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (NumCast(this.Document._height) / NumCast(this.Document._width)) * defaultNativeWidth);
nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
}
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
- const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth + WebBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth;
+ const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth + WebBox.sidebarResizerWidth : 0) + NumCast(this.layoutDoc.width)) / NumCast(this.layoutDoc.width);
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
if (preview) {
this._previewNativeWidth = nativeWidth * sideratio;
@@ -890,6 +890,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (!this.layoutDoc._layout_showSidebar && !(this.dataDoc[this.fieldKey] instanceof WebField)) {
this.layoutDoc.nativeWidth = this.dataDoc[this.fieldKey + '_nativeWidth'] = undefined;
} else {
+ !this.layoutDoc._layout_showSidebar && (this.dataDoc[this.fieldKey + '_nativeWidth'] = this.dataDoc[this.fieldKey + '_nativeHeight'] = undefined);
this.layoutDoc.nativeWidth = nativeWidth * pdfratio;
}
}
@@ -917,7 +918,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
className={'webBox-cont' + (interactive ? '-interactive' : '')}
onKeyDown={e => e.stopPropagation()}
style={{
- width: !this.layoutDoc.layout_forceReflow ? NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']) || `100%` : '100%',
+ width: !this.layoutDoc.layout_reflowHorizontal ? NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']) || `100%` : '100%',
transform: `scale(${this.zoomScaling()}) translate(${-NumCast(this.layoutDoc.freeform_panX)}px, ${-NumCast(this.layoutDoc.freeform_panY)}px)`,
}}>
{this._hackHide ? null : this.urlContent}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 9ab3189a6..a80c1e030 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -704,14 +704,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
@action
toggleSidebar = (preview: boolean = false) => {
+ const defaultSidebar = 250;
const prevWidth = 1 - this.sidebarWidth() / Number(getComputedStyle(this._ref.current!).width.replace('px', ''));
if (preview) this._showSidebar = true;
else {
this.layoutDoc[this.SidebarKey + '_freeform_scale_max'] = 1;
- this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%';
+ this.layoutDoc._layout_showSidebar =
+ (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(defaultSidebar / (NumCast(this.layoutDoc._width) + defaultSidebar)) * 100}%` : '0%') !== '0%';
}
- this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) * prevWidth);
+ this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) + defaultSidebar : Math.max(20, NumCast(this.layoutDoc._width) * prevWidth);
};
sidebarDown = (e: React.PointerEvent) => {
const batch = UndoManager.StartBatch('toggle sidebar');
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 6dece87b5..e91fcd858 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1295,17 +1295,11 @@ export namespace Doc {
layoutDoc._freeform_scale = NumCast(layoutDoc._freeform_scale, 1) * contentScale;
layoutDoc._nativeWidth = undefined;
layoutDoc._nativeHeight = undefined;
- layoutDoc._layout_forceReflow = undefined;
- layoutDoc._nativeHeightUnfrozen = undefined;
- layoutDoc._nativeDimModifiable = undefined;
} else {
layoutDoc._layout_autoHeight = false;
if (!Doc.NativeWidth(layoutDoc)) {
layoutDoc._nativeWidth = NumCast(layoutDoc._width, panelWidth);
layoutDoc._nativeHeight = NumCast(layoutDoc._height, panelHeight);
- layoutDoc._layout_forceReflow = true;
- layoutDoc._nativeHeightUnfrozen = true;
- layoutDoc._nativeDimModifiable = true;
}
}
});