Skip to content

Commit 1a3ed38

Browse files
authored
Inputs mapper (#313)
Default/inner inputs concept in (specs need to be adapted) NodePorts belong to NodeModel Inputs Mapper TreeItemRenamer
1 parent 8d7d44f commit 1a3ed38

File tree

18 files changed

+1181
-337
lines changed

18 files changed

+1181
-337
lines changed

services/dy-modeling/client/source/class/qxapp/Application.js

+32-17
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,19 @@ qx.Class.define("qxapp.Application", {
7676
let docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
7777

7878
// initialize components
79-
const menuBarHeight = 35;
80-
const avaiBarHeight = 55;
79+
let menuBarHeight = 35;
80+
let avaiBarHeight = 55;
81+
const showMenuBar = false;
82+
const showUserMenu = false;
83+
const showModelingTools = true;
8184

8285
this._menuBar = new qxapp.component.MenuBar(
8386
docWidth, menuBarHeight,
8487
this._appModel.getColors().getMenuBar()
8588
.getBackground(), this._appModel.getColors().getMenuBar()
8689
.getFont());
8790

88-
this._userMenu = new qxapp.component.UserMenu(
91+
let userMenu = new qxapp.component.UserMenu(
8992
this._appModel,
9093
this._appModel.getColors().getMenuBar()
9194
.getBackground(), this._appModel.getColors().getMenuBar()
@@ -116,15 +119,23 @@ qx.Class.define("qxapp.Application", {
116119
backgroundColor: "white",
117120
allowGrowY: false
118121
});
119-
toolBarcontainer.add(this._menuBar);
120-
toolBarcontainer.add(this.__availableServicesBar);
121-
// toolBarcontainer.add(this.__threeView);
122+
123+
if (showMenuBar) {
124+
toolBarcontainer.add(this._menuBar);
125+
}
126+
if (showModelingTools) {
127+
toolBarcontainer.add(this.__availableServicesBar);
128+
}
122129
doc.add(toolBarcontainer);
123130

124-
doc.add(this._userMenu, {
125-
right: 30
126-
});
131+
if (showUserMenu) {
132+
doc.add(userMenu, {
133+
right: 30
134+
});
135+
}
127136

137+
menuBarHeight = showMenuBar ? menuBarHeight : 0;
138+
avaiBarHeight = showModelingTools ? avaiBarHeight : 0;
128139
this.__entityList.moveTo(10, menuBarHeight + avaiBarHeight + 10);
129140
this.__entityList.open();
130141

@@ -177,6 +188,17 @@ qx.Class.define("qxapp.Application", {
177188
return this._appModel.getUsers().toArray()[activeUserId].getName();
178189
},
179190

191+
loadModel: function(modelName) {
192+
if (!this._socket.slotExists("importModelScene")) {
193+
this._socket.on("importModelScene", function(val) {
194+
if (val.type === "importModelScene") {
195+
this.__threeView.importSceneFromBuffer(val.value);
196+
}
197+
}, this);
198+
}
199+
this._socket.emit("importModel", modelName);
200+
},
201+
180202
_initSignals: function() {
181203
// Menu bar
182204
this._menuBar.addListener("fileNewPressed", function(e) {
@@ -208,14 +230,7 @@ qx.Class.define("qxapp.Application", {
208230

209231
this._menuBar.addListener("fileLoadModelPressed", function(e) {
210232
let selectedModel = e.getData();
211-
if (!this._socket.slotExists("importModelScene")) {
212-
this._socket.on("importModelScene", function(val) {
213-
if (val.type === "importModelScene") {
214-
this.__threeView.importSceneFromBuffer(val.value);
215-
}
216-
}, this);
217-
}
218-
this._socket.emit("importModel", selectedModel);
233+
this.loadModel(selectedModel);
219234
}, this);
220235

221236
this._menuBar.addListener("editPreferencesPressed", function(e) {

services/sidecar/boot.sh

100755100644
File mode changed.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/* eslint no-underscore-dangle: ["error", { "allowAfterThis": true, "allow": ["__willBeBranch", "__willBeLeaf", "__tree"] }] */
2+
3+
qx.Class.define("qxapp.component.widget.InputsMapper", {
4+
extend: qx.ui.core.Widget,
5+
6+
construct: function(nodeModel, mapper) {
7+
this.base();
8+
9+
let widgetLayout = new qx.ui.layout.VBox(5);
10+
this._setLayout(widgetLayout);
11+
12+
this.setNodeModel(nodeModel);
13+
this.setMapper(mapper);
14+
15+
let tree = this.__tree = new qx.ui.tree.VirtualTree(null, "label", "children").set({
16+
openMode: "none"
17+
});
18+
this._add(tree, {
19+
flex: 1
20+
});
21+
tree.getSelection().addListener("change", this.__onTreeSelectionChanged, this);
22+
23+
let that = this;
24+
tree.setDelegate({
25+
createItem: () => new qxapp.component.widget.inputs.NodeOutputListItem(),
26+
bindItem: (c, item, id) => {
27+
c.bindDefaultProperties(item, id);
28+
// c.bindProperty("key", "key", null, item, id);
29+
c.bindProperty("isDir", "isDir", null, item, id);
30+
c.bindProperty("isRoot", "isRoot", null, item, id);
31+
},
32+
configureItem: item => {
33+
item.set({
34+
droppable: true
35+
});
36+
item.addListener("dragover", e => {
37+
item.set({
38+
droppable: item.getIsDir()
39+
});
40+
let compatible = false;
41+
if (e.supportsType("osparc-mapping")) {
42+
const from = e.getRelatedTarget();
43+
const to = e.getCurrentTarget();
44+
const fromKey = from.getNodeKey();
45+
if (to.getIsRoot()) {
46+
// root
47+
compatible = from.getIsDir() && that.__willBeBranch(fromKey);
48+
} else {
49+
// non root
50+
compatible = to.getIsDir() && !from.getIsDir() && that.__willBeLeaf(fromKey);
51+
}
52+
}
53+
if (!compatible) {
54+
e.preventDefault();
55+
}
56+
});
57+
item.addListener("drop", e => {
58+
if (e.supportsType("osparc-mapping")) {
59+
const from = e.getRelatedTarget();
60+
const fromNodeKey = from.getNodeKey();
61+
const fromPortKey = from.getPortKey();
62+
let data = {
63+
key: from.getModel(),
64+
label: from.getLabel(),
65+
nodeKey: from.getNodeKey(),
66+
portKey: from.getPortKey(),
67+
isDir: from.getIsDir()
68+
};
69+
const willBeBranch = that.__willBeBranch(fromNodeKey);
70+
if (willBeBranch) {
71+
data["children"] = [];
72+
}
73+
let newItem = qx.data.marshal.Json.createModel(data, true);
74+
const to = e.getCurrentTarget();
75+
to.getModel().getChildren()
76+
.push(newItem);
77+
if (willBeBranch) {
78+
const nodeInstanceUUID = null;
79+
const itemProps = qxapp.data.Store.getInstance().getItem(nodeInstanceUUID, fromPortKey, newItem.getKey());
80+
if (itemProps) {
81+
let form = new qxapp.component.form.Auto(itemProps);
82+
let propsWidget = new qxapp.component.form.renderer.PropForm(form);
83+
newItem["propsWidget"] = propsWidget;
84+
}
85+
}
86+
to.setOpen(true);
87+
tree.focus();
88+
}
89+
});
90+
}
91+
});
92+
93+
let data = {
94+
label: nodeModel.getLabel(),
95+
isRoot: true,
96+
children: []
97+
};
98+
let model = qx.data.marshal.Json.createModel(data, true);
99+
tree.setModel(model);
100+
101+
this.addListener("keypress", function(keyEvent) {
102+
let treeSelection = this.__tree.getSelection();
103+
if (treeSelection.length < 1) {
104+
return;
105+
}
106+
let selectedItem = treeSelection.toArray()[0];
107+
if (selectedItem.getIsRoot && selectedItem.getIsRoot()) {
108+
return;
109+
}
110+
switch (keyEvent.getKeyIdentifier()) {
111+
case "F2": {
112+
let treeItemRenamer = new qxapp.component.widget.TreeItemRenamer(selectedItem);
113+
treeItemRenamer.addListener("LabelChanged", e => {
114+
let newLabel = e.getData()["newLabel"];
115+
selectedItem.setLabel(newLabel);
116+
}, this);
117+
treeItemRenamer.center();
118+
treeItemRenamer.open();
119+
break;
120+
}
121+
case "Delete": {
122+
let branches = this.__tree.getModel().getChildren();
123+
// branch
124+
let removed = branches.remove(selectedItem);
125+
if (!removed) {
126+
// leaf
127+
let br = branches.toArray();
128+
for (let i=0; i<br.length; i++) {
129+
let branch = br[i];
130+
removed = branch.getChildren().remove(selectedItem);
131+
if (removed) {
132+
break;
133+
}
134+
}
135+
}
136+
break;
137+
}
138+
}
139+
}, this);
140+
},
141+
142+
properties: {
143+
nodeModel: {
144+
check: "qxapp.data.model.NodeModel",
145+
nullable: false
146+
},
147+
148+
mapper: {
149+
nullable: false
150+
}
151+
},
152+
153+
members: {
154+
__tree: null,
155+
156+
__willBeBranch: function(candidate) {
157+
let isBranch = false;
158+
const maps = this.getMapper().maps;
159+
if (Object.prototype.hasOwnProperty.call(maps, "branch")) {
160+
if (maps["branch"] === candidate) {
161+
isBranch = true;
162+
}
163+
}
164+
const isDefault = candidate === this.getNodeModel().getKey();
165+
return isDefault || isBranch;
166+
},
167+
168+
__willBeLeaf: function(candidate) {
169+
let isLeave = false;
170+
const maps = this.getMapper().maps;
171+
if (Object.prototype.hasOwnProperty.call(maps, "leaf")) {
172+
if (maps["leaf"] === candidate) {
173+
isLeave = true;
174+
}
175+
}
176+
return isLeave;
177+
},
178+
179+
__onTreeSelectionChanged: function() {
180+
// remove all but the tree
181+
while (this._getChildren().length > 1) {
182+
this._removeAt(1);
183+
}
184+
let selectedItems = this.__tree.getSelection();
185+
if (selectedItems.length < 1) {
186+
return;
187+
}
188+
let selectedItem = selectedItems.toArray()[0];
189+
if (Object.prototype.hasOwnProperty.call(selectedItem, "propsWidget")) {
190+
this._add(selectedItem["propsWidget"]);
191+
}
192+
}
193+
}
194+
});

services/web/client/source/class/qxapp/component/widget/NodeExposed.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
/* ************************************************************************
2+
Copyright: 2018 ITIS Foundation
3+
License: MIT
4+
Authors: Odei Maiz <[email protected]>
5+
Utf8Check: äöü
6+
************************************************************************ */
7+
8+
/**
9+
* Creates the widget that represents what needs to be exposed
10+
* to outsise the container.
11+
*
12+
*/
13+
114
qx.Class.define("qxapp.component.widget.NodeExposed", {
215
extend: qx.ui.core.Widget,
316

@@ -56,7 +69,6 @@ qx.Class.define("qxapp.component.widget.NodeExposed", {
5669
this.__inputPort = {};
5770
this.__outputPort = {};
5871
this.__createUIPorts(true, metaData.inputs);
59-
// this.__createUIPorts(false, metaData.outputs);
6072
},
6173

6274
getInputPort: function() {

services/web/client/source/class/qxapp/component/widget/NodeInput.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
/* ************************************************************************
2+
Copyright: 2018 ITIS Foundation
3+
License: MIT
4+
Authors: Odei Maiz <[email protected]>
5+
Utf8Check: äöü
6+
************************************************************************ */
7+
8+
/**
9+
* Creates the widget that represents an input node.
10+
* It shows nothing more than the name of the input node in the middle of a box.
11+
*
12+
*/
13+
114
qx.Class.define("qxapp.component.widget.NodeInput", {
215
extend: qx.ui.core.Widget,
316

@@ -13,10 +26,14 @@ qx.Class.define("qxapp.component.widget.NodeInput", {
1326

1427
let atom = new qx.ui.basic.Atom().set({
1528
label: nodeModel.getLabel(),
16-
center : true,
29+
center: true,
1730
draggable: true,
1831
droppable: true
1932
});
33+
const title16Font = qx.bom.Font.fromConfig(qxapp.theme.Font.fonts["title-16"]);
34+
atom.getChildControl("label").set({
35+
font: title16Font
36+
});
2037

2138
this._add(atom, {
2239
flex: 1

0 commit comments

Comments
 (0)