Skip to content

Commit

Permalink
Showing 5 changed files with 242 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -21,20 +21,22 @@ qx.Class.define("osparc.editor.AnnotationEditor", {
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._setLayout(new qx.ui.layout.VBox(10));

this.set({
padding: 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",
"deleteAnnotation": "qx.event.type.Event",
},

properties: {
annotation: {
check: "osparc.workbench.Annotation",
@@ -52,113 +54,155 @@ qx.Class.define("osparc.editor.AnnotationEditor", {
},

members: {
__addColor: function() {
this._add(new qx.ui.basic.Label(this.tr("Color")), {
row: 0,
column: 0
});
const colorPicker = new osparc.form.ColorPicker();
this._add(colorPicker, {
row: 0,
column: 1
});
return colorPicker;
__form: null,

getForm: function() {
return this.__form;
},

__applyAnnotation: function(annotation) {
this._removeAll();
_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");
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 "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;
}
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);
},

__applyAnnotation: function(annotation) {
if (annotation === null) {
return;
}

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")), {
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.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("font-size").set({
value: attrs.fontSize
})
fontSizeField.addListener("changeValue", e => annotation.setFontSize(e.getData()));
this._add(fontSizeField, {
row,
column: 1
});
row++;
}

this.__makeItModal();
},

__applyMarker: function(marker) {
this._removeAll();

if (marker === null) {
return;
}

const colorPicker = this.__addColor();
const colorPicker = this.getChildControl("color-picker");
marker.bind("color", colorPicker, "color");
colorPicker.bind("color", marker, "color");
},

addDeleteButton: function() {
this.getChildControl("delete-btn");
},

this.__makeItModal();
addAddButtons: 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() {
makeItModal: function() {
this.set({
padding: 10
});

this.show();

const showHint = () => this.show();
const hideHint = () => this.exclude();
const showEditor = () => this.show();
const hideEditor = () => 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);
}
}
Original file line number Diff line number Diff line change
@@ -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: 60,
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();
},
}
});
Original file line number Diff line number Diff line change
@@ -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;
},

/**
Original file line number Diff line number Diff line change
@@ -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 = `<center>&nbsp&nbsp<a href="mailto:${email}?subject=${subject}" style='color: ${color}' target='_blank'>${email}</a>&nbsp&nbsp<center>`;
const textLink = `<center><a href="mailto:${email}?subject=${subject}" style='color: ${color}' target='_blank'>${email}</a>&nbsp&nbsp<center>`;
return textLink;
},

Original file line number Diff line number Diff line change
@@ -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);
@@ -197,7 +198,6 @@ qx.Class.define("osparc.workbench.WorkbenchUI", {
this.__addStartHint();
this.__addToolHint();
this.__addDeleteItemButton();
this.__annotationEditorView();
},

__addStartHint: function() {
@@ -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);

@@ -248,16 +244,23 @@ 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"
});
annotationEditor.addDeleteButton();

this.__workbenchLayer.add(annotationEditor, {
top: 10,
right: 10
});

return annotationEditor;
},

__getWorkbench: function() {
@@ -1182,13 +1185,21 @@ qx.Class.define("osparc.workbench.WorkbenchUI", {
} else if (this.__isSelectedItemAnAnnotation()) {
const annotation = this.__getAnnotation(newID);
this.__setSelectedAnnotations([annotation]);
this.__annotationEditor.setAnnotation(annotation);
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");
}
},

@@ -1260,7 +1271,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 +1591,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) {
@@ -1605,7 +1624,9 @@ qx.Class.define("osparc.workbench.WorkbenchUI", {
const node = this.getStudy().getWorkbench().getNode(nodeId);
const marker = node.getMarker();
if (marker) {
this.__annotationEditor.setMarker(marker);
const annotationEditor = this.__getAnnotationEditorView();
annotationEditor.setMarker(marker);
annotationEditor.makeItModal();
}
}
},
@@ -1684,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();
@@ -1866,20 +1878,23 @@ 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") {
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);
@@ -1905,16 +1920,36 @@ 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,
attributes: {
text: "",
fontSize: 12
}
});
const annotationEditor = new osparc.editor.AnnotationEditor(tempAnnotation);
annotationEditor.addAddButtons();
tempAnnotation.addListener("changeColor", e => this.__annotationLastColor = e.getData());
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();
serializeData.color = form.getItem("color").getValue();
serializeData.attributes.fontSize = form.getItem("size").getValue();
this.__addAnnotation(serializeData);
}, this);
titleEditor.center();
titleEditor.open();
win.open();
}
return true;
},

0 comments on commit 2757343

Please sign in to comment.