aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-11-18 23:47:13 -0500
committerbobzel <zzzman@gmail.com>2023-11-18 23:47:13 -0500
commit2b0e4ccc096998eb1d727f2e85ea8c1a63b27e08 (patch)
tree1d5bc81e4cf74b20b599a5069c3448a2de4784fb /src/client/views/nodes
parent1b568af6b2725b9eed6f591bfce193d39d5804de (diff)
fixed ctrl-drag for expressions, maps, fform doc selections. fixed using shift to add Doc to a selection and also when bounding box already covers the doc to add. fixed dragging maximize button to start goldenlayout drag properly. fixed typing character to group,etc a multiselection when a text doc has input focus. fixed using clusters. add Shift-U to ungroup alternate group style. multi-select blurs() all active inputs. shift-selecting a multi-selected Doc, deselects it.
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx25
-rw-r--r--src/client/views/nodes/EquationBox.tsx14
-rw-r--r--src/client/views/nodes/FieldView.tsx2
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx12
8 files changed, 44 insertions, 31 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index c4703a47c..8c8c987fe 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -119,7 +119,7 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
@observer
export class DocumentContentsView extends React.Component<
DocumentViewProps & {
- isSelected: (outsideReaction: boolean) => boolean;
+ isSelected: () => boolean;
select: (ctrl: boolean) => void;
NativeDimScaling?: () => number;
setHeight?: (height: number) => void;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e3d6c3fdf..a61396275 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -176,7 +176,7 @@ export interface DocumentViewSharedProps {
searchFilterDocs: () => Doc[];
layout_showTitle?: () => string;
whenChildContentsActiveChanged: (isActive: boolean) => void;
- rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected
+ rootSelected: () => boolean; // whether the root of a template has been selected
addDocTab: (doc: Doc, where: OpenWhere) => boolean;
filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
@@ -243,7 +243,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
export interface DocumentViewInternalProps extends DocumentViewProps {
NativeWidth: () => number;
NativeHeight: () => number;
- isSelected: (outsideReaction?: boolean) => boolean;
+ isSelected: () => boolean;
select: (ctrlPressed: boolean, shiftPress?: boolean) => void;
DocumentView: () => DocumentView;
viewPath: () => DocumentView[];
@@ -738,7 +738,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (e && !(e.nativeEvent as any).dash) {
const onDisplay = () => {
- if (this.rootDoc.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
+ if (this.rootDoc.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected() && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY));
};
if (navigator.userAgent.includes('Macintosh')) {
@@ -902,7 +902,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
};
@computed get _rootSelected() {
- return this.props.isSelected(false) || (this.props.Document.rootDocument && this.props.rootSelected?.(false)) || false;
+ return this.props.isSelected() || (this.props.Document.rootDocument && this.props.rootSelected?.()) || false;
}
rootSelected = () => this._rootSelected;
panelHeight = () => this.props.PanelHeight() - this.headerMargin;
@@ -1598,13 +1598,16 @@ export class DocumentView extends React.Component<DocumentViewProps> {
docViewPathFunc = () => this.docViewPath;
isSelected = () => SelectionManager.IsSelected(this);
select = (extendSelection: boolean, focusSelection?: boolean) => {
- SelectionManager.SelectView(this, extendSelection);
- if (focusSelection) {
- DocumentManager.Instance.showDocument(this.rootDoc, {
- willZoomCentered: true,
- zoomScale: 0.9,
- zoomTime: 500,
- });
+ if (this.isSelected() && SelectionManager.Views().length > 1) SelectionManager.DeselectView(this);
+ else {
+ SelectionManager.SelectView(this, extendSelection);
+ if (focusSelection) {
+ DocumentManager.Instance.showDocument(this.rootDoc, {
+ willZoomCentered: true,
+ zoomScale: 0.9,
+ zoomTime: 500,
+ });
+ }
}
};
NativeWidth = () => this.effectiveNativeWidth;
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index d8b8bcb27..d347c285b 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -84,8 +84,18 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
updateSize = () => {
const style = this._ref.current && getComputedStyle(this._ref.current.element.current);
if (style?.width.endsWith('px') && style?.height.endsWith('px')) {
- this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', '')));
- this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', '')));
+ if (this.layoutDoc._nativeWidth) {
+ // if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio
+ const prevNwidth = NumCast(this.layoutDoc._nativeWidth);
+ const prevNheight = NumCast(this.layoutDoc._nativeHeight);
+ this.layoutDoc._nativeWidth = Math.max(35, Number(style.width.replace('px', '')));
+ this.layoutDoc._nativeHeight = Math.max(25, Number(style.height.replace('px', '')));
+ this.layoutDoc._width = (NumCast(this.layoutDoc._width) * NumCast(this.layoutDoc._nativeWidth)) / prevNwidth;
+ this.layoutDoc._height = (NumCast(this.layoutDoc._height) * NumCast(this.layoutDoc._nativeHeight)) / prevNheight;
+ } else {
+ this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', '')));
+ this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', '')));
+ }
}
};
render() {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f014f842e..f7f94c546 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -21,7 +21,7 @@ export interface FieldViewProps extends DocumentViewSharedProps {
select: (isCtrlPressed: boolean) => void;
isContentActive: (outsideReaction?: boolean) => boolean | undefined;
isDocumentActive?: () => boolean | undefined;
- isSelected: (outsideReaction?: boolean) => boolean;
+ isSelected: () => boolean;
setHeight?: (height: number) => void;
NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NOTE: Must also be added to DocumentViewInternalsProps
onBrowseClick?: () => ScriptField | undefined;
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index 7af4d9b59..f6680aac0 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -48,7 +48,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentDidMount() {
this._disposer = reaction(
() => SelectionManager.Views().slice(),
- selected => MapAnchorMenu.Instance.fadeOut(true)
+ sel => MapAnchorMenu.Instance.fadeOut(true)
);
}
// audioDown = (e: React.PointerEvent) => {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 185c6553a..108fa5ce5 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -195,7 +195,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
() => this.props.isSelected(),
() => {
document.removeEventListener('keydown', this.onKeyDown);
- this.props.isSelected(true) && document.addEventListener('keydown', this.onKeyDown);
+ this.props.isSelected() && document.addEventListener('keydown', this.onKeyDown);
},
{ fireImmediately: true }
);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index a80c1e030..c828297b3 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -315,7 +315,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
});
const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
- this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
+ this.props.isSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
};
dispatchTransaction = (tx: Transaction) => {
@@ -1439,7 +1439,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const self = this;
return new Plugin({
view(newView) {
- runInAction(() => self.props.isSelected(true) && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView));
+ runInAction(() => self.props.isSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView));
return new RichTextMenuPlugin({ editorProps: this.props });
},
});
@@ -1612,7 +1612,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._downX = e.clientX;
this._downY = e.clientY;
FormattedTextBoxComment.textBox = this;
- if (e.button === 0 && (this.props.rootSelected(true) || this.props.isSelected(true)) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+ if (e.button === 0 && (this.props.rootSelected() || this.props.isSelected()) && !e.altKey && !e.ctrlKey && !e.metaKey) {
if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
// stop propagation if not in sidebar, otherwise nested boxes will lose focus to outer boxes.
e.stopPropagation(); // if the text box's content is active, then it consumes all down events
@@ -1649,7 +1649,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
@action
onDoubleClick = (e: React.MouseEvent): void => {
FormattedTextBoxComment.textBox = this;
- if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+ if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) {
if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
// stop propagation if not in sidebar
e.stopPropagation(); // if the text box is selected, then it consumes all click events
@@ -1660,7 +1660,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
FormattedTextBoxComment.Hide();
- if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
+ if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
e.stopPropagation();
}
};
@@ -1706,7 +1706,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._editorView!.dispatch(this._editorView!.state.tr.setSelection(NodeSelection.create(this._editorView!.state.doc, pcords.pos)));
}
}
- if (this.props.isSelected(true)) {
+ if (this.props.isSelected()) {
// if text box is selected, then it consumes all click events
(e.nativeEvent as any).handledByInnerReactInstance = true;
this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, this._forceDownNode, e.shiftKey);
@@ -1720,7 +1720,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
clearStyleSheetRules(FormattedTextBox._bulletStyleSheet);
const clickPos = this._editorView!.posAtCoords({ left: x, top: y });
let olistPos = clickPos?.pos;
- if (clickPos && olistPos && this.props.isSelected(true)) {
+ if (clickPos && olistPos && this.props.isSelected()) {
const clickNode = this._editorView?.state.doc.nodeAt(olistPos);
const nodeBef = this._editorView?.state.doc.nodeAt(Math.max(0, olistPos - 1));
olistPos = nodeBef?.type === this._editorView?.state.schema.nodes.ordered_list ? olistPos - 1 : olistPos;
@@ -1769,7 +1769,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
tr && this._editorView.dispatch(tr);
}
}
- if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
+ if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected()) {
RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
}
FormattedTextBox._hadSelection = window.getSelection()?.toString() !== '';
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index e3ac4fb9d..712be91c8 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -181,7 +181,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// finds font sizes and families in selection
getActiveAlignment() {
- if (this.view && this.TextView?.props.isSelected(true)) {
+ if (this.view && this.TextView?.props.isSelected()) {
const path = (this.view.state.selection.$from as any).path;
for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
@@ -194,7 +194,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// finds font sizes and families in selection
getActiveListStyle() {
- if (this.view && this.TextView?.props.isSelected(true)) {
+ if (this.view && this.TextView?.props.isSelected()) {
const path = (this.view.state.selection.$from as any).path;
for (let i = 0; i < path.length; i += 3) {
if (path[i].type === this.view.state.schema.nodes.ordered_list) {
@@ -214,7 +214,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const activeSizes = new Set<string>();
const activeColors = new Set<string>();
const activeHighlights = new Set<string>();
- if (this.view && this.TextView?.props.isSelected(true)) {
+ if (this.view && this.TextView?.props.isSelected()) {
const state = this.view.state;
const pos = this.view.state.selection.$from;
const marks: Mark[] = [...(state.storedMarks ?? [])];
@@ -249,7 +249,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
//finds all active marks on selection in given group
getActiveMarksOnSelection() {
let activeMarks: MarkType[] = [];
- if (!this.view || !this.TextView?.props.isSelected(true)) return activeMarks;
+ if (!this.view || !this.TextView?.props.isSelected()) return activeMarks;
const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript];
if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type);
@@ -286,7 +286,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
destroy() {
- !this.TextView?.props.isSelected(true) && this.fadeOut(true);
+ !this.TextView?.props.isSelected() && this.fadeOut(true);
}
@action
@@ -443,7 +443,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => {
- if (this.TextView?.props.isSelected(true)) {
+ if (this.TextView?.props.isSelected()) {
var tr = view.state.tr;
view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => {
if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) {