fix designer event pipe

This commit is contained in:
kangwei 2020-03-10 14:16:29 +08:00
parent b59934eb2f
commit fe12ab02f9
12 changed files with 183 additions and 161 deletions

View File

@ -31,22 +31,12 @@ export default class App extends ViewController {
SettingsPane SettingsPane
}; };
editor = { editor = emitter;
on(type: string, fn: any) {
emitter.on(type, fn);
}
}
$didMount() { $didMount() {
const designer = this.$refs.d.designer; const designer = this.$refs.d.designer;
const pane = this.$refs.pane; const pane = this.$refs.pane;
(window as any).LCDesigner = designer; (window as any).LCDesigner = designer;
if (designer.project.activedDocument) {
emitter.emit('designer.actived-document-change', designer.project.activedDocument);
}
designer.project.onActivedDocumentChange((doc: any) => {
emitter.emit('designer.actived-document-change', doc);
});
(this.editor as any).designer = designer; (this.editor as any).designer = designer;
designer.dragon.from(pane, () => { designer.dragon.from(pane, () => {
return { return {

View File

@ -1,5 +1,6 @@
<div className="editor"> <div className="editor">
<DesignView <DesignView
eventPipe={editor}
defaultSchema={{ defaultSchema={{
componentsTree: [ componentsTree: [
{ {
@ -643,7 +644,7 @@
}, },
], ],
}} }}
componentDescriptionSpecs={[ componentsDescription={[
{ {
description: 'Button', description: 'Button',
npm: { package: '@ali/deep', subName: 'Button', destructuring: false, exportName: 'Next', version: '1.17.2' }, npm: { package: '@ali/deep', subName: 'Button', destructuring: false, exportName: 'Next', version: '1.17.2' },

View File

@ -14,6 +14,7 @@ import { ComponentDescription, ComponentType } from './component-type';
import Scroller, { IScrollable } from './helper/scroller'; import Scroller, { IScrollable } from './helper/scroller';
import { INodeSelector } from './simulator'; import { INodeSelector } from './simulator';
import OffsetObserver, { createOffsetObserver } from './helper/offset-observer'; import OffsetObserver, { createOffsetObserver } from './helper/offset-observer';
import { EventEmitter } from 'events';
export interface DesignerProps { export interface DesignerProps {
className?: string; className?: string;
@ -24,12 +25,12 @@ export interface DesignerProps {
simulatorComponent?: ReactComponentType<any>; simulatorComponent?: ReactComponentType<any>;
dragGhostComponent?: ReactComponentType<any>; dragGhostComponent?: ReactComponentType<any>;
suspensed?: boolean; suspensed?: boolean;
componentDescriptionSpecs?: ComponentDescription[]; componentsDescription?: ComponentDescription[];
eventPipe?: EventEmitter;
onMount?: (designer: Designer) => void; onMount?: (designer: Designer) => void;
onDragstart?: (e: LocateEvent) => void; onDragstart?: (e: LocateEvent) => void;
onDrag?: (e: LocateEvent) => void; onDrag?: (e: LocateEvent) => void;
onDragend?: (e: { dragObject: DragObject; copy: boolean }, loc?: Location) => void; onDragend?: (e: { dragObject: DragObject; copy: boolean }, loc?: Location) => void;
// TODO: ...add other events support
[key: string]: any; [key: string]: any;
} }
@ -40,7 +41,21 @@ export default class Designer {
readonly hovering = new Hovering(); readonly hovering = new Hovering();
readonly project: Project; readonly project: Project;
get currentDocument() {
return this.project.currentDocument;
}
get currentHistory() {
return this.currentDocument?.history;
}
get currentSelection() {
return this.currentDocument?.selection;
}
constructor(props: DesignerProps) { constructor(props: DesignerProps) {
this.setProps(props);
this.project = new Project(this, props.defaultSchema); this.project = new Project(this, props.defaultSchema);
this.dragon.onDragstart(e => { this.dragon.onDragstart(e => {
@ -53,12 +68,14 @@ export default class Designer {
if (this.props?.onDragstart) { if (this.props?.onDragstart) {
this.props.onDragstart(e); this.props.onDragstart(e);
} }
this.postEvent('dragstart', e);
}); });
this.dragon.onDrag(e => { this.dragon.onDrag(e => {
if (this.props?.onDrag) { if (this.props?.onDrag) {
this.props.onDrag(e); this.props.onDrag(e);
} }
this.postEvent('drag', e);
}); });
this.dragon.onDragend(e => { this.dragon.onDragend(e => {
@ -84,6 +101,7 @@ export default class Designer {
if (this.props?.onDragend) { if (this.props?.onDragend) {
this.props.onDragend(e, loc); this.props.onDragend(e, loc);
} }
this.postEvent('dragend', e, loc);
this.hovering.enable = true; this.hovering.enable = true;
}); });
@ -91,7 +109,30 @@ export default class Designer {
node.document.simulator?.scrollToNode(node, detail); node.document.simulator?.scrollToNode(node, detail);
}); });
this.setProps(props); let selectionDispose: undefined | (() => void);
const setupSelection = () => {
if (selectionDispose) {
selectionDispose();
selectionDispose = undefined;
}
if (this.currentSelection) {
const currentSelection = this.currentSelection;
selectionDispose = currentSelection.onSelectionChange(() => {
this.postEvent('current-selection-change', currentSelection);
});
}
}
this.project.onCurrentDocumentChange(() => {
this.postEvent('current-document-change', this.currentDocument);
this.postEvent('current-selection-change', this.currentSelection);
this.postEvent('current-history-change', this.currentHistory);
setupSelection();
});
setupSelection();
}
postEvent(event: string, ...args: any[]) {
this.props?.eventPipe?.emit(`designer.${event}`, ...args);
} }
private _dropLocation?: Location; private _dropLocation?: Location;
@ -128,7 +169,7 @@ export default class Designer {
* *
*/ */
getSuitableInsertion() { getSuitableInsertion() {
const activedDoc = this.project.activedDocument; const activedDoc = this.project.currentDocument;
if (!activedDoc) { if (!activedDoc) {
return null; return null;
} }
@ -165,8 +206,8 @@ export default class Designer {
if (props.suspensed !== this.props.suspensed && props.suspensed != null) { if (props.suspensed !== this.props.suspensed && props.suspensed != null) {
this.suspensed = props.suspensed; this.suspensed = props.suspensed;
} }
if (props.componentDescriptionSpecs !== this.props.componentDescriptionSpecs && props.componentDescriptionSpecs != null) { if (props.componentsDescription !== this.props.componentsDescription && props.componentsDescription != null) {
this.buildComponentTypesMap(props.componentDescriptionSpecs); this.buildComponentTypesMap(props.componentsDescription);
} }
} else { } else {
// init hotkeys // init hotkeys
@ -182,8 +223,8 @@ export default class Designer {
if (props.suspensed != null) { if (props.suspensed != null) {
this.suspensed = props.suspensed; this.suspensed = props.suspensed;
} }
if (props.componentDescriptionSpecs != null) { if (props.componentsDescription != null) {
this.buildComponentTypesMap(props.componentDescriptionSpecs); this.buildComponentTypesMap(props.componentsDescription);
} }
} }
this.props = props; this.props = props;

View File

@ -41,11 +41,11 @@ export default class DocumentModel {
} }
get fileName(): string { get fileName(): string {
return (this.rootNode.extras.get('fileName')?.value as string) || this.id; return (this.rootNode.getExtraProp('fileName')?.getAsString()) || this.id;
} }
set fileName(fileName: string) { set fileName(fileName: string) {
this.rootNode.extras.get('fileName', true).value = fileName; this.rootNode.getExtraProp('fileName', true)?.setValue(fileName);
} }
constructor(readonly project: Project, schema: RootSchema) { constructor(readonly project: Project, schema: RootSchema) {
@ -290,7 +290,7 @@ export default class DocumentModel {
return this.designer.getComponentType(componentName); return this.designer.getComponentType(componentName);
} }
@obx.ref private _opened: boolean = true; @obx.ref private _opened: boolean = false;
@obx.ref private _suspensed: boolean = false; @obx.ref private _suspensed: boolean = false;
/** /**
@ -341,7 +341,11 @@ export default class DocumentModel {
* *
*/ */
open(): void { open(): void {
const originState = this._opened;
this._opened = true; this._opened = true;
if (originState === false) {
this.designer.postEvent('document-open', this);
}
if (this._suspensed) { if (this._suspensed) {
this.setSuspense(false); this.setSuspense(false);
} else { } else {

View File

@ -1,6 +1,6 @@
import { obx, computed, untracked } from '@recore/obx'; import { obx, computed, untracked } from '@recore/obx';
import { NodeSchema, NodeData, PropsMap, PropsList } from '../../schema'; import { NodeSchema, NodeData, PropsMap, PropsList } from '../../schema';
import Props from './props/props'; import Props, { EXTRA_KEY_PREFIX } from './props/props';
import DocumentModel from '../document-model'; import DocumentModel from '../document-model';
import NodeChildren from './node-children'; import NodeChildren from './node-children';
import Prop from './props/prop'; import Prop from './props/prop';
@ -8,8 +8,6 @@ import NodeContent from './node-content';
import { Component } from '../../simulator'; import { Component } from '../../simulator';
import { ComponentType } from '../../component-type'; import { ComponentType } from '../../component-type';
const DIRECTIVES = ['condition', 'conditionGroup', 'loop', 'loopArgs', 'title', 'ignore', 'hidden', 'locked'];
/** /**
* *
* *
@ -51,20 +49,11 @@ export default class Node {
*/ */
readonly componentName: string; readonly componentName: string;
protected _props?: Props; protected _props?: Props;
protected _directives?: Props;
protected _extras?: Props;
protected _children: NodeChildren | NodeContent; protected _children: NodeChildren | NodeContent;
@obx.ref private _parent: NodeParent | null = null; @obx.ref private _parent: NodeParent | null = null;
@obx.ref private _zLevel = 0;
get props(): Props | undefined { get props(): Props | undefined {
return this._props; return this._props;
} }
get directives(): Props | undefined {
return this._directives;
}
get extras(): Props | undefined {
return this._extras;
}
/** /**
* *
*/ */
@ -88,7 +77,7 @@ export default class Node {
} }
@computed get title(): string { @computed get title(): string {
let t = this.getDirective('x-title'); let t = this.getExtraProp('title');
if (!t && this.componentType.descriptor) { if (!t && this.componentType.descriptor) {
t = this.getProp(this.componentType.descriptor, false); t = this.getProp(this.componentType.descriptor, false);
} }
@ -111,15 +100,7 @@ export default class Node {
this.componentName = componentName; this.componentName = componentName;
this._slotFor = slotFor; this._slotFor = slotFor;
if (isNodeParent(this)) { if (isNodeParent(this)) {
this._props = new Props(this, props); this._props = new Props(this, props, extras);
this._directives = new Props(this, {});
Object.keys(extras).forEach(key => {
if (DIRECTIVES.indexOf(key) > -1) {
this._directives!.add((extras as any)[key], key);
delete (extras as any)[key];
}
});
this._extras = new Props(this, extras as any);
this._children = new NodeChildren(this as NodeParent, children || []); this._children = new NodeChildren(this as NodeParent, children || []);
} else { } else {
this._children = new NodeContent(children); this._children = new NodeContent(children);
@ -197,22 +178,15 @@ export default class Node {
/** /**
* *
*/ */
@obx.ref get componentType(): ComponentType { @computed get componentType(): ComponentType {
return this.document.getComponentType(this.componentName, this.component); return this.document.getComponentType(this.componentName, this.component);
} }
@obx.ref get propsData(): PropsMap | PropsList | null { @computed get propsData(): PropsMap | PropsList | null {
if (!this.isNodeParent || this.componentName === 'Fragment') { if (!this.isNodeParent || this.componentName === 'Fragment') {
return null; return null;
} }
return this.props?.value || null; return this.props?.export(true).props || null;
}
get directivesData(): PropsMap | null {
if (!this.isNodeParent) {
return null;
}
return this.directives?.value as PropsMap || null;
} }
private _conditionGroup: string | null = null; private _conditionGroup: string | null = null;
@ -261,6 +235,10 @@ export default class Node {
return this.props?.query(path, useStash as any) || null; return this.props?.query(path, useStash as any) || null;
} }
getExtraProp(key: string, useStash: boolean = true): Prop | null {
return this.props?.get(EXTRA_KEY_PREFIX + key, useStash) || null;
}
/** /**
* *
*/ */
@ -289,10 +267,6 @@ export default class Node {
this.props?.import(props); this.props?.import(props);
} }
getDirective(name: string, useStash: boolean = true): Prop | null {
return this.directives?.get(name, useStash as any) || null;
}
/** /**
* *
*/ */
@ -346,16 +320,7 @@ export default class Node {
const { componentName, id, children, props, ...extras } = data; const { componentName, id, children, props, ...extras } = data;
if (isNodeParent(this)) { if (isNodeParent(this)) {
const directives: any = {}; this._props!.import(props, extras);
Object.keys(extras).forEach(key => {
if (DIRECTIVES.indexOf(key) > -1) {
directives[key] = (extras as any)[key];
delete (extras as any)[key];
}
});
this._props!.import(data.props);
this._directives!.import(directives);
this._extras!.import(extras as any);
this._children.import(children, checkId); this._children.import(children, checkId);
} else { } else {
this._children.import(children); this._children.import(children);
@ -367,12 +332,11 @@ export default class Node {
* @param serialize id * @param serialize id
*/ */
export(serialize = false): NodeSchema { export(serialize = false): NodeSchema {
// TODO... const { props, extras } = this.props?.export(serialize) || {};
const schema: any = { const schema: any = {
componentName: this.componentName, componentName: this.componentName,
...this.extras?.export(serialize), props,
props: this.props?.export(serialize) || {}, ...extras,
...this.directives?.export(serialize),
}; };
if (serialize) { if (serialize) {
schema.id = this.id; schema.id = this.id;
@ -437,8 +401,6 @@ export default class Node {
this.children.purge(); this.children.purge();
} }
this.props?.purge(); this.props?.purge();
this.directives?.purge();
this.extras?.purge();
this.document.internalRemoveAndPurgeNode(this); this.document.internalRemoveAndPurgeNode(this);
} }
} }
@ -446,8 +408,6 @@ export default class Node {
export interface NodeParent extends Node { export interface NodeParent extends Node {
readonly children: NodeChildren; readonly children: NodeChildren;
readonly props: Props; readonly props: Props;
readonly directives: Props;
readonly extras: Props;
} }
export function isNode(node: any): node is Node { export function isNode(node: any): node is Node {

View File

@ -140,6 +140,10 @@ export default class Prop implements IPropParent {
this.dispose(); this.dispose();
} }
getValue(serialize = true) {
// todo:
}
private dispose() { private dispose() {
const items = untracked(() => this._items); const items = untracked(() => this._items);
if (items) { if (items) {

View File

@ -1,10 +1,12 @@
import { computed, obx } from '@recore/obx'; import { computed, obx } from '@recore/obx';
import { uniqueId } from '../../../../../../utils/unique-id'; import { uniqueId } from '../../../../../../utils/unique-id';
import { CompositeValue, PropsList, PropsMap } from '../../../schema'; import { CompositeValue, PropsList, PropsMap, CompositeObject } from '../../../schema';
import PropStash from './prop-stash'; import PropStash from './prop-stash';
import Prop, { IPropParent, UNSET } from './prop'; import Prop, { IPropParent, UNSET } from './prop';
import { NodeParent } from '../node'; import { NodeParent } from '../node';
export const EXTRA_KEY_PREFIX = '__';
export default class Props implements IPropParent { export default class Props implements IPropParent {
readonly id = uniqueId('props'); readonly id = uniqueId('props');
@obx.val private items: Prop[] = []; @obx.val private items: Prop[] = [];
@ -36,22 +38,23 @@ export default class Props implements IPropParent {
return this.items.length; return this.items.length;
} }
@computed get value(): PropsMap | PropsList | null {
return this.export(true);
}
@obx type: 'map' | 'list' = 'map'; @obx type: 'map' | 'list' = 'map';
constructor(readonly owner: NodeParent, value?: PropsMap | PropsList | null) { constructor(readonly owner: NodeParent, value?: PropsMap | PropsList | null, extras?: object) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
this.type = 'list'; this.type = 'list';
this.items = value.map(item => new Prop(this, item.value, item.name, item.spread)); this.items = value.map(item => new Prop(this, item.value, item.name, item.spread));
} else if (value != null) { } else if (value != null) {
this.items = Object.keys(value).map(key => new Prop(this, value[key], key)); this.items = Object.keys(value).map(key => new Prop(this, value[key], key));
} }
if (extras) {
Object.keys(extras).forEach(key => {
this.items.push(new Prop(this, (extras as any)[key], EXTRA_KEY_PREFIX + key));
});
}
} }
import(value?: PropsMap | PropsList | null) { import(value?: PropsMap | PropsList | null, extras?: object) {
this.stash.clear(); this.stash.clear();
const originItems = this.items; const originItems = this.items;
if (Array.isArray(value)) { if (Array.isArray(value)) {
@ -64,6 +67,11 @@ export default class Props implements IPropParent {
this.type = 'map'; this.type = 'map';
this.items = []; this.items = [];
} }
if (extras) {
Object.keys(extras).forEach(key => {
this.items.push(new Prop(this, (extras as any)[key], EXTRA_KEY_PREFIX + key));
});
}
originItems.forEach(item => item.purge()); originItems.forEach(item => item.purge());
} }
@ -73,27 +81,52 @@ export default class Props implements IPropParent {
}); });
} }
export(serialize = false): PropsMap | PropsList | null { export(serialize = false): { props?: PropsMap | PropsList; extras?: object} {
if (this.items.length < 1) { if (this.items.length < 1) {
return null; return {};
} }
let props: any = {};
const extras: any = {};
if (this.type === 'list') { if (this.type === 'list') {
return this.items.map(item => { props = [];
const v = item.export(serialize); this.items.forEach(item => {
return { let value = item.export(serialize);
spread: item.spread, if (value === UNSET) {
name: item.key as string, value = null;
value: v === UNSET ? null : v, }
}; let name = item.key as string;
if (name && typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) {
name = name.substr(EXTRA_KEY_PREFIX.length);
extras[name] = value;
} else {
props.push({
spread: item.spread,
name,
value,
});
}
});
} else {
this.items.forEach(item => {
let name = item.key as string;
if (name == null) {
// todo ...spread
return;
}
let value = item.export(serialize);
if (value === UNSET) {
value = null;
}
if (typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) {
name = name.substr(EXTRA_KEY_PREFIX.length);
extras[name] = value;
} else {
props[name] = value;
}
}); });
} }
const maps: any = {};
this.items.forEach(prop => { return { props, extras };
if (prop.key) {
maps[prop.key] = prop.export(serialize);
}
});
return maps;
} }
/** /**

View File

@ -59,12 +59,6 @@ export default class RootNode extends Node implements NodeParent {
get props(): Props { get props(): Props {
return this._props as any; return this._props as any;
} }
get extras(): Props {
return this._extras as any;
}
get directives(): Props {
return this._directives as any;
}
internalSetParent(parent: null) {} internalSetParent(parent: null) {}
constructor(readonly document: DocumentModel, rootSchema: RootSchema) { constructor(readonly document: DocumentModel, rootSchema: RootSchema) {

View File

@ -4,57 +4,63 @@ import DocumentModel from './document-model';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
export class Selection { export class Selection {
@obx.val private selected: string[] = [];
private emitter = new EventEmitter(); private emitter = new EventEmitter();
@obx.val private _selected: string[] = [];
/**
* id
*/
get selected(): string[] {
return this._selected;
}
constructor(private doc: DocumentModel) {} constructor(readonly doc: DocumentModel) {}
/** /**
* *
*/ */
select(id: string) { select(id: string) {
if (this.selected.length === 1 && this.selected.indexOf(id) > -1) { if (this._selected.length === 1 && this._selected.indexOf(id) > -1) {
// avoid cause reaction // avoid cause reaction
return; return;
} }
this.selected = [id]; this._selected = [id];
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
/** /**
* *
*/ */
selectAll(ids: string[]) { selectAll(ids: string[]) {
this.selected = ids; this._selected = ids;
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
/** /**
* *
*/ */
clear() { clear() {
if (this.selected.length < 1) { if (this._selected.length < 1) {
return; return;
} }
this.selected = []; this._selected = [];
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
/** /**
* *
*/ */
dispose() { dispose() {
const l = this.selected.length; const l = this._selected.length;
let i = l; let i = l;
while (i-- > 0) { while (i-- > 0) {
const id = this.selected[i]; const id = this._selected[i];
if (!this.doc.hasNode(id)) { if (!this.doc.hasNode(id)) {
this.selected.splice(i, 1); this._selected.splice(i, 1);
} }
} }
if (this.selected.length !== l) { if (this._selected.length !== l) {
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
} }
@ -62,29 +68,29 @@ export class Selection {
* *
*/ */
add(id: string) { add(id: string) {
if (this.selected.indexOf(id) > -1) { if (this._selected.indexOf(id) > -1) {
return; return;
} }
this.selected.push(id); this._selected.push(id);
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
/** /**
* *
*/ */
has(id: string) { has(id: string) {
return this.selected.indexOf(id) > -1; return this._selected.indexOf(id) > -1;
} }
/** /**
* *
*/ */
remove(id: string) { remove(id: string) {
let i = this.selected.indexOf(id); let i = this._selected.indexOf(id);
if (i > -1) { if (i > -1) {
this.selected.splice(i, 1); this._selected.splice(i, 1);
this.emitter.emit('selectionchange'); this.emitter.emit('selectionchange', this._selected);
} }
} }
@ -92,7 +98,7 @@ export class Selection {
* *
*/ */
containsNode(node: Node) { containsNode(node: Node) {
for (const id of this.selected) { for (const id of this._selected) {
const parent = this.doc.getNode(id); const parent = this.doc.getNode(id);
if (parent?.contains(node)) { if (parent?.contains(node)) {
return true; return true;
@ -106,7 +112,7 @@ export class Selection {
*/ */
getNodes() { getNodes() {
const nodes = []; const nodes = [];
for (const id of this.selected) { for (const id of this._selected) {
const node = this.doc.getNode(id); const node = this.doc.getNode(id);
if (node) { if (node) {
nodes.push(node); nodes.push(node);
@ -120,7 +126,7 @@ export class Selection {
*/ */
getTopNodes() { getTopNodes() {
const nodes = []; const nodes = [];
for (const id of this.selected) { for (const id of this._selected) {
const node = this.doc.getNode(id); const node = this.doc.getNode(id);
if (!node) { if (!node) {
continue; continue;

View File

@ -27,7 +27,7 @@ export default class Project {
}); });
} }
@computed get activedDocument() { @computed get currentDocument() {
return this.documents.find(doc => doc.actived); return this.documents.find(doc => doc.actived);
} }
@ -111,7 +111,7 @@ export default class Project {
doc.suspense(); doc.suspense();
} }
}); });
this.emitter.emit('actived-document-change', actived); this.emitter.emit('current-document-change', actived);
} }
closeOthers(opened: DocumentModel) { closeOthers(opened: DocumentModel) {
@ -122,13 +122,14 @@ export default class Project {
}); });
} }
onCurrentDocumentChange(fn: (doc: DocumentModel) => void): () => void {
this.emitter.on('current-document-change', fn);
return () => {
this.emitter.removeListener('current-document-change', fn);
};
}
// 通知标记删除,需要告知服务端 // 通知标记删除,需要告知服务端
// 项目角度编辑不是全量打开所有文档,是按需加载,哪个更新就通知更新谁, // 项目角度编辑不是全量打开所有文档,是按需加载,哪个更新就通知更新谁,
// 哪个删除就 // 哪个删除就
onActivedDocumentChange(fn: (doc: DocumentModel) => void): () => void {
this.emitter.on('actived-document-change', fn);
return () => {
this.emitter.removeListener('actived-document-change', fn);
};
}
} }

View File

@ -1,5 +1,5 @@
import { Component } from "react"; import { Component } from "react";
import { FieldConfig } from '../../main'; import { FieldConfig, SettingField } from '../../main';
class ObjectSetter extends Component<{ class ObjectSetter extends Component<{
mode?: 'popup' | 'row' | 'form'; mode?: 'popup' | 'row' | 'form';
@ -29,6 +29,7 @@ interface ObjectSetterConfig {
// for table|list row // for table|list row
class RowSetter extends Component<{ class RowSetter extends Component<{
decriptor?: string | ((rowField: SettingField) => string);
config: ObjectSetterConfig; config: ObjectSetterConfig;
columnsLimit?: number; columnsLimit?: number;
}> { }> {

View File

@ -4,9 +4,9 @@ import { ComponentType } from '../../designer/src/designer/component-type';
import Node from '../../designer/src/designer/document/node/node'; import Node from '../../designer/src/designer/document/node/node';
import { TitleContent } from './title'; import { TitleContent } from './title';
import { ReactElement, ComponentType as ReactComponentType, isValidElement } from 'react'; import { ReactElement, ComponentType as ReactComponentType, isValidElement } from 'react';
import DocumentModel from '../../designer/src/designer/document/document-model';
import { isReactComponent } from '../../utils/is-react'; import { isReactComponent } from '../../utils/is-react';
import Designer from '../../designer/src/designer/designer'; import Designer from '../../designer/src/designer/designer';
import { Selection } from '../../designer/src/designer/document/selection';
export interface SettingTarget { export interface SettingTarget {
// 所设置的节点集,至少一个 // 所设置的节点集,至少一个
@ -347,7 +347,6 @@ export function isSettingField(obj: any): obj is SettingField {
return obj && obj.isSettingField; return obj && obj.isSettingField;
} }
export class SettingsMain implements SettingTarget { export class SettingsMain implements SettingTarget {
private emitter = new EventEmitter(); private emitter = new EventEmitter();
@ -402,38 +401,26 @@ export class SettingsMain implements SettingTarget {
private _designer?: Designer; private _designer?: Designer;
get designer() { get designer() {
return this._designer; return this._designer || this.editor.designer;
} }
constructor(readonly editor: any) { constructor(readonly editor: any) {
let selectionChangeDispose: any = null; const setupSelection = (selection?: Selection) => {
const setupDoc = (doc: DocumentModel) => { if (selection) {
if (selectionChangeDispose) {
selectionChangeDispose();
selectionChangeDispose = null;
}
if (doc) {
if (!this._designer) { if (!this._designer) {
this._designer = doc.designer; this._designer = selection.doc.designer;
} }
const selection = doc.selection;
this.setup(selection.getNodes()); this.setup(selection.getNodes());
selectionChangeDispose = doc.selection.onSelectionChange(() => {
this.setup(selection.getNodes());
});
} else { } else {
this.setup([]); this.setup([]);
} }
}; };
const activedDispose = editor.on('designer.actived-document-change', setupDoc); editor.on('designer.current-selection-change', setupSelection);
if (editor.designer) { if (editor.designer) {
setupDoc(editor.designer.project.activedDocument); setupSelection(editor.designer.currentSelection);
} }
this.disposeListener = () => { this.disposeListener = () => {
if (selectionChangeDispose) { editor.removeListener('designer.current-selection-change', setupSelection);
selectionChangeDispose();
}
activedDispose();
}; };
} }