From 9bff82f5d53f7d13802f8affc4759db0953d7dc7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 14:15:52 -0400 Subject: made goldenlayout tabs/buttons follow color scheme + added hover highlights. got rid of old color scheme code. --- src/client/goldenLayout.js | 14 +- src/client/util/CurrentUserUtils.ts | 14 +- src/client/views/DocumentDecorations.tsx | 10 +- src/client/views/MainView.scss | 90 +---- src/client/views/MainView.tsx | 9 +- src/client/views/StyleProvider.tsx | 26 +- .../views/collections/CollectionDockingView.scss | 396 +++++++++++++++++++-- .../views/collections/CollectionDockingView.tsx | 57 +-- src/client/views/collections/TabDocView.tsx | 1 + .../CollectionFreeFormLayoutEngines.tsx | 2 +- .../views/nodes/formattedText/DashDocView.tsx | 2 +- src/mobile/MobileInterface.tsx | 5 +- 12 files changed, 448 insertions(+), 178 deletions(-) diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js index 843b8bb5f..00ec5e439 100644 --- a/src/client/goldenLayout.js +++ b/src/client/goldenLayout.js @@ -1606,10 +1606,10 @@ dragProxyHeight: 200 }, labels: { - close: 'close', - maximise: 'maximise', + close: 'close tab stack', + maximise: 'maximize stack', minimise: 'minimise', - popout: 'new tab', + popout: 'create new collection tab', popin: 'pop in', tabDropdown: 'additional tabs' } @@ -2922,7 +2922,7 @@ * @type {String} */ lm.controls.Tab._template = '
  • ' + - '
    ' + + '
    ' + '
  • '; lm.utils.copy(lm.controls.Tab.prototype, { @@ -5083,10 +5083,10 @@ 'column', 'stack', 'component', - 'close', - 'maximise', + 'close tab stack', + 'maximize stack', 'minimise', - 'new tab' + 'create new collection tab' ]; }; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 452bb74cd..2983d778f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -476,7 +476,6 @@ export class CurrentUserUtils { static setupDashboards(doc: Doc, field:string) { var myDashboards = DocCast(doc[field]); - const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`; const newDashboard = `createNewDashboard()`; const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, @@ -487,10 +486,10 @@ export class CurrentUserUtils { const contextMenuScripts = [/*newDashboard*/] as string[]; const contextMenuLabels = [/*"Create New Dashboard"*/] as string[]; const contextMenuIcons = [/*"plus"*/] as string[]; - const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters - const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts - const childContextMenuLabels = ["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters - const childContextMenuIcons = ["chalkboard", "tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters + const childContextMenuScripts = [`toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + const childContextMenuLabels = ["Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters + const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { title: "My Dashboards", childHideLinkButton: true, treeView_FreezeChildren: "remove|add", treeView_HideTitle: true, layout_boxShadow: "0 0", childDontRegisterViews: true, dropAction: "same", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, @@ -892,7 +891,6 @@ export class CurrentUserUtils { doc.defaultAclPrivate ?? (doc.defaultAclPrivate = false); doc.savedFilters ?? (doc.savedFilters = new List()); doc.userBackgroundColor ?? (doc.userBackgroundColor = Colors.DARK_GRAY); - addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${doc.userBackgroundColor} !important` }); doc.userVariantColor ?? (doc.userVariantColor = Colors.MEDIUM_BLUE); doc.userColor ?? (doc.userColor = Colors.LIGHT_GRAY); doc.userTheme ?? (doc.userTheme = ColorScheme.Dark); @@ -920,10 +918,6 @@ export class CurrentUserUtils { Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org") - if (doc.activeDashboard instanceof Doc) { - // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) - doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme; - } new LinkManager(); DocServer.CacheNeedsUpdate && setTimeout(DocServer.UPDATE_SERVER_CACHE, 2500); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 7e55b0ebc..327bb5585 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -804,8 +804,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); - const colorScheme = StrCast(Doc.ActiveDashboard?.colorScheme); - const leftBounds = this.props.boundsLeft; const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop; bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; @@ -818,7 +816,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const useRotation = !hideResizers && seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.props.CollectionFreeFormDocumentView; // when do we want an object to not rotate? const rotation = SelectionManager.Views().length == 1 ? NumCast(seldocview.rootDoc._rotation) : 0; - const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; + const resizerScheme = ''; // Radius constants const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView; @@ -853,7 +851,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const titleArea = this._editingTitle ? ( {hideTitle ? null : ( - + {this.selectionTitle} )} @@ -887,7 +885,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); return ( -
    +
    ; @computed private get mainContainer() { if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') { @@ -800,7 +797,7 @@ export class MainView extends React.Component { return ( <> {this._hideUI ? null : this.leftMenuPanel} -
    +
    {this.flyout}
    @@ -1003,7 +1000,7 @@ export class MainView extends React.Component { render() { return (
    @@ -135,7 +131,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt, props: Opt 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (darkScheme() ? Colors.BLACK : Colors.MEDIUM_GRAY)); + (Colors.DARK_GRAY) + : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY)); break; //if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)"; - default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); + default: docColor = docColor || (Colors.WHITE); } return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor; } @@ -247,7 +243,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt .lm_item { + float: left; +} +.lm_content { + overflow: hidden; + position: relative; +} +.lm_dragging, +.lm_dragging * { + cursor: move !important; + user-select: none; +} +.lm_maximised { + position: absolute; + top: 0; + left: 0; + z-index: 40; +} +.lm_maximise_placeholder { + display: none; +} +.lm_splitter { + position: relative; + z-index: 20; +} +.lm_splitter:hover, +.lm_splitter.lm_dragging { + background: orange; +} +.lm_splitter.lm_vertical .lm_drag_handle { + width: 100%; + position: absolute; + cursor: ns-resize; +} +.lm_splitter.lm_horizontal { + float: left; + height: 100%; +} +.lm_splitter.lm_horizontal .lm_drag_handle { + height: 100%; + position: absolute; + cursor: ew-resize; +} +.lm_header { + overflow: visible; + position: relative; + z-index: 1; +} +// .lm_header [class^='lm_'] { +// box-sizing: content-box !important; +// } +.lm_header .lm_controls { + position: absolute; + right: 3px; +} +.lm_header .lm_controls > li { + cursor: pointer; + float: left; + width: 18px; + height: 18px; + text-align: center; +} +.lm_header ul { + margin: 0; + padding: 0; + list-style-type: none; +} +.lm_header .lm_tabs { + position: absolute; +} +.lm_header .lm_tab { + cursor: pointer; + float: left; + height: 25px; + padding: 0 10px 5px; + padding-right: 25px; + position: relative; + box-shadow: unset !important; +} +.lm_header .lm_tab i { + width: 2px; + height: 19px; + position: absolute; +} +.lm_header .lm_tab i.lm_left { + top: 0; + left: -2px; +} +.lm_header .lm_tab i.lm_right { + top: 0; + right: -2px; +} +.lm_header .lm_tab .lm_title { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; +} +.lm_header .lm_tab .lm_close_tab { + width: 14px; + height: 14px; + position: absolute; + top: 0; + right: 0; + text-align: center; +} +.lm_stack.lm_left .lm_header, +.lm_stack.lm_right .lm_header { + height: 100%; +} +.lm_dragProxy.lm_left .lm_header, +.lm_dragProxy.lm_right .lm_header, +.lm_stack.lm_left .lm_header, +.lm_stack.lm_right .lm_header { + width: 20px; + float: left; + vertical-align: top; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs, +.lm_dragProxy.lm_right .lm_header .lm_tabs, +.lm_stack.lm_left .lm_header .lm_tabs, +.lm_stack.lm_right .lm_header .lm_tabs { + transform-origin: left top; + top: 0; + width: 1000px; +} +.lm_dragProxy.lm_left .lm_header .lm_controls, +.lm_dragProxy.lm_right .lm_header .lm_controls, +.lm_stack.lm_left .lm_header .lm_controls, +.lm_stack.lm_right .lm_header .lm_controls { + bottom: 0; +} +.lm_dragProxy.lm_left .lm_items, +.lm_dragProxy.lm_right .lm_items, +.lm_stack.lm_left .lm_items, +.lm_stack.lm_right .lm_items { + float: left; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs, +.lm_stack.lm_left .lm_header .lm_tabs { + transform: rotate(-90deg) scaleX(-1); + left: 0; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs .lm_tab, +.lm_stack.lm_left .lm_header .lm_tabs .lm_tab { + transform: scaleX(-1); + margin-top: 1px; +} +.lm_dragProxy.lm_left .lm_header .lm_tabdropdown_list, +.lm_stack.lm_left .lm_header .lm_tabdropdown_list { + top: initial; + right: initial; + left: 20px; +} +.lm_dragProxy.lm_right .lm_content { + float: left; +} +.lm_dragProxy.lm_right .lm_header .lm_tabs, +.lm_stack.lm_right .lm_header .lm_tabs { + transform: rotate(90deg) scaleX(1); + left: 100%; + margin-left: 0; +} +.lm_dragProxy.lm_right .lm_header .lm_controls, +.lm_stack.lm_right .lm_header .lm_controls { + left: 3px; +} +.lm_dragProxy.lm_right .lm_header .lm_tabdropdown_list, +.lm_stack.lm_right .lm_header .lm_tabdropdown_list { + top: initial; + right: 20px; +} +.lm_dragProxy.lm_bottom .lm_header .lm_tab, +.lm_stack.lm_bottom .lm_header .lm_tab { + margin-top: 0; + border-top: none; +} +.lm_dragProxy.lm_bottom .lm_header .lm_controls, +.lm_stack.lm_bottom .lm_header .lm_controls { + top: 3px; +} +.lm_dragProxy.lm_bottom .lm_header .lm_tabdropdown_list, +.lm_stack.lm_bottom .lm_header .lm_tabdropdown_list { + top: initial; + bottom: 20px; +} +.lm_drop_tab_placeholder { + float: left; + width: 100px; + height: 10px; + visibility: hidden; +} +.lm_header .lm_controls .lm_tabdropdown:before { + content: ''; + width: 0; + height: 0; + vertical-align: middle; + display: inline-block; + border-top: 5px dashed; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + color: white; +} +.lm_header .lm_tabdropdown_list { + position: absolute; + top: 20px; + right: 0; + z-index: 5; + overflow: hidden; +} +.lm_header .lm_tabdropdown_list .lm_tab { + clear: both; + padding-right: 10px; + margin: 0; +} +.lm_header .lm_tabdropdown_list .lm_tab .lm_title { + width: 100px; +} +.lm_header .lm_tabdropdown_list .lm_close_tab { + display: none !important; +} +.lm_dragProxy { + position: absolute; + top: 0; + left: 0; + z-index: 30; +} +.lm_dragProxy .lm_header { + background: transparent; +} +.lm_dragProxy .lm_content { + border-top: none; + overflow: hidden; +} +.lm_dropTargetIndicator { + display: none; + position: absolute; + z-index: 20; +} +.lm_dropTargetIndicator .lm_inner { + width: 100%; + height: 100%; + position: relative; + top: 0; + left: 0; +} +.lm_transition_indicator { + display: none; + width: 20px; + height: 20px; + position: absolute; + top: 0; + left: 0; + z-index: 20; +} +.lm_popin { + width: 20px; + height: 20px; + position: absolute; + bottom: 0; + right: 0; + z-index: 9999; +} +.lm_popin > * { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} +.lm_popin > .lm_bg { + z-index: 10; +} +.lm_popin > .lm_icon { + z-index: 20; +} /*# sourceMappingURL=goldenlayout-base.css.map */ + @import '../../../../node_modules/golden-layout/src/css/goldenlayout-dark-theme.css'; .lm_title { @@ -46,18 +325,33 @@ // font-weight: 700; } +.lm_header .lm_tabs { + overflow-y: hidden; + width: 100%; +} +ul.lm_tabs::before { + content: ' '; + position: absolute; + bottom: 0; + width: 100%; + z-index: 1; + pointer-events: none; + border: solid 1px black; +} .lm_header .lm_tab { // padding: 0px; // moved to MainView.scss, othwerise they get overridden by default stylings // opacity: 0.7; // box-shadow: none; // height: 25px; // border-bottom: black solid; + border-bottom: unset !important; + border-top-right-radius: 5px; + border-top-left-radius: 5px; .collectionDockingView-gear { display: none; } } - .lm_header .lm_tab.lm_active { padding: 0; opacity: 1; @@ -65,7 +359,11 @@ box-shadow: none; height: 27px; margin-right: 2px; - // border-bottom: unset; + z-index: 2 !important; + border-right: solid 2px; + border-left: solid 2px; + border-top: solid 2px; + border-color: black; .collectionDockingView-gear { display: inline-block; @@ -123,20 +421,63 @@ } .lm_close_tab { + display: inline-flex !important; + opacity: 0 !important; padding: 0; align-self: center; margin-right: 5px; - background-color: black; border-radius: 3px; - opacity: 1 !important; width: 15px !important; height: 15px !important; position: relative !important; - display: inline-flex !important; align-items: center; top: 0 !important; right: unset !important; left: 0 !important; + background-image: unset !important; + &::before { + content: 'x'; + color: rgb(50, 50, 50); + margin: auto; + position: relative; + top: -2px; + } + &:hover { + display: inline-flex !important; + &::before { + color: white; + } + } +} +.lm_close { + background-image: unset !important; + &:hover { + background: gray; + color: white !important; + } + &::before { + content: 'x'; + margin: auto; + position: relative; + top: -2; + font-size: medium; + font-family: sans-serif; + } +} +.lm_active .lm_close_tab { + opacity: 1 !important; +} +.lm_tab:hover { + .lm_close_tab { + opacity: 1 !important; + } +} + +.lm_iconWrap { + &:hover { + background: gray; + color: white !important; + } } .lm_tab, @@ -154,14 +495,6 @@ top: 0; left: 0; - // overflow: hidden; // bcz: menus don't show up when this is on (e.g., the parentSelectorMenu) - .collectionDockingView-gear { - padding-left: 5px; - height: 15px; - width: 18px; - margin: auto; - } - .collectionDockingView-drag { touch-action: none; position: absolute; @@ -180,7 +513,6 @@ display: flex; align-content: center; justify-content: center; - background: $dark-gray; } .lm_controls > li { @@ -190,14 +522,38 @@ } .lm_controls .lm_popout { - transform: rotate(45deg); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAQUlEQVR4nHXOQQ4AMAgCQeT/f6aXpsGK3jSTuCVJAAr7iBdoAwCKd0nwfaAdHbYERw5b44+E8JoBjEYGMBq5gAYP3usUDu2IvoUAAAAASUVORK5CYII=); + background-image: unset; + left: -3; + &:hover { + background: gray; + color: white !important; + } + } + li.lm_popout::before { + content: '+'; + margin: auto; + font-size: x-large; + top: -8; + position: relative; + } + .lm_maximise { + background-image: unset !important; + &::before { + content: '\25A3'; + margin: auto; + font-size: medium; + position: relative; + } + &:hover { + background: gray; + color: white !important; + } } .lm_maximised .lm_controls .lm_maximise { - opacity: 1; - transform: scale(0.8); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKElEQVR4nGP8////fwYCgImQAgYGBgYWKM2IR81/okwajIpgvsMbVgAwgQYRVakEKQAAAABJRU5ErkJggg==) !important; + &::before { + content: '\25A2'; + } } .flexlayout__layout { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 8472c59db..4873a61ff 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -10,7 +10,7 @@ import { List } from '../../../fields/List'; import { ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { GetEffectiveAcl, inheritParentAcls } from '../../../fields/util'; -import { emptyFunction, incrementTitleCopy } from '../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, incrementTitleCopy } from '../../../Utils'; import { DocServer } from '../../DocServer'; import { Docs } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; @@ -31,6 +31,7 @@ import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; import React = require('react'); +import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; @observer @@ -60,7 +61,7 @@ export class CollectionDockingView extends CollectionSubView() { return this._goldenLayout._maximisedItem !== null; } private _goldenLayout: any = null; - + static _highlightStyleSheet: any = addStyleSheet(); constructor(props: SubCollectionViewProps) { super(props); if (this.props.renderDepth < 0) runInAction(() => (CollectionDockingView.Instance = this)); @@ -330,6 +331,16 @@ export class CollectionDockingView extends CollectionSubView() { width => !this._goldenLayout && width > 20 && setTimeout(() => this.setupGoldenLayout()), // need to wait for the collectiondockingview-container to have it's width/height since golden layout reads that to configure its windows { fireImmediately: true } ); + reaction( + () => [SettingsManager.userBackgroundColor, SettingsManager.userBackgroundColor], + () => { + clearStyleSheetRules(CollectionDockingView._highlightStyleSheet); + addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SettingsManager.userBackgroundColor} !important` }); + addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SettingsManager.userColor} !important` }); + addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${SettingsManager.userBackgroundColor} !important` }); + }, + { fireImmediately: true } + ); } }; @@ -505,6 +516,23 @@ export class CollectionDockingView extends CollectionSubView() { } }); + let addNewDoc = action(() => { + const dashboard = Doc.ActiveDashboard; + if (dashboard) { + dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; + const docToAdd = Docs.Create.FreeformDocument([], { + _width: this.props.PanelWidth(), + _height: this.props.PanelHeight(), + _layout_fitWidth: true, + _freeform_backgroundGrid: true, + title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, + }); + Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd); + inheritParentAcls(this.dataDoc, docToAdd, false); + CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack); + } + }); + stack.header?.controlsContainer .find('.lm_close') //get the close icon .off('click') //unbind the current click handler @@ -524,31 +552,18 @@ export class CollectionDockingView extends CollectionSubView() { }) ); + stack.element.click((e: any) => { + if (stack.contentItems.length === 0 && Array.from(document.elementsFromPoint(e.originalEvent.x, e.originalEvent.y)).some(ele => ele?.className === 'empty-tabs-message')) { + addNewDoc(); + } + }); stack.header?.controlsContainer .find('.lm_maximise') //get the close icon .click(() => setTimeout(this.stateChanged)); stack.header?.controlsContainer .find('.lm_popout') //get the popout icon .off('click') //unbind the current click handler - .click( - action(() => { - // stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size - const dashboard = Doc.ActiveDashboard; - if (dashboard) { - dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; - const docToAdd = Docs.Create.FreeformDocument([], { - _width: this.props.PanelWidth(), - _height: this.props.PanelHeight(), - _layout_fitWidth: true, - _freeform_backgroundGrid: true, - title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, - }); - Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd); - inheritParentAcls(this.dataDoc, docToAdd, false); - CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack); - } - }) - ); + .click(addNewDoc); }; render() { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index dab53b671..26aa5a121 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -132,6 +132,7 @@ export class TabDocView extends React.Component { if (tab.element[0].children[1].children.length === 1) { iconWrap.className = 'lm_iconWrap lm_moreInfo'; + iconWrap.title = 'click for menu, drag to embed in document'; const dragBtnDown = (e: React.PointerEvent) => { setupMoveUpEvents( this, diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 1e76d373c..15b6e1d37 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -350,7 +350,7 @@ export function computeTimelineLayout(poolData: Map, pivotDoc: groupNames.push({ type: 'text', text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined }); } - const divider = { type: 'div', color: Doc.ActiveDashboard?.colorScheme === ColorScheme.Dark ? 'dimgray' : 'black', x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; + const divider = { type: 'div', color: 'black', x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]); function layoutDocsAtTime(keyDocs: Doc[], key: number) { diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 48f4c2afd..5349e6966 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -22,7 +22,7 @@ export class DashDocView { this.dom = document.createElement('span'); this.dom.style.position = 'relative'; this.dom.style.textIndent = '0'; - this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, Doc.ActiveDashboard?.colorScheme === ColorScheme.Dark ? 'dimgray' : 'lightGray'); + this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, 'lightGray'); this.dom.style.width = node.attrs.width; this.dom.style.height = node.attrs.height; this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index c16a1c124..498bec6ed 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -588,11 +588,10 @@ export class MobileInterface extends React.Component { const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row'); - const toggleTheme = ScriptField.MakeScript(`self.colorScheme = self.colorScheme ? undefined: ${ColorScheme.Dark}}`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`); - dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, cloneDashboard!]); - dashboardDoc.contextMenuLabels = new List(['Toggle Theme Colors', 'Toggle Comic Mode', 'New Dashboard Layout']); + dashboardDoc.contextMenuScripts = new List([toggleComic!, cloneDashboard!]); + dashboardDoc.contextMenuLabels = new List(['Toggle Comic Mode', 'New Dashboard Layout']); Doc.AddDocToList(scens, 'data', dashboardDoc); }; -- cgit v1.2.3-70-g09d2 From f9b61316dc920baac1d993cb7867d8f015254ff8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 14:26:45 -0400 Subject: fixing golden layout button positions. --- src/client/views/collections/CollectionDockingView.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 132250bae..8fa5665cc 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -64,6 +64,7 @@ width: 18px; height: 18px; text-align: center; + top: 3px; } .lm_header ul { margin: 0; @@ -533,7 +534,7 @@ ul.lm_tabs::before { content: '+'; margin: auto; font-size: x-large; - top: -8; + top: -6; position: relative; } .lm_maximise { -- cgit v1.2.3-70-g09d2 From 6d30addf66c59be4c1ee47de36ee7173a549be3f Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 14:42:57 -0400 Subject: made close tab 'x' a little wider. --- src/client/views/collections/CollectionDockingView.scss | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 8fa5665cc..b8f0b2347 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -423,8 +423,8 @@ ul.lm_tabs::before { .lm_close_tab { display: inline-flex !important; - opacity: 0 !important; padding: 0; + opacity: 1 !important; align-self: center; margin-right: 5px; border-radius: 3px; @@ -437,15 +437,15 @@ ul.lm_tabs::before { left: 0 !important; background-image: unset !important; &::before { - content: 'x'; + content: '\a0x\a0'; color: rgb(50, 50, 50); margin: auto; position: relative; top: -2px; } &:hover { - display: inline-flex !important; &::before { + background: gray; color: white; } } @@ -465,14 +465,6 @@ ul.lm_tabs::before { font-family: sans-serif; } } -.lm_active .lm_close_tab { - opacity: 1 !important; -} -.lm_tab:hover { - .lm_close_tab { - opacity: 1 !important; - } -} .lm_iconWrap { &:hover { -- cgit v1.2.3-70-g09d2 From f4af59c20fe64cfb5f2a034546520484788033d9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 15:27:30 -0400 Subject: fixed issue with clicking at end of text range selecting list_item, not text causing bulleted items to behave weirdly. --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 360dfca04..6a92d09d9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1637,8 +1637,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent 0 && !state.doc.resolve(xpos).node()?.isTextblock) { + xpos = xpos - 1; + } + editor.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(xpos)))); let target = e.target as any; // hrefs are stored on the dataset of the node that wraps the hyerlink while (target && !target.dataset?.targethrefs) target = target.parentElement; FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true'); -- cgit v1.2.3-70-g09d2 From be8ec99f04405fea89f42b98b318ad023fb58821 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 15:30:58 -0400 Subject: made ink strokes not fit width by default --- src/client/documents/Documents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 254be67b9..f7ceef4f4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1042,7 +1042,7 @@ export namespace Docs { I[Initializing] = true; I.type = DocumentType.INK; I.layout = InkingStroke.LayoutString('stroke'); - I.layout_fitWidth = true; + I.layout_fitWidth = false; I.layout_hideDecorationTitle = true; // don't show title when selected // I.layout_hideOpenButton = true; // don't show open full screen button when selected I.color = color; -- cgit v1.2.3-70-g09d2 From 174c86efd17f40b3bca402b253eb8026848dfe0b Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 15:39:56 -0400 Subject: fixed pinning ink strokes to honor save layout/content. --- src/client/views/InkingStroke.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index f5ffff639..3b9edbc56 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -82,9 +82,8 @@ export class InkingStroke extends ViewBoxBaseComponent() { screenToLocal = () => this.props.ScreenToLocalTransform().scale(this.props.NativeDimScaling?.() || 1); getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { - if (this._subContentView) { - return this._subContentView.getAnchor?.(addAsAnnotation) || this.rootDoc; - } + const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation); + if (subAnchor !== this.rootDoc) return subAnchor; if (!addAsAnnotation && !pinProps) return this.rootDoc; -- cgit v1.2.3-70-g09d2 From 8c8bbfe3ac8e17f9716abaf4560f6490538dc004 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 16:19:25 -0400 Subject: fixed match system color settings. --- src/client/util/SettingsManager.tsx | 43 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 085ff4bb1..dc852596f 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -20,10 +20,9 @@ import { undoBatch } from './UndoManager'; export enum ColorScheme { Dark = 'Dark', Light = 'Light', - CoolBlue = 'Cool Blue', - Cupcake = 'Cupcake', - System = 'Match System', Custom = 'Custom', + CoolBlue = 'CoolBlue', + Cupcake = 'Cupcake', } export enum freeformScrollMode { @@ -50,7 +49,21 @@ export class SettingsManager extends React.Component<{}> { constructor(props: {}) { super(props); SettingsManager.Instance = this; + this.matchSystem(); + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + if (Doc.UserDoc().userThemeSystem) { + if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark); + if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light); + } + // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) + }); } + matchSystem = () => { + if (Doc.UserDoc().userThemeSystem) { + if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark); + if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light); + } + }; public close = action(() => (this.isOpen = false)); public open = action(() => (this.isOpen = true)); @@ -88,6 +101,10 @@ export class SettingsManager extends React.Component<{}> { }); @undoBatch switchUserColor = action((color: string) => (Doc.UserDoc().userColor = color)); @undoBatch switchUserVariantColor = action((color: string) => (Doc.UserDoc().userVariantColor = color)); + @undoBatch userThemeSystemToggle = action(() => { + Doc.UserDoc().userThemeSystem = !Doc.UserDoc().userThemeSystem; + this.matchSystem(); + }); @undoBatch playgroundModeToggle = action(() => { this.playgroundMode = !this.playgroundMode; if (this.playgroundMode) { @@ -123,18 +140,11 @@ export class SettingsManager extends React.Component<{}> { break; case ColorScheme.Custom: break; - case ColorScheme.System: - default: - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) - }); - break; } }); @computed get colorsContent() { - const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.Cupcake, ColorScheme.CoolBlue, ColorScheme.Custom, ColorScheme.System]; - const schemeMap = ['Light', 'Dark', 'Cupcake', 'Cool Blue', 'Custom', 'Match System']; + const schemeMap = Array.from(Object.keys(ColorScheme)); const userTheme = StrCast(Doc.UserDoc().userTheme); return (
    @@ -144,15 +154,20 @@ export class SettingsManager extends React.Component<{}> { type={Type.TERT} closeOnSelect={false} selectedVal={userTheme} - setSelectedVal={scheme => this.changeColorScheme(scheme as string)} - items={colorSchemes.map((scheme, i) => ({ - text: schemeMap[i], + setSelectedVal={scheme => { + this.changeColorScheme(scheme as string); + Doc.UserDoc().userThemeSystem = false; + }} + items={Object.keys(ColorScheme).map((scheme, i) => ({ + text: schemeMap[i].replace(/([a-z])([A-Z])/, '$1 $2'), val: scheme, }))} dropdownType={DropdownType.SELECT} color={SettingsManager.userColor} fillWidth /> + + {userTheme === ColorScheme.Custom && ( Date: Tue, 19 Sep 2023 16:28:40 -0400 Subject: fixed tree view hierarchy opening icons --- src/client/views/collections/TreeView.scss | 4 +++- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/nodes/formattedText/DashDocView.tsx | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 0cc11bf1c..cbcc7c710 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -21,7 +21,7 @@ } .treeView-bulletIcons { - width: 100%; + margin: auto; height: 100%; // changes start here. @@ -64,6 +64,8 @@ position: relative; width: fit-content; min-height: 20px; + min-width: 15px; + margin-right: 3px; color: $medium-gray; border: #80808030 1px solid; border-radius: 5px; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 832e102bc..cd526c77e 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -761,7 +761,7 @@ export class TreeView extends React.Component { } size={Size.XSMALL} /> ) ) : ( -
    +
    Date: Tue, 19 Sep 2023 16:40:27 -0400 Subject: can't create text boxes now in explore mode. --- src/client/views/PreviewCursor.tsx | 1 - src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 1d88e9ad6..e3a43d45f 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -2,7 +2,6 @@ import { action, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, Opt } from '../../fields/Doc'; -import { StrCast } from '../../fields/Types'; import { lightOrDark, returnFalse } from '../../Utils'; import { Docs, DocumentOptions, DocUtils } from '../documents/Documents'; import { ImageUtils } from '../util/Import & Export/ImageUtils'; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index cd7bd28e9..4c502021d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -18,7 +18,7 @@ import { SelectionManager } from '../../../util/SelectionManager'; import { Transform } from '../../../util/Transform'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; -import { OpenWhere } from '../../nodes/DocumentView'; +import { DocumentView, OpenWhere } from '../../nodes/DocumentView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { pasteImageBitmap } from '../../nodes/WebBoxRenderer'; import { PreviewCursor } from '../../PreviewCursor'; @@ -335,7 +335,7 @@ export class MarqueeView extends React.Component Date: Tue, 19 Sep 2023 16:44:45 -0400 Subject: turned off document decorations and context menus in explore mode. --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 327bb5585..a30252b0c 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -90,7 +90,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @computed get Bounds() { - if (LinkFollower.IsFollowing) return { x: 0, y: 0, r: 0, b: 0 }; + if (LinkFollower.IsFollowing || DocumentView.ExploreMode) return { x: 0, y: 0, r: 0, b: 0 }; const views = SelectionManager.Views(); return views .filter(dv => dv.props.renderDepth > 0) diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 72c1a9806..ef96e64be 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -702,7 +702,7 @@ export class DocumentViewInternal extends DocComponent { -- cgit v1.2.3-70-g09d2 From 4bf7ab5246b9af2199458692cf020b169aab7bf3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 16:52:57 -0400 Subject: turned off ink and dragging in explore mode. --- src/client/util/CurrentUserUtils.ts | 11 ++++++----- src/client/util/DragManager.ts | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2983d778f..cbdc2fc81 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -8,10 +8,10 @@ import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; import { ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types"; -import { nullAudio, URLField, WebField } from "../../fields/URLField"; +import { nullAudio, WebField } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; -import { addStyleSheetRule, OmitKeys, Utils } from "../../Utils"; +import { OmitKeys, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents"; import { CollectionViewType, DocumentType } from "../documents/DocumentTypes"; @@ -19,7 +19,7 @@ import { TreeViewType } from "../views/collections/CollectionTreeView"; import { DashboardView } from "../views/DashboardView"; import { Colors } from "../views/global/globalEnums"; import { media_state } from "../views/nodes/AudioBox"; -import { OpenWhere } from "../views/nodes/DocumentView"; +import { DocumentView, OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; import { OverlayView } from "../views/OverlayView"; @@ -28,7 +28,7 @@ import { MakeTemplate } from "./DropConverter"; import { FollowLinkScript } from "./LinkFollower"; import { LinkManager } from "./LinkManager"; import { ScriptingGlobals } from "./ScriptingGlobals"; -import { ColorScheme, SettingsManager } from "./SettingsManager"; +import { ColorScheme } from "./SettingsManager"; import { UndoManager } from "./UndoManager"; interface Button { @@ -714,7 +714,7 @@ export class CurrentUserUtils { { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available - { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available + { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available @@ -1022,6 +1022,7 @@ export class CurrentUserUtils { } ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "document containing all shared Docs"); +ScriptingGlobals.add(function IsExploreMode() { return DocumentView.ExploreMode; }, "is Dash in exploration mode"); ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode"); ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6d6eaebec..ed22e70bd 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -324,7 +324,7 @@ export namespace DragManager { export let CanEmbed = false; export let DocDragData: DocumentDragData | undefined; export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void, dragUndoName?: string) { - if (dragData.dropAction === 'none') return; + if (dragData.dropAction === 'none' || DocumentView.ExploreMode) return; DocDragData = dragData as DocumentDragData; const batch = UndoManager.StartBatch(dragUndoName ?? 'document drag'); eles = eles.filter(e => e); -- cgit v1.2.3-70-g09d2 From b98fad407e2214512d526dcff3812879ad9b4035 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 18:20:29 -0400 Subject: fixed closing a text box while typing in it. --- src/client/views/DocumentDecorations.tsx | 1 + src/client/views/InkingStroke.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index a30252b0c..40eb1fe2b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -262,6 +262,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } }); if (!this._iconifyBatch) { + (document.activeElement as any).blur?.(); this._iconifyBatch = UndoManager.StartBatch(forceDeleteOrIconify ? 'delete selected docs' : 'iconifying'); } else { forceDeleteOrIconify = false; // can't force immediate close in the middle of iconifying -- have to wait until iconifying completes diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 3b9edbc56..f63a27426 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -83,7 +83,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation); - if (subAnchor !== this.rootDoc) return subAnchor; + if (subAnchor !== this.rootDoc && subAnchor) return subAnchor; if (!addAsAnnotation && !pinProps) return this.rootDoc; -- cgit v1.2.3-70-g09d2 From b6920e6ffc50eb46f3ac3657c9d5b4fe45e1dd0a Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 20 Sep 2023 01:25:40 -0400 Subject: shifted carousel fwd/back buttons away from edges of screen. made caption width of carousel inset by 30. made 3d carousel images bigger vertically. made properties dragger handle smaller when minimized. --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/MainView.scss | 6 +++++- src/client/views/MainView.tsx | 6 +++++- .../collections/CollectionCarousel3DView.scss | 4 ++-- .../views/collections/CollectionCarouselView.scss | 23 +++++++++++----------- .../views/collections/CollectionCarouselView.tsx | 16 ++++++++------- src/client/views/global/globalCssVariables.scss | 2 +- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index cbdc2fc81..259c028cc 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -707,8 +707,8 @@ export class CurrentUserUtils { CollectionViewType.Grid, CollectionViewType.NoteTaking]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, - { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: true, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, + { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 98367969b..4fb2ac279 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -96,6 +96,7 @@ h1, top: 0; } +.mainView-propertiesDragger-minified, .mainView-propertiesDragger { //background-color: rgb(140, 139, 139); background-color: $light-gray; @@ -108,9 +109,9 @@ h1, border-bottom-left-radius: 10px; border-right: unset; z-index: 41; // lm_maximised has a z-index of 40 and this needs to be above that - display: flex; align-items: center; padding: 4px; + display: flex; .mainView-propertiesDragger-icon { width: 10px; @@ -124,6 +125,9 @@ h1, cursor: grab; } } +.mainView-propertiesDragger-minified { + width: 10px; +} .mainView-innerContent { display: contents; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 6d08c01fa..d6f5d63fe 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -809,7 +809,11 @@ export class MainView extends React.Component { {this.dockingContent} {this._hideUI ? null : ( -
    +
    )} diff --git a/src/client/views/collections/CollectionCarousel3DView.scss b/src/client/views/collections/CollectionCarousel3DView.scss index 6bd1d9f5f..7622043e3 100644 --- a/src/client/views/collections/CollectionCarousel3DView.scss +++ b/src/client/views/collections/CollectionCarousel3DView.scss @@ -87,13 +87,13 @@ .carousel3DView-fwd, .carousel3DView-fwd-scroll, .carousel3DView-fwd-scroll-hidden { - right: 0; + right: 20; } .carousel3DView-back, .carousel3DView-back-scroll, .carousel3DView-back-scroll-hidden { - left: 0; + left: 20; } .carousel3DView-fwd-scroll-hidden, diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss index 8660113cd..130b31325 100644 --- a/src/client/views/collections/CollectionCarouselView.scss +++ b/src/client/views/collections/CollectionCarouselView.scss @@ -1,8 +1,7 @@ - .collectionCarouselView-outer { - height : 100%; + height: 100%; .collectionCarouselView-caption { - height: 50; + height: 50; display: inline-block; width: 100%; } @@ -13,7 +12,8 @@ user-select: none; } } -.carouselView-back, .carouselView-fwd { +.carouselView-back, +.carouselView-fwd { position: absolute; display: flex; top: 42.5%; @@ -22,18 +22,19 @@ align-items: center; border-radius: 5px; justify-content: center; - color: rgba(255,255,255,0.5); - background : rgba(0,0,0, 0.1); + color: rgba(255, 255, 255, 0.5); + background: rgba(0, 0, 0, 0.1); &:hover { - color:white; + color: white; } } .carouselView-fwd { - right: 0; + right: 20; } .carouselView-back { - left: 0; + left: 20; } -.carouselView-back:hover, .carouselView-fwd:hover { +.carouselView-back:hover, +.carouselView-fwd:hover { background: lightgray; -} \ No newline at end of file +} diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 7fa36d228..040a584b8 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, Opt } from '../../../fields/Doc'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnFalse, returnZero, StopEvent } from '../../../Utils'; +import { emptyFunction, returnFalse, returnOne, returnZero, StopEvent } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; @@ -44,12 +44,14 @@ export class CollectionCarouselView extends CollectionSubView() { panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._layout_showCaption) ? 50 : 0); onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); + @computed get marginX() { + return NumCast(this.layoutDoc.caption_xMargin, 50); + } + captionWidth = () => this.props.PanelWidth() - 2 * this.marginX; @computed get content() { const index = NumCast(this.layoutDoc._carousel_index); const curDoc = this.childLayoutPairs?.[index]; - const captionProps = { ...this.props, fieldKey: 'caption', setHeight: undefined, setContentView: undefined }; - const marginX = NumCast(this.layoutDoc['caption_xMargin']); - const marginY = NumCast(this.layoutDoc['caption_yMargin']); + const captionProps = { ...this.props, NativeScaling: returnOne, PanelWidth: this.captionWidth, fieldKey: 'caption', setHeight: undefined, setContentView: undefined }; const show_captions = StrCast(this.layoutDoc._layout_showCaption); return !(curDoc?.layout instanceof Doc) ? null : ( <> @@ -80,9 +82,9 @@ export class CollectionCarouselView extends CollectionSubView() { style={{ display: show_captions ? undefined : 'none', borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding), - marginRight: marginX, - marginLeft: marginX, - width: `calc(100% - ${marginX * 2}px)`, + marginRight: this.marginX, + marginLeft: this.marginX, + width: `calc(100% - ${this.marginX * 2}px)`, }}>
    diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss index 7b2ac5713..ddd99c836 100644 --- a/src/client/views/global/globalCssVariables.scss +++ b/src/client/views/global/globalCssVariables.scss @@ -71,7 +71,7 @@ $LEFT_MENU_WIDTH: 60px; $TREE_BULLET_WIDTH: 20px; $CAROUSEL3D_CENTER_SCALE: 1.3; -$CAROUSEL3D_SIDE_SCALE: 0.3; +$CAROUSEL3D_SIDE_SCALE: 0.6; $CAROUSEL3D_TOP: 15; :export { -- cgit v1.2.3-70-g09d2 From 34f3bab0f4d55b2f55f38e451bfd024994ecff42 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 20 Sep 2023 13:20:53 -0400 Subject: added carousel3D to novice and fixed it's button positions and its focus so that it works with trails. added dragging documents within single collection for rearranging order of docs in a tab collection. fixed freeform views set to fitWidth to show decorations properly. turned off scaling of tree views. updated lightbox buttons. fixed tooltips on properties toggles. --- src/client/util/CurrentUserUtils.ts | 4 +- src/client/util/DragManager.ts | 2 +- src/client/views/LightboxView.scss | 11 +-- src/client/views/LightboxView.tsx | 106 +++++++++++++-------- src/client/views/PropertiesButtons.tsx | 12 ++- .../views/collections/CollectionCarousel3DView.tsx | 17 +++- src/client/views/collections/CollectionSubView.tsx | 5 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/TreeView.tsx | 6 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 9 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 +- 11 files changed, 109 insertions(+), 69 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 259c028cc..2ea5972ee 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -492,8 +492,8 @@ export class CurrentUserUtils { const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { title: "My Dashboards", childHideLinkButton: true, treeView_FreezeChildren: "remove|add", treeView_HideTitle: true, layout_boxShadow: "0 0", childDontRegisterViews: true, - dropAction: "same", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, - layout_headerButton: newDashboardButton, childDragAction: "none", + dropAction: "inSame", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, + layout_headerButton: newDashboardButton, childDragAction: "inSame", _layout_showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true, contextMenuLabels:new List(contextMenuLabels), contextMenuIcons:new List(contextMenuIcons), diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index ed22e70bd..f86f9a3e5 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -14,7 +14,7 @@ import { SelectionManager } from './SelectionManager'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; -export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove +export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'inSame' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove /** * Initialize drag diff --git a/src/client/views/LightboxView.scss b/src/client/views/LightboxView.scss index f86a1d211..9a9b8a437 100644 --- a/src/client/views/LightboxView.scss +++ b/src/client/views/LightboxView.scss @@ -5,7 +5,6 @@ top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -17,11 +16,10 @@ .lightboxView-tabBtn { margin: auto; position: absolute; - right: 38; + right: 45; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -33,11 +31,10 @@ .lightboxView-penBtn { margin: auto; position: absolute; - right: 70; + right: 80; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -49,11 +46,10 @@ .lightboxView-exploreBtn { margin: auto; position: absolute; - right: 100; + right: 115; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -68,7 +64,6 @@ left: 0; width: 100%; height: 100%; - background: #000000bb; z-index: 1000; .lightboxView-contents { position: absolute; diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 8f081b321..93eaec959 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,15 +1,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { InkTool } from '../../fields/InkField'; -import { Cast, NumCast, StrCast } from '../../fields/Types'; +import { BoolCast, Cast, NumCast, StrCast } from '../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../Utils'; import { DocUtils } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; +import { SettingsManager } from '../util/SettingsManager'; import { Transform } from '../util/Transform'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline'; @@ -118,7 +120,7 @@ export class LightboxView extends React.Component { width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]), bottom, }}> -
    +
    {color}
    @@ -229,6 +231,7 @@ export class LightboxView extends React.Component { downx = e.clientX; downy = e.clientY; }} + style={{ background: SettingsManager.userBackgroundColor }} onClick={e => { if (Math.abs(downx - e.clientX) < 4 && Math.abs(downy - e.clientY) < 4) { LightboxView.SetLightboxDoc(undefined); @@ -242,6 +245,8 @@ export class LightboxView extends React.Component { width: this.lightboxWidth(), height: this.lightboxHeight(), clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`, + background: SettingsManager.userBackgroundColor, + color: SettingsManager.userColor, }}> {/* TODO:glr This is where it would go*/} @@ -299,47 +304,68 @@ export class LightboxView extends React.Component { this.future()?.length.toString() )} -
    { - e.stopPropagation(); - LightboxView.LightboxDoc!._layout_fitWidth = !LightboxView.LightboxDoc!._layout_fitWidth; - }}> - +
    + { + e.stopPropagation(); + LightboxView.LightboxDoc!._layout_fitWidth = !LightboxView.LightboxDoc!._layout_fitWidth; + }} + icon={} + />
    -
    { - const lightdoc = LightboxView._docTarget || LightboxView._doc!; - e.stopPropagation(); - Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', lightdoc); - CollectionDockingView.AddSplit(lightdoc, OpenWhereMod.none); - SelectionManager.DeselectAll(); - LightboxView.SetLightboxDoc(undefined); - }}> - +
    + } + onClick={e => { + const lightdoc = LightboxView._docTarget || LightboxView._doc!; + e.stopPropagation(); + Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', lightdoc); + CollectionDockingView.AddSplit(lightdoc, OpenWhereMod.none); + SelectionManager.DeselectAll(); + LightboxView.SetLightboxDoc(undefined); + }} + />
    -
    { - e.stopPropagation(); - Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; - }}> - +
    + } + onClick={e => { + e.stopPropagation(); + Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; + }} + />
    -
    { - e.stopPropagation(); - DocumentView.ExploreMode = !DocumentView.ExploreMode; - })}> - +
    + } + onClick={action(e => { + e.stopPropagation(); + DocumentView.ExploreMode = !DocumentView.ExploreMode; + })} + />
    ); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 40d42a4de..d1561fd67 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -57,6 +57,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !targetDoc ? null : ( { @computed get forceActiveButton() { //select text return this.propertyToggleBtn( - on => (on ? 'INACTIVE INTERACTION' : 'ACTIVE INTERACTION'), + on => (on ? 'SELECT TO INTERACT' : 'ALWAYS INTERACTIVE'), '_forceActive', - on => `${on ? 'Select to activate' : 'Contents always active'} `, + on => `${on ? 'Document must be selected to interact with its contents' : 'Contents always active (respond to click/drag events)'} `, on => // 'eye' ); } @@ -210,9 +211,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get layout_fitWidthButton() { return this.propertyToggleBtn( - on => (on ? 'RESTRICT WIDTH' : 'FIT WIDTH'), //'Fit\xA0Width', + on => (on ? 'SCALED VIEW' : 'READING VIEW'), //'Fit\xA0Width', '_layout_fitWidth', - on => `${on ? "Don't" : 'Do'} fit content to width of container`, + on => + on + ? "Scale document so it's width and height fit container (no effect when document is viewed on freeform canvas)" + : "Scale document so it's width fits container and its height expands/contracts to fit available space (no effect when document is viewed on freeform canvas)", on => (on ? : ) // 'arrows-alt-h' ); } diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index d94e552b4..cd59a91a1 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -2,14 +2,15 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc } from '../../../fields/Doc'; +import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; +import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { returnFalse, returnZero, Utils } from '../../../Utils'; +import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } from '../global/globalCssVariables.scss'; -import { DocumentView } from '../nodes/DocumentView'; +import { DocFocusOptions, DocumentView } from '../nodes/DocumentView'; import { StyleProp } from '../StyleProvider'; import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; @@ -46,6 +47,15 @@ export class CollectionCarousel3DView extends CollectionSubView() { .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this.props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) .scale(1 / this.centerScale); + focus = (anchor: Doc, options: DocFocusOptions) => { + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; + options.didMove = true; + const target = DocCast(anchor.annotationOn) ?? anchor; + const index = docs.indexOf(target); + index !== -1 && (this.layoutDoc._carousel_index = index); + return undefined; + }; @computed get content() { const currentIndex = NumCast(this.layoutDoc._carousel_index); const displayDoc = (childPair: { layout: Doc; data: Doc }) => { @@ -61,6 +71,7 @@ export class CollectionCarousel3DView extends CollectionSubView() { LayoutTemplateString={this.props.childLayoutString} Document={childPair.layout} DataDoc={childPair.data} + focus={this.focus} ScreenToLocalTransform={this.childScreenToLocal} isContentActive={this.isChildContentActive} isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive} diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 54a60271a..26272d2ee 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -210,11 +210,12 @@ export function CollectionSubView(moreProps?: X) { const targetDocments = DocListCast(this.dataDoc[this.props.fieldKey]); const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag)); if (someMoved) docDragData.droppedDocuments = docDragData.droppedDocuments.map((drop, i) => (targetDocments.includes(docDragData.draggedDocuments[i]) ? docDragData.draggedDocuments[i] : drop)); - if ((!dropAction || dropAction === 'same' || dropAction === 'move' || someMoved) && docDragData.moveDocument) { + if ((!dropAction || dropAction === 'inSame' || dropAction === 'same' || dropAction === 'move' || someMoved) && docDragData.moveDocument) { const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); if (movedDocs.length) { - const canAdd = de.embedKey || dropAction || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.rootDoc); + const canAdd = + (de.embedKey || dropAction || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.rootDoc)) && (dropAction !== 'inSame' || docDragData.draggedDocuments.every(d => d.embedContainer === this.rootDoc)); const moved = docDragData.moveDocument(movedDocs, this.rootDoc, canAdd ? this.addDocument : returnFalse); added = canAdd || moved ? moved : undefined; } else { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index eed04b3ee..9e5ac77d9 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -149,7 +149,7 @@ export class CollectionTreeView extends CollectionSubView {!(this.doc instanceof Doc) || !this.treeChildren ? null : this.doc.treeView_HasOverlay ? ( diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index cd526c77e..f89aa065b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -433,9 +433,9 @@ export class TreeView extends React.Component { return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean); }; const addDoc = inside ? localAdd : parentAddDoc; - const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same') && moveDocument; + const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same' || dropAction === 'inSame') && moveDocument; const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.treeViewParent)?.treeView_FreezeChildren).includes('add')) || forceAdd; - if (canAdd) { + if (canAdd && (dropAction !== 'inSame' || droppedDocuments.every(d => d.embedContainer === this.props.parentTreeView?.doc))) { this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = true); const res = droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false); this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = false); @@ -598,7 +598,7 @@ export class TreeView extends React.Component { } const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField; const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); - !dataIsComputed && added && Doc.SetContainer(doc, DocCast(this.doc.embedContainer)); + !dataIsComputed && added && Doc.SetContainer(doc, this.doc); return added; }; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8a812c671..9df96fabc 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -33,7 +33,6 @@ import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { COLLECTION_BORDER_WIDTH } from '../../../views/global/globalCssVariables.scss'; import { Timeline } from '../../animationtimeline/Timeline'; import { ContextMenu } from '../../ContextMenu'; -import { DocumentDecorations } from '../../DocumentDecorations'; import { GestureOverlay } from '../../GestureOverlay'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke'; import { LightboxView } from '../../LightboxView'; @@ -187,7 +186,10 @@ export class CollectionFreeFormView extends CollectionSubView + const segments = this.segmentInkStroke(intersect.inkView, intersect.t); + segments.forEach(segment => this.forceStrokeGesture( e, GestureUtils.Gestures.Stroke, diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 394108be4..14a3d16ef 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -226,7 +226,7 @@ export class FontIconBox extends DocComponent() { } else { return