Browse Source

Merge pull request #952 in VISUAL/fineui from ~WINDY/fineui:master to master

* commit '6c9a2e712ec45e001e932366ac107eaea1ba29b6':
  fix_comment
  fix_comment
  KERNEL-702 feat: 两个单选下拉树支持异步加载搜索
master
guy 6 years ago
parent
commit
357c79dd07
  1. 3
      src/base/combination/loader.js
  2. 1
      src/case/button/node/node.plus.js
  3. 144
      src/widget/multilayerselecttree/multilayerselecttree.combo.js
  4. 25
      src/widget/multilayerselecttree/multilayerselecttree.leveltree.js
  5. 20
      src/widget/multilayerselecttree/multilayerselecttree.popup.js
  6. 123
      src/widget/multilayerselecttree/multilayerselecttree.trigger.js
  7. 141
      src/widget/multilayersingletree/multilayersingletree.combo.js
  8. 25
      src/widget/multilayersingletree/multilayersingletree.leveltree.js
  9. 20
      src/widget/multilayersingletree/multilayersingletree.popup.js
  10. 123
      src/widget/multilayersingletree/multilayersingletree.trigger.js

3
src/base/combination/loader.js

@ -78,7 +78,8 @@ BI.Loader = BI.inherit(BI.Widget, {
behaviors: {},
layouts: [{
type: "bi.vertical"
}]
}],
value: o.value
});
this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) {
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);

1
src/case/button/node/node.plus.js

@ -33,6 +33,7 @@ BI.PlusGroupNode = BI.inherit(BI.NodeButton, {
hgap: o.hgap,
text: o.text,
value: o.value,
keyword: o.keyword,
py: o.py
});
this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) {

144
src/widget/multilayerselecttree/multilayerselecttree.combo.js

@ -6,72 +6,156 @@ BI.MultiLayerSelectTreeCombo = BI.inherit(BI.Widget, {
_defaultConfig: function () {
return BI.extend(BI.MultiLayerSelectTreeCombo.superclass._defaultConfig.apply(this, arguments), {
baseCls: "bi-multilayer_select_tree-combo",
baseCls: "bi-multilayer-select-tree-combo",
isDefaultInit: false,
height: 24,
text: "",
itemsCreator: BI.emptyFn,
items: [],
value: "",
attributes: {
tabIndex: 0
}
},
allowEdit: false
});
},
_init: function () {
BI.MultiLayerSelectTreeCombo.superclass._init.apply(this, arguments);
render: function () {
var self = this, o = this.options;
this.trigger = BI.createWidget({
type: "bi.single_tree_trigger",
text: o.text,
height: o.height,
items: o.items,
value: o.value
});
var combo = (o.itemsCreator === BI.emptyFn) ? this._getSyncConfig() : this._getAsyncConfig();
this.popup = BI.createWidget({
type: "bi.multilayer_select_tree_popup",
isDefaultInit: o.isDefaultInit,
items: o.items,
value: o.value
});
return (!o.allowEdit && o.itemsCreator === BI.emptyFn) ? combo : {
type: "bi.absolute",
items: [{
el: combo,
left: 0,
right: 0,
top: 0,
bottom: 0
}, {
el: {
type: "bi.trigger_icon_button",
cls: "trigger-icon-button",
ref: function (_ref) {
self.triggerBtn = _ref;
},
width: o.height,
height: o.height,
handler: function () {
if (self.combo.isViewVisible()) {
self.combo.hideView();
} else {
self.combo.showView();
}
}
},
right: 0,
bottom: 0,
top: 0
}]
};
},
this.combo = BI.createWidget({
_getBaseConfig: function () {
var self = this, o = this.options;
return {
type: "bi.combo",
container: o.container,
element: this,
adjustLength: 2,
el: this.trigger,
ref: function (_ref) {
self.combo = _ref;
},
popup: {
el: this.popup
el: {
type: "bi.multilayer_select_tree_popup",
isDefaultInit: o.isDefaultInit,
itemsCreator: o.itemsCreator,
items: o.items,
ref: function (_ref) {
self.trigger && self.trigger.getSearcher().setAdapter(_ref);
},
listeners: [{
eventName: BI.MultiLayerSelectTreePopup.EVENT_CHANGE,
action: function () {
self.setValue(this.getValue());
self.combo.hideView();
self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE);
}
});
}]
},
value: o.value,
minHeight: 400
}
};
},
this.combo.on(BI.Controller.EVENT_CHANGE, function () {
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);
});
_getSyncConfig: function () {
var o = this.options;
var baseConfig = this._getBaseConfig();
baseConfig.el = {
type: "bi.single_tree_trigger",
text: o.text,
height: o.height,
items: o.items,
value: o.value
};
return baseConfig;
},
this.popup.on(BI.MultiLayerSelectTreePopup.EVENT_CHANGE, function () {
self.setValue(self.popup.getValue());
_getAsyncConfig: function () {
var self = this, o = this.options;
var config = this._getBaseConfig();
return BI.extend(config, {
el: {
type: "bi.multilayer_select_tree_trigger",
allowEdit: o.allowEdit,
cls: "multilayer-select-tree-trigger",
ref: function (_ref) {
self.trigger = _ref;
},
items: o.items,
itemsCreator: o.itemsCreator,
height: o.height - 2,
text: o.text,
value: o.value,
tipType: o.tipType,
warningTitle: o.warningTitle,
title: o.title,
listeners: [{
eventName: BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE,
action: function () {
self.setValue(this.getValue());
self.combo.hideView();
self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE);
}
}]
},
hideChecker: function (e) {
return self.triggerBtn.element.find(e.target).length === 0;
},
listeners: [{
eventName: BI.Combo.EVENT_AFTER_HIDEVIEW,
action: function () {
self.trigger.stopEditing();
}
}]
});
},
setValue: function (v) {
v = BI.isArray(v) ? v : [v];
this.trigger.setValue(v);
this.popup.setValue(v);
this.combo.setValue(v);
},
getValue: function () {
return this.popup.getValue();
return this.combo.getValue();
},
populate: function (items) {
this.combo.populate(items);
}
});
BI.MultiLayerSelectTreeCombo.EVENT_CHANGE = "EVENT_CHANGE";
BI.shortcut("bi.multilayer_select_tree_combo", BI.MultiLayerSelectTreeCombo);

25
src/widget/multilayerselecttree/multilayerselecttree.leveltree.js

@ -11,6 +11,7 @@ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, {
isDefaultInit: false,
items: [],
itemsCreator: BI.emptyFn,
keywordGetter: BI.emptyFn,
value: "",
scrollable: true
});
@ -23,13 +24,15 @@ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, {
},
_formatItems: function (nodes, layer, pNode) {
var self = this;
var self = this, o = this.options;
var keyword = o.keywordGetter();
BI.each(nodes, function (i, node) {
var extend = {};
node.layer = layer;
if (!BI.isKey(node.id)) {
node.id = BI.UUID();
}
node.keyword = keyword;
extend.pNode = pNode;
if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) {
extend.type = "bi.multilayer_select_tree_mid_plus_group_node";
@ -68,6 +71,7 @@ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, {
// 构造树结构,
initTree: function (nodes) {
var self = this, o = this.options;
var hasNext = false;
this.empty();
this._assertId(nodes);
this.tree = BI.createWidget({
@ -83,15 +87,28 @@ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, {
},
items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0),
itemsCreator: o.itemsCreator,
itemsCreator: function (op, callback) {
o.itemsCreator(op, function (ob) {
hasNext = ob.hasNext;
callback(self._formatItems(BI.Tree.transformToTreeFormat(ob.items), op.node ? op.node.layer + 1 : 0, op.node));
});
},
value: o.value,
el: {
type: "bi.loader",
isDefaultInit: true,
chooseType: o.chooseType,
el: {
type: "bi.button_tree",
chooseType: BI.Selection.Single,
behaviors: o.behaviors,
layouts: [{
type: "bi.vertical"
}]
},
hasNext: function () {
return hasNext;
}
}
});
this.tree.on(BI.Controller.EVENT_CHANGE, function (type) {
@ -110,7 +127,7 @@ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, {
},
populate: function (nodes) {
this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0));
BI.isNull(nodes) ? this.tree.populate() : this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0));
},
setValue: function (v) {

20
src/widget/multilayerselecttree/multilayerselecttree.popup.js

@ -27,8 +27,20 @@ BI.MultiLayerSelectTreePopup = BI.inherit(BI.Pane, {
type: "bi.multilayer_select_level_tree",
isDefaultInit: o.isDefaultInit,
items: o.items,
itemsCreator: function (op, callback) {
(op.times === 1 && !op.node) && BI.nextTick(function () {
self.loading();
});
o.itemsCreator(op, function (ob) {
self._populate(ob.items);
callback(ob);
(op.times === 1 && !op.node) && BI.nextTick(function () {
self.loaded();
});
});
},
keywordGetter: o.keywordGetter,
value: o.value,
itemsCreator: o.itemsCreator,
scrollable: null
});
@ -52,6 +64,10 @@ BI.MultiLayerSelectTreePopup = BI.inherit(BI.Pane, {
this.check();
},
_populate: function() {
BI.MultiLayerSelectTreePopup.superclass.populate.apply(this, arguments);
},
getValue: function () {
return this.tree.getValue();
},
@ -62,7 +78,7 @@ BI.MultiLayerSelectTreePopup = BI.inherit(BI.Pane, {
},
populate: function (items) {
BI.MultiLayerSelectTreePopup.superclass.populate.apply(this, arguments);
this._populate(items);
this.tree.populate(items);
}
});

123
src/widget/multilayerselecttree/multilayerselecttree.trigger.js

@ -0,0 +1,123 @@
/**
* Created by Windy on 2018/2/2.
*/
BI.MultiLayerSelectTreeTrigger = BI.inherit(BI.Trigger, {
props: {
extraCls: "bi-multi-layer-select-tree-trigger bi-border bi-focus-shadow",
height: 24,
valueFormatter: function (v) {
return v;
},
itemsCreator: BI.emptyFn
},
render: function () {
var self = this, o = this.options;
var content = {
type: "bi.htape",
items: [
{
el: {
type: "bi.searcher",
ref: function () {
self.searcher = this;
},
isAutoSearch: false,
el: {
type: "bi.state_editor",
ref: function () {
self.editor = this;
},
text: this._digest(o.value),
value: o.value,
height: o.height,
tipText: ""
},
popup: {
type: "bi.multilayer_select_tree_popup",
itemsCreator: function (op, callback) {
op.keyword = self.editor.getValue();
o.itemsCreator(op, callback);
},
keywordGetter: function () {
return self.editor.getValue();
},
cls: "bi-card"
},
onSearch: function (obj, callback) {
var keyword = obj.keyword;
if(o.itemsCreator === BI.emptyFn) {
var finding = BI.Func.getSearchResult(o.items, keyword);
var matched = finding.match, find = finding.find;
callback(find.concat(matched));
} else {
callback();
}
},
listeners: [{
eventName: BI.Searcher.EVENT_CHANGE,
action: function () {
self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE);
}
}]
}
}, {
el: {
type: "bi.layout",
width: 24
},
width: 24
}
]
};
return o.allowEdit ? content : {
type: "bi.absolute",
items: [{
el: content,
left: 0,
right: 0,
top: 0,
bottom: 0
}, {
el: {
type: "bi.layout"
},
left: 0,
right: 24,
top: 0,
bottom: 0
}]
};
},
_digest: function (v) {
return this.options.valueFormatter(v);
},
stopEditing: function () {
this.searcher.stopSearch();
},
getSearcher: function () {
return this.searcher;
},
populate: function (items) {
this.options.items = items;
},
setValue: function (v) {
this.editor.setState(this._digest(v[0]));
},
getValue: function () {
return this.searcher.getValue();
}
});
BI.MultiLayerSelectTreeTrigger.EVENT_SEARCHING = "EVENT_SEARCHING";
BI.MultiLayerSelectTreeTrigger.EVENT_STOP = "EVENT_STOP";
BI.MultiLayerSelectTreeTrigger.EVENT_START = "EVENT_START";
BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE = "EVENT_CHANGE";
BI.shortcut("bi.multilayer_select_tree_trigger", BI.MultiLayerSelectTreeTrigger);

141
src/widget/multilayersingletree/multilayersingletree.combo.js

@ -18,60 +18,141 @@ BI.MultiLayerSingleTreeCombo = BI.inherit(BI.Widget, {
value: "",
attributes: {
tabIndex: 0
}
},
allowEdit: false
});
},
_init: function () {
BI.MultiLayerSingleTreeCombo.superclass._init.apply(this, arguments);
render: function () {
var self = this, o = this.options;
this.trigger = BI.createWidget({
type: "bi.single_tree_trigger",
text: o.text,
height: o.height,
items: o.items,
value: o.value
});
var combo = (o.itemsCreator === BI.emptyFn) ? this._getSyncConfig() : this._getAsyncConfig();
this.popup = BI.createWidget({
type: "bi.multilayer_single_tree_popup",
isDefaultInit: o.isDefaultInit,
itemsCreator: o.itemsCreator,
items: o.items,
value: o.value
});
return (!o.allowEdit && o.itemsCreator === BI.emptyFn) ? combo : {
type: "bi.absolute",
items: [{
el: combo,
left: 0,
right: 0,
top: 0,
bottom: 0
}, {
el: {
type: "bi.trigger_icon_button",
cls: "trigger-icon-button",
ref: function (_ref) {
self.triggerBtn = _ref;
},
width: o.height,
height: o.height,
handler: function () {
if (self.combo.isViewVisible()) {
self.combo.hideView();
} else {
self.combo.showView();
}
}
},
right: 0,
bottom: 0,
top: 0
}]
};
},
this.combo = BI.createWidget({
_getBaseConfig: function () {
var self = this, o = this.options;
return {
type: "bi.combo",
container: o.container,
element: this,
adjustLength: 2,
el: this.trigger,
ref: function (_ref) {
self.combo = _ref;
},
popup: {
el: this.popup
el: {
type: "bi.multilayer_single_tree_popup",
isDefaultInit: o.isDefaultInit,
itemsCreator: o.itemsCreator,
items: o.items,
ref: function (_ref) {
self.trigger && self.trigger.getSearcher().setAdapter(_ref);
},
listeners: [{
eventName: BI.MultiLayerSingleTreePopup.EVENT_CHANGE,
action: function () {
self.setValue(this.getValue());
self.combo.hideView();
self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE);
}
});
}]
},
value: o.value,
minHeight: 400
}
};
},
this.combo.on(BI.Controller.EVENT_CHANGE, function () {
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);
});
_getSyncConfig: function () {
var o = this.options;
var baseConfig = this._getBaseConfig();
baseConfig.el = {
type: "bi.single_tree_trigger",
text: o.text,
height: o.height,
items: o.items,
value: o.value
};
return baseConfig;
},
this.popup.on(BI.MultiLayerSingleTreePopup.EVENT_CHANGE, function () {
self.setValue(self.popup.getValue());
_getAsyncConfig: function () {
var self = this, o = this.options;
var config = this._getBaseConfig();
return BI.extend(config, {
el: {
type: "bi.multilayer_single_tree_trigger",
allowEdit: o.allowEdit,
cls: "multilayer-single-tree-trigger",
ref: function (_ref) {
self.trigger = _ref;
},
items: o.items,
itemsCreator: o.itemsCreator,
height: o.height - 2,
text: o.text,
value: o.value,
tipType: o.tipType,
warningTitle: o.warningTitle,
title: o.title,
listeners: [{
eventName: BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE,
action: function () {
self.setValue(this.getValue());
self.combo.hideView();
self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE);
}
}]
},
hideChecker: function (e) {
return self.triggerBtn.element.find(e.target).length === 0;
},
listeners: [{
eventName: BI.Combo.EVENT_AFTER_HIDEVIEW,
action: function () {
self.trigger.stopEditing();
}
}]
});
},
setValue: function (v) {
v = BI.isArray(v) ? v : [v];
this.trigger.setValue(v);
this.popup.setValue(v);
this.combo.setValue(v);
},
getValue: function () {
return this.popup.getValue();
return this.combo.getValue();
},
populate: function (items) {

25
src/widget/multilayersingletree/multilayersingletree.leveltree.js

@ -11,6 +11,7 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
isDefaultInit: false,
items: [],
itemsCreator: BI.emptyFn,
keywordGetter: BI.emptyFn,
chooseType: BI.Selection.Single,
scrollable: true
});
@ -23,13 +24,15 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
},
_formatItems: function (nodes, layer, pNode) {
var self = this;
var self = this, o = this.options;
var keyword = o.keywordGetter();
BI.each(nodes, function (i, node) {
var extend = {};
node.layer = layer;
if (!BI.isKey(node.id)) {
node.id = BI.UUID();
}
node.keyword = keyword;
extend.pNode = pNode;
if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) {
extend.type = "bi.multilayer_single_tree_mid_plus_group_node";
@ -48,7 +51,7 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
} else {
extend.type = "bi.multilayer_single_tree_mid_tree_leaf_item";
if (i === 0 && !pNode) {
extend.type = "bi.multilayer_single_tree_first_tree_leaf_item"
extend.type = "bi.multilayer_single_tree_first_tree_leaf_item";
}
if (i === nodes.length - 1) {
extend.type = "bi.multilayer_single_tree_last_tree_leaf_item";
@ -68,6 +71,7 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
// 构造树结构,
initTree: function (nodes) {
var self = this, o = this.options;
var hasNext = false;
this.empty();
this._assertId(nodes);
this.tree = BI.createWidget({
@ -84,17 +88,26 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0),
value: o.value,
itemsCreator: function (op, callback) {
o.itemsCreator(op, function (items) {
callback(BI.Tree.transformToTreeFormat(items), 0);
o.itemsCreator(op, function (ob) {
hasNext = ob.hasNext;
callback(self._formatItems(BI.Tree.transformToTreeFormat(ob.items), op.node ? op.node.layer + 1 : 0, op.node));
});
},
el: {
type: "bi.button_tree",
type: "bi.loader",
isDefaultInit: true,
chooseType: o.chooseType,
el: {
type: "bi.button_tree",
behaviors: o.behaviors,
layouts: [{
type: "bi.vertical"
}]
},
hasNext: function () {
return hasNext;
}
}
});
this.tree.on(BI.Controller.EVENT_CHANGE, function (type, v) {
@ -113,7 +126,7 @@ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, {
},
populate: function (nodes) {
this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0));
BI.isNull(nodes) ? this.tree.populate() : this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0));
},
setValue: function (v) {

20
src/widget/multilayersingletree/multilayersingletree.popup.js

@ -26,7 +26,19 @@ BI.MultiLayerSingleTreePopup = BI.inherit(BI.Pane, {
type: "bi.multilayer_single_level_tree",
isDefaultInit: o.isDefaultInit,
items: o.items,
itemsCreator: o.itemsCreator,
itemsCreator: function (op, callback) {
(op.times === 1 && !op.node) && BI.nextTick(function () {
self.loading();
});
o.itemsCreator(op, function (ob) {
self._populate(ob.items);
callback(ob);
(op.times === 1 && !op.node) && BI.nextTick(function () {
self.loaded();
});
});
},
keywordGetter: o.keywordGetter,
value: o.value,
scrollable: null
});
@ -51,6 +63,10 @@ BI.MultiLayerSingleTreePopup = BI.inherit(BI.Pane, {
this.check();
},
_populate: function() {
BI.MultiLayerSingleTreePopup.superclass.populate.apply(this, arguments);
},
getValue: function () {
return this.tree.getValue();
},
@ -61,7 +77,7 @@ BI.MultiLayerSingleTreePopup = BI.inherit(BI.Pane, {
},
populate: function (items) {
BI.MultiLayerSingleTreePopup.superclass.populate.apply(this, arguments);
this._populate(items);
this.tree.populate(items);
}
});

123
src/widget/multilayersingletree/multilayersingletree.trigger.js

@ -0,0 +1,123 @@
/**
* Created by Windy on 2018/2/2.
*/
BI.MultiLayerSingleTreeTrigger = BI.inherit(BI.Trigger, {
props: {
extraCls: "bi-multi-layer-single-tree-trigger bi-border bi-focus-shadow",
height: 24,
valueFormatter: function (v) {
return v;
},
itemsCreator: BI.emptyFn
},
render: function () {
var self = this, o = this.options;
var content = {
type: "bi.htape",
items: [
{
el: {
type: "bi.searcher",
ref: function () {
self.searcher = this;
},
isAutoSearch: false,
el: {
type: "bi.state_editor",
ref: function () {
self.editor = this;
},
text: this._digest(o.value),
value: o.value,
height: o.height,
tipText: ""
},
popup: {
type: "bi.multilayer_single_tree_popup",
itemsCreator: function (op, callback) {
op.keyword = self.editor.getValue();
o.itemsCreator(op, callback);
},
keywordGetter: function () {
return self.editor.getValue();
},
cls: "bi-card"
},
onSearch: function (obj, callback) {
var keyword = obj.keyword;
if(o.itemsCreator === BI.emptyFn) {
var finding = BI.Func.getSearchResult(o.items, keyword);
var matched = finding.match, find = finding.find;
callback(find.concat(matched));
} else {
callback();
}
},
listeners: [{
eventName: BI.Searcher.EVENT_CHANGE,
action: function () {
self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE);
}
}]
}
}, {
el: {
type: "bi.layout",
width: 24
},
width: 24
}
]
};
return o.allowEdit ? content : {
type: "bi.absolute",
items: [{
el: content,
left: 0,
right: 0,
top: 0,
bottom: 0
}, {
el: {
type: "bi.layout"
},
left: 0,
right: 24,
top: 0,
bottom: 0
}]
};
},
_digest: function (v) {
return this.options.valueFormatter(v);
},
stopEditing: function () {
this.searcher.stopSearch();
},
getSearcher: function () {
return this.searcher;
},
populate: function (items) {
this.options.items = items;
},
setValue: function (v) {
this.editor.setState(this._digest(v[0]));
},
getValue: function () {
return this.searcher.getValue();
}
});
BI.MultiLayerSingleTreeTrigger.EVENT_SEARCHING = "EVENT_SEARCHING";
BI.MultiLayerSingleTreeTrigger.EVENT_STOP = "EVENT_STOP";
BI.MultiLayerSingleTreeTrigger.EVENT_START = "EVENT_START";
BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE = "EVENT_CHANGE";
BI.shortcut("bi.multilayer_single_tree_trigger", BI.MultiLayerSingleTreeTrigger);
Loading…
Cancel
Save