Commit e2ac6d1e authored by techird's avatar techird

stash

parent e3974368
{
"indent_size": 4,
"indent_char": " ",
"indent_level": 0,
"indent_with_tabs": false,
"preserve_newlines": true,
"max_preserve_newlines": 4,
"max_preserve_newlines": 10,
"jslint_happy": false,
"space_in_paren": false,
"jslint_happy": true,
"brace_style": "collapse",
"keep_array_indentation": false,
"keep_function_indentation": false,
"space_before_conditional": false,
"break_chained_methods": false,
"eval_code": false,
"unescape_strings": false,
"break_chained_methods": false,
"e4x": false,
"wrap_line_length": 0
}
\ No newline at end of file
/**
* FEX Style Guide (Javascript)
*
* TODO:
*
* 1. 找不到选项:每行只允许一个语句
* 2. 找不到选项:块状代码需要用大括号括起来
*/
{
// 缩进「MUST」使用 4 个空格
"validateIndentation": 4,
// 大括号(块状代码)前「MUST」使用空格
"requireSpaceBeforeBlockStatements": true,
// 下列关键字「MUST」使用空格
"requireSpaceAfterKeywords": ["if", "else", "for", "while",
"do", "try", "catch", "finally"
],
// `,` 和 `;` 前面不允许「MUST NOT」使用空格。
"requireLeftStickedOperators": [",", ";"],
// 二元运算符前后「MUST」使用空格
"requireSpaceBeforeBinaryOperators": [
"+",
"-",
"*",
"/",
"=",
"==",
"===",
"!=",
"!==",
"|",
"||",
"&",
"&&"
],
"requireSpaceAfterBinaryOperators": [
"+",
"-",
"*",
"/",
"=",
"==",
"===",
"!=",
"!==",
"|",
"||",
"&",
"&&",
":"
],
// 一元运算符与操作对象间「MUST NOT」使用空格
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
// 函数参数小括号前「MUST NOT」使用空格
"disallowSpacesInFunctionExpression": {
"beforeOpeningRoundBrace": true
},
// 小括号里面「MUST NOT」使用空格
"disallowSpacesInsideParentheses": true,
// 行尾「MUST NOT」使用空格
"disallowTrailingWhitespace": true,
// 每行「MUST NOT」超过 120 个字符
"maximumLineLength": 120,
// 一下操作符「MUST NOT」放在一行的最前面,需要放在上一行的后面
"requireOperatorBeforeLineBreak": [
"?",
"+",
"-",
"/",
"*",
"=",
"==",
"===",
"!=",
"!==",
">",
">=",
"<",
"<=",
",",
";",
"&&",
"&",
"||",
"|"
],
// 字符串统一「MUST」使用单引号
"validateQuoteMarks": "'",
// 「MUST NOT」使用多行字符串
"disallowMultipleLineStrings": true
}
\ No newline at end of file
......@@ -9,18 +9,129 @@ KityMinder 渲染和布局重构方案
为了不产生误会,下面约定一些词汇的意思。
样式:对节点或脑图其他内容的外观的描述。
渲染:对节点的绘制的过程。渲染参照的坐标系是节点画布的坐标系。
布局:对节点定位的过程,发生在渲染之后。定位使用的坐标系是脑图画布的坐标系。
节点树多边形:表示一个节点以及其子树所占的多边形区域。
### Layout
## 样式、渲染和布局的梳理
### Theme
负责注册和管理样式。
注册样式:
```js
KityMinder.registerTheme( 'default', {
'root-padding': [30, 20],
'root-color': 'black',
'root-background': '#A4c5c0',
'root-stroke': 'none',
'root-radius': 4,
'root-space': [10, 5],
'root-font-family': 'Arial',
'root-font-size': 14,
'main-connect-width': 2,
'main-connect-color': 'white',
'main-connect-type': 'arc',
'sub-connect-type': 'fold'
...
});
```
切换样式:
Layout
```js
minder.useTheme('default');
```
读取样式:
```js
minder.getStyle('root-radius'); // returns 4
```
```js
node.getStyle('radius'); // node.getType() 返回 'root', 会自动拼接样式项,返回 4
node.getStyle('padding-left'); // returns 20 发现结尾是 '-left'、'-right' 等的会自动找到样式表描述的数组按照 CSS 的方式查找值
```
### Render
### Connect
Render 负责渲染工作。
对于一个节点,有两个渲染容器(以前是多个),一个是通过 `getContentGroup()` 来获取的内容容器,一个是通过 `getDecorationGroup()` 来获得的装饰容器。布局的时候,内容容器最终决定该节点的渲染大小,装饰容器里的内容会被忽略。
节点的渲染分步进行,按顺序描述是:`center`, `left`, `right`, `top`, `bottom`。之前渲染这五个步骤是通过事件的形式来通知,每次渲染都清除了原本的内容重新创建节点,造成性能浪费。修改渲染的机制,改成从模块直接注册渲染的节:
```js
KityMinder.registerModule( 'MyModule', {
commands: { ... },
events: { ... },
renderers: {
left: kity.createClass( 'MyRenderer', {
base: Renderer,
create: function(node) {
this.content = new kity.Group();
// 添加元素
node.getContentGroup().addShape(this.content);
},
update: function(node) {
var content = this.content;
// update content
// 需要返回更新后内容所占的矩形区域,简单的返回形式是 return this.content.getRenderBox();
return {
x: 30,
y: -30,
width: 24,
height: 24
};
}
}
}
});
```
`renderers` 节来描述渲染器,节的 `key` 指定渲染器使用的阶段,节的 `value` 给出渲染器的类。渲染器需要继承 `Renderer` 类,并且实现两个抽象方法:`create()``update()`
`create` 方法只会在节点创建的时候调用一次,此时应该创建渲染所需要的元素,并且附加到节点上。
`update` 方法会在节点需要重新渲染的时候被调用,此时可以选择隐藏、显示或更新元素。
在渲染过程中,节点提供下述信息:
- `node.getStyle(name)` 获得节点当前的某个样式描述
- `node.getContentBox()` 获得节点当前已渲染的内容在节点的 ConentGroup 的坐标系中所占的矩形区域。
- `node.getType()` 获得节点的类型('root' | 'main' | 'sub')
要触发一个节点的渲染,直接调用 'node.render()' 即可。
### Layout
Layout 负责布局工作,布局一般发生在渲染之后。对一个节点的布局,指的是排列其子树。
允许多种布局,布局注册的方式如下:
```js
KityMinder.registerLayout('default', kity.createClass('DefaultLayout', {
base: Layout,
doLayout: function(node) {
// do layout
}
}));
```
让节点布局的方式是调用节点的 `node.layout([name])` 方法。该方法的执行过程如下:
- 调用 `node.getLayout()` 获得节点的布局名称
- 如果节点中的 data 包含布局名称,返回该布局名称,否则下一步
- 如果节点是根节点,返回 KityMinder.getDefaultLayout()
- 返回父节点的 `getLayout()`
- 根据布局名称获得相应的布局方法,把节点作为参数传进去调用
### Expander
......@@ -22,14 +22,14 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
return val === null || val === undefined ? this._options[ key ] : val;
}else{
val = this.getPreferences();
if(val){
return utils.extend(val,this._options,true)
}else{
if (val) {
return utils.extend(val, this._options, true);
} else {
return this._options;
}
}
},
setDefaultOptions: function ( key, val,cover) {
setDefaultOptions: function ( key, val, cover) {
var obj = {};
if ( Utils.isString( key ) ) {
obj[ key ] = val;
......@@ -40,7 +40,7 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
},
setOptions: function ( key, val ) {
this.setPreferences(key,val)
this.setPreferences(key,val);
},
_initMinder: function () {
......@@ -89,7 +89,7 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
addShortcutKeys: function ( cmd, keys ) {
var obj = {}, km = this;
if ( keys ) {
obj[ cmd ] = keys
obj[ cmd ] = keys;
} else {
obj = cmd;
}
......@@ -99,7 +99,7 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
},
getShortcutKey: function ( cmdName ) {
return this._shortcutkeys[ cmdName ]
return this._shortcutkeys[ cmdName ];
},
_bindshortcutKeys: function () {
var me = this,
......@@ -115,7 +115,7 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
break;
case 'alt':
if ( e.altKey ) {
return true
return true;
}
break;
case 'shift':
......@@ -127,7 +127,7 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
if ( keyCode == keymap[ key ] ) {
return true;
}
return false
return false;
}
me.on( 'keydown', function ( e ) {
......@@ -227,11 +227,3 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
me.fire( 'interactchange' );
}
} );
\ No newline at end of file
/**
* @include <minder.data.js>
* @include <minder.event.js>
* @include <minder.module.js>
* @include <minder.node.js>
* @include <minder.select.js>
*/
\ No newline at end of file
kity.extendClass( Minder, {
kity.extendClass(Minder, {
getRoot: function () {
getRoot: function() {
return this._root;
},
setRoot: function ( root ) {
setRoot: function(root) {
this._root = root;
},
handelNodeInsert: function ( node ) {
handelNodeInsert: function(node) {
var rc = this._rc;
// node.traverse( function ( current ) {
// rc.addShape( current.getRenderContainer() );
// } );
rc.addShape( node.getRenderContainer() );
rc.addShape(node.getRenderContainer());
},
handelNodeRemove: function ( node ) {
handelNodeRemove: function(node) {
var rc = this._rc;
node.traverse( function ( current ) {
rc.removeShape( current.getRenderContainer() );
} );
node.traverse(function(current) {
rc.removeShape(current.getRenderContainer());
});
},
renderNodes: function ( nodes ) {
renderNodes: function(nodes) {
var km = this;
if ( nodes instanceof Array ) {
if ( nodes.length === 0 ) return false;
for ( var i = 0; i < nodes.length; i++ ) {
km.renderNode( nodes[ i ] );
if (nodes instanceof Array) {
if (nodes.length === 0) return false;
for (var i = 0; i < nodes.length; i++) {
km.renderNode(nodes[i]);
}
} else {
km.renderNode( nodes );
km.renderNode(nodes);
}
},
getMinderTitle: function () {
getMinderTitle: function() {
return this.getRoot().getText();
}
} );
\ No newline at end of file
});
\ No newline at end of file
......@@ -9,62 +9,8 @@ var MinderNode = KityMinder.MinderNode = kity.createClass( "MinderNode", {
} else {
this.setData( options );
}
this._createShapeDom();
this.setData( "layout", {} );
},
_createShapeDom: function () {
this.rc = new kity.Group();
this.rc.addClass( 'km-minderNode' );
this.rc.minderNode = this;
this._createBgGroup();
this._createContGroup();
},
_createGroup: function ( type ) {
var g = new kity.Group();
g.setData( 'rctype', type );
this.rc.appendShape( g );
},
_createBgGroup: function () {
this._createGroup( 'bgrc' );
},
_createContGroup: function () {
this._createGroup( 'contrc' );
},
getContRc: function () {
var groups = this.rc.getShapesByType( 'group' ),
result;
Utils.each( groups, function ( i, p ) {
if ( p.getData( 'rctype' ) == 'contrc' ) {
result = p;
return false;
}
} );
return result;
},
getBgRc: function () {
var groups = this.rc.getShapesByType( 'group' ),
result;
Utils.each( groups, function ( i, p ) {
if ( p.getData( 'rctype' ) == 'bgrc' ) {
result = p;
return false;
}
} );
return result;
},
setPoint: function ( x, y ) {
if ( arguments.length < 2 ) {
this.setData( "point", x );
} else {
this.setData( 'point', {
x: x,
y: y
} );
}
},
getPoint: function () {
return this.getData( 'point' );
},
setType: function ( type ) {
this.setData( 'type', type );
},
......@@ -186,26 +132,21 @@ var MinderNode = KityMinder.MinderNode = kity.createClass( "MinderNode", {
if ( index >= 0 ) {
removed = this.children.splice( index, 1 )[ 0 ];
removed.parent = null;
// this.handelRemove( removed );
}
},
// handelRemove: function ( node ) {
// var root = this.getRoot();
// if ( root.tnh ) {
// root.tnh.handelNodeRemove.call( root.tnh, node );
// }
// },
getChild: function ( index ) {
return this.children[ index ];
},
getFirstChild: function () {
return this.children[ 0 ];
},
getLastChild: function () {
return this.children[ this.children.length - 1 ];
},
getData: function ( name ) {
if ( name === undefined ) {
return this.data;
......
var cssLikeValueMatcher = {
left: function(value) {
return 3 in value && value[3] ||
1 in value && value[1] ||
value[0];
},
right: function(value) {
return 1 in value && value[1] || value[0];
},
top: function(value) {
return value[0];
},
bottom: function(value) {
return 2 in value && value[2] || value[0];
}
};
Utils.extend(KityMinder, {
_themes: {},
/**
* 注册一个主题
*
* @param {String} name 主题的名称
* @param {Plain} theme 主题的样式描述
*
* @example
* KityMinder.registerTheme('default', {
* 'root-color': 'red',
* 'root-stroke': 'none',
* 'root-padding': [10, 20]
* });
*/
registerTheme: function(name, theme) {
KityMinder._themes[name] = theme;
// 首个注册的主题为默认主题
if (!KityMinder._defaultTheme) KityMinder._defaultTheme = name;
}
});
kity.extendClass(Minder, {
/**
* 切换脑图实例上的主题
* @param {String} name 要使用的主题的名称
*/
useTheme: function(name) {
if (!KityMinder._theme[name]) {
return false;
}
this._theme = name;
this.getRoot().traverse(function(node) {
node.render();
});
this.getRoot().layout();
},
/**
* 获取脑图实例上的当前主题
* @return {[type]} [description]
*/
getTheme: function() {
return this._theme || KityMinder._defaultTheme;
},
/**
* 获得脑图实例上的样式
* @param {String} item 样式名称
*/
getStyle: function(item) {
var theme = KityMinder._theme[this.getTheme()];
var segment, dir, selector, value, matcher;
if (item in theme) return theme[item];
// 尝试匹配 CSS 数组形式的值
// 比如 item 为 'pading-left'
// theme 里有 {'padding': [10, 20]} 的定义,则可以返回 20
segment = item.split('-');
if (segment.length < 2) return;
dir = segment.pop();
item = segment.join('-');
if (item in theme) {
value = theme[item];
if (!isNaN(value)) return value;
if (Utils.isArray(value) && (matcher = cssLikeValueMatcher[dir])) {
return matcher(value);
}
}
return null;
}
});
kity.extendClass(Node, {
/**
* 获得节点的样式
* @param {String} name 样式名称
*/
getStyle: function(name) {
var minder = this.minder,
value;
if (!this.minder) return null;
value = minder.getStyle(name);
return value !== null ? value : minder.getStyle(this.getType() + '-' + name);
}
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment