From 4fdb31a347f8b1c99f7babd91ce60c303ac04b81 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Fri, 9 Aug 2024 12:26:30 +0200 Subject: [PATCH 01/19] namedColorToHex --- .../client/source/class/osparc/utils/Utils.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/utils/Utils.js b/services/static-webserver/client/source/class/osparc/utils/Utils.js index 93ccf8858a5..3b4b78061e0 100644 --- a/services/static-webserver/client/source/class/osparc/utils/Utils.js +++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js @@ -679,6 +679,14 @@ qx.Class.define("osparc.utils.Utils", { return L > 0.35 ? "#FFF" : "#000"; }, + namedColorToHex: function(namedColor) { + if (qx.util.ExtendedColor.isExtendedColor(namedColor)) { + const rgb = qx.util.ExtendedColor.toRgb(namedColor); + return qx.util.ColorUtil.rgbToHexString(rgb); + } + return "#888888"; + }, + bytesToSize: function(bytes, decimals = 2, isDecimalCollapsed = true) { if (!+bytes) { return "0 Bytes"; From b44dcf5f6df942e33d5e57dd2da9b665ebabebe0 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Fri, 9 Aug 2024 12:26:52 +0200 Subject: [PATCH 02/19] convert annotation's named color --- .../client/source/class/osparc/workbench/Annotation.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/Annotation.js b/services/static-webserver/client/source/class/osparc/workbench/Annotation.js index fb2bb848d2f..904b71125eb 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/Annotation.js +++ b/services/static-webserver/client/source/class/osparc/workbench/Annotation.js @@ -33,10 +33,14 @@ qx.Class.define("osparc.workbench.Annotation", { if (id === undefined) { id = osparc.utils.Utils.uuidV4(); } + let color = "color" in data ? data.color : this.getColor(); + if (color && color[0] !== "#") { + color = osparc.utils.Utils.namedColorToHex(color); + } this.set({ id, type: data.type, - color: "color" in data ? data.color : this.getColor(), + color, attributes: data.attributes }); }, From 37c95d86a3fae45c5706f5994d3731c5e27ba9f6 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Fri, 9 Aug 2024 14:11:56 +0200 Subject: [PATCH 03/19] typo --- .../client/source/class/osparc/workbench/WorkbenchUI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index 8850ddf9312..2784c3c21a9 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -1879,7 +1879,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { }; if (type === "rect") { if ([null, undefined].includes(annotation)) { - osparc.FlashMessenger.getInstance().logAs(this.tr("Draw a rectanlge first"), "WARNING"); + osparc.FlashMessenger.getInstance().logAs(this.tr("Draw a rectangle first"), "WARNING"); return false; } serializeData.attributes = osparc.wrapper.Svg.getRectAttributes(annotation); From 7228112854d3e7a98a697785003004d865c0b669 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Fri, 9 Aug 2024 14:19:50 +0200 Subject: [PATCH 04/19] minors --- .../class/osparc/editor/AnnotationEditor.js | 22 +++++++++---------- .../source/class/osparc/form/ColorPicker.js | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index ec0f956c590..32d5e2f0d4b 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -52,14 +52,14 @@ qx.Class.define("osparc.editor.AnnotationEditor", { }, members: { - __addColor: function() { + __addColor: function(row) { this._add(new qx.ui.basic.Label(this.tr("Color")), { - row: 0, + row, column: 0 }); const colorPicker = new osparc.form.ColorPicker(); this._add(colorPicker, { - row: 0, + row, column: 1 }); return colorPicker; @@ -73,13 +73,6 @@ qx.Class.define("osparc.editor.AnnotationEditor", { } let row = 0; - if (["text", "rect"].includes(annotation.getType())) { - const colorPicker = this.__addColor(); - annotation.bind("color", colorPicker, "color"); - colorPicker.bind("color", annotation, "color"); - row++; - } - const attrs = annotation.getAttributes(); if (annotation.getType() === "text") { this._add(new qx.ui.basic.Label(this.tr("Text")), { @@ -111,6 +104,13 @@ qx.Class.define("osparc.editor.AnnotationEditor", { row++; } + if (["text", "rect"].includes(annotation.getType())) { + const colorPicker = this.__addColor(row); + annotation.bind("color", colorPicker, "color"); + colorPicker.bind("color", annotation, "color"); + row++; + } + if (annotation.getType() === "text") { this._add(new qx.ui.basic.Label(this.tr("Size")), { row, @@ -135,7 +135,7 @@ qx.Class.define("osparc.editor.AnnotationEditor", { return; } - const colorPicker = this.__addColor(); + const colorPicker = this.__addColor(0); marker.bind("color", colorPicker, "color"); colorPicker.bind("color", marker, "color"); diff --git a/services/static-webserver/client/source/class/osparc/form/ColorPicker.js b/services/static-webserver/client/source/class/osparc/form/ColorPicker.js index 7c1498f189f..57af71e7590 100644 --- a/services/static-webserver/client/source/class/osparc/form/ColorPicker.js +++ b/services/static-webserver/client/source/class/osparc/form/ColorPicker.js @@ -49,7 +49,7 @@ qx.Class.define("osparc.form.ColorPicker", { break; case "color-input": control = new qx.ui.form.TextField().set({ - width: 60, + width: 80, required: true }); this.bind("color", control, "value"); From 039bb3f1cdbba9277b66817ec684b3a2b16ecab4 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Fri, 9 Aug 2024 15:04:34 +0200 Subject: [PATCH 05/19] Add text with one click --- .../source/class/osparc/workbench/WorkbenchUI.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index 2784c3c21a9..93f253e88bd 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -1260,7 +1260,10 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { }, drawText: { "text": "\uf040", // pencil - "action": () => this.startAnnotationsText() + "action": () => { + const pointerPos = this.__pointerEventToWorkbenchPos(e); + this.startAnnotationsText(pointerPos); + } }, drawRect: { "text": "\uf044", // brush with rect @@ -1577,11 +1580,16 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { this.__toolHint.setValue(this.tr("Draw a rectangle")); }, - startAnnotationsText: function() { + startAnnotationsText: function(workbenchPos) { this.__annotatingNote = false; this.__annotatingText = true; this.__annotatingRect = false; - this.__toolHint.setValue(this.tr("Pick the position")); + if (workbenchPos) { + this.__annotationInitPos = workbenchPos; + this.__mouseUp(); + } else { + this.__toolHint.setValue(this.tr("Pick the position")); + } }, __openNodeRenamer: function(nodeId) { From 208659e14f108ea7c098ea5b3a63352952327518 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 11:34:12 +0200 Subject: [PATCH 06/19] expose make it modal --- .../client/source/class/osparc/editor/AnnotationEditor.js | 6 +----- .../client/source/class/osparc/workbench/WorkbenchUI.js | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index 32d5e2f0d4b..edb77399ce8 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -124,8 +124,6 @@ qx.Class.define("osparc.editor.AnnotationEditor", { }); row++; } - - this.__makeItModal(); }, __applyMarker: function(marker) { @@ -138,11 +136,9 @@ qx.Class.define("osparc.editor.AnnotationEditor", { const colorPicker = this.__addColor(0); marker.bind("color", colorPicker, "color"); colorPicker.bind("color", marker, "color"); - - this.__makeItModal(); }, - __makeItModal: function() { + makeItModal: function() { this.show(); const showHint = () => this.show(); diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index 93f253e88bd..f5392c200d5 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -1183,6 +1183,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const annotation = this.__getAnnotation(newID); this.__setSelectedAnnotations([annotation]); this.__annotationEditor.setAnnotation(annotation); + this.__annotationEditor.makeItModal(); } else { this.fireDataEvent("changeSelectedNode", newID); } @@ -1614,6 +1615,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const marker = node.getMarker(); if (marker) { this.__annotationEditor.setMarker(marker); + this.__annotationEditor.makeItModal(); } } }, From cb71d74678e18e8ce7a8f71a94037a370990ae9a Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 12:31:17 +0200 Subject: [PATCH 07/19] ColorPicker is a form item --- .../source/class/osparc/form/ColorPicker.js | 69 ++++++++++++++----- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/ColorPicker.js b/services/static-webserver/client/source/class/osparc/form/ColorPicker.js index 57af71e7590..f8a9ab9ec64 100644 --- a/services/static-webserver/client/source/class/osparc/form/ColorPicker.js +++ b/services/static-webserver/client/source/class/osparc/form/ColorPicker.js @@ -8,55 +8,74 @@ qx.Class.define("osparc.form.ColorPicker", { extend: qx.ui.core.Widget, + include : [ + qx.ui.form.MForm + ], + implement : [ + qx.ui.form.IStringForm, + qx.ui.form.IForm + ], construct: function() { this.base(arguments); - this._setLayout(new qx.ui.layout.HBox()); + const layout = new qx.ui.layout.HBox(); + this._setLayout(layout); - this._add(this.getChildControl("random-button")); - this._add(this.getChildControl("selector-button")); - this._add(this.getChildControl("color-input")); + this.getChildControl("random-button"); + this.getChildControl("selector-button"); + this.getChildControl("color-input"); }, properties: { - color: { + value: { check: "Color", - event: "changeColor", + event: "changeValue", init: "#303030" } }, + // eslint-disable-next-line qx-rules/no-refs-in-members members: { + _forwardStates: { + focused : true, + invalid : true + }, + _createChildControlImpl: function(id) { let control; switch (id) { case "random-button": control = new qx.ui.form.Button(null, "@FontAwesome5Solid/sync-alt/12"); - control.addListener("execute", () => this.setColor(osparc.utils.Utils.getRandomColor()), this); - this.bind("color", control, "backgroundColor"); - this.bind("color", control, "textColor", { + control.addListener("execute", () => this.setValue(osparc.utils.Utils.getRandomColor()), this); + this.bind("value", control, "backgroundColor"); + this.bind("value", control, "textColor", { converter: value => qx.theme.manager.Color.getInstance().resolve(osparc.utils.Utils.getContrastedTextColor(value)) }); + this._add(control); break; case "selector-button": control = new qx.ui.form.Button(null, "@FontAwesome5Solid/eye-dropper/12"); control.addListener("execute", () => this.__openColorSelector(), this); - this.bind("color", control, "backgroundColor"); - this.bind("color", control, "textColor", { + this.bind("value", control, "backgroundColor"); + this.bind("value", control, "textColor", { converter: value => qx.theme.manager.Color.getInstance().resolve(osparc.utils.Utils.getContrastedTextColor(value)) }); + this._add(control); break; case "color-input": control = new qx.ui.form.TextField().set({ width: 80, required: true }); - this.bind("color", control, "value"); + this._add(control, { + flex: 1 + }); + this.bind("value", control, "value"); control.addListener("changeValue", e => { const newColor = e.getData(); if (osparc.utils.Validators.hexColor(newColor, control)) { - this.setColor(newColor); + this.setValue(newColor); } }); break; @@ -66,12 +85,30 @@ qx.Class.define("osparc.form.ColorPicker", { __openColorSelector: function() { const colorSelector = new qx.ui.control.ColorSelector(); - const rgb = qx.util.ColorUtil.hexStringToRgb(this.getColor()); + const rgb = qx.util.ColorUtil.hexStringToRgb(this.getValue()); colorSelector.setRed(rgb[0]); colorSelector.setGreen(rgb[1]); colorSelector.setBlue(rgb[2]); osparc.ui.window.Window.popUpInWindow(colorSelector, this.tr("Pick a color"), 590, 380); - colorSelector.addListener("changeValue", e => this.setColor(e.getData())); - } + colorSelector.addListener("changeValue", e => this.setValue(e.getData())); + }, + + // overridden + resetValue: function() { + this.getChildControl("color-input").resetValue(); + }, + + // overridden + focus: function() { + this.base(arguments); + this.getChildControl("color-input").getFocusElement().focus(); + }, + + // overridden + tabFocus: function() { + const field = this.getChildControl("color-input"); + field.getFocusElement().focus(); + field.selectAllText(); + }, } }); From 310022a06ced6e1fe20b64fb7fcb5720c0af489c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 12:31:44 +0200 Subject: [PATCH 08/19] AnnotationEditor is a form --- .../class/osparc/editor/AnnotationEditor.js | 103 +++++++----------- 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index edb77399ce8..30a05506874 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -16,19 +16,11 @@ ************************************************************************ */ qx.Class.define("osparc.editor.AnnotationEditor", { - extend: qx.ui.core.Widget, + extend: qx.ui.form.renderer.Single, construct: function(annotation) { - this.base(arguments); - - const layout = new qx.ui.layout.Grid(5, 5); - layout.setColumnAlign(0, "right", "middle"); - layout.setColumnAlign(1, "left", "middle"); - this._setLayout(layout); - - this.set({ - padding: 10 - }); + const form = this.__form = new qx.ui.form.Form(); + this.base(arguments, form); if (annotation) { this.setAnnotation(annotation); @@ -52,88 +44,75 @@ qx.Class.define("osparc.editor.AnnotationEditor", { }, members: { - __addColor: function(row) { - this._add(new qx.ui.basic.Label(this.tr("Color")), { - row, - column: 0 - }); - const colorPicker = new osparc.form.ColorPicker(); - this._add(colorPicker, { - row, - column: 1 - }); - return colorPicker; + __form: null, + + _createChildControlImpl: function(id) { + let control; + switch (id) { + case "text-field": + control = new qx.ui.form.TextField(); + this.__form.add(control, "Text", null, "text"); + break; + case "text-area": + control = new qx.ui.form.TextArea().set({ + autoSize: true, + minHeight: 70, + maxHeight: 140 + }); + this.__form.add(control, "Note", null, "note"); + break; + case "color-picker": + control = new osparc.form.ColorPicker(); + this.__form.add(control, "Color", null, "color"); + break; + case "size": + control = new qx.ui.form.Spinner(); + this.__form.add(control, "Size", null, "size"); + break; + } + return control || this.base(arguments, id); }, __applyAnnotation: function(annotation) { this._removeAll(); - if (annotation === null) { return; } - let row = 0; const attrs = annotation.getAttributes(); if (annotation.getType() === "text") { - this._add(new qx.ui.basic.Label(this.tr("Text")), { - row, - column: 0 + const textField = this.getChildControl("text-field").set({ + value: attrs.text }); - const textField = new qx.ui.form.TextField(attrs.text); textField.addListener("changeValue", e => annotation.setText(e.getData())); - this._add(textField, { - row, - column: 1 - }); - row++; } else if (annotation.getType() === "note") { - this._add(new qx.ui.basic.Label(this.tr("Note")), { - row, - column: 0 - }); - const textArea = new qx.ui.form.TextArea(attrs.text).set({ - autoSize: true, - minHeight: 70, - maxHeight: 140 + const textArea = this.getChildControl("text-area").set({ + value: attrs.text }); textArea.addListener("changeValue", e => annotation.setText(e.getData())); - this._add(textArea, { - row, - column: 1 - }); - row++; } if (["text", "rect"].includes(annotation.getType())) { - const colorPicker = this.__addColor(row); - annotation.bind("color", colorPicker, "color"); - colorPicker.bind("color", annotation, "color"); - row++; + const colorPicker = this.getChildControl("color-picker"); + annotation.bind("color", colorPicker, "value"); + colorPicker.bind("value", annotation, "color"); } if (annotation.getType() === "text") { - this._add(new qx.ui.basic.Label(this.tr("Size")), { - row, - column: 0 - }); - const fontSizeField = new qx.ui.form.Spinner(attrs.fontSize); + const fontSizeField = this.getChildControl("size").set({ + value: attrs.fontSize + }) fontSizeField.addListener("changeValue", e => annotation.setFontSize(e.getData())); - this._add(fontSizeField, { - row, - column: 1 - }); - row++; } }, __applyMarker: function(marker) { this._removeAll(); - if (marker === null) { return; } - const colorPicker = this.__addColor(0); + const colorPicker = this.getChildControl("color-picker"); marker.bind("color", colorPicker, "color"); colorPicker.bind("color", marker, "color"); }, From df527439d741891c2b64eb79ca362046fb58bf1d Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 13:39:30 +0200 Subject: [PATCH 09/19] refactoring --- .../class/osparc/editor/AnnotationEditor.js | 58 ++++++++++++++++--- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index 30a05506874..7ff2a68db75 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -16,17 +16,26 @@ ************************************************************************ */ qx.Class.define("osparc.editor.AnnotationEditor", { - extend: qx.ui.form.renderer.Single, + extend: qx.ui.core.Widget, construct: function(annotation) { - const form = this.__form = new qx.ui.form.Form(); - this.base(arguments, form); + this.base(arguments); + + this._setLayout(new qx.ui.layout.VBox(10)); + + this.__form = new qx.ui.form.Form(); + this.getChildControl("form-renderer"); if (annotation) { this.setAnnotation(annotation); } }, + events: { + "addAnnotation": "qx.event.type.Event", + "cancel": "qx.event.type.Event" + }, + properties: { annotation: { check: "osparc.workbench.Annotation", @@ -46,9 +55,17 @@ qx.Class.define("osparc.editor.AnnotationEditor", { members: { __form: null, + getForm: function() { + return this.__form; + }, + _createChildControlImpl: function(id) { let control; switch (id) { + case "form-renderer": + control = new qx.ui.form.renderer.Single(this.__form); + this._add(control); + break; case "text-field": control = new qx.ui.form.TextField(); this.__form.add(control, "Text", null, "text"); @@ -65,16 +82,39 @@ qx.Class.define("osparc.editor.AnnotationEditor", { control = new osparc.form.ColorPicker(); this.__form.add(control, "Color", null, "color"); break; - case "size": + case "font-size": control = new qx.ui.form.Spinner(); this.__form.add(control, "Size", null, "size"); break; + case "buttons-layout": + control = new qx.ui.container.Composite(new qx.ui.layout.HBox(10).set({ + alignX: "right" + })); + this._add(control); + break; + case "cancel-btn": { + const buttons = this.getChildControl("buttons-layout"); + control = new qx.ui.form.Button(this.tr("Cancel")).set({ + appearance: "form-button-text" + }); + control.addListener("execute", () => this.fireEvent("cancel"), this); + buttons.add(control); + break; + } + case "add-btn": { + const buttons = this.getChildControl("buttons-layout"); + control = new qx.ui.form.Button(this.tr("Add")).set({ + appearance: "form-button" + }); + control.addListener("execute", () => this.fireEvent("addAnnotation"), this); + buttons.add(control); + break; + } } return control || this.base(arguments, id); }, __applyAnnotation: function(annotation) { - this._removeAll(); if (annotation === null) { return; } @@ -99,7 +139,7 @@ qx.Class.define("osparc.editor.AnnotationEditor", { } if (annotation.getType() === "text") { - const fontSizeField = this.getChildControl("size").set({ + const fontSizeField = this.getChildControl("font-size").set({ value: attrs.fontSize }) fontSizeField.addListener("changeValue", e => annotation.setFontSize(e.getData())); @@ -107,7 +147,6 @@ qx.Class.define("osparc.editor.AnnotationEditor", { }, __applyMarker: function(marker) { - this._removeAll(); if (marker === null) { return; } @@ -117,6 +156,11 @@ qx.Class.define("osparc.editor.AnnotationEditor", { colorPicker.bind("color", marker, "color"); }, + addButtons: function() { + this.getChildControl("cancel-btn"); + this.getChildControl("add-btn"); + }, + makeItModal: function() { this.show(); From 7ec6279bbea68cb5725407f297457380c7fcd17c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 13:39:50 +0200 Subject: [PATCH 10/19] Annotation editor for creating new annotation text --- .../class/osparc/workbench/WorkbenchUI.js | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index f5392c200d5..ac1a657a8a5 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -1915,16 +1915,28 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { } else if (type === "rect") { this.__addAnnotation(serializeData); } else if (type === "text") { - const title = this.tr("Add Text"); - const titleEditor = new osparc.widget.Renamer(null, null, title); - titleEditor.addListener("labelChanged", e => { - titleEditor.close(); - serializeData.attributes.text = e.getData()["newLabel"]; - serializeData.attributes.fontSize = 12; + const tempAnnotation = new osparc.workbench.Annotation(null, { + type: "text", + color: osparc.workbench.Annotation.DEFAULT_COLOR, + attributes: { + text: "", + fontSize: 12 + } + }); + const annotationEditor = new osparc.editor.AnnotationEditor(tempAnnotation); + annotationEditor.addButtons(); + const win = osparc.ui.window.Window.popUpInWindow(annotationEditor, "Add Text Annotation", 220, 135).set({ + clickAwayClose: true, + showClose: true + }); + annotationEditor.addListener("addAnnotation", () => { + const form = annotationEditor.getForm(); + serializeData.attributes.text = form.getItem("text").getValue(); + serializeData.attributes.color = form.getItem("color").getValue(); + serializeData.attributes.fontSize = form.getItem("size").getValue(); this.__addAnnotation(serializeData); }, this); - titleEditor.center(); - titleEditor.open(); + win.open(); } return true; }, From ac075d1faaf40903c8592e8fbdb93bbc0b33492b Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 13:44:41 +0200 Subject: [PATCH 11/19] focus textField --- .../client/source/class/osparc/workbench/WorkbenchUI.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index ac1a657a8a5..823e5b161f7 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -1925,11 +1925,17 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { }); const annotationEditor = new osparc.editor.AnnotationEditor(tempAnnotation); annotationEditor.addButtons(); + annotationEditor.addListener("appear", () => { + const textField = annotationEditor.getChildControl("text-field"); + textField.focus(); + textField.activate(); + }); const win = osparc.ui.window.Window.popUpInWindow(annotationEditor, "Add Text Annotation", 220, 135).set({ clickAwayClose: true, showClose: true }); annotationEditor.addListener("addAnnotation", () => { + win.close(); const form = annotationEditor.getForm(); serializeData.attributes.text = form.getItem("text").getValue(); serializeData.attributes.color = form.getItem("color").getValue(); From 2ef81e25140f4353e3d0d4a55472442b73858944 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 13:52:30 +0200 Subject: [PATCH 12/19] Listen to "Enter" key --- .../client/source/class/osparc/editor/AnnotationEditor.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index 7ff2a68db75..433f7b5f82a 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -159,6 +159,13 @@ qx.Class.define("osparc.editor.AnnotationEditor", { addButtons: function() { this.getChildControl("cancel-btn"); this.getChildControl("add-btn"); + + // Listen to "Enter" key + this.addListener("keypress", keyEvent => { + if (keyEvent.getKeyIdentifier() === "Enter") { + this.fireEvent("addAnnotation"); + } + }, this); }, makeItModal: function() { From ccc8525c0f36a096244076af1eef3494d17f97e1 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 13:52:49 +0200 Subject: [PATCH 13/19] recreate annotationEditor --- .../class/osparc/workbench/WorkbenchUI.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index 823e5b161f7..4965c03616b 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -197,7 +197,6 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { this.__addStartHint(); this.__addToolHint(); this.__addDeleteItemButton(); - this.__annotationEditorView(); }, __addStartHint: function() { @@ -248,7 +247,11 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { }); }, - __annotationEditorView: function() { + __getAnnotationEditorView: function() { + if (this.__annotationEditor) { + this.__workbenchLayer.remove(this.__annotationEditor); + } + const annotationEditor = this.__annotationEditor = new osparc.editor.AnnotationEditor().set({ backgroundColor: "background-main-2", visibility: "excluded" @@ -258,6 +261,8 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { top: 10, right: 10 }); + + return annotationEditor; }, __getWorkbench: function() { @@ -1182,8 +1187,9 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { } else if (this.__isSelectedItemAnAnnotation()) { const annotation = this.__getAnnotation(newID); this.__setSelectedAnnotations([annotation]); - this.__annotationEditor.setAnnotation(annotation); - this.__annotationEditor.makeItModal(); + const annotationEditor = this.__getAnnotationEditorView(); + annotationEditor.setAnnotation(annotation); + annotationEditor.makeItModal(); } else { this.fireDataEvent("changeSelectedNode", newID); } @@ -1614,8 +1620,9 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const node = this.getStudy().getWorkbench().getNode(nodeId); const marker = node.getMarker(); if (marker) { - this.__annotationEditor.setMarker(marker); - this.__annotationEditor.makeItModal(); + const annotationEditor = this.__getAnnotationEditorView(); + annotationEditor.setMarker(marker); + annotationEditor.makeItModal(); } } }, From 2be3ffb60d7118cddaeb8fb6102acf1eba84fca4 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 14:22:49 +0200 Subject: [PATCH 14/19] minor --- .../client/source/class/osparc/editor/AnnotationEditor.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index 433f7b5f82a..3cff3e0f600 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -169,6 +169,10 @@ qx.Class.define("osparc.editor.AnnotationEditor", { }, makeItModal: function() { + this.set({ + padding: 10 + }); + this.show(); const showHint = () => this.show(); From df9d3e958bc918e0f906cb04d9a2933076760745 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 15:08:36 +0200 Subject: [PATCH 15/19] keep annotation color --- .../source/class/osparc/workbench/WorkbenchUI.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index 4965c03616b..f82112327c2 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -141,6 +141,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { __annotationInitPos: null, __selectedAnnotations: null, __annotationEditor: null, + __annotationLastColor: null, __applyStudy: function(study) { study.getWorkbench().addListener("reloadModel", () => this.__reloadCurrentModel(), this); @@ -1190,6 +1191,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const annotationEditor = this.__getAnnotationEditorView(); annotationEditor.setAnnotation(annotation); annotationEditor.makeItModal(); + annotation.addListener("changeColor", e => this.__annotationLastColor = e.getData()); } else { this.fireDataEvent("changeSelectedNode", newID); } @@ -1883,15 +1885,18 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const width = Math.abs(initPos.x - currentPos.x); const height = Math.abs(initPos.y - currentPos.y); if ([null, undefined].includes(this.__rectAnnotationRepr)) { - this.__rectAnnotationRepr = this.__svgLayer.drawAnnotationRect(width, height, x, y, osparc.workbench.Annotation.DEFAULT_COLOR); + const color = this.__annotationLastColor ? this.__annotationLastColor : osparc.workbench.Annotation.DEFAULT_COLOR; + this.__rectAnnotationRepr = this.__svgLayer.drawAnnotationRect(width, height, x, y, color); } else { osparc.wrapper.Svg.updateRect(this.__rectAnnotationRepr, width, height, x, y); } }, __consolidateAnnotation: function(type, initPos, annotation) { + const color = this.__annotationLastColor ? this.__annotationLastColor : osparc.workbench.Annotation.DEFAULT_COLOR; const serializeData = { type, + color, attributes: {} }; if (type === "rect") { @@ -1924,7 +1929,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { } else if (type === "text") { const tempAnnotation = new osparc.workbench.Annotation(null, { type: "text", - color: osparc.workbench.Annotation.DEFAULT_COLOR, + color, attributes: { text: "", fontSize: 12 @@ -1932,6 +1937,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { }); const annotationEditor = new osparc.editor.AnnotationEditor(tempAnnotation); annotationEditor.addButtons(); + tempAnnotation.addListener("changeColor", e => this.__annotationLastColor = e.getData()); annotationEditor.addListener("appear", () => { const textField = annotationEditor.getChildControl("text-field"); textField.focus(); From a31303f96bc917e6d667a96efc16c53a398e760c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 15:22:41 +0200 Subject: [PATCH 16/19] fire close event --- .../source/class/osparc/editor/AnnotationEditor.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index 3cff3e0f600..b47ea257f9d 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -33,7 +33,8 @@ qx.Class.define("osparc.editor.AnnotationEditor", { events: { "addAnnotation": "qx.event.type.Event", - "cancel": "qx.event.type.Event" + "cancel": "qx.event.type.Event", + "close": "qx.event.type.Event", }, properties: { @@ -175,20 +176,23 @@ qx.Class.define("osparc.editor.AnnotationEditor", { this.show(); - const showHint = () => this.show(); - const hideHint = () => this.exclude(); + const showEditor = () => this.show(); + const hideEditor = () => { + this.fireEvent("close"); + this.exclude(); + }; const tapListener = event => { if (osparc.utils.Utils.isMouseOnElement(this, event)) { return; } - hideHint(); + hideEditor(); this.set({ annotation: null, marker: null }); document.removeEventListener("mousedown", tapListener); }; - showHint(); + showEditor(); document.addEventListener("mousedown", tapListener); } } From 3c2c116842909ff1c7b984085ec4d9234c52decf Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 15:33:33 +0200 Subject: [PATCH 17/19] delete button --- .../class/osparc/editor/AnnotationEditor.js | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js index b47ea257f9d..f62e7b8ef1e 100644 --- a/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/AnnotationEditor.js @@ -34,7 +34,7 @@ qx.Class.define("osparc.editor.AnnotationEditor", { events: { "addAnnotation": "qx.event.type.Event", "cancel": "qx.event.type.Event", - "close": "qx.event.type.Event", + "deleteAnnotation": "qx.event.type.Event", }, properties: { @@ -111,6 +111,15 @@ qx.Class.define("osparc.editor.AnnotationEditor", { buttons.add(control); break; } + case "delete-btn": { + const buttons = this.getChildControl("buttons-layout"); + control = new qx.ui.form.Button(this.tr("Delete")).set({ + appearance: "danger-button" + }); + control.addListener("execute", () => this.fireEvent("deleteAnnotation"), this); + buttons.add(control); + break; + } } return control || this.base(arguments, id); }, @@ -157,7 +166,11 @@ qx.Class.define("osparc.editor.AnnotationEditor", { colorPicker.bind("color", marker, "color"); }, - addButtons: function() { + addDeleteButton: function() { + this.getChildControl("delete-btn"); + }, + + addAddButtons: function() { this.getChildControl("cancel-btn"); this.getChildControl("add-btn"); @@ -177,10 +190,7 @@ qx.Class.define("osparc.editor.AnnotationEditor", { this.show(); const showEditor = () => this.show(); - const hideEditor = () => { - this.fireEvent("close"); - this.exclude(); - }; + const hideEditor = () => this.exclude(); const tapListener = event => { if (osparc.utils.Utils.isMouseOnElement(this, event)) { return; From 2097a8ae7376d8e4ca8176c4b2159c26ec174399 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 15:39:11 +0200 Subject: [PATCH 18/19] Make the delete option more visible --- .../class/osparc/workbench/WorkbenchUI.js | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js index f82112327c2..e76fc5d09fa 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/workbench/WorkbenchUI.js @@ -235,10 +235,6 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { if (this.__isSelectedItemAnEdge()) { this.__removeEdge(this.__getEdgeUI(this.__selectedItemId)); this.__selectedItemChanged(null); - } else if (this.__isSelectedItemAnAnnotation()) { - const id = this.__selectedItemId; - this.__selectedItemChanged(null); - this.__removeAnnotation(id); } }, this); @@ -257,6 +253,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { backgroundColor: "background-main-2", visibility: "excluded" }); + annotationEditor.addDeleteButton(); this.__workbenchLayer.add(annotationEditor, { top: 10, @@ -1191,13 +1188,18 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const annotationEditor = this.__getAnnotationEditorView(); annotationEditor.setAnnotation(annotation); annotationEditor.makeItModal(); + annotationEditor.addListener("deleteAnnotation", () => { + annotationEditor.exclude(); + this.__selectedItemChanged(null); + this.__removeAnnotation(annotation.getId()); + }, this); annotation.addListener("changeColor", e => this.__annotationLastColor = e.getData()); } else { this.fireDataEvent("changeSelectedNode", newID); } if (this.__deleteItemButton) { - this.__deleteItemButton.setVisibility(this.__isSelectedItemAnEdge() || this.__isSelectedItemAnAnnotation() ? "visible" : "excluded"); + this.__deleteItemButton.setVisibility(this.__isSelectedItemAnEdge() ? "visible" : "excluded"); } }, @@ -1703,15 +1705,6 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { this.__removeEdge(this.__getEdgeUI(this.__selectedItemId)); this.__selectedItemChanged(null); } - if (this.__isSelectedItemAnAnnotation()) { - const selectedAnnotation = this.__getAnnotation(this.__selectedItemId); - // Only delete if it's a rectangle, for the other cases the user might be editing the text - if (selectedAnnotation.getType() === "rect") { - const id = this.__selectedItemId; - this.__selectedItemChanged(null); - this.__removeAnnotation(id); - } - } break; case "Escape": this.resetSelection(); @@ -1936,7 +1929,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { } }); const annotationEditor = new osparc.editor.AnnotationEditor(tempAnnotation); - annotationEditor.addButtons(); + annotationEditor.addAddButtons(); tempAnnotation.addListener("changeColor", e => this.__annotationLastColor = e.getData()); annotationEditor.addListener("appear", () => { const textField = annotationEditor.getChildControl("text-field"); @@ -1952,6 +1945,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", { const form = annotationEditor.getForm(); serializeData.attributes.text = form.getItem("text").getValue(); serializeData.attributes.color = form.getItem("color").getValue(); + serializeData.color = form.getItem("color").getValue(); serializeData.attributes.fontSize = form.getItem("size").getValue(); this.__addAnnotation(serializeData); }, this); From 6e98e00e3d86e1c86e57103a678d4e9ddc33ecbe Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Wed, 14 Aug 2024 16:37:26 +0200 Subject: [PATCH 19/19] contact shows email --- .../client/source/class/osparc/info/ServiceUtils.js | 11 ++++++----- .../client/source/class/osparc/store/Support.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js b/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js index 0c4594d3376..4ebd0569c0c 100644 --- a/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js +++ b/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js @@ -86,12 +86,13 @@ qx.Class.define("osparc.info.ServiceUtils", { * @param serviceData {Object} Serialized Service Object */ createContact: function(serviceData) { - const owner = new qx.ui.basic.Label(); - owner.set({ - value: osparc.utils.Utils.getNameFromEmail(serviceData["contact"]), - toolTipText: serviceData["contact"] + const contact = new qx.ui.basic.Label(); + contact.set({ + value: osparc.store.Support.mailToText(serviceData["contact"], (serviceData["name"] + ":" + serviceData["version"])), + selectable: true, + rich: true }); - return owner; + return contact; }, /** diff --git a/services/static-webserver/client/source/class/osparc/store/Support.js b/services/static-webserver/client/source/class/osparc/store/Support.js index 508ad582644..e79de4d1a27 100644 --- a/services/static-webserver/client/source/class/osparc/store/Support.js +++ b/services/static-webserver/client/source/class/osparc/store/Support.js @@ -137,7 +137,7 @@ qx.Class.define("osparc.store.Support", { mailToText: function(email, subject) { const color = qx.theme.manager.Color.getInstance().resolve("text"); - const textLink = `
  ${email}  
`; + const textLink = `
${email}  
`; return textLink; },