allow a node's icon to be set dynamically (#1490)

* create a proto type

* Fixed some problems after reviewing
This commit is contained in:
Kazuki Nakanishi
2017-11-30 13:13:35 +00:00
committed by Nick O'Leary
parent cc88ebd2b9
commit 6d2389945b
16 changed files with 367 additions and 19 deletions

View File

@@ -108,6 +108,14 @@ RED.editor = (function() {
}
}
}
if (node.icon) {
var iconPath = RED.utils.separateIconPath(node.icon);
var iconSets = RED.nodes.getIconSets();
var iconFileList = iconSets[iconPath.module];
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
isValid = false;
}
}
return isValid;
}
@@ -159,6 +167,23 @@ RED.editor = (function() {
}
}
}
if (node.icon) {
var iconPath = RED.utils.separateIconPath(node.icon);
var iconSets = RED.nodes.getIconSets();
var iconFileList = iconSets[iconPath.module];
var iconModule = $("#node-settings-icon-module");
var iconFile = $("#node-settings-icon-file");
if (!iconFileList) {
iconModule.addClass("input-error");
iconFile.removeClass("input-error");
} else if (iconFileList.indexOf(iconPath.file) === -1) {
iconModule.removeClass("input-error");
iconFile.addClass("input-error");
} else {
iconModule.removeClass("input-error");
iconFile.removeClass("input-error");
}
}
}
function validateNodeEditorProperty(node,defaults,property,prefix) {
var input = $("#"+prefix+"-"+property);
@@ -710,10 +735,76 @@ RED.editor = (function() {
} else {
buildLabelRow().appendTo(outputsDiv);
}
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
var iconDiv = $("#node-settings-icon");
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
var iconForm = $('<div>',{class:"node-label-form-row"});
iconForm.appendTo(iconDiv);
$('<label>').appendTo(iconForm);
var selectIconModule = $('<select id="node-settings-icon-module"><option value=""></option></select>').appendTo(iconForm);
var iconPath;
if (node.icon) {
iconPath = RED.utils.separateIconPath(node.icon);
} else {
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
}
var iconSets = RED.nodes.getIconSets();
Object.keys(iconSets).forEach(function(moduleName) {
selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
});
if (iconPath.module && !iconSets[iconPath.module]) {
selectIconModule.append($("<option disabled></option>").val(iconPath.module).text(iconPath.module));
}
selectIconModule.val(iconPath.module);
var iconModuleHidden = $('<input type="hidden" id="node-settings-icon-module-hidden"></input>').appendTo(iconForm);
iconModuleHidden.val(iconPath.module);
var selectIconFile = $('<select id="node-settings-icon-file"><option value=""></option></select>').appendTo(iconForm);
selectIconModule.change(function() {
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
});
var iconFileHidden = $('<input type="hidden" id="node-settings-icon-file-hidden"></input>').appendTo(iconForm);
iconFileHidden.val(iconPath.file);
selectIconFile.change(function() {
selectIconFile.removeClass("input-error");
var fileName = selectIconFile.val();
iconFileHidden.val(fileName);
});
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, false);
var iconFileList = iconSets[selectIconModule.val()];
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
selectIconFile.append($("<option disabled></option>").val(iconPath.file).text(iconPath.file));
}
selectIconFile.val(iconPath.file);
}
function moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, updateIconFile) {
selectIconFile.children().remove();
var moduleName = selectIconModule.val();
if (moduleName !== null) {
iconModuleHidden.val(moduleName);
}
var iconFileList = iconSets[moduleName];
if (iconFileList) {
iconFileList.forEach(function(fileName) {
if (updateIconFile) {
updateIconFile = false;
iconFileHidden.val(fileName);
}
selectIconFile.append($("<option></option>").val(fileName).text(fileName));
});
}
selectIconFile.prop("disabled", !iconFileList);
selectIconModule.removeClass("input-error");
}
function showEditDialog(node) {
var editing_node = node;
var isDefaultIcon;
var defaultIcon;
editStack.push(node);
RED.view.state(RED.state.EDITING);
var type = node.type;
@@ -960,6 +1051,31 @@ RED.editor = (function() {
changed = true;
}
var iconModule = $("#node-settings-icon-module-hidden").val();
var iconFile = $("#node-settings-icon-file-hidden").val();
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
if (!isDefaultIcon) {
if (icon !== editing_node.icon) {
changes.icon = editing_node.icon;
editing_node.icon = icon;
changed = true;
}
} else {
if (icon !== defaultIcon) {
changes.icon = editing_node.icon;
editing_node.icon = icon;
changed = true;
} else {
var iconPath = RED.utils.getDefaultNodeIcon(editing_node._def, editing_node);
var currentDefaultIcon = iconPath.module+"/"+iconPath.file;
if (defaultIcon !== currentDefaultIcon) {
changes.icon = editing_node.icon;
editing_node.icon = currentDefaultIcon;
changed = true;
}
}
}
if (changed) {
var wasChanged = editing_node.changed;
editing_node.changed = true;
@@ -1051,6 +1167,13 @@ RED.editor = (function() {
} else {
ns = node._def.set.id;
}
var iconPath = RED.utils.getDefaultNodeIcon(node._def,node);
defaultIcon = iconPath.module+"/"+iconPath.file;
if (node.icon && node.icon !== defaultIcon) {
isDefaultIcon = false;
} else {
isDefaultIcon = true;
}
buildEditForm(nodeProperties.content,"dialog-form",type,ns);
buildLabelForm(portLabels.content,node);

View File

@@ -689,16 +689,21 @@ RED.utils = (function() {
return result;
}
function getNodeIcon(def,node) {
if (def.category === 'config') {
return "icons/node-red/cog.png"
} else if (node && node.type === 'tab') {
return "icons/node-red/subflow.png"
} else if (node && node.type === 'unknown') {
return "icons/node-red/alert.png"
} else if (node && node.type === 'subflow') {
return "icons/node-red/subflow.png"
function separateIconPath(icon) {
var result = {module: "", file: ""};
if (icon) {
var index = icon.indexOf('/');
if (index !== -1) {
result.module = icon.slice(0, index);
result.file = icon.slice(index + 1);
} else {
result.file = icon;
}
}
return result;
}
function getDefaultNodeIcon(def,node) {
var icon_url;
if (typeof def.icon === "function") {
try {
@@ -710,7 +715,34 @@ RED.utils = (function() {
} else {
icon_url = def.icon;
}
return "icons/"+def.set.module+"/"+icon_url;
var iconPath = separateIconPath(icon_url);
if (!iconPath.module) {
iconPath.module = def.set.module;
}
return iconPath;
}
function getNodeIcon(def,node) {
if (def.category === 'config') {
return "icons/node-red/cog.png"
} else if (node && node.type === 'tab') {
return "icons/node-red/subflow.png"
} else if (node && node.type === 'unknown') {
return "icons/node-red/alert.png"
} else if (node && node.type === 'subflow') {
return "icons/node-red/subflow.png"
} else if (node && node.icon) {
var iconPath = separateIconPath(node.icon);
var iconSets = RED.nodes.getIconSets();
var iconFileList = iconSets[iconPath.module];
if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) {
return "icons/" + node.icon;
}
}
var iconPath = getDefaultNodeIcon(def, node);
return "icons/"+iconPath.module+"/"+iconPath.file;
}
function getNodeLabel(node,defaultLabel) {
@@ -735,6 +767,8 @@ RED.utils = (function() {
getMessageProperty: getMessageProperty,
normalisePropertyExpression: normalisePropertyExpression,
validatePropertyExpression: validatePropertyExpression,
separateIconPath: separateIconPath,
getDefaultNodeIcon: getDefaultNodeIcon,
getNodeIcon: getNodeIcon,
getNodeLabel: getNodeLabel,
}