From 031a607100700f818f96b7fbf478f1b75292be9b Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 5 Apr 2025 00:01:53 -0400 Subject: fixed sizing of text box annotations sidebar button. cleaned up TagsView to not overlap button bar below doc decorations or bottom resize handle --- src/client/views/AntimodeMenu.tsx | 2 + src/client/views/DocumentDecorations.scss | 3 +- src/client/views/DocumentDecorations.tsx | 34 +++++------ src/client/views/SidebarAnnos.scss | 10 ++++ src/client/views/SidebarAnnos.tsx | 7 +-- src/client/views/TagsView.scss | 3 +- src/client/views/TagsView.tsx | 21 +++++-- .../views/global/globalCssVariables.module.scss | 2 +- src/client/views/nodes/DocumentView.scss | 4 +- src/client/views/nodes/DocumentView.tsx | 3 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 65 ++++++++++++++-------- 11 files changed, 98 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 99dee6410..b5e56cad5 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -4,6 +4,7 @@ import { SnappingManager } from '../util/SnappingManager'; import './AntimodeMenu.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; +// eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface AntimodeMenuProps {} /** @@ -162,6 +163,7 @@ export abstract class AntimodeMenu extends Observab transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, position: this.Pinned ? 'unset' : undefined, + border: `${SnappingManager.userColor} solid 1px`, }}> {buttons} diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 732c2645e..28cebe23c 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -41,6 +41,7 @@ $resizeHandler: 8px; .documentDecorations-tagsView { position: absolute; height: 100%; + width: 100%; pointer-events: all; border-radius: 50%; color: black; @@ -327,7 +328,7 @@ $resizeHandler: 8px; .documentDecorations-rightResizer { pointer-events: auto; background: global.$medium-gray-dim; - //opacity: 0.2; + opacity: 0.2; &:hover { opacity: 1; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 875eb45e0..452dd60ee 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -49,7 +49,7 @@ export class DocumentDecorations extends ObservableReactComponent(); - private _resizeBorderWidth = 16; + private _resizeBorderWidth = 8; private _linkBoxHeight = 20 + 3; // link button height + margin private _titleHeight = 20; private _resizeUndo?: UndoManager.Batch; @@ -98,11 +98,11 @@ export class DocumentDecorations extends ObservableReactComponent
- {(seldocview.TagPanelHeight ?? 0) > 30 ? null :
} + {seldocview.TagPanelHeight !== 0 || seldocview.TagPanelEditing ? null :
}
)} @@ -850,12 +850,12 @@ export class DocumentDecorations extends ObservableReactComponent )} - {hideDocumentButtonBar || this._showNothing ? null : ( + {seldocview.TagPanelEditing || hideDocumentButtonBar || this._showNothing ? null : (
1 ? 0 : `${seldocview.showTags ? 4 + seldocview.TagPanelHeight : 4}px`, - transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `, + top: DocumentView.Selected().length > 1 || !seldocview.showTags ? 0 : `${seldocview.TagPanelHeight}px`, + transform: `translate(${-this._resizeBorderWidth + 10}px, ${(seldocview.TagPanelHeight === 0 ? 2 * this._resizeBorderWidth : this._resizeBorderWidth) + bounds.b - bounds.y + this._titleHeight}px) `, }}> DocumentView.Selected()} />
@@ -864,7 +864,7 @@ export class DocumentDecorations extends ObservableReactComponent {DocumentView.Selected().length > 1 ? : null}
diff --git a/src/client/views/SidebarAnnos.scss b/src/client/views/SidebarAnnos.scss index d7de2b641..abfd04f11 100644 --- a/src/client/views/SidebarAnnos.scss +++ b/src/client/views/SidebarAnnos.scss @@ -1,3 +1,13 @@ +.sidebarAnnos-container { + position: absolute; + width: 100%; + height: 100%; + right: 0; + .sidebarAnnos-stacking { + width: 100%; + position: relative; + } +} .sidebarAnnos-tagList { display: flex; flex-direction: row; diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 3c0611f03..b7e6318b1 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -213,14 +213,11 @@ export class SidebarAnnos extends ObservableReactComponent
e.stopPropagation()}> {this.allUsers.length > 1 ? this.allUsers.map(renderUsers) : null} @@ -228,7 +225,7 @@ export class SidebarAnnos extends ObservableReactComponent -
+
{ super(props); makeObservable(this); } - InsetDist = 25; // how far tag panel is moved up to overlap DocumentView. @observable _panelHeightDirty = 0; @observable _currentInput = ''; @@ -298,8 +297,8 @@ export class TagsView extends ObservableReactComponent { @computed get isEditing() { const selected = DocumentView.Selected().length === 1 && DocumentView.Selected().includes(this.View); - if (this._isEditing === undefined) return selected && !StrListCast(this.View.dataDoc.tags).length && !StrListCast(this.View.dataDoc[Doc.LayoutFieldKey(this.View.Document) + '_audioAnnotations_text']).length; - return this._isEditing && (this._props.Views.length > 1 || selected); + if (this._isEditing === undefined) return selected && this.View.TagPanelEditing; // && !StrListCast(this.View.dataDoc.tags).length && !StrListCast(this.View.dataDoc[Doc.LayoutFieldKey(this.View.Document) + '_audioAnnotations_text']).length; + return this._isEditing && (this._props.Views.length > 1 || (selected && this.View.TagPanelEditing)); } /** @@ -309,7 +308,10 @@ export class TagsView extends ObservableReactComponent { @action setToEditing = (editing = true) => { this._isEditing = editing; - editing && this._props.Views.length === 1 && this.View.select(false); + if (this._props.Views.length === 1) { + this.View.TagPanelEditing = editing; + editing && this.View.select(false); + } }; /** @@ -350,7 +352,16 @@ export class TagsView extends ObservableReactComponent { return this.View.ComponentView?.isUnstyledView?.() || (!this.View.showTags && this._props.Views.length === 1) ? null : (
r && new ResizeObserver(action(() => this._props.Views.length === 1 && (this.View.TagPanelHeight = Math.max(0, (r?.getBoundingClientRect().height ?? 0) - this.InsetDist)))).observe(r)} + ref={r => + r && + new ResizeObserver( + action(() => { + if (this._props.Views.length === 1) { + this.View.TagPanelHeight = Math.floor(r?.children[0].children[0].getBoundingClientRect().height ?? 0) - Math.floor(r?.children[0].children[0].children[0].getBoundingClientRect().height ?? 0); + } + }) + ).observe(r?.children[0]) + } style={{ display: SnappingManager.IsResizing === this.View.Document[Id] ? 'none' : undefined, backgroundColor: this.isEditing ? this._props.background : Colors.TRANSPARENT, diff --git a/src/client/views/global/globalCssVariables.module.scss b/src/client/views/global/globalCssVariables.module.scss index ad0c5c21d..82f6caa52 100644 --- a/src/client/views/global/globalCssVariables.module.scss +++ b/src/client/views/global/globalCssVariables.module.scss @@ -4,7 +4,7 @@ $white: #ffffff; $off-white: #fdfdfd; $light-gray: #dfdfdf; $medium-gray: #9f9f9f; -$medium-gray-dim: #9f9f9f30; +$medium-gray-dim: #9f9f9f; $dark-gray: #323232; $black: #000000; diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index dd5fd0d0c..f60f33608 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -273,7 +273,9 @@ .documentView-noAIWidgets { transform-origin: top left; - position: relative; + position: absolute; + bottom: 0; + pointer-events: none; } .documentView-editorView-history { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 37f888ddd..4cf60d356 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -748,7 +748,7 @@ export class DocumentViewInternal extends DocComponent {this._props.DocumentView?.() && !this._props.docViewPath().slice(-2)[0].ComponentView?.isUnstyledView?.() ? : null}
@@ -1163,6 +1163,7 @@ export class DocumentView extends DocComponent() { @observable private _selected = false; @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing @observable public TagPanelHeight = 0; + @observable public TagPanelEditing = false; @computed get showTags() { return this.Document._layout_showTags || this._props.showTags; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f7e6d8e1e..d90be007f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -154,11 +154,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { const defaultSidebar = 250; - const prevWidth = 1 - this.sidebarWidth() / DivWidth(this._ref.current!); + const dw = DivWidth(this._ref.current); + const prevWidth = 1 - this.sidebarWidth() / dw / this.nativeScaling(); 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%' ? `${(defaultSidebar / (NumCast(this.layoutDoc._width) + defaultSidebar)) * 100}%` : '0%') !== '0%'; + this.layoutDoc._layout_sidebarWidthPercent = + this.sidebarWidthPercent === '0%' // + ? `${(defaultSidebar / (NumCast(this.layoutDoc._width) + defaultSidebar)) * 100}%` // + : '0%'; + this.layoutDoc._layout_showSidebar = this.sidebarWidthPercent !== '0%'; } - this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) + defaultSidebar : 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'); @@ -769,7 +775,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { const localDelta = this.DocumentView?.().screenToViewTransform().transformDirection(delta[0], delta[1]) ?? delta; - const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.layout_sidebarWidthPercent.replace('%', ''))) / 100; + const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.sidebarWidthPercent.replace('%', ''))) / 100; const width = NumCast(this.layoutDoc._width) + localDelta[0]; this.layoutDoc._layout_sidebarWidthPercent = Math.max(0, (sidebarWidth + localDelta[0]) / width) * 100 + '%'; this.layoutDoc.width = width; @@ -1223,7 +1229,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent BoolCast(this.Document._freeform_fitContentsToBox); - sidebarContentScaling = () => (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); + nativeScaling = () => this._props.NativeDimScaling?.() || 1; sidebarAddDocument = (doc: Doc | Doc[], sidebarKey: string = this.sidebarKey) => { if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); return this.addDocument(doc, sidebarKey); @@ -1901,12 +1907,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { this.dataDoc[this.sidebarKey + '_height'] = height; }; - sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth(); + sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth(); sidebarScreenToLocal = () => this._props .ScreenToLocalTransform() - .translate(-(this._props.PanelWidth() - this.sidebarWidth()) / (this._props.NativeDimScaling?.() || 1), 0) - .scale(1 / NumCast(this.layoutDoc._freeform_scale, 1) / (this._props.NativeDimScaling?.() || 1)); + .translate(-(this._props.PanelWidth() - this.sidebarWidth()) / this.nativeScaling(), 0) + .scale(1 / this.nativeScaling()); @computed get audioHandle() { return !this.recordingDictation ? null : ( @@ -1927,6 +1933,20 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent ); } + private _sideBtnWidth = 35; + /** + * How much the content of the view is being scaled based on its nesting and its fit-to-width settings + */ + @computed get viewScaling() { return this.ScreenToLocalBoxXf().Scale ; } // prettier-ignore + /** + * The maximum size a UI widget can be scaled so that it won't be bigger in screen pixels than its normal 35 pixel size. + */ + @computed get maxWidgetSize() { return Math.min(this._sideBtnWidth, 0.2 * this._props.PanelWidth())*this.viewScaling; } // prettier-ignore + /** + * How much to reactively scale a UI element so that it is as big as it can be (up to its normal 35pixel size) without being too big for the Doc content + */ + @computed get uiBtnScaling() { return this.maxWidgetSize / this._sideBtnWidth; } // prettier-ignore + @computed get sidebarHandle() { TraceMobx(); const annotated = DocListCast(this.dataDoc[this.sidebarKey]).filter(d => d?.author).length; @@ -1941,7 +1961,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent
@@ -1986,7 +2006,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent +
{renderComponent(StrCast(this.layoutDoc[this.sidebarKey + '_type_collection']))}
); @@ -2061,7 +2081,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent const height = Number(styleFromLayout.height?.replace('px', '')); // prevent default if selected || child is active but this doc isn't scrollable @@ -2078,8 +2098,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent !this._props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide); const scrSize = (which: number, view = this._props.docViewPath().slice(-which)[0]) => @@ -2107,7 +2127,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent
- {this.noSidebar || !this.SidebarShown || this.layout_sidebarWidthPercent === '0%' ? null : this.sidebarCollection} + {this.noSidebar || !this.SidebarShown || this.sidebarWidthPercent === '0%' ? null : this.sidebarCollection} {this.noSidebar || this.Document._layout_noSidebar || this.Document._createDocOnCR || this.layoutDoc._chromeHidden || this.Document.quiz ? null : this.sidebarHandle} {this.audioHandle} {this.layoutDoc._layout_enableAltContentUI && !this.layoutDoc._chromeHidden ? this.overlayAlternateIcon : null} -- cgit v1.2.3-70-g09d2