mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-18 02:26:21 +08:00
refactor(editor): improve edgeless editors (#11019)
This commit is contained in:
+28
-14
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
EdgelessCRUDIdentifier,
|
||||
getSurfaceBlock,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { ConnectorElementModel } from '@blocksuite/affine-model';
|
||||
@@ -7,9 +8,11 @@ import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { almostEqual } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
type BlockComponent,
|
||||
RANGE_SYNC_EXCLUDE_ATTR,
|
||||
ShadowlessElement,
|
||||
} from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { Bound, Vec } from '@blocksuite/global/gfx';
|
||||
import { WithDisposable } from '@blocksuite/global/lit';
|
||||
import { css, html, nothing } from 'lit';
|
||||
@@ -17,8 +20,6 @@ import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||
|
||||
const HORIZONTAL_PADDING = 2;
|
||||
const VERTICAL_PADDING = 2;
|
||||
const BORDER_WIDTH = 1;
|
||||
@@ -63,6 +64,14 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
get gfx() {
|
||||
return this.edgeless.std.get(GfxControllerIdentifier);
|
||||
}
|
||||
|
||||
get selection() {
|
||||
return this.gfx.selection;
|
||||
}
|
||||
|
||||
private _isComposition = false;
|
||||
|
||||
private _keeping = false;
|
||||
@@ -113,8 +122,9 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
const { edgeless, connector } = this;
|
||||
const { dispatcher } = edgeless;
|
||||
const { edgeless, connector, selection } = this;
|
||||
const dispatcher = edgeless.std.event;
|
||||
const store = edgeless.std.store;
|
||||
|
||||
this._resizeObserver = new ResizeObserver(() => {
|
||||
this._updateLabelRect();
|
||||
@@ -142,7 +152,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
if (!isComposing && (isModEnter || isEscape)) {
|
||||
this.inlineEditorContainer?.blur();
|
||||
|
||||
edgeless.service.selection.set({
|
||||
selection.set({
|
||||
elements: [connector.id],
|
||||
editing: false,
|
||||
});
|
||||
@@ -152,14 +162,18 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
})
|
||||
);
|
||||
|
||||
this.disposables.add(
|
||||
edgeless.service.surface.elementUpdated.subscribe(({ id }) => {
|
||||
if (id === connector.id) this.requestUpdate();
|
||||
})
|
||||
);
|
||||
const surface = getSurfaceBlock(store);
|
||||
|
||||
if (surface) {
|
||||
this.disposables.add(
|
||||
surface.elementUpdated.subscribe(({ id }) => {
|
||||
if (id === connector.id) this.requestUpdate();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.disposables.add(
|
||||
edgeless.service.viewport.viewportUpdated.subscribe(() => {
|
||||
this.gfx.viewport.viewportUpdated.subscribe(() => {
|
||||
this.requestUpdate();
|
||||
})
|
||||
);
|
||||
@@ -189,7 +203,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
|
||||
connector.lableEditing = false;
|
||||
|
||||
edgeless.service.selection.set({
|
||||
selection.set({
|
||||
elements: [],
|
||||
editing: false,
|
||||
});
|
||||
@@ -254,7 +268,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
fontSize,
|
||||
fontWeight
|
||||
);
|
||||
const { translateX, translateY, zoom } = this.edgeless.service.viewport;
|
||||
const { translateX, translateY, zoom } = this.gfx.viewport;
|
||||
const [x, y] = Vec.mul(connector.getPointByOffsetDistance(distance), zoom);
|
||||
const transformOperation = [
|
||||
'translate(-50%, -50%)',
|
||||
@@ -316,7 +330,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
accessor connector!: ConnectorElementModel;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor edgeless!: EdgelessRootBlockComponent;
|
||||
accessor edgeless!: BlockComponent;
|
||||
|
||||
@query('rich-text')
|
||||
accessor richText!: RichText;
|
||||
|
||||
+16
-8
@@ -6,9 +6,11 @@ import {
|
||||
frameTitleStyleVars,
|
||||
} from '@blocksuite/affine-widget-frame-title';
|
||||
import {
|
||||
type BlockComponent,
|
||||
RANGE_SYNC_EXCLUDE_ATTR,
|
||||
ShadowlessElement,
|
||||
} from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { WithDisposable } from '@blocksuite/global/lit';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
@@ -16,8 +18,6 @@ import { css, html, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||
|
||||
export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
ShadowlessElement
|
||||
) {
|
||||
@@ -46,10 +46,18 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
return this.richText?.inlineEditor;
|
||||
}
|
||||
|
||||
get gfx() {
|
||||
return this.edgeless.std.get(GfxControllerIdentifier);
|
||||
}
|
||||
|
||||
get selection() {
|
||||
return this.gfx.selection;
|
||||
}
|
||||
|
||||
private _unmount() {
|
||||
// dispose in advance to avoid execute `this.remove()` twice
|
||||
this.disposables.dispose();
|
||||
this.edgeless.service.selection.set({
|
||||
this.selection.set({
|
||||
elements: [],
|
||||
editing: false,
|
||||
});
|
||||
@@ -62,7 +70,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
}
|
||||
|
||||
override firstUpdated(): void {
|
||||
const dispatcher = this.edgeless.dispatcher;
|
||||
const dispatcher = this.edgeless.std.event;
|
||||
this.updateComplete
|
||||
.then(() => {
|
||||
if (!this.inlineEditor) return;
|
||||
@@ -87,7 +95,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
})
|
||||
);
|
||||
this.disposables.add(
|
||||
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
|
||||
this.gfx.viewport.viewportUpdated.subscribe(() => {
|
||||
this.requestUpdate();
|
||||
})
|
||||
);
|
||||
@@ -117,10 +125,10 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
const rootBlockId = this.editorHost.doc.root?.id;
|
||||
if (!rootBlockId) return nothing;
|
||||
|
||||
const viewport = this.edgeless.service.viewport;
|
||||
const viewport = this.gfx.viewport;
|
||||
const bound = Bound.deserialize(this.frameModel.xywh);
|
||||
const [x, y] = viewport.toViewCoord(bound.x, bound.y);
|
||||
const isInner = this.edgeless.service.gfx.grid.has(
|
||||
const isInner = this.gfx.grid.has(
|
||||
this.frameModel.elementBound,
|
||||
true,
|
||||
true,
|
||||
@@ -167,7 +175,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor edgeless!: EdgelessRootBlockComponent;
|
||||
accessor edgeless!: BlockComponent;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor frameModel!: FrameBlockModel;
|
||||
|
||||
+15
-7
@@ -6,17 +6,17 @@ import {
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import {
|
||||
type BlockComponent,
|
||||
RANGE_SYNC_EXCLUDE_ATTR,
|
||||
ShadowlessElement,
|
||||
} from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { WithDisposable } from '@blocksuite/global/lit';
|
||||
import { html, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||
|
||||
export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
ShadowlessElement
|
||||
) {
|
||||
@@ -28,11 +28,19 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
return this.inlineEditor?.rootElement;
|
||||
}
|
||||
|
||||
get gfx() {
|
||||
return this.edgeless.std.get(GfxControllerIdentifier);
|
||||
}
|
||||
|
||||
get selection() {
|
||||
return this.gfx.selection;
|
||||
}
|
||||
|
||||
private _unmount() {
|
||||
// dispose in advance to avoid execute `this.remove()` twice
|
||||
this.disposables.dispose();
|
||||
this.group.showTitle = true;
|
||||
this.edgeless.service.selection.set({
|
||||
this.selection.set({
|
||||
elements: [this.group.id],
|
||||
editing: false,
|
||||
});
|
||||
@@ -45,7 +53,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
}
|
||||
|
||||
override firstUpdated(): void {
|
||||
const dispatcher = this.edgeless.dispatcher;
|
||||
const dispatcher = this.edgeless.std.event;
|
||||
|
||||
this.updateComplete
|
||||
.then(() => {
|
||||
@@ -72,7 +80,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
})
|
||||
);
|
||||
this.disposables.add(
|
||||
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
|
||||
this.gfx.viewport.viewportUpdated.subscribe(() => {
|
||||
this.requestUpdate();
|
||||
})
|
||||
);
|
||||
@@ -103,7 +111,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
console.error('group.externalXYWH is not set');
|
||||
return nothing;
|
||||
}
|
||||
const viewport = this.edgeless.service.viewport;
|
||||
const viewport = this.gfx.viewport;
|
||||
const bound = Bound.deserialize(this.group.externalXYWH);
|
||||
const [x, y] = viewport.toViewCoord(bound.x, bound.y);
|
||||
|
||||
@@ -137,7 +145,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor edgeless!: EdgelessRootBlockComponent;
|
||||
accessor edgeless!: BlockComponent;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor group!: GroupElementModel;
|
||||
|
||||
+30
-27
@@ -8,9 +8,11 @@ import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { getSelectedRect } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
type BlockComponent,
|
||||
RANGE_SYNC_EXCLUDE_ATTR,
|
||||
ShadowlessElement,
|
||||
} from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { Bound, toRadian, Vec } from '@blocksuite/global/gfx';
|
||||
import { WithDisposable } from '@blocksuite/global/lit';
|
||||
import { html, nothing } from 'lit';
|
||||
@@ -18,13 +20,7 @@ import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||
|
||||
export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
private _keeping = false;
|
||||
|
||||
private _lastXYWH = '';
|
||||
@@ -35,6 +31,18 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
return this.richText.inlineEditor;
|
||||
}
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
get gfx() {
|
||||
return this.edgeless.std.get(GfxControllerIdentifier);
|
||||
}
|
||||
|
||||
get selection() {
|
||||
return this.gfx.selection;
|
||||
}
|
||||
|
||||
get inlineEditorContainer() {
|
||||
return this.inlineEditor?.rootElement;
|
||||
}
|
||||
@@ -47,8 +55,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
if (!this.isMindMapNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const service = this.edgeless.service;
|
||||
const selection = this.selection;
|
||||
|
||||
this._disposables.addFromEvent(this, 'keydown', evt => {
|
||||
switch (evt.key) {
|
||||
@@ -57,7 +64,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
if (evt.shiftKey || evt.isComposing) return;
|
||||
|
||||
(this.ownerDocument.activeElement as HTMLElement).blur();
|
||||
service.selection.set({
|
||||
selection.set({
|
||||
elements: [this.element.id],
|
||||
editing: false,
|
||||
});
|
||||
@@ -67,7 +74,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
case 'Tab': {
|
||||
evt.stopPropagation();
|
||||
(this.ownerDocument.activeElement as HTMLElement).blur();
|
||||
service.selection.set({
|
||||
selection.set({
|
||||
elements: [this.element.id],
|
||||
editing: false,
|
||||
});
|
||||
@@ -109,7 +116,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
this.element.textDisplay = true;
|
||||
|
||||
this.remove();
|
||||
this.edgeless.service.selection.set({
|
||||
this.selection.set({
|
||||
elements: [],
|
||||
editing: false,
|
||||
});
|
||||
@@ -134,8 +141,10 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
toRadian(-this.element.rotate)
|
||||
);
|
||||
|
||||
const [modelLeftTopX, modelLeftTopY] =
|
||||
this.edgeless.service.viewport.toModelCoord(leftTopX, leftTopY);
|
||||
const [modelLeftTopX, modelLeftTopY] = this.gfx.viewport.toModelCoord(
|
||||
leftTopX,
|
||||
leftTopY
|
||||
);
|
||||
|
||||
this.crud.updateElement(this.element.id, {
|
||||
xywh: new Bound(
|
||||
@@ -161,7 +170,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
this.richText.style.minHeight = `${containerHeight}px`;
|
||||
}
|
||||
|
||||
this.edgeless.service.selection.set({
|
||||
this.selection.set({
|
||||
elements: [this.element.id],
|
||||
editing: true,
|
||||
});
|
||||
@@ -173,12 +182,12 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
|
||||
override firstUpdated(): void {
|
||||
const dispatcher = this.edgeless.dispatcher;
|
||||
const dispatcher = this.edgeless.std.event;
|
||||
|
||||
this.element.textDisplay = false;
|
||||
|
||||
this.disposables.add(
|
||||
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
|
||||
this.gfx.viewport.viewportUpdated.subscribe(() => {
|
||||
this.requestUpdate();
|
||||
this.updateComplete
|
||||
.then(() => {
|
||||
@@ -228,7 +237,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
this.disposables.addFromEvent(this, 'keydown', evt => {
|
||||
if (evt.key === 'Escape') {
|
||||
requestAnimationFrame(() => {
|
||||
this.edgeless.service.selection.set({
|
||||
this.selection.set({
|
||||
elements: [this.element.id],
|
||||
editing: false,
|
||||
});
|
||||
@@ -256,7 +265,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
const [verticalPadding, horiPadding] = this.element.padding;
|
||||
const textResizing = this.element.textResizing;
|
||||
const viewport = this.edgeless.service.viewport;
|
||||
const viewport = this.gfx.viewport;
|
||||
const zoom = viewport.zoom;
|
||||
const rect = getSelectedRect([this.element]);
|
||||
const rotate = this.element.rotate;
|
||||
@@ -265,10 +274,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
[rect.left + rect.width / 2, rect.top + rect.height / 2],
|
||||
toRadian(rotate)
|
||||
);
|
||||
const [x, y] = this.edgeless.service.viewport.toViewCoord(
|
||||
leftTopX,
|
||||
leftTopY
|
||||
);
|
||||
const [x, y] = this.gfx.viewport.toViewCoord(leftTopX, leftTopY);
|
||||
const autoWidth = textResizing === TextResizing.AUTO_WIDTH_AND_HEIGHT;
|
||||
const color = this.edgeless.std
|
||||
.get(ThemeProvider)
|
||||
@@ -344,17 +350,14 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor edgeless!: EdgelessRootBlockComponent;
|
||||
accessor edgeless!: BlockComponent;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor element!: ShapeElementModel;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor mountEditor:
|
||||
| ((
|
||||
element: ShapeElementModel,
|
||||
edgeless: EdgelessRootBlockComponent
|
||||
) => void)
|
||||
| ((element: ShapeElementModel, edgeless: BlockComponent) => void)
|
||||
| undefined = undefined;
|
||||
|
||||
@query('rich-text')
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
handleNativeRangeAtPoint,
|
||||
resetNativeSelection,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type { PointerEventState } from '@blocksuite/block-std';
|
||||
import type { BlockComponent, PointerEventState } from '@blocksuite/block-std';
|
||||
import {
|
||||
BaseTool,
|
||||
getTopElements,
|
||||
@@ -41,12 +41,11 @@ import {
|
||||
import { DisposableGroup } from '@blocksuite/global/disposable';
|
||||
import type { IVec } from '@blocksuite/global/gfx';
|
||||
import { Bound, getCommonBoundWithRotation, Vec } from '@blocksuite/global/gfx';
|
||||
import { noop } from '@blocksuite/global/utils';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import clamp from 'lodash-es/clamp';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||
import type { EdgelessRootBlockComponent } from '../index.js';
|
||||
import { prepareCloneData } from '../utils/clone-utils.js';
|
||||
import { calPanDelta } from '../utils/panning-utils.js';
|
||||
import { isCanvasElement, isEdgelessTextBlock } from '../utils/query.js';
|
||||
@@ -191,10 +190,8 @@ export class DefaultTool extends BaseTool {
|
||||
|
||||
enableHover = true;
|
||||
|
||||
private get _edgeless(): EdgelessRootBlockComponent | null {
|
||||
const block = this.std.view.getBlock(this.doc.root!.id);
|
||||
|
||||
return (block as EdgelessRootBlockComponent) ?? null;
|
||||
private get _edgeless(): BlockComponent | null {
|
||||
return this.std.view.getBlock(this.doc.root!.id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,7 +240,11 @@ export class DefaultTool extends BaseTool {
|
||||
private async _cloneContent() {
|
||||
if (!this._edgeless) return;
|
||||
|
||||
const clipboardController = this._edgeless?.clipboardController;
|
||||
// FIXME: edgeless clipboard should be an extension
|
||||
const clipboardController = (
|
||||
this._edgeless as EdgelessRootBlockComponent | null
|
||||
)?.clipboardController;
|
||||
if (!clipboardController) return;
|
||||
const snapshot = prepareCloneData(this._toBeMoved, this.std);
|
||||
|
||||
const bound = getCommonBoundWithRotation(this._toBeMoved);
|
||||
@@ -551,7 +552,6 @@ export class DefaultTool extends BaseTool {
|
||||
this._stopAutoPanning();
|
||||
this._clearDisposable();
|
||||
this._accumulateDelta = [0, 0];
|
||||
noop();
|
||||
}
|
||||
|
||||
override doubleClick(e: PointerEventState) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
EdgelessFrameManager,
|
||||
EdgelessFrameManagerIdentifier,
|
||||
isFrameBlock,
|
||||
} from '@blocksuite/affine-block-frame';
|
||||
import { isNoteBlock } from '@blocksuite/affine-block-surface';
|
||||
@@ -13,6 +14,7 @@ import type {
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { getElementsWithoutGroup } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockComponent } from '@blocksuite/block-std';
|
||||
import {
|
||||
generateKeyBetweenV2,
|
||||
type GfxModel,
|
||||
@@ -99,7 +101,7 @@ type FrameSnapshot = BlockSnapshot & {
|
||||
|
||||
export function createNewPresentationIndexes(
|
||||
raw: (SerializedElement | BlockSnapshot)[],
|
||||
edgeless: EdgelessRootBlockComponent
|
||||
edgeless: BlockComponent
|
||||
) {
|
||||
const frames = raw
|
||||
.filter((block): block is FrameSnapshot => {
|
||||
@@ -108,7 +110,7 @@ export function createNewPresentationIndexes(
|
||||
})
|
||||
.sort((a, b) => EdgelessFrameManager.framePresentationComparator(a, b));
|
||||
|
||||
const frameMgr = edgeless.service.frame;
|
||||
const frameMgr = edgeless.std.get(EdgelessFrameManagerIdentifier);
|
||||
let before = frameMgr.generatePresentationIndex();
|
||||
const result = new Map<string, string>();
|
||||
frames.forEach(frame => {
|
||||
|
||||
@@ -5,6 +5,8 @@ import type {
|
||||
GroupElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { ShapeElementModel } from '@blocksuite/affine-model';
|
||||
import type { BlockComponent } from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type { IVec } from '@blocksuite/global/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
@@ -14,28 +16,31 @@ import { EdgelessConnectorLabelEditor } from '../components/text/edgeless-connec
|
||||
import { EdgelessFrameTitleEditor } from '../components/text/edgeless-frame-title-editor.js';
|
||||
import { EdgelessGroupTitleEditor } from '../components/text/edgeless-group-title-editor.js';
|
||||
import { EdgelessShapeTextEditor } from '../components/text/edgeless-shape-text-editor.js';
|
||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||
|
||||
export function mountShapeTextEditor(
|
||||
shapeElement: ShapeElementModel,
|
||||
edgeless: EdgelessRootBlockComponent
|
||||
edgeless: BlockComponent
|
||||
) {
|
||||
if (!edgeless.mountElm) {
|
||||
const mountElm = edgeless.querySelector('.edgeless-mount-point');
|
||||
if (!mountElm) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.ValueNotExists,
|
||||
"edgeless block's mount point does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
const updatedElement = edgeless.service.crud.getElementById(shapeElement.id);
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
const crud = edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
|
||||
const updatedElement = crud.getElementById(shapeElement.id);
|
||||
|
||||
if (!(updatedElement instanceof ShapeElementModel)) {
|
||||
console.error('Cannot mount text editor on a non-shape element');
|
||||
return;
|
||||
}
|
||||
|
||||
edgeless.gfx.tool.setTool('default');
|
||||
edgeless.gfx.selection.set({
|
||||
gfx.tool.setTool('default');
|
||||
gfx.selection.set({
|
||||
elements: [shapeElement.id],
|
||||
editing: true,
|
||||
});
|
||||
@@ -52,22 +57,25 @@ export function mountShapeTextEditor(
|
||||
shapeEditor.edgeless = edgeless;
|
||||
shapeEditor.mountEditor = mountShapeTextEditor;
|
||||
|
||||
edgeless.mountElm.append(shapeEditor);
|
||||
mountElm.append(shapeEditor);
|
||||
}
|
||||
|
||||
export function mountFrameTitleEditor(
|
||||
frame: FrameBlockModel,
|
||||
edgeless: EdgelessRootBlockComponent
|
||||
edgeless: BlockComponent
|
||||
) {
|
||||
if (!edgeless.mountElm) {
|
||||
const mountElm = edgeless.querySelector('.edgeless-mount-point');
|
||||
if (!mountElm) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.ValueNotExists,
|
||||
"edgeless block's mount point does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
edgeless.gfx.tool.setTool('default');
|
||||
edgeless.gfx.selection.set({
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
gfx.tool.setTool('default');
|
||||
gfx.selection.set({
|
||||
elements: [frame.id],
|
||||
editing: true,
|
||||
});
|
||||
@@ -76,22 +84,25 @@ export function mountFrameTitleEditor(
|
||||
frameEditor.frameModel = frame;
|
||||
frameEditor.edgeless = edgeless;
|
||||
|
||||
edgeless.mountElm.append(frameEditor);
|
||||
mountElm.append(frameEditor);
|
||||
}
|
||||
|
||||
export function mountGroupTitleEditor(
|
||||
group: GroupElementModel,
|
||||
edgeless: EdgelessRootBlockComponent
|
||||
edgeless: BlockComponent
|
||||
) {
|
||||
if (!edgeless.mountElm) {
|
||||
const mountElm = edgeless.querySelector('.edgeless-mount-point');
|
||||
if (!mountElm) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.ValueNotExists,
|
||||
"edgeless block's mount point does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
edgeless.gfx.tool.setTool('default');
|
||||
edgeless.gfx.selection.set({
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
gfx.tool.setTool('default');
|
||||
gfx.selection.set({
|
||||
elements: [group.id],
|
||||
editing: true,
|
||||
});
|
||||
@@ -100,23 +111,26 @@ export function mountGroupTitleEditor(
|
||||
groupEditor.group = group;
|
||||
groupEditor.edgeless = edgeless;
|
||||
|
||||
edgeless.mountElm.append(groupEditor);
|
||||
mountElm.append(groupEditor);
|
||||
}
|
||||
|
||||
export function mountConnectorLabelEditor(
|
||||
connector: ConnectorElementModel,
|
||||
edgeless: EdgelessRootBlockComponent,
|
||||
edgeless: BlockComponent,
|
||||
point?: IVec
|
||||
) {
|
||||
if (!edgeless.mountElm) {
|
||||
const mountElm = edgeless.querySelector('.edgeless-mount-point');
|
||||
if (!mountElm) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.ValueNotExists,
|
||||
"edgeless block's mount point does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
edgeless.gfx.tool.setTool('default');
|
||||
edgeless.gfx.selection.set({
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
gfx.tool.setTool('default');
|
||||
gfx.selection.set({
|
||||
elements: [connector.id],
|
||||
editing: true,
|
||||
});
|
||||
@@ -146,7 +160,7 @@ export function mountConnectorLabelEditor(
|
||||
editor.connector = connector;
|
||||
editor.edgeless = edgeless;
|
||||
|
||||
edgeless.mountElm.append(editor);
|
||||
mountElm.append(editor);
|
||||
editor.updateComplete
|
||||
.then(() => {
|
||||
editor.inlineEditor?.focusEnd();
|
||||
|
||||
Reference in New Issue
Block a user