From 6d2389945b283d68247d1763a16ee24fe00a428a Mon Sep 17 00:00:00 2001 From: Kazuki Nakanishi Date: Thu, 30 Nov 2017 13:13:35 +0000 Subject: [PATCH] allow a node's icon to be set dynamically (#1490) * create a proto type * Fixed some problems after reviewing --- editor/js/main.js | 22 +++- editor/js/nodes.js | 17 +++ editor/js/ui/editor.js | 123 ++++++++++++++++++ editor/js/ui/utils.js | 54 ++++++-- editor/sass/editor.scss | 7 + red/api/index.js | 3 +- red/api/locales/en-US/editor.json | 3 +- red/api/locales/ja/editor.json | 3 +- red/api/nodes.js | 5 + red/runtime/nodes/index.js | 1 + red/runtime/nodes/registry/index.js | 1 + red/runtime/nodes/registry/localfilesystem.js | 25 +++- red/runtime/nodes/registry/registry.js | 34 +++++ test/red/api/nodes_spec.js | 27 +++- .../nodes/registry/localfilesystem_spec.js | 39 +++++- .../runtime/nodes/registry/registry_spec.js | 22 +++- 16 files changed, 367 insertions(+), 19 deletions(-) diff --git a/editor/js/main.js b/editor/js/main.js index f4f42b90d..3cf8ca549 100644 --- a/editor/js/main.js +++ b/editor/js/main.js @@ -24,7 +24,25 @@ url: 'nodes', success: function(data) { RED.nodes.setNodeList(data); - RED.i18n.loadNodeCatalogs(loadNodes); + RED.i18n.loadNodeCatalogs(function() { + loadIconList(loadNodes); + }); + } + }); + } + + function loadIconList(done) { + $.ajax({ + headers: { + "Accept":"application/json" + }, + cache: false, + url: 'icons', + success: function(data) { + RED.nodes.setIconSets(data); + if (done) { + done(); + } } }); } @@ -122,6 +140,7 @@ typeList = ""; RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); } + loadIconList(); } else if (topic == "notification/node/removed") { for (i=0;i 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) { node.outputLabels = n.outputLabels.slice(); } + if (n.icon) { + var defIcon = RED.utils.getDefaultNodeIcon(n._def, n); + if (n.icon !== defIcon.module+"/"+defIcon.file) { + node.icon = n.icon; + } + } } return node; } @@ -915,6 +928,7 @@ RED.nodes = (function() { wires:n.wires, inputLabels: n.inputLabels, outputLabels: n.outputLabels, + icon: n.icon, changed:false, _config:{} }; @@ -1272,6 +1286,9 @@ RED.nodes = (function() { enableNodeSet: registry.enableNodeSet, disableNodeSet: registry.disableNodeSet, + setIconSets: registry.setIconSets, + getIconSets: registry.getIconSets, + registerType: registry.registerNodeType, getType: registry.getNodeType, convertNode: convertNode, diff --git a/editor/js/ui/editor.js b/editor/js/ui/editor.js index ceea0beff..b91b06a25 100644 --- a/editor/js/ui/editor.js +++ b/editor/js/ui/editor.js @@ -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); } + + $('
').appendTo(dialogForm); + var iconDiv = $("#node-settings-icon"); + $('