optimize outline

This commit is contained in:
kangwei 2020-03-26 14:06:33 +08:00
parent 4edf3fce6b
commit e76f65a4c7
8 changed files with 64 additions and 45 deletions

View File

@ -287,11 +287,11 @@ export default class Designer {
}
get schema(): ProjectSchema {
return this.project.schema;
return this.project.getSchema();
}
setSchema(schema: ProjectSchema) {
// todo:
setSchema(schema?: ProjectSchema) {
this.project.setSchema(schema);
}
@obx.val private _componentMetasMap = new Map<string, ComponentMeta>();

View File

@ -390,6 +390,8 @@ export default class DocumentModel {
// todo:
}
purge() {}
checkNesting(dropTarget: NodeParent, dragObject: DragNodeObject | DragNodeDataObject): boolean {
let items: Array<Node | NodeSchema>;
if (isDragNodeDataObject(dragObject)) {

View File

@ -7,25 +7,14 @@ export default class Project {
private emitter = new EventEmitter();
@obx.val readonly documents: DocumentModel[] = [];
private data: ProjectSchema;
private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [] };
@obx.ref canvasDisplayMode: 'exclusive' | 'overview' = 'exclusive';
// TODO: 考虑项目级别 History
constructor(readonly designer: Designer, schema?: ProjectSchema) {
this.data = {
version: '1.0.0',
componentsMap: [],
componentsTree: [],
...schema,
};
this.open(
this.data.componentsTree[0] || {
componentName: 'Page',
fileName: '',
},
);
this.setSchema(schema);
}
@computed get currentDocument() {
@ -35,7 +24,7 @@ export default class Project {
/**
* schema
*/
get schema(): ProjectSchema {
getSchema(): ProjectSchema {
return {
...this.data,
componentsTree: this.documents.map(doc => doc.schema),
@ -45,7 +34,24 @@ export default class Project {
/**
* schema
*/
set schema(schema: ProjectSchema) {}
setSchema(schema?: ProjectSchema) {
this.data = {
version: '1.0.0',
componentsMap: [],
componentsTree: [],
...schema,
};
if (this.documents.length > 0) {
this.documents.forEach(doc => doc.purge());
this.documents.length = 0;
}
this.open(
this.data.componentsTree[0] || {
componentName: 'Page',
fileName: '',
},
);
}
/**
*

View File

@ -147,6 +147,19 @@ export default {
disableAppComponent: true
}
},
{
pluginKey: 'outlineTree',
type: 'PanelIcon',
props: {
align: 'top',
icon: 'dengpao',
title: '大纲树'
},
config: {
version: '^1.0.0'
},
pluginProps: {}
},
{
pluginKey: 'leftPanelIcon',
type: 'PanelIcon',
@ -238,7 +251,6 @@ export default {
}
],
rightArea: [
/*
{
pluginKey: 'settings',
type: 'Panel',
@ -247,16 +259,7 @@ export default {
version: '^1.0.0'
},
pluginProps: {}
},*/
{
pluginKey: 'outlineTree',
type: 'Panel',
props: {},
config: {
version: '^1.0.0'
},
pluginProps: {}
}
},
],
centerArea: [
{

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1562677547122" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1131" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1020.14942288-40.33632922H3.85057712c-24.44088257 0-44.18690634 19.74602377-44.18690634 44.18690634v1016.29884576c0 24.44088257 19.74602377 44.18690634 44.18690634 44.18690634h1016.29884576c24.44088257 0 44.18690634-19.74602377 44.18690634-44.18690634V3.85057712c0-24.44088257-19.74602377-44.18690634-44.18690634-44.18690634z m-55.23363292 1005.25211918H59.08421004V59.08421004h905.83157992v905.83157992z" fill="#ffffff" p-id="1132"></path><path d="M473.33645695 310.39723984h77.3270861c6.07569962 0 11.04672658-4.97102697 11.04672658-11.04672659v-77.32708608c0-6.07569962-4.97102697-11.04672658-11.04672658-11.04672658h-77.3270861c-6.07569962 0-11.04672658 4.97102697-11.04672658 11.04672658v77.32708608c0 6.07569962 4.97102697 11.04672658 11.04672658 11.04672659zM222.02342717 561.71026963h77.32708608c6.07569962 0 11.04672658-4.97102697 11.04672659-11.04672658v-77.3270861c0-6.07569962-4.97102697-11.04672658-11.04672659-11.04672658h-77.32708608c-6.07569962 0-11.04672658 4.97102697-11.04672658 11.04672658v77.3270861c0 6.07569962 4.97102697 11.04672658 11.04672658 11.04672658zM724.64948675 561.71026963h77.32708608c6.07569962 0 11.04672658-4.97102697 11.04672658-11.04672658v-77.3270861c0-6.07569962-4.97102697-11.04672658-11.04672658-11.04672658h-77.32708608c-6.07569962 0-11.04672658 4.97102697-11.04672659 11.04672658v77.3270861c0 6.07569962 4.97102697 11.04672658 11.04672659 11.04672658zM473.33645695 561.71026963h77.3270861c6.07569962 0 11.04672658-4.97102697 11.04672658-11.04672658v-77.3270861c0-6.07569962-4.97102697-11.04672658-11.04672658-11.04672658h-77.3270861c-6.07569962 0-11.04672658 4.97102697-11.04672658 11.04672658v77.3270861c0 6.07569962 4.97102697 11.04672658 11.04672658 11.04672658zM473.33645695 813.02329941h77.3270861c6.07569962 0 11.04672658-4.97102697 11.04672658-11.04672658v-77.32708608c0-6.07569962-4.97102697-11.04672658-11.04672658-11.04672659h-77.3270861c-6.07569962 0-11.04672658 4.97102697-11.04672658 11.04672659v77.32708608c0 6.07569962 4.97102697 11.04672658 11.04672658 11.04672658z" fill="#ffffff" p-id="1133"></path></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -489,14 +489,15 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
* @see IScrollBoard
*/
scrollToNode(treeNode: TreeNode, detail?: any, tryTimes: number = 0) {
this.tryScrollAgain = null;
if (tryTimes < 1 && this.tryScrollAgain) {
(window as any).cancelIdleCallback(this.tryScrollAgain);
this.tryScrollAgain = null;
}
if (this.sensing || !this.bounds || !this.scroller || !this.scrollTarget) {
// is a active sensor
return;
}
const opt: any = {};
let scroll = false;
let rect: ClientRect | undefined;
if (detail && isLocationChildrenDetail(detail)) {
rect = this.getInsertionRect();
@ -505,24 +506,25 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
}
if (!rect) {
if (!this.tryScrollAgain && tryTimes < 3) {
this.tryScrollAgain = requestAnimationFrame(() => this.scrollToNode(treeNode, detail, tryTimes + 1));
if (tryTimes < 3) {
this.tryScrollAgain = (window as any).requestIdleCallback(() => this.scrollToNode(treeNode, detail, tryTimes + 1));
}
return;
}
const scrollTarget = this.scrollTarget;
const st = scrollTarget.top;
const scrollHeight = scrollTarget.scrollHeight;
const { scrollHeight, top: scrollTop } = this.scrollTarget;
const { height, top, bottom } = this.bounds;
if (rect.top < top || rect.bottom > bottom) {
opt.top = Math.min(rect.top + rect.height / 2 + st - top - height / 2, scrollHeight - height);
scroll = true;
}
if (scroll) {
const opt: any = {};
opt.top = Math.min(rect.top + rect.height / 2 + scrollTop - top - height / 2, scrollHeight - height);
if (rect.height >= height) {
opt.top = Math.min(scrollTop + rect.top - top, opt.top);
}
this.scroller.scrollTo(opt);
}
// make tail scroll be sure
if (tryTimes < 4) {
this.tryScrollAgain = (window as any).requestIdleCallback(() => this.scrollToNode(treeNode, detail, 4));
}
}
private sensing = false;

View File

@ -188,7 +188,9 @@ class ExpandBtn extends Component<{
<div
className="tree-node-expand-btn"
onClick={e => {
e.stopPropagation();
if (treeNode.expanded) {
e.stopPropagation();
}
treeNode.setExpanded(!treeNode.expanded);
}}
>

View File

@ -36,11 +36,14 @@ export default class TreeView extends Component<{ tree: Tree }> {
private onClick = (e: ReactMouseEvent) => {
if (this.ignoreUpSelected) {
this.boostEvent = undefined;
return;
}
if (this.boostEvent && isShaken(this.boostEvent, e.nativeEvent)) {
this.boostEvent = undefined;
return;
}
this.boostEvent = undefined;
const treeNode = this.getTreeNodeFromEvent(e);
if (!treeNode) {
return;
@ -105,6 +108,8 @@ export default class TreeView extends Component<{ tree: Tree }> {
selection.remove(doc.rootNode.id);
// 获得顶层 nodes
nodes = selection.getTopNodes();
} else if (selection.has(node.id)) {
nodes = selection.getTopNodes();
}
this.boostEvent = e.nativeEvent;
designer.dragon.boost(