Skip to content

Commit 2757343

Browse files
authored
🎨 [Frontend] Annotation creation enhancements (#6164)
1 parent c1da03c commit 2757343

File tree

5 files changed

+242
-125
lines changed

5 files changed

+242
-125
lines changed

services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js

Lines changed: 115 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ qx.Class.define("osparc.editor.AnnotationEditor", {
2121
construct: function(annotation) {
2222
this.base(arguments);
2323

24-
const layout = new qx.ui.layout.Grid(5, 5);
25-
layout.setColumnAlign(0, "right", "middle");
26-
layout.setColumnAlign(1, "left", "middle");
27-
this._setLayout(layout);
24+
this._setLayout(new qx.ui.layout.VBox(10));
2825

29-
this.set({
30-
padding: 10
31-
});
26+
this.__form = new qx.ui.form.Form();
27+
this.getChildControl("form-renderer");
3228

3329
if (annotation) {
3430
this.setAnnotation(annotation);
3531
}
3632
},
3733

34+
events: {
35+
"addAnnotation": "qx.event.type.Event",
36+
"cancel": "qx.event.type.Event",
37+
"deleteAnnotation": "qx.event.type.Event",
38+
},
39+
3840
properties: {
3941
annotation: {
4042
check: "osparc.workbench.Annotation",
@@ -52,113 +54,155 @@ qx.Class.define("osparc.editor.AnnotationEditor", {
5254
},
5355

5456
members: {
55-
__addColor: function() {
56-
this._add(new qx.ui.basic.Label(this.tr("Color")), {
57-
row: 0,
58-
column: 0
59-
});
60-
const colorPicker = new osparc.form.ColorPicker();
61-
this._add(colorPicker, {
62-
row: 0,
63-
column: 1
64-
});
65-
return colorPicker;
57+
__form: null,
58+
59+
getForm: function() {
60+
return this.__form;
6661
},
6762

68-
__applyAnnotation: function(annotation) {
69-
this._removeAll();
63+
_createChildControlImpl: function(id) {
64+
let control;
65+
switch (id) {
66+
case "form-renderer":
67+
control = new qx.ui.form.renderer.Single(this.__form);
68+
this._add(control);
69+
break;
70+
case "text-field":
71+
control = new qx.ui.form.TextField();
72+
this.__form.add(control, "Text", null, "text");
73+
break;
74+
case "text-area":
75+
control = new qx.ui.form.TextArea().set({
76+
autoSize: true,
77+
minHeight: 70,
78+
maxHeight: 140
79+
});
80+
this.__form.add(control, "Note", null, "note");
81+
break;
82+
case "color-picker":
83+
control = new osparc.form.ColorPicker();
84+
this.__form.add(control, "Color", null, "color");
85+
break;
86+
case "font-size":
87+
control = new qx.ui.form.Spinner();
88+
this.__form.add(control, "Size", null, "size");
89+
break;
90+
case "buttons-layout":
91+
control = new qx.ui.container.Composite(new qx.ui.layout.HBox(10).set({
92+
alignX: "right"
93+
}));
94+
this._add(control);
95+
break;
96+
case "cancel-btn": {
97+
const buttons = this.getChildControl("buttons-layout");
98+
control = new qx.ui.form.Button(this.tr("Cancel")).set({
99+
appearance: "form-button-text"
100+
});
101+
control.addListener("execute", () => this.fireEvent("cancel"), this);
102+
buttons.add(control);
103+
break;
104+
}
105+
case "add-btn": {
106+
const buttons = this.getChildControl("buttons-layout");
107+
control = new qx.ui.form.Button(this.tr("Add")).set({
108+
appearance: "form-button"
109+
});
110+
control.addListener("execute", () => this.fireEvent("addAnnotation"), this);
111+
buttons.add(control);
112+
break;
113+
}
114+
case "delete-btn": {
115+
const buttons = this.getChildControl("buttons-layout");
116+
control = new qx.ui.form.Button(this.tr("Delete")).set({
117+
appearance: "danger-button"
118+
});
119+
control.addListener("execute", () => this.fireEvent("deleteAnnotation"), this);
120+
buttons.add(control);
121+
break;
122+
}
123+
}
124+
return control || this.base(arguments, id);
125+
},
70126

127+
__applyAnnotation: function(annotation) {
71128
if (annotation === null) {
72129
return;
73130
}
74131

75-
let row = 0;
76-
if (["text", "rect"].includes(annotation.getType())) {
77-
const colorPicker = this.__addColor();
78-
annotation.bind("color", colorPicker, "color");
79-
colorPicker.bind("color", annotation, "color");
80-
row++;
81-
}
82-
83132
const attrs = annotation.getAttributes();
84133
if (annotation.getType() === "text") {
85-
this._add(new qx.ui.basic.Label(this.tr("Text")), {
86-
row,
87-
column: 0
134+
const textField = this.getChildControl("text-field").set({
135+
value: attrs.text
88136
});
89-
const textField = new qx.ui.form.TextField(attrs.text);
90137
textField.addListener("changeValue", e => annotation.setText(e.getData()));
91-
this._add(textField, {
92-
row,
93-
column: 1
94-
});
95-
row++;
96138
} else if (annotation.getType() === "note") {
97-
this._add(new qx.ui.basic.Label(this.tr("Note")), {
98-
row,
99-
column: 0
100-
});
101-
const textArea = new qx.ui.form.TextArea(attrs.text).set({
102-
autoSize: true,
103-
minHeight: 70,
104-
maxHeight: 140
139+
const textArea = this.getChildControl("text-area").set({
140+
value: attrs.text
105141
});
106142
textArea.addListener("changeValue", e => annotation.setText(e.getData()));
107-
this._add(textArea, {
108-
row,
109-
column: 1
110-
});
111-
row++;
143+
}
144+
145+
if (["text", "rect"].includes(annotation.getType())) {
146+
const colorPicker = this.getChildControl("color-picker");
147+
annotation.bind("color", colorPicker, "value");
148+
colorPicker.bind("value", annotation, "color");
112149
}
113150

114151
if (annotation.getType() === "text") {
115-
this._add(new qx.ui.basic.Label(this.tr("Size")), {
116-
row,
117-
column: 0
118-
});
119-
const fontSizeField = new qx.ui.form.Spinner(attrs.fontSize);
152+
const fontSizeField = this.getChildControl("font-size").set({
153+
value: attrs.fontSize
154+
})
120155
fontSizeField.addListener("changeValue", e => annotation.setFontSize(e.getData()));
121-
this._add(fontSizeField, {
122-
row,
123-
column: 1
124-
});
125-
row++;
126156
}
127-
128-
this.__makeItModal();
129157
},
130158

131159
__applyMarker: function(marker) {
132-
this._removeAll();
133-
134160
if (marker === null) {
135161
return;
136162
}
137163

138-
const colorPicker = this.__addColor();
164+
const colorPicker = this.getChildControl("color-picker");
139165
marker.bind("color", colorPicker, "color");
140166
colorPicker.bind("color", marker, "color");
167+
},
168+
169+
addDeleteButton: function() {
170+
this.getChildControl("delete-btn");
171+
},
141172

142-
this.__makeItModal();
173+
addAddButtons: function() {
174+
this.getChildControl("cancel-btn");
175+
this.getChildControl("add-btn");
176+
177+
// Listen to "Enter" key
178+
this.addListener("keypress", keyEvent => {
179+
if (keyEvent.getKeyIdentifier() === "Enter") {
180+
this.fireEvent("addAnnotation");
181+
}
182+
}, this);
143183
},
144184

145-
__makeItModal: function() {
185+
makeItModal: function() {
186+
this.set({
187+
padding: 10
188+
});
189+
146190
this.show();
147191

148-
const showHint = () => this.show();
149-
const hideHint = () => this.exclude();
192+
const showEditor = () => this.show();
193+
const hideEditor = () => this.exclude();
150194
const tapListener = event => {
151195
if (osparc.utils.Utils.isMouseOnElement(this, event)) {
152196
return;
153197
}
154-
hideHint();
198+
hideEditor();
155199
this.set({
156200
annotation: null,
157201
marker: null
158202
});
159203
document.removeEventListener("mousedown", tapListener);
160204
};
161-
showHint();
205+
showEditor();
162206
document.addEventListener("mousedown", tapListener);
163207
}
164208
}

services/static-webserver/client/source/class/osparc/form/ColorPicker.js

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,74 @@
88

99
qx.Class.define("osparc.form.ColorPicker", {
1010
extend: qx.ui.core.Widget,
11+
include : [
12+
qx.ui.form.MForm
13+
],
14+
implement : [
15+
qx.ui.form.IStringForm,
16+
qx.ui.form.IForm
17+
],
1118

1219
construct: function() {
1320
this.base(arguments);
1421

15-
this._setLayout(new qx.ui.layout.HBox());
22+
const layout = new qx.ui.layout.HBox();
23+
this._setLayout(layout);
1624

17-
this._add(this.getChildControl("random-button"));
18-
this._add(this.getChildControl("selector-button"));
19-
this._add(this.getChildControl("color-input"));
25+
this.getChildControl("random-button");
26+
this.getChildControl("selector-button");
27+
this.getChildControl("color-input");
2028
},
2129

2230
properties: {
23-
color: {
31+
value: {
2432
check: "Color",
25-
event: "changeColor",
33+
event: "changeValue",
2634
init: "#303030"
2735
}
2836
},
2937

38+
// eslint-disable-next-line qx-rules/no-refs-in-members
3039
members: {
40+
_forwardStates: {
41+
focused : true,
42+
invalid : true
43+
},
44+
3145
_createChildControlImpl: function(id) {
3246
let control;
3347
switch (id) {
3448
case "random-button":
3549
control = new qx.ui.form.Button(null, "@FontAwesome5Solid/sync-alt/12");
36-
control.addListener("execute", () => this.setColor(osparc.utils.Utils.getRandomColor()), this);
37-
this.bind("color", control, "backgroundColor");
38-
this.bind("color", control, "textColor", {
50+
control.addListener("execute", () => this.setValue(osparc.utils.Utils.getRandomColor()), this);
51+
this.bind("value", control, "backgroundColor");
52+
this.bind("value", control, "textColor", {
3953
converter: value => qx.theme.manager.Color.getInstance().resolve(osparc.utils.Utils.getContrastedTextColor(value))
4054
});
55+
this._add(control);
4156
break;
4257
case "selector-button":
4358
control = new qx.ui.form.Button(null, "@FontAwesome5Solid/eye-dropper/12");
4459
control.addListener("execute", () => this.__openColorSelector(), this);
45-
this.bind("color", control, "backgroundColor");
46-
this.bind("color", control, "textColor", {
60+
this.bind("value", control, "backgroundColor");
61+
this.bind("value", control, "textColor", {
4762
converter: value => qx.theme.manager.Color.getInstance().resolve(osparc.utils.Utils.getContrastedTextColor(value))
4863
});
64+
this._add(control);
4965
break;
5066
case "color-input":
5167
control = new qx.ui.form.TextField().set({
52-
width: 60,
68+
width: 80,
5369
required: true
5470
});
55-
this.bind("color", control, "value");
71+
this._add(control, {
72+
flex: 1
73+
});
74+
this.bind("value", control, "value");
5675
control.addListener("changeValue", e => {
5776
const newColor = e.getData();
5877
if (osparc.utils.Validators.hexColor(newColor, control)) {
59-
this.setColor(newColor);
78+
this.setValue(newColor);
6079
}
6180
});
6281
break;
@@ -66,12 +85,30 @@ qx.Class.define("osparc.form.ColorPicker", {
6685

6786
__openColorSelector: function() {
6887
const colorSelector = new qx.ui.control.ColorSelector();
69-
const rgb = qx.util.ColorUtil.hexStringToRgb(this.getColor());
88+
const rgb = qx.util.ColorUtil.hexStringToRgb(this.getValue());
7089
colorSelector.setRed(rgb[0]);
7190
colorSelector.setGreen(rgb[1]);
7291
colorSelector.setBlue(rgb[2]);
7392
osparc.ui.window.Window.popUpInWindow(colorSelector, this.tr("Pick a color"), 590, 380);
74-
colorSelector.addListener("changeValue", e => this.setColor(e.getData()));
75-
}
93+
colorSelector.addListener("changeValue", e => this.setValue(e.getData()));
94+
},
95+
96+
// overridden
97+
resetValue: function() {
98+
this.getChildControl("color-input").resetValue();
99+
},
100+
101+
// overridden
102+
focus: function() {
103+
this.base(arguments);
104+
this.getChildControl("color-input").getFocusElement().focus();
105+
},
106+
107+
// overridden
108+
tabFocus: function() {
109+
const field = this.getChildControl("color-input");
110+
field.getFocusElement().focus();
111+
field.selectAllText();
112+
},
76113
}
77114
});

services/static-webserver/client/source/class/osparc/info/ServiceUtils.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,13 @@ qx.Class.define("osparc.info.ServiceUtils", {
8686
* @param serviceData {Object} Serialized Service Object
8787
*/
8888
createContact: function(serviceData) {
89-
const owner = new qx.ui.basic.Label();
90-
owner.set({
91-
value: osparc.utils.Utils.getNameFromEmail(serviceData["contact"]),
92-
toolTipText: serviceData["contact"]
89+
const contact = new qx.ui.basic.Label();
90+
contact.set({
91+
value: osparc.store.Support.mailToText(serviceData["contact"], (serviceData["name"] + ":" + serviceData["version"])),
92+
selectable: true,
93+
rich: true
9394
});
94-
return owner;
95+
return contact;
9596
},
9697

9798
/**

0 commit comments

Comments
 (0)