mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-15 00:56:26 +08:00
refactor(editor): separate the element renders (#11461)
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-inline-preset": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { TextUtils } from '@blocksuite/affine-block-surface';
|
||||
import { formatBlockCommand } from '@blocksuite/affine-inline-preset';
|
||||
import {
|
||||
EDGELESS_TEXT_BLOCK_MIN_HEIGHT,
|
||||
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
|
||||
type EdgelessTextBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
@@ -23,9 +25,6 @@ import { css, html } from 'lit';
|
||||
import { query, state } from 'lit/decorators.js';
|
||||
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
export const EDGELESS_TEXT_BLOCK_MIN_WIDTH = 50;
|
||||
export const EDGELESS_TEXT_BLOCK_MIN_HEIGHT = 50;
|
||||
|
||||
export class EdgelessTextBlockComponent extends GfxBlockComponent<EdgelessTextBlockModel> {
|
||||
static override styles = css`
|
||||
.edgeless-text-block-container[data-max-width='false'] .inline-editor span {
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
import { createTextActions } from '@blocksuite/affine-gfx-text';
|
||||
import { EdgelessTextBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { createTextActions } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/std';
|
||||
|
||||
export const edgelessTextToolbarConfig = {
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './commands';
|
||||
export * from './edgeless-text-block.js';
|
||||
export * from './edgeless-text-spec.js';
|
||||
export * from './edgelss-toolbar';
|
||||
export * from './edgeless-toolbar';
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"references": [
|
||||
{ "path": "../block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../gfx/text" },
|
||||
{ "path": "../../inlines/preset" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
|
||||
@@ -1,9 +1,26 @@
|
||||
import { FileDropExtension } from '@blocksuite/affine-components/drop-indicator';
|
||||
import { ConnectorElementView } from '@blocksuite/affine-gfx-connector';
|
||||
import { GroupElementView } from '@blocksuite/affine-gfx-group';
|
||||
import { MindMapView } from '@blocksuite/affine-gfx-mindmap';
|
||||
import { ShapeElementView } from '@blocksuite/affine-gfx-shape';
|
||||
import { TextElementView } from '@blocksuite/affine-gfx-text';
|
||||
import { BrushElementRendererExtension } from '@blocksuite/affine-gfx-brush';
|
||||
import {
|
||||
ConnectorElementRendererExtension,
|
||||
ConnectorElementView,
|
||||
} from '@blocksuite/affine-gfx-connector';
|
||||
import {
|
||||
GroupElementRendererExtension,
|
||||
GroupElementView,
|
||||
} from '@blocksuite/affine-gfx-group';
|
||||
import {
|
||||
MindmapElementRendererExtension,
|
||||
MindMapView,
|
||||
} from '@blocksuite/affine-gfx-mindmap';
|
||||
import {
|
||||
HighlighterElementRendererExtension,
|
||||
ShapeElementRendererExtension,
|
||||
ShapeElementView,
|
||||
} from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
TextElementRendererExtension,
|
||||
TextElementView,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
DNDAPIExtension,
|
||||
@@ -45,6 +62,16 @@ const EdgelessElementViews = [
|
||||
ShapeElementView,
|
||||
];
|
||||
|
||||
export const EdgelessElementRendererExtension: ExtensionType[] = [
|
||||
BrushElementRendererExtension,
|
||||
HighlighterElementRendererExtension,
|
||||
ShapeElementRendererExtension,
|
||||
TextElementRendererExtension,
|
||||
ConnectorElementRendererExtension,
|
||||
GroupElementRendererExtension,
|
||||
MindmapElementRendererExtension,
|
||||
];
|
||||
|
||||
export const CommonSpecs: ExtensionType[] = [
|
||||
FlavourExtension('affine:page'),
|
||||
DocModeService,
|
||||
@@ -57,7 +84,7 @@ export const CommonSpecs: ExtensionType[] = [
|
||||
...RootBlockAdapterExtensions,
|
||||
...clipboardConfigs,
|
||||
...EdgelessElementViews,
|
||||
|
||||
...EdgelessElementRendererExtension,
|
||||
modalWidget,
|
||||
innerModalWidget,
|
||||
SlashMenuExtension,
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
EdgelessCRUDIdentifier,
|
||||
ExportManager,
|
||||
getSurfaceComponent,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { splitIntoLines } from '@blocksuite/affine-gfx-text';
|
||||
import type { ShapeElementModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
BookmarkStyles,
|
||||
@@ -609,7 +609,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
||||
});
|
||||
|
||||
if (typeof content === 'string') {
|
||||
TextUtils.splitIntoLines(content).forEach((line, idx) => {
|
||||
splitIntoLines(content).forEach((line, idx) => {
|
||||
this.crud.addBlock(
|
||||
'affine:paragraph',
|
||||
{ text: new Y.Text(line) },
|
||||
|
||||
+4
-2
@@ -1,4 +1,3 @@
|
||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { EdgelessFrameManagerIdentifier } from '@blocksuite/affine-block-frame';
|
||||
import {
|
||||
CanvasElementType,
|
||||
@@ -13,7 +12,10 @@ import {
|
||||
SHAPE_OVERLAY_WIDTH,
|
||||
ShapeComponentConfig,
|
||||
} from '@blocksuite/affine-gfx-shape';
|
||||
import { mountTextElementEditor } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
insertEdgelessTextCommand,
|
||||
mountTextElementEditor,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import type {
|
||||
Connection,
|
||||
ConnectorElementModel,
|
||||
|
||||
+4
-4
@@ -1,5 +1,4 @@
|
||||
import type { EdgelessTextBlockComponent } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { EDGELESS_TEXT_BLOCK_MIN_WIDTH } from '@blocksuite/affine-block-edgeless-text';
|
||||
import {
|
||||
EMBED_HTML_MIN_HEIGHT,
|
||||
EMBED_HTML_MIN_WIDTH,
|
||||
@@ -14,14 +13,15 @@ import {
|
||||
import {
|
||||
CanvasElementType,
|
||||
isNoteBlock,
|
||||
normalizeShapeBound,
|
||||
OverlayIdentifier,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { isMindmapNode } from '@blocksuite/affine-gfx-mindmap';
|
||||
import { normalizeShapeBound } from '@blocksuite/affine-gfx-shape';
|
||||
import { normalizeTextBound } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
type BookmarkBlockModel,
|
||||
ConnectorElementModel,
|
||||
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
|
||||
type EdgelessTextBlockModel,
|
||||
type EmbedHtmlModel,
|
||||
type EmbedSyncedDocModel,
|
||||
@@ -1278,7 +1278,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
||||
} = element;
|
||||
// If the width of the text element has been changed by dragging,
|
||||
// We need to set hasMaxWidth to true for wrapping the text
|
||||
bound = TextUtils.normalizeTextBound(
|
||||
bound = normalizeTextBound(
|
||||
{
|
||||
yText,
|
||||
fontFamily,
|
||||
|
||||
@@ -6,7 +6,10 @@ import {
|
||||
} from '@blocksuite/affine-gfx-brush';
|
||||
import { connectorToolbarExtension } from '@blocksuite/affine-gfx-connector';
|
||||
import { groupToolbarExtension } from '@blocksuite/affine-gfx-group';
|
||||
import { mindmapToolbarExtension } from '@blocksuite/affine-gfx-mindmap';
|
||||
import {
|
||||
mindmapToolbarExtension,
|
||||
shapeMindmapToolbarExtension,
|
||||
} from '@blocksuite/affine-gfx-mindmap';
|
||||
import { shapeToolbarExtension } from '@blocksuite/affine-gfx-shape';
|
||||
import { textToolbarExtension } from '@blocksuite/affine-gfx-text';
|
||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
||||
@@ -26,14 +29,16 @@ export const EdgelessElementToolbarExtension: ExtensionType[] = [
|
||||
|
||||
connectorToolbarExtension,
|
||||
|
||||
shapeToolbarExtension,
|
||||
|
||||
shapeMindmapToolbarExtension,
|
||||
|
||||
mindmapToolbarExtension,
|
||||
|
||||
textToolbarExtension,
|
||||
|
||||
edgelessTextToolbarExtension,
|
||||
|
||||
shapeToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:*'),
|
||||
config: builtinMiscToolbarConfig,
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
} from '@blocksuite/affine-block-frame';
|
||||
import { ConnectionOverlay } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
BrushElementRendererExtension,
|
||||
BrushTool,
|
||||
EraserTool,
|
||||
HighlighterTool,
|
||||
@@ -53,10 +52,6 @@ export const EdgelessToolExtension: ExtensionType[] = [
|
||||
HighlighterTool,
|
||||
];
|
||||
|
||||
export const EdgelessElementRendererExtension: ExtensionType[] = [
|
||||
BrushElementRendererExtension,
|
||||
];
|
||||
|
||||
export const EdgelessEditExtensions: ExtensionType[] = [
|
||||
ElementTransformManager,
|
||||
ConnectorFilter,
|
||||
@@ -79,5 +74,4 @@ export const EdgelessBuiltInSpecs: ExtensionType[] = [
|
||||
EdgelessToolExtension,
|
||||
EdgelessBuiltInManager,
|
||||
EdgelessEditExtensions,
|
||||
EdgelessElementRendererExtension,
|
||||
].flat();
|
||||
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { addText } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
addText,
|
||||
insertEdgelessTextCommand,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
TelemetryProvider,
|
||||
|
||||
@@ -20,21 +20,10 @@ export {
|
||||
PathGenerator,
|
||||
} from './managers/connector-manager.js';
|
||||
export { CanvasRenderer } from './renderer/canvas-renderer.js';
|
||||
export * from './renderer/elements/group/consts.js';
|
||||
export type { ElementRenderer } from './renderer/elements/index.js';
|
||||
export { normalizeShapeBound } from './renderer/elements/index.js';
|
||||
export { fitContent } from './renderer/elements/shape/utils.js';
|
||||
export * from './renderer/elements/type.js';
|
||||
export { Overlay, OverlayIdentifier } from './renderer/overlay.js';
|
||||
export { ToolOverlay } from './renderer/tool-overlay.js';
|
||||
import {
|
||||
getCursorByCoord,
|
||||
getLineHeight,
|
||||
isFontStyleSupported,
|
||||
isFontWeightSupported,
|
||||
normalizeTextBound,
|
||||
splitIntoLines,
|
||||
} from './renderer/elements/text/utils.js';
|
||||
import {
|
||||
getFontFaces,
|
||||
getFontFacesByFontFamily,
|
||||
@@ -80,12 +69,6 @@ export const ConnectorUtils = {
|
||||
};
|
||||
|
||||
export const TextUtils = {
|
||||
splitIntoLines,
|
||||
normalizeTextBound,
|
||||
getLineHeight,
|
||||
getCursorByCoord,
|
||||
isFontWeightSupported,
|
||||
isFontStyleSupported,
|
||||
wrapFontFamily,
|
||||
getFontFaces,
|
||||
getFontFacesByFontFamily,
|
||||
|
||||
@@ -4,16 +4,8 @@ import type {
|
||||
GfxPrimitiveElementModel,
|
||||
} from '@blocksuite/std/gfx';
|
||||
|
||||
import { ElementRendererExtension } from '../../extensions/element-renderer.js';
|
||||
import type { RoughCanvas } from '../../index.js';
|
||||
import type { CanvasRenderer } from '../canvas-renderer.js';
|
||||
import { connector } from './connector/index.js';
|
||||
import { group } from './group/index.js';
|
||||
import { highlighter } from './highlighter/index.js';
|
||||
import { mindmap } from './mindmap.js';
|
||||
import { shape } from './shape/index.js';
|
||||
import { text } from './text/index.js';
|
||||
export { normalizeShapeBound } from './shape/utils.js';
|
||||
|
||||
export type ElementRenderer<
|
||||
T extends
|
||||
@@ -28,41 +20,4 @@ export type ElementRenderer<
|
||||
viewportBound: IBound
|
||||
) => void;
|
||||
|
||||
export const HighlighterElementRendererExtension = ElementRendererExtension(
|
||||
'highlighter',
|
||||
highlighter
|
||||
);
|
||||
|
||||
export const ConnectorElementRendererExtension = ElementRendererExtension(
|
||||
'connector',
|
||||
connector
|
||||
);
|
||||
|
||||
export const GroupElementRendererExtension = ElementRendererExtension(
|
||||
'group',
|
||||
group
|
||||
);
|
||||
|
||||
export const ShapeElementRendererExtension = ElementRendererExtension(
|
||||
'shape',
|
||||
shape
|
||||
);
|
||||
|
||||
export const TextElementRendererExtension = ElementRendererExtension(
|
||||
'text',
|
||||
text
|
||||
);
|
||||
|
||||
export const MindmapElementRendererExtension = ElementRendererExtension(
|
||||
'mindmap',
|
||||
mindmap
|
||||
);
|
||||
|
||||
export const elementRendererExtensions = [
|
||||
HighlighterElementRendererExtension,
|
||||
ConnectorElementRendererExtension,
|
||||
GroupElementRendererExtension,
|
||||
ShapeElementRendererExtension,
|
||||
TextElementRendererExtension,
|
||||
MindmapElementRendererExtension,
|
||||
];
|
||||
export const elementRendererExtensions = [];
|
||||
|
||||
@@ -11,14 +11,12 @@ import {
|
||||
EdgelessLegacySlotExtension,
|
||||
} from './extensions';
|
||||
import { ExportManagerExtension } from './extensions/export-manager/export-manager';
|
||||
import { elementRendererExtensions } from './renderer/elements';
|
||||
|
||||
const CommonSurfaceBlockSpec: ExtensionType[] = [
|
||||
FlavourExtension('affine:surface'),
|
||||
EdgelessCRUDExtension,
|
||||
EdgelessLegacySlotExtension,
|
||||
ExportManagerExtension,
|
||||
...elementRendererExtensions,
|
||||
];
|
||||
|
||||
export const PageSurfaceBlockSpec: ExtensionType[] = [
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
|
||||
+25
-20
@@ -1,3 +1,18 @@
|
||||
import {
|
||||
type CanvasRenderer,
|
||||
ConnectorUtils,
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
type RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
getTextWidth,
|
||||
isRTL,
|
||||
type TextDelta,
|
||||
wrapTextDeltas,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
type ConnectorElementModel,
|
||||
ConnectorMode,
|
||||
@@ -11,17 +26,6 @@ import {
|
||||
} from '@blocksuite/global/gfx';
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
|
||||
import { isConnectorWithLabel } from '../../../managers/connector-manager.js';
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
getTextWidth,
|
||||
isRTL,
|
||||
type TextDelta,
|
||||
wrapTextDeltas,
|
||||
} from '../text/utils.js';
|
||||
import {
|
||||
DEFAULT_ARROW_SIZE,
|
||||
getArrowOptions,
|
||||
@@ -31,13 +35,9 @@ import {
|
||||
renderTriangle,
|
||||
} from './utils.js';
|
||||
|
||||
export function connector(
|
||||
model: ConnectorElementModel | LocalConnectorElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer,
|
||||
rc: RoughCanvas
|
||||
) {
|
||||
export const connector: ElementRenderer<
|
||||
ConnectorElementModel | LocalConnectorElementModel
|
||||
> = (model, ctx, matrix, renderer, rc) => {
|
||||
const {
|
||||
mode,
|
||||
path: points,
|
||||
@@ -55,7 +55,7 @@ export function connector(
|
||||
|
||||
ctx.setTransform(matrix);
|
||||
|
||||
const hasLabel = isConnectorWithLabel(model);
|
||||
const hasLabel = ConnectorUtils.isConnectorWithLabel(model);
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
|
||||
@@ -120,7 +120,12 @@ export function connector(
|
||||
renderer
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const ConnectorElementRendererExtension = ElementRendererExtension(
|
||||
'connector',
|
||||
connector
|
||||
);
|
||||
|
||||
function renderPoints(
|
||||
model: ConnectorElementModel | LocalConnectorElementModel,
|
||||
+1
-2
@@ -1,3 +1,4 @@
|
||||
import type { RoughCanvas } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
type ConnectorElementModel,
|
||||
ConnectorMode,
|
||||
@@ -14,8 +15,6 @@ import {
|
||||
Vec,
|
||||
} from '@blocksuite/global/gfx';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
|
||||
type ConnectorEnd = 'Front' | 'Rear';
|
||||
|
||||
export const DEFAULT_ARROW_SIZE = 15;
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './connector-tool';
|
||||
export * from './element-renderer';
|
||||
export * from './element-transform';
|
||||
export * from './text';
|
||||
export * from './toolbar/config';
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import {
|
||||
EdgelessCRUDIdentifier,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import { getLineHeight } from '@blocksuite/affine-gfx-text';
|
||||
import type { ConnectorElementModel } from '@blocksuite/affine-model';
|
||||
import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -319,11 +317,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
||||
labelConstraints: { hasMaxWidth, maxWidth },
|
||||
} = connector;
|
||||
|
||||
const lineHeight = TextUtils.getLineHeight(
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight
|
||||
);
|
||||
const lineHeight = getLineHeight(fontFamily, fontSize, fontWeight);
|
||||
const { translateX, translateY, zoom } = this.gfx.viewport;
|
||||
const [x, y] = Vec.mul(connector.getPointByOffsetDistance(distance), zoom);
|
||||
const transformOperation = [
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import {
|
||||
ConnectorUtils,
|
||||
EdgelessCRUDIdentifier,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
packColor,
|
||||
type PickColorEvent,
|
||||
} from '@blocksuite/affine-components/color-picker';
|
||||
import type { LineDetailType } from '@blocksuite/affine-components/edgeless-line-styles-panel';
|
||||
import {
|
||||
createTextActions,
|
||||
normalizeTextBound,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
ConnectorElementModel,
|
||||
type ConnectorElementProps,
|
||||
@@ -33,7 +36,6 @@ import {
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type { MenuItem } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import {
|
||||
createTextActions,
|
||||
getRootBlock,
|
||||
LINE_STYLE_LIST,
|
||||
renderMenu,
|
||||
@@ -368,7 +370,7 @@ export const connectorToolbarConfig = {
|
||||
} = model;
|
||||
const prevBounds = Bound.fromXYWH(labelXYWH || [0, 0, 16, 16]);
|
||||
const center = prevBounds.center;
|
||||
const bounds = TextUtils.normalizeTextBound(
|
||||
const bounds = normalizeTextBound(
|
||||
{
|
||||
yText: text!,
|
||||
fontFamily,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
{ "path": "../../shared" },
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
|
||||
+17
-8
@@ -1,15 +1,19 @@
|
||||
import {
|
||||
type CanvasRenderer,
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import { titleRenderParams } from './utils.js';
|
||||
|
||||
export function group(
|
||||
model: GroupElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer
|
||||
) {
|
||||
export const group: ElementRenderer<GroupElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer
|
||||
) => {
|
||||
const { xywh } = model;
|
||||
const bound = Bound.deserialize(xywh);
|
||||
const elements = renderer.provider.selectedElements?.() || [];
|
||||
@@ -34,7 +38,12 @@ export function group(
|
||||
|
||||
if (model.showTitle) renderTitle(model, ctx, renderer, renderParams);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const GroupElementRendererExtension = ElementRendererExtension(
|
||||
'group',
|
||||
group
|
||||
);
|
||||
|
||||
function renderTitle(
|
||||
model: GroupElementModel,
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { FontWeight } from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
getLineWidth,
|
||||
truncateTextByWidth,
|
||||
} from '../text/utils.js';
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { FontWeight } from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
|
||||
import {
|
||||
GROUP_TITLE_FONT,
|
||||
GROUP_TITLE_FONT_SIZE,
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './command';
|
||||
export * from './element-renderer';
|
||||
export * from './text/text';
|
||||
export * from './toolbar/config';
|
||||
export * from './view';
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import {
|
||||
GROUP_TITLE_FONT_SIZE,
|
||||
GROUP_TITLE_OFFSET,
|
||||
GROUP_TITLE_PADDING,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
@@ -21,6 +16,12 @@ import { html, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import {
|
||||
GROUP_TITLE_FONT_SIZE,
|
||||
GROUP_TITLE_OFFSET,
|
||||
GROUP_TITLE_PADDING,
|
||||
} from '../element-renderer/consts';
|
||||
|
||||
export function mountGroupTitleEditor(
|
||||
group: GroupElementModel,
|
||||
edgeless: BlockComponent
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
{ "path": "../../shared" },
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"@blocksuite/affine-block-image": "workspace:*",
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
|
||||
+29
-16
@@ -1,23 +1,23 @@
|
||||
import {
|
||||
ConnectorPathGenerator,
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { connector as renderConnector } from '@blocksuite/affine-gfx-connector';
|
||||
import type {
|
||||
MindmapElementModel,
|
||||
MindmapNode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type { IBound } from '@blocksuite/global/gfx';
|
||||
import type { GfxModel } from '@blocksuite/std/gfx';
|
||||
|
||||
import { ConnectorPathGenerator } from '../../managers/connector-manager.js';
|
||||
import type { RoughCanvas } from '../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../canvas-renderer.js';
|
||||
import { connector as renderConnector } from './connector/index.js';
|
||||
|
||||
export function mindmap(
|
||||
model: MindmapElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer,
|
||||
rc: RoughCanvas,
|
||||
bound: IBound
|
||||
) {
|
||||
export const mindmap: ElementRenderer<MindmapElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer,
|
||||
rc,
|
||||
bound
|
||||
) => {
|
||||
const dx = model.x - bound.x;
|
||||
const dy = model.y - bound.y;
|
||||
|
||||
@@ -48,7 +48,15 @@ export function mindmap(
|
||||
ctx.globalAlpha = connector.opacity * mindmapOpacity;
|
||||
}
|
||||
|
||||
renderConnector(connector, ctx, matrix.translate(dx, dy), renderer, rc);
|
||||
renderConnector(
|
||||
connector,
|
||||
ctx,
|
||||
matrix.translate(dx, dy),
|
||||
renderer,
|
||||
rc,
|
||||
// NOTE: should we add this?
|
||||
bound
|
||||
);
|
||||
|
||||
if (shouldSetGlobalAlpha) {
|
||||
ctx.globalAlpha = origin;
|
||||
@@ -63,4 +71,9 @@ export function mindmap(
|
||||
};
|
||||
|
||||
model.tree && traverse(model.tree);
|
||||
}
|
||||
};
|
||||
|
||||
export const MindmapElementRendererExtension = ElementRendererExtension(
|
||||
'mindmap',
|
||||
mindmap
|
||||
);
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './element-renderer';
|
||||
export * from './element-transform';
|
||||
export * from './indicator-overlay';
|
||||
export * from './toolbar/config';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { addImages } from '@blocksuite/affine-block-image';
|
||||
import {
|
||||
CanvasElementType,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { mountTextElementEditor } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
insertEdgelessTextCommand,
|
||||
mountTextElementEditor,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
MAX_IMAGE_WIDTH,
|
||||
type MindmapStyle,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { hasGrouped } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
LayoutType,
|
||||
MindmapElementModel,
|
||||
MindmapStyle,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
type ToolbarContext,
|
||||
@@ -130,7 +132,68 @@ export const mindmapToolbarConfig = {
|
||||
when: ctx => ctx.getSurfaceModelsByType(MindmapElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const shapeMindmapToolbarConfig = {
|
||||
actions: [
|
||||
{
|
||||
id: 'a.mindmap-style',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
return createMindmapStyleActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'b.mindmap-layout',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
// It's a sub node.
|
||||
if (models.length === 1 && mindmaps[0].tree.element !== models[0])
|
||||
return null;
|
||||
|
||||
return createMindmapLayoutActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
],
|
||||
when: ctx => ctx.getSurfaceModelsByType(ShapeElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const mindmapToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:mindmap'),
|
||||
config: mindmapToolbarConfig,
|
||||
});
|
||||
|
||||
export const shapeMindmapToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('custom:affine:surface:shape'),
|
||||
config: shapeMindmapToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fitContent } from '@blocksuite/affine-block-surface';
|
||||
import { fitContent } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
applyNodeStyle,
|
||||
LayoutType,
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
{ "path": "../../blocks/block-image" },
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../connector" },
|
||||
{ "path": "../shape" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
|
||||
+16
-9
@@ -1,16 +1,18 @@
|
||||
import {
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTheme,
|
||||
type HighlighterElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
|
||||
export function highlighter(
|
||||
model: HighlighterElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer
|
||||
) {
|
||||
export const highlighter: ElementRenderer<HighlighterElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer
|
||||
) => {
|
||||
const {
|
||||
rotate,
|
||||
deserializedXYWH: [, , w, h],
|
||||
@@ -31,4 +33,9 @@ export function highlighter(
|
||||
ctx.fillStyle = color;
|
||||
|
||||
ctx.fill(new Path2D(model.commands));
|
||||
}
|
||||
};
|
||||
|
||||
export const HighlighterElementRendererExtension = ElementRendererExtension(
|
||||
'highlighter',
|
||||
highlighter
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './highlighter';
|
||||
export * from './shape';
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
import type {
|
||||
CanvasRenderer,
|
||||
RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import { type Colors, drawGeneralShape } from './utils.js';
|
||||
|
||||
export function diamond(
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
import type {
|
||||
CanvasRenderer,
|
||||
RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import { type Colors, drawGeneralShape } from './utils.js';
|
||||
|
||||
export function ellipse(
|
||||
+29
-18
@@ -1,3 +1,17 @@
|
||||
import {
|
||||
type CanvasRenderer,
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
type RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
getFontMetrics,
|
||||
getFontString,
|
||||
getLineWidth,
|
||||
isRTL,
|
||||
measureTextInDOM,
|
||||
wrapTextDeltas,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
@@ -8,16 +22,6 @@ import type { IBound } from '@blocksuite/global/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import {
|
||||
getFontMetrics,
|
||||
getFontString,
|
||||
getLineWidth,
|
||||
isRTL,
|
||||
measureTextInDOM,
|
||||
wrapTextDeltas,
|
||||
} from '../text/utils.js';
|
||||
import { diamond } from './diamond.js';
|
||||
import { ellipse } from './ellipse.js';
|
||||
import { rect } from './rect.js';
|
||||
@@ -41,13 +45,13 @@ const shapeRenderers: Record<
|
||||
ellipse,
|
||||
};
|
||||
|
||||
export function shape(
|
||||
model: ShapeElementModel | LocalShapeElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer,
|
||||
rc: RoughCanvas
|
||||
) {
|
||||
export const shape: ElementRenderer<ShapeElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer,
|
||||
rc
|
||||
) => {
|
||||
const color = renderer.getColorValue(
|
||||
model.color,
|
||||
DefaultTheme.shapeTextColor,
|
||||
@@ -70,7 +74,14 @@ export function shape(
|
||||
if (model.textDisplay) {
|
||||
renderText(model, ctx, colors);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const ShapeElementRendererExtension = ElementRendererExtension(
|
||||
'shape',
|
||||
shape
|
||||
);
|
||||
|
||||
export * from './utils';
|
||||
|
||||
function renderText(
|
||||
model: ShapeElementModel | LocalShapeElementModel,
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
import type {
|
||||
CanvasRenderer,
|
||||
RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import { type Colors, drawGeneralShape } from './utils.js';
|
||||
|
||||
/**
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
import type {
|
||||
CanvasRenderer,
|
||||
RoughCanvas,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
import type { RoughCanvas } from '../../../utils/rough/canvas.js';
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import { type Colors, drawGeneralShape } from './utils.js';
|
||||
|
||||
export function triangle(
|
||||
+11
-12
@@ -1,14 +1,4 @@
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
TextAlign,
|
||||
TextVerticalAlign,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { Bound, SerializedXYWH } from '@blocksuite/global/gfx';
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import type { CanvasRenderer } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
@@ -18,7 +8,16 @@ import {
|
||||
type TextDelta,
|
||||
wrapText,
|
||||
wrapTextDeltas,
|
||||
} from '../text/utils.js';
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import type {
|
||||
LocalShapeElementModel,
|
||||
ShapeElementModel,
|
||||
TextAlign,
|
||||
TextVerticalAlign,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { Bound, SerializedXYWH } from '@blocksuite/global/gfx';
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
|
||||
export type Colors = {
|
||||
color: string;
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './consts';
|
||||
export * from './draggable';
|
||||
export * from './element-renderer';
|
||||
export * from './overlay';
|
||||
export * from './shape-tool';
|
||||
export * from './text';
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
import {
|
||||
EdgelessCRUDIdentifier,
|
||||
normalizeShapeBound,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
packColor,
|
||||
type PickColorEvent,
|
||||
} from '@blocksuite/affine-components/color-picker';
|
||||
import type { LineDetailType } from '@blocksuite/affine-components/edgeless-line-styles-panel';
|
||||
import {
|
||||
createMindmapLayoutActionMenu,
|
||||
createMindmapStyleActionMenu,
|
||||
} from '@blocksuite/affine-gfx-mindmap';
|
||||
import { createTextActions } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
type Color,
|
||||
DefaultTheme,
|
||||
@@ -35,7 +29,6 @@ import {
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { getMostCommonValue } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
createTextActions,
|
||||
getRootBlock,
|
||||
LINE_STYLE_LIST,
|
||||
renderMenu,
|
||||
@@ -46,62 +39,13 @@ import { BlockFlavourIdentifier } from '@blocksuite/std';
|
||||
import { html } from 'lit';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
|
||||
import { normalizeShapeBound } from '../element-renderer';
|
||||
import type { ShapeToolOption } from '../shape-tool';
|
||||
import { mountShapeTextEditor } from '../text/edgeless-shape-text-editor';
|
||||
import { ShapeComponentConfig } from './shape-menu-config';
|
||||
|
||||
export const shapeToolbarConfig = {
|
||||
actions: [
|
||||
{
|
||||
id: 'a.mindmap-style',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
return createMindmapStyleActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'b.mindmap-layout',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
// It's a sub node.
|
||||
if (models.length === 1 && mindmaps[0].tree.element !== models[0])
|
||||
return null;
|
||||
|
||||
return createMindmapLayoutActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'c.switch-type',
|
||||
when(ctx) {
|
||||
@@ -386,7 +330,7 @@ function getTextColor(fillColor: Color, isNotTransparent = false) {
|
||||
return DefaultTheme.shapeTextColor;
|
||||
}
|
||||
|
||||
function hasGrouped(model: ShapeElementModel) {
|
||||
export function hasGrouped(model: ShapeElementModel) {
|
||||
return model.group instanceof MindmapElementModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../mindmap" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
{ "path": "../../shared" },
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*",
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
|
||||
+10
-9
@@ -2,16 +2,16 @@ import {
|
||||
EdgelessCRUDIdentifier,
|
||||
getSurfaceBlock,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { focusTextModel } from '@blocksuite/affine-rich-text';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import type { Command } from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
import {
|
||||
EDGELESS_TEXT_BLOCK_MIN_HEIGHT,
|
||||
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
|
||||
EdgelessTextBlockComponent,
|
||||
} from '../edgeless-text-block.js';
|
||||
EdgelessTextBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { focusTextModel } from '@blocksuite/affine-rich-text';
|
||||
import { matchModels } from '@blocksuite/affine-shared/utils';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import type { Command } from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
export const insertEdgelessTextCommand: Command<
|
||||
{
|
||||
@@ -59,8 +59,9 @@ export const insertEdgelessTextCommand: Command<
|
||||
const id = selection.selectedIds[0];
|
||||
if (!editing || id !== textId) {
|
||||
const textBlock = host.view.getBlock(textId);
|
||||
if (textBlock instanceof EdgelessTextBlockComponent) {
|
||||
textBlock.model.props.hasMaxWidth = true;
|
||||
const model = textBlock?.model;
|
||||
if (matchModels(model, [EdgelessTextBlockModel])) {
|
||||
model.props.hasMaxWidth = true;
|
||||
}
|
||||
|
||||
disposable.unsubscribe();
|
||||
@@ -26,6 +26,8 @@ import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { getCursorByCoord, getLineHeight } from './element-renderer/utils';
|
||||
|
||||
export function mountTextElementEditor(
|
||||
textElement: TextElementModel,
|
||||
edgeless: BlockComponent,
|
||||
@@ -34,7 +36,7 @@ export function mountTextElementEditor(
|
||||
let cursorIndex = textElement.text.length;
|
||||
if (focusCoord) {
|
||||
cursorIndex = Math.min(
|
||||
TextUtils.getCursorByCoord(textElement, focusCoord),
|
||||
getCursorByCoord(textElement, focusCoord),
|
||||
cursorIndex
|
||||
);
|
||||
}
|
||||
@@ -413,11 +415,7 @@ export class EdgelessTextEditor extends WithDisposable(ShadowlessElement) {
|
||||
hasMaxWidth,
|
||||
w,
|
||||
} = this.element;
|
||||
const lineHeight = TextUtils.getLineHeight(
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight
|
||||
);
|
||||
const lineHeight = getLineHeight(fontFamily, fontSize, fontWeight);
|
||||
const rect = getSelectedRect([this.element]);
|
||||
|
||||
const { translateX, translateY, zoom } = this.gfx.viewport;
|
||||
|
||||
+18
-8
@@ -1,7 +1,10 @@
|
||||
import {
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { DefaultTheme, type TextElementModel } from '@blocksuite/affine-model';
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
|
||||
import type { CanvasRenderer } from '../../canvas-renderer.js';
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
@@ -10,12 +13,12 @@ import {
|
||||
wrapTextDeltas,
|
||||
} from './utils.js';
|
||||
|
||||
export function text(
|
||||
model: TextElementModel,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
matrix: DOMMatrix,
|
||||
renderer: CanvasRenderer
|
||||
) {
|
||||
export const text: ElementRenderer<TextElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer
|
||||
) => {
|
||||
const { fontSize, fontWeight, fontStyle, fontFamily, textAlign, rotate } =
|
||||
model;
|
||||
const [, , w, h] = model.deserializedXYWH;
|
||||
@@ -81,4 +84,11 @@ export function text(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const TextElementRendererExtension = ElementRendererExtension(
|
||||
'text',
|
||||
text
|
||||
);
|
||||
|
||||
export * from './utils';
|
||||
+2
-4
@@ -1,3 +1,4 @@
|
||||
import { TextUtils } from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
FontFamily,
|
||||
FontStyle,
|
||||
@@ -12,10 +13,7 @@ import {
|
||||
import { deltaInsertsToChunks } from '@blocksuite/std/inline';
|
||||
import type * as Y from 'yjs';
|
||||
|
||||
import {
|
||||
getFontFacesByFontFamily,
|
||||
wrapFontFamily,
|
||||
} from '../../../utils/font.js';
|
||||
const { getFontFacesByFontFamily, wrapFontFamily } = TextUtils;
|
||||
|
||||
export type TextDelta = {
|
||||
insert: string;
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from './commands';
|
||||
export * from './edgeless-text-editor';
|
||||
export * from './element-renderer';
|
||||
export * from './tool';
|
||||
export * from './toolbar';
|
||||
export * from './view';
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
CanvasElementType,
|
||||
EdgelessCRUDIdentifier,
|
||||
type IModelCoord,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { TextElementModel } from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
@@ -11,6 +10,7 @@ import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { EdgelessTextEditor } from './edgeless-text-editor';
|
||||
import { getCursorByCoord } from './element-renderer/utils';
|
||||
|
||||
export function mountTextElementEditor(
|
||||
textElement: TextElementModel,
|
||||
@@ -20,7 +20,7 @@ export function mountTextElementEditor(
|
||||
let cursorIndex = textElement.text.length;
|
||||
if (focusCoord) {
|
||||
cursorIndex = Math.min(
|
||||
TextUtils.getCursorByCoord(textElement, focusCoord),
|
||||
getCursorByCoord(textElement, focusCoord),
|
||||
cursorIndex
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||
import type { TextElementModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
@@ -9,6 +8,7 @@ import type { PointerEventState } from '@blocksuite/std';
|
||||
import { BaseTool, type GfxController } from '@blocksuite/std/gfx';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { insertEdgelessTextCommand } from './commands/insert-edgeless-text';
|
||||
import { mountTextElementEditor } from './mount-text-editor';
|
||||
|
||||
function addText(gfx: GfxController, event: PointerEventState) {
|
||||
|
||||
+11
-4
@@ -25,6 +25,11 @@ import {
|
||||
getMostCommonResolvedValue,
|
||||
getMostCommonValue,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
type MenuItem,
|
||||
renderCurrentMenuItemWith,
|
||||
renderMenu,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import {
|
||||
TextAlignCenterIcon,
|
||||
TextAlignLeftIcon,
|
||||
@@ -35,8 +40,10 @@ import { signal } from '@preact/signals-core';
|
||||
import { html } from 'lit';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { MenuItem } from './types';
|
||||
import { renderCurrentMenuItemWith, renderMenu } from './utils';
|
||||
import {
|
||||
isFontStyleSupported,
|
||||
isFontWeightSupported,
|
||||
} from '../element-renderer/utils';
|
||||
|
||||
const FONT_WEIGHT_LIST = [
|
||||
{
|
||||
@@ -133,10 +140,10 @@ export function createTextActions<
|
||||
getMostCommonValue(models.map(mapInto), 'fontStyle') ??
|
||||
FontStyle.Normal;
|
||||
|
||||
if (!TextUtils.isFontWeightSupported(fontFamily, fontWeight)) {
|
||||
if (!isFontWeightSupported(fontFamily, fontWeight)) {
|
||||
fontWeight = FontWeight.Regular;
|
||||
}
|
||||
if (!TextUtils.isFontStyleSupported(fontFamily, fontStyle)) {
|
||||
if (!isFontStyleSupported(fontFamily, fontStyle)) {
|
||||
fontStyle = FontStyle.Normal;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import {
|
||||
EdgelessCRUDIdentifier,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import { TextElementModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { createTextActions } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/std';
|
||||
|
||||
import { normalizeTextBound } from '../element-renderer/utils';
|
||||
import { createTextActions } from './actions';
|
||||
|
||||
export const textToolbarConfig = {
|
||||
actions: createTextActions(TextElementModel, 'text', (ctx, model, props) => {
|
||||
// No need to adjust element bounds
|
||||
@@ -30,7 +29,7 @@ export const textToolbarConfig = {
|
||||
|
||||
const { fontFamily, fontStyle, fontSize, fontWeight } = textStyle;
|
||||
|
||||
const bounds = TextUtils.normalizeTextBound(
|
||||
const bounds = normalizeTextBound(
|
||||
{
|
||||
yText,
|
||||
fontFamily,
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './actions';
|
||||
export * from './config';
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-edgeless-text" },
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../model" },
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export const EDGELESS_TEXT_BLOCK_MIN_WIDTH = 50;
|
||||
export const EDGELESS_TEXT_BLOCK_MIN_HEIGHT = 50;
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './connector.js';
|
||||
export * from './doc.js';
|
||||
export * from './edgeless-text.js';
|
||||
export * from './image.js';
|
||||
export * from './line.js';
|
||||
export * from './mindmap.js';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './consts.js';
|
||||
export * from './text-common.js';
|
||||
export * from './types.js';
|
||||
export * from './utils.js';
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import {
|
||||
EDGELESS_TEXT_BLOCK_MIN_HEIGHT,
|
||||
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
|
||||
} from '@blocksuite/affine/blocks/edgeless-text';
|
||||
import { addImages } from '@blocksuite/affine/blocks/image';
|
||||
import { fitContent, getSurfaceBlock } from '@blocksuite/affine/blocks/surface';
|
||||
import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface';
|
||||
import { LightLoadingIcon } from '@blocksuite/affine/components/icons';
|
||||
import { addTree } from '@blocksuite/affine/gfx/mindmap';
|
||||
import { fitContent } from '@blocksuite/affine/gfx/shape';
|
||||
import { Bound } from '@blocksuite/affine/global/gfx';
|
||||
import type {
|
||||
MindmapElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine/model';
|
||||
import {
|
||||
EDGELESS_TEXT_BLOCK_MIN_HEIGHT,
|
||||
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
|
||||
EdgelessTextBlockModel,
|
||||
ImageBlockModel,
|
||||
NoteDisplayMode,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { uploadBlobForImage } from '@blocksuite/affine/blocks/image';
|
||||
import {
|
||||
fitContent,
|
||||
getSurfaceBlock,
|
||||
SurfaceBlockModel,
|
||||
} from '@blocksuite/affine/blocks/surface';
|
||||
import { fitContent } from '@blocksuite/affine/gfx/shape';
|
||||
import { Bound, getCommonBound } from '@blocksuite/affine/global/gfx';
|
||||
import type {
|
||||
MindmapElementModel,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* oxlint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import {
|
||||
CanvasRenderer,
|
||||
fitContent,
|
||||
type SurfaceBlockModel,
|
||||
} from '@blocksuite/affine/blocks/surface';
|
||||
import { fitContent } from '@blocksuite/affine/gfx/shape';
|
||||
import type { Bound } from '@blocksuite/affine/global/gfx';
|
||||
import type { Color, ShapeElementModel } from '@blocksuite/affine/model';
|
||||
import { ThemeProvider } from '@blocksuite/affine/shared/services';
|
||||
|
||||
@@ -173,6 +173,7 @@ export const PackageList = [
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/inlines/preset',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
@@ -475,6 +476,7 @@ export const PackageList = [
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
'blocksuite/affine/shared',
|
||||
@@ -490,6 +492,7 @@ export const PackageList = [
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
'blocksuite/affine/shared',
|
||||
@@ -508,6 +511,8 @@ export const PackageList = [
|
||||
'blocksuite/affine/blocks/block-image',
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/connector',
|
||||
'blocksuite/affine/gfx/shape',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
@@ -542,7 +547,7 @@ export const PackageList = [
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/mindmap',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
'blocksuite/affine/shared',
|
||||
@@ -556,7 +561,6 @@ export const PackageList = [
|
||||
location: 'blocksuite/affine/gfx/text',
|
||||
name: '@blocksuite/affine-gfx-text',
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-edgeless-text',
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/model',
|
||||
|
||||
@@ -2538,6 +2538,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-inline-preset": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
@@ -3049,6 +3050,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
"@blocksuite/affine-shared": "workspace:*"
|
||||
@@ -3076,6 +3078,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
"@blocksuite/affine-shared": "workspace:*"
|
||||
@@ -3106,6 +3109,8 @@ __metadata:
|
||||
"@blocksuite/affine-block-image": "workspace:*"
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*"
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
@@ -3165,7 +3170,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
"@blocksuite/affine-shared": "workspace:*"
|
||||
@@ -3191,7 +3196,6 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@blocksuite/affine-gfx-text@workspace:blocksuite/affine/gfx/text"
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*"
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
|
||||
Reference in New Issue
Block a user