diff options
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 112 |
1 files changed, 66 insertions, 46 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 042e8f6d0..2811c96eb 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -12,7 +12,7 @@ import { InkField } from '../../fields/InkField'; import { ScriptField } from '../../fields/ScriptField'; import { Cast, NumCast, StrCast } from '../../fields/Types'; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils'; +import { aggregateBounds, emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils'; import { Docs } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; @@ -34,6 +34,7 @@ import React = require('react'); import { RichTextField } from '../../fields/RichTextField'; import { LinkFollower } from '../util/LinkFollower'; import _ = require('lodash'); +import { DocumentManager } from '../util/DocumentManager'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { @@ -509,73 +510,86 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P dragRight = false, dragBotRight = false, dragTop = false; - let dX = 0, - dY = 0, - dW = 0, - dH = 0; + let dXin = 0, + dYin = 0, + dWin = 0, + dHin = 0; switch (this._resizeHdlId.split(' ')[0]) { case '': break; case 'documentDecorations-topLeftResizer': - dX = -1; - dY = -1; - dW = -move[0]; - dH = -move[1]; + dXin = -1; + dYin = -1; + dWin = -move[0]; + dHin = -move[1]; break; case 'documentDecorations-topRightResizer': - dW = move[0]; - dY = -1; - dH = -move[1]; + dWin = move[0]; + dYin = -1; + dHin = -move[1]; break; case 'documentDecorations-topResizer': - dY = -1; - dH = -move[1]; + dYin = -1; + dHin = -move[1]; dragTop = true; break; case 'documentDecorations-bottomLeftResizer': - dX = -1; - dW = -move[0]; - dH = move[1]; + dXin = -1; + dWin = -move[0]; + dHin = move[1]; break; case 'documentDecorations-bottomRightResizer': - dW = move[0]; - dH = move[1]; + dWin = move[0]; + dHin = move[1]; dragBotRight = true; break; case 'documentDecorations-bottomResizer': - dH = move[1]; + dHin = move[1]; dragBottom = true; break; case 'documentDecorations-leftResizer': - dX = -1; - dW = -move[0]; + dXin = -1; + dWin = -move[0]; break; case 'documentDecorations-rightResizer': - dW = move[0]; + dWin = move[0]; dragRight = true; break; } - SelectionManager.Views().forEach( + 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 (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { - const doc = Document(docView.rootDoc); + 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._nativeHeight = (NumCast(doc._height) / NumCast(doc._width, 1)) * docView.nativeWidth; } const nwidth = docView.nativeWidth; const nheight = docView.nativeHeight; - let docheight = doc._height || 0; - let docwidth = doc._width || 0; - const width = docwidth; - let height = docheight || (nheight / nwidth) * width; - height = !height || isNaN(height) ? 20 : height; + 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.forceReflow) && doc.nativeDimModifiable && ((!dragBottom && !dragTop) || e.ctrlKey || doc.nativeHeightUnfrozen); if (nwidth && nheight) { - if (nwidth / nheight !== width / height && !dragBottom && !dragTop) { - height = (nheight / nwidth) * width; + 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 @@ -583,21 +597,25 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P else dW = (dH * nwidth) / nheight; } } - let actualdW = Math.max(width + dW * scale, 20); - let actualdH = Math.max(height + dH * scale, 20); + let actualdW = Math.max(docwidth + dW * scale, 20); + let actualdH = Math.max(docheight + dH * scale, 20); + let dX = !dWin ? 0 : scale * refCent[0] * (1 - (1 + dWin / refWidth)); + let dY = !dHin ? 0 : scale * refCent[1] * (1 - (1 + dHin / refHeight)); const preserveNativeDim = doc._nativeHeightUnfrozen === false && doc._nativeDimModifiable === false; const fixedAspect = nwidth && nheight && (!doc._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 / (doc._width || 1)) * Doc.NativeWidth(doc); + doc._nativeWidth = (actualdW / (docwidth || 1)) * Doc.NativeWidth(doc); } } else { if (!doc._fitWidth || preserveNativeDim) { actualdH = (nheight / nwidth) * actualdW; doc._height = actualdH; - } else if (!modifyNativeDim || dragBotRight) doc._height = actualdH; + } else if (!modifyNativeDim || dragBotRight) { + doc._height = actualdH; + } } doc._width = actualdW; } else { @@ -605,21 +623,23 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P // 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 / (doc._height || 1)) * Doc.NativeHeight(doc); + doc._nativeHeight = (actualdH / (docheight || 1)) * Doc.NativeHeight(doc); doc._autoHeight = false; } else { if (!doc._fitWidth || preserveNativeDim) { actualdW = (nwidth / nheight) * actualdH; doc._width = actualdW; - } else if (!modifyNativeDim || dragBotRight) doc._width = actualdW; + } else if (!modifyNativeDim || dragBotRight) { + doc._width = actualdW; + } } if (!modifyNativeDim) { - actualdH = Math.min((nheight / nwidth) * NumCast(doc._width), actualdH); - doc._height = actualdH; - } else doc._height = actualdH; + actualdH = Math.min((nheight / nwidth) * docwidth, actualdH); + } + doc._height = actualdH; } } else { - const rotCtr = [NumCast(doc._width) / 2, NumCast(doc._height) / 2]; + 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(); @@ -632,8 +652,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P 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 = (doc.x || 0) + dX * (actualdW - docwidth); - doc.y = (doc.y || 0) + (dragBottom ? 0 : dY * (actualdH - docheight)); + doc.x = NumCast(doc.x) + dX; + doc.y = NumCast(doc.y) + dY; doc._lastModified = new DateField(); } const val = this._dragHeights.get(docView.layoutDoc); @@ -726,7 +746,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } // hide the decorations if the parent chooses to hide it or if the document itself hides it const hideDecorations = seldocview.props.hideDecorations || seldocview.rootDoc.hideDecorations; - const hideResizers = hideDecorations || seldocview.props.hideResizeHandles || seldocview.rootDoc.hideResizeHandles || seldocview.rootDoc._isGroup || this._isRounding || this._isRotating; + const hideResizers = hideDecorations || seldocview.props.hideResizeHandles || seldocview.rootDoc.hideResizeHandles || this._isRounding || this._isRotating; const hideTitle = hideDecorations || seldocview.props.hideDecorationTitle || seldocview.rootDoc.hideDecorationTitle || this._isRounding || this._isRotating; const hideDocumentButtonBar = hideDecorations || seldocview.props.hideDocumentButtonBar || seldocview.rootDoc.hideDocumentButtonBar || this._isRounding || this._isRotating; // if multiple documents have been opened at the same time, then don't show open button |