1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Move view and keyboard into user settings dialog

This commit is contained in:
Nick O'Leary 2017-04-28 20:49:01 +01:00
parent 8135da71bd
commit 5938143002
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
17 changed files with 643 additions and 124 deletions

View File

@ -171,10 +171,10 @@
function loadEditor() { function loadEditor() {
var menuOptions = []; var menuOptions = [];
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
{id:"menu-item-view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"}, // {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"},
{id:"menu-item-view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"}, // {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
{id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true}, // {id:"menu-item-status",setting:"node-show-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true},
null, //null,
// {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[ // {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[
// {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}}, // {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}},
// {id:"menu-item-bidi-ltr",toggle:"text-direction",label:RED._("menu.label.view.ltr"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("ltr")}}}, // {id:"menu-item-bidi-ltr",toggle:"text-direction",label:RED._("menu.label.view.ltr"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("ltr")}}},
@ -182,7 +182,8 @@
// {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}} // {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}}
// ]}, // ]},
// null, // null,
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true} {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true},
null
]}); ]});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[
@ -217,7 +218,6 @@
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"}); menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"});
menuOptions.push({id:"menu-item-show-tips",label:RED._("menu.label.showTips"),toggle:true,selected:true,onselect:"core:toggle-show-tips"});
menuOptions.push({id:"menu-item-help", menuOptions.push({id:"menu-item-help",
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"), label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")

View File

@ -21,7 +21,7 @@ RED.actions = (function() {
var result = []; var result = [];
Object.keys(actions).forEach(function(action) { Object.keys(actions).forEach(function(action) {
var shortcut = RED.keyboard.getShortcut(action); var shortcut = RED.keyboard.getShortcut(action);
result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined}) result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined,user:shortcut?shortcut.user:undefined})
}) })
return result; return result;
} }

View File

@ -170,7 +170,7 @@
var that = this; var that = this;
var count = 0; var count = 0;
if (!this.activeFilter) { if (!this.activeFilter) {
this.element.children().show(); return this.element.children().show();
} }
var items = this.items(); var items = this.items();
items.each(function (i,el) { items.each(function (i,el) {

View File

@ -28,7 +28,17 @@ RED.menu = (function() {
} }
function setInitialState() { function setInitialState() {
var savedStateActive = isSavedStateActive(opt.id); var savedStateActive = RED.settings.get("menu-" + opt.id);
if (opt.setting) {
// May need to migrate pre-0.17 setting
if (savedStateActive !== null) {
RED.settings.set(opt.setting,savedStateActive);
RED.settings.remove("menu-" + opt.id);
} else {
savedStateActive = RED.settings.get(opt.setting);
}
}
if (savedStateActive) { if (savedStateActive) {
link.addClass("active"); link.addClass("active");
triggerAction(opt.id,true); triggerAction(opt.id,true);
@ -176,18 +186,10 @@ RED.menu = (function() {
} }
} }
function isSavedStateActive(id) {
return RED.settings.get("menu-" + id);
}
function isSelected(id) { function isSelected(id) {
return $("#" + id).hasClass("active"); return $("#" + id).hasClass("active");
} }
function setSavedState(id, state) {
RED.settings.set("menu-" + id, state);
}
function setSelected(id,state) { function setSelected(id,state) {
if (isSelected(id) == state) { if (isSelected(id) == state) {
return; return;
@ -201,7 +203,7 @@ RED.menu = (function() {
if (opt && opt.onselect) { if (opt && opt.onselect) {
triggerAction(opt.id,state); triggerAction(opt.id,state);
} }
setSavedState(id, state); RED.settings.set(opt.setting||("menu-"+opt.id), state);
} }
function toggleSelected(id) { function toggleSelected(id) {

View File

@ -26,6 +26,9 @@ RED.tabs = (function() {
var wrapper = ul.wrap( "<div>" ).parent(); var wrapper = ul.wrap( "<div>" ).parent();
var scrollContainer = ul.wrap( "<div>" ).parent(); var scrollContainer = ul.wrap( "<div>" ).parent();
wrapper.addClass("red-ui-tabs"); wrapper.addClass("red-ui-tabs");
if (options.vertical) {
wrapper.addClass("red-ui-tabs-vertical");
}
if (options.addButton && typeof options.addButton === 'function') { if (options.addButton && typeof options.addButton === 'function') {
wrapper.addClass("red-ui-tabs-add"); wrapper.addClass("red-ui-tabs-add");
var addButton = $('<div class="red-ui-tab-button"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper); var addButton = $('<div class="red-ui-tab-button"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper);
@ -146,6 +149,9 @@ RED.tabs = (function() {
} }
function updateTabWidths() { function updateTabWidths() {
if (options.vertical) {
return;
}
var tabs = ul.find("li.red-ui-tab"); var tabs = ul.find("li.red-ui-tab");
var width = wrapper.width(); var width = wrapper.width();
var tabCount = tabs.size(); var tabCount = tabs.size();

View File

@ -48,6 +48,7 @@ RED.keyboard = (function() {
93: true 93: true
} }
var actionToKeyMap = {} var actionToKeyMap = {}
var defaultKeyMap = {};
// FF generates some different keycodes because reasons. // FF generates some different keycodes because reasons.
var firefoxKeyCodeMap = { var firefoxKeyCodeMap = {
@ -57,20 +58,45 @@ RED.keyboard = (function() {
} }
function init() { function init() {
var userKeymap = RED.settings.get('keymap') || {};
$.getJSON("red/keymap.json",function(data) { $.getJSON("red/keymap.json",function(data) {
for (var scope in data) { for (var scope in data) {
if (data.hasOwnProperty(scope)) { if (data.hasOwnProperty(scope)) {
var keys = data[scope]; var keys = data[scope];
for (var key in keys) { for (var key in keys) {
if (keys.hasOwnProperty(key)) { if (keys.hasOwnProperty(key)) {
addHandler(scope,key,keys[key]); if (!userKeymap.hasOwnProperty(keys[key])) {
addHandler(scope,key,keys[key],false);
defaultKeyMap[keys[key]] = {
scope:scope,
key:key,
user:false
};
}
} }
} }
} }
} }
for (var action in userKeymap) {
if (userKeymap.hasOwnProperty(action)) {
var obj = userKeymap[action];
if (obj.hasOwnProperty('key')) {
addHandler(obj.scope, obj.key, action, true);
}
}
}
}) })
RED.actions.add("core:show-help", showKeyboardHelp); }
function revertToDefault(action) {
var currentAction = actionToKeyMap[action];
if (currentAction) {
removeHandler(currentAction.key);
}
if (defaultKeyMap.hasOwnProperty(action)) {
var obj = defaultKeyMap[action];
addHandler(obj.scope, obj.key, action, false);
}
} }
function parseKeySpecifier(key) { function parseKeySpecifier(key) {
var parts = key.toLowerCase().split("-"); var parts = key.toLowerCase().split("-");
@ -126,10 +152,12 @@ RED.keyboard = (function() {
if (partialState) { if (partialState) {
partialState = null; partialState = null;
return resolveKeyEvent(evt); return resolveKeyEvent(evt);
} else { } else if (Object.keys(handler).length > 0) {
partialState = handler; partialState = handler;
evt.preventDefault(); evt.preventDefault();
return null; return null;
} else {
return null;
} }
} else if (handler.scope && handler.scope !== "*") { } else if (handler.scope && handler.scope !== "*") {
var target = evt.target; var target = evt.target;
@ -174,6 +202,9 @@ RED.keyboard = (function() {
if (typeof key === 'string') { if (typeof key === 'string') {
if (typeof cbdown === 'string') { if (typeof cbdown === 'string') {
actionToKeyMap[cbdown] = {scope:scope,key:key}; actionToKeyMap[cbdown] = {scope:scope,key:key};
if (typeof ondown === 'boolean') {
actionToKeyMap[cbdown].user = ondown;
}
} }
var parts = key.split(" "); var parts = key.split(" ");
for (i=0;i<parts.length;i++) { for (i=0;i<parts.length;i++) {
@ -181,7 +212,6 @@ RED.keyboard = (function() {
if (parsedKey) { if (parsedKey) {
keys.push(parsedKey); keys.push(parsedKey);
} else { } else {
console.log("Unrecognised key specifier:",key)
return; return;
} }
} }
@ -217,7 +247,7 @@ RED.keyboard = (function() {
var keys = []; var keys = [];
var i=0; var i=0;
if (typeof key === 'string') { if (typeof key === 'string') {
delete actionToKeyMap[key];
var parts = key.split(" "); var parts = key.split(" ");
for (i=0;i<parts.length;i++) { for (i=0;i<parts.length;i++) {
var parsedKey = parseKeySpecifier(parts[i]); var parsedKey = parseKeySpecifier(parts[i]);
@ -249,78 +279,19 @@ RED.keyboard = (function() {
} }
slot = slot[key]; slot = slot[key];
} }
if (typeof slot.ondown === "string") {
if (typeof modifiers === 'boolean' && modifiers) {
actionToKeyMap[slot.ondown] = {user: modifiers}
} else {
delete actionToKeyMap[slot.ondown];
}
}
delete slot.scope; delete slot.scope;
delete slot.ondown; delete slot.ondown;
} }
var shortcutDialog = null;
var cmdCtrlKey = '<span class="help-key">'+(isMac?'&#8984;':'Ctrl')+'</span>'; var cmdCtrlKey = '<span class="help-key">'+(isMac?'&#8984;':'Ctrl')+'</span>';
function showKeyboardHelp() {
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
return;
}
if (!shortcutDialog) {
shortcutDialog = $('<div id="keyboard-help-dialog" class="hide">'+
'<div class="keyboard-shortcut-entry keyboard-shortcut-list-header">'+
'<div class="keyboard-shortcut-entry-key">shortcut</div>'+
'<div class="keyboard-shortcut-entry-key">action</div>'+
'<div class="keyboard-shortcut-entry-scope">scope</div>'+
'</div>'+
'<ol id="keyboard-shortcut-list"></ol>'+
'</div>')
.appendTo("body");
var shortcutList = $('#keyboard-shortcut-list').editableList({
addButton: false,
scrollOnAdd: false,
addItem: function(container,i,object) {
var item = $('<div class="keyboard-shortcut-entry">').appendTo(container);
var key = $('<div class="keyboard-shortcut-entry-key">').appendTo(item);
if (object.key) {
key.append(formatKey(object.key));
} else {
item.addClass("keyboard-shortcut-entry-unassigned");
key.html(RED._('keyboard.unassigned'));
}
var text = object.id.replace(/(^.+:([a-z]))|(-([a-z]))/g,function() {
if (arguments[5] === 0) {
return arguments[2].toUpperCase();
} else {
return " "+arguments[4].toUpperCase();
}
});
var label = $('<div>').html(text).appendTo(item);
if (object.scope) {
$('<div class="keyboard-shortcut-entry-scope">').html(object.scope).appendTo(item);
}
},
});
var shortcuts = RED.actions.list();
shortcuts.sort(function(A,B) {
return A.id.localeCompare(B.id);
});
shortcuts.forEach(function(s) {
shortcutList.editableList('addItem',s);
})
shortcutDialog.dialog({
modal: true,
autoOpen: false,
width: "800",
height: "400",
title:RED._("keyboard.title"),
resizable: false
});
}
shortcutDialog.dialog("open");
}
function formatKey(key) { function formatKey(key) {
var formattedKey = isMac?key.replace(/ctrl-?/,"&#8984;"):key; var formattedKey = isMac?key.replace(/ctrl-?/,"&#8984;"):key;
formattedKey = isMac?formattedKey.replace(/alt-?/,"&#8997;"):key; formattedKey = isMac?formattedKey.replace(/alt-?/,"&#8997;"):key;
@ -332,6 +303,206 @@ RED.keyboard = (function() {
return '<span class="help-key-block"><span class="help-key">'+formattedKey.split(" ").join('</span> <span class="help-key">')+'</span></span>'; return '<span class="help-key-block"><span class="help-key">'+formattedKey.split(" ").join('</span> <span class="help-key">')+'</span></span>';
} }
function validateKey(key) {
key = key.trim();
var parts = key.split(" ");
for (i=0;i<parts.length;i++) {
var parsedKey = parseKeySpecifier(parts[i]);
if (!parsedKey) {
return false;
}
}
return true;
}
function editShortcut(e) {
e.preventDefault();
var container = $(this);
var object = container.data('data');
if (!container.hasClass('keyboard-shortcut-entry-expanded')) {
endEditShortcut();
var key = container.find(".keyboard-shortcut-entry-key");
var scope = container.find(".keyboard-shortcut-entry-scope");
container.addClass('keyboard-shortcut-entry-expanded');
var keyInput = $('<input type="text">').attr('placeholder',RED._('keyboard.unassigned')).val(object.key||"").appendTo(key);
keyInput.on("keyup",function(e) {
if (e.keyCode === 13) {
return endEditShortcut();
}
var currentVal = $(this).val();
currentVal = currentVal.trim();
var valid = (currentVal === "" || RED.keyboard.validateKey(currentVal));
$(this).toggleClass("input-error",!valid);
})
var scopeSelect = $('<select><option value="*">global</option><option value="workspace">workspace</option></select>').appendTo(scope);
scopeSelect.val(object.scope||'*');
var div = $('<div class="keyboard-shortcut-edit button-group-vertical"></div>').appendTo(scope);
var okButton = $('<button class="editor-button editor-button-small"><i class="fa fa-check"></i></button>').appendTo(div);
var revertButton = $('<button class="editor-button editor-button-small"><i class="fa fa-reply"></i></button>').appendTo(div);
okButton.click(function(e) {
e.stopPropagation();
endEditShortcut();
});
revertButton.click(function(e) {
e.stopPropagation();
RED.keyboard.revertToDefault(object.id);
container.empty();
container.removeClass('keyboard-shortcut-entry-expanded');
var shortcut = RED.keyboard.getShortcut(object.id);
var userKeymap = RED.settings.get('keymap') || {};
delete userKeymap[object.id];
RED.settings.set('keymap',userKeymap);
var obj = {
id:object.id,
scope:shortcut?shortcut.scope:undefined,
key:shortcut?shortcut.key:undefined,
user:shortcut?shortcut.user:undefined
}
buildShortcutRow(container,obj);
})
keyInput.focus();
}
}
function endEditShortcut(cancel) {
var container = $('.keyboard-shortcut-entry-expanded');
if (container.length === 1) {
var object = container.data('data');
var keyInput = container.find(".keyboard-shortcut-entry-key input");
var scopeSelect = container.find(".keyboard-shortcut-entry-scope select");
if (!cancel) {
var key = keyInput.val().trim();
var scope = scopeSelect.val();
var valid = (key === "" || RED.keyboard.validateKey(key));
if (valid) {
var current = RED.keyboard.getShortcut(object.id);
if ((!current && key) || (current && (current.scope !== scope || current.key !== key))) {
var keyDiv = container.find(".keyboard-shortcut-entry-key");
var scopeDiv = container.find(".keyboard-shortcut-entry-scope");
keyDiv.empty();
scopeDiv.empty();
if (object.key) {
RED.keyboard.remove(object.key,true);
}
container.find(".keyboard-shortcut-entry-text i").css("opacity",1);
if (key === "") {
keyDiv.parent().addClass("keyboard-shortcut-entry-unassigned");
keyDiv.append($('<span>').text(RED._('keyboard.unassigned')) );
delete object.key;
delete object.scope;
} else {
keyDiv.parent().removeClass("keyboard-shortcut-entry-unassigned");
keyDiv.append(RED.keyboard.formatKey(key))
$("<span>").text(scope).appendTo(scopeDiv);
object.key = key;
object.scope = scope;
RED.keyboard.add(object.scope,object.key,object.id,true);
}
var userKeymap = RED.settings.get('keymap') || {};
userKeymap[object.id] = RED.keyboard.getShortcut(object.id);
RED.settings.set('keymap',userKeymap);
}
}
}
keyInput.remove();
scopeSelect.remove();
$('.keyboard-shortcut-edit').remove();
container.removeClass('keyboard-shortcut-entry-expanded');
}
}
function buildShortcutRow(container,object) {
var item = $('<div class="keyboard-shortcut-entry">').appendTo(container);
container.data('data',object);
var text = object.id.replace(/(^.+:([a-z]))|(-([a-z]))/g,function() {
if (arguments[5] === 0) {
return arguments[2].toUpperCase();
} else {
return " "+arguments[4].toUpperCase();
}
});
var label = $('<div>').addClass("keyboard-shortcut-entry-text").text(text).appendTo(item);
var user = $('<i class="fa fa-user"></i>').prependTo(label);
if (!object.user) {
user.css("opacity",0);
}
var key = $('<div class="keyboard-shortcut-entry-key">').appendTo(item);
if (object.key) {
key.append(RED.keyboard.formatKey(object.key));
} else {
item.addClass("keyboard-shortcut-entry-unassigned");
key.append($('<span>').text(RED._('keyboard.unassigned')) );
}
var scope = $('<div class="keyboard-shortcut-entry-scope">').appendTo(item);
$("<span>").text(object.scope === '*'?'global':object.scope||"").appendTo(scope);
container.click(editShortcut);
}
function getSettingsPane() {
var pane = $('<div id="user-settings-tab-keyboard"></div>');
$('<div class="keyboard-shortcut-entry keyboard-shortcut-list-header">'+
'<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input type="text" placeholder="filter actions"></div>'+
'<div class="keyboard-shortcut-entry-key">shortcut</div>'+
'<div class="keyboard-shortcut-entry-scope">scope</div>'+
'</div>').appendTo(pane);
pane.find("input").searchBox({
delay: 100,
change: function() {
var filterValue = $(this).val().trim();
if (filterValue === "") {
shortcutList.editableList('filter', null);
} else {
filterValue = filterValue.replace(/\s/g,"");
shortcutList.editableList('filter', function(data) {
return data.id.toLowerCase().replace(/^.*:/,"").replace("-","").indexOf(filterValue) > -1;
})
}
}
});
var shortcutList = $('<ol class="keyboard-shortcut-list"></ol>').css({
position: "absolute",
top: "32px",
bottom: "0",
left: "0",
right: "0"
}).appendTo(pane).editableList({
addButton: false,
scrollOnAdd: false,
addItem: function(container,i,object) {
buildShortcutRow(container,object);
},
});
var shortcuts = RED.actions.list();
shortcuts.sort(function(A,B) {
var Aid = A.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase();
var Bid = B.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase();
return Aid.localeCompare(Bid);
});
shortcuts.forEach(function(s) {
shortcutList.editableList('addItem',s);
});
return pane;
}
return { return {
init: init, init: init,
add: addHandler, add: addHandler,
@ -339,7 +510,10 @@ RED.keyboard = (function() {
getShortcut: function(actionName) { getShortcut: function(actionName) {
return actionToKeyMap[actionName]; return actionToKeyMap[actionName];
}, },
formatKey: formatKey revertToDefault: revertToDefault,
formatKey: formatKey,
validateKey: validateKey,
getSettingsPane: getSettingsPane
} }
})(); })();

View File

@ -74,7 +74,7 @@ RED.sidebar.info = (function() {
tipClose.click(function(e) { tipClose.click(function(e) {
e.preventDefault(); e.preventDefault();
RED.actions.invoke("core:toggle-show-tips"); RED.actions.invoke("core:toggle-show-tips");
RED.notify("You can re-open the tips from the side menu"); RED.notify(RED._("sidebar.info.showTips"));
}); });
RED.sidebar.addTab({ RED.sidebar.addTab({
@ -267,7 +267,7 @@ RED.sidebar.info = (function() {
RED.actions.add("core:toggle-show-tips",function(state) { RED.actions.add("core:toggle-show-tips",function(state) {
if (state === undefined) { if (state === undefined) {
RED.menu.toggleSelected("menu-item-show-tips"); RED.userSettings.toggle("view-show-tips");
} else { } else {
enabled = state; enabled = state;
if (enabled) { if (enabled) {

View File

@ -16,14 +16,15 @@
RED.userSettings = (function() { RED.userSettings = (function() {
var trayWidth = null; var trayWidth = 700;
var settingsVisible = false; var settingsVisible = false;
function show() { function show(initialTab) {
if (settingsVisible) { if (settingsVisible) {
return; return;
} }
settingsVisible = true; settingsVisible = true;
var tabContainer;
var trayOptions = { var trayOptions = {
title: "User Settings", title: "User Settings",
@ -42,17 +43,20 @@ RED.userSettings = (function() {
}, },
open: function(tray) { open: function(tray) {
var trayBody = tray.find('.editor-tray-body'); var trayBody = tray.find('.editor-tray-body');
var tabContainer = $('<div></div>',{id:"user-settings-tabs-container"}).appendTo(trayBody);
$('<ul></ul>',{id:"user-settings-tabs"}).appendTo(trayBody); $('<ul></ul>',{id:"user-settings-tabs"}).appendTo(tabContainer);
var tabContents = $('<div></div>',{id:"user-settings-tabs-content"}).appendTo(trayBody); var tabContents = $('<div></div>',{id:"user-settings-tabs-content"}).appendTo(trayBody);
$('<div class="hide" id="user-settings-tab-view">View Tab</div>').appendTo(tabContents); createViewPane().hide().appendTo(tabContents);
$('<div class="hide" id="user-settings-tab-keyboard">Keyboard Tab</div>').appendTo(tabContents); RED.keyboard.getSettingsPane().hide().appendTo(tabContents);
$('<div class="hide" id="user-settings-tab-something">Something Tab</div>').appendTo(tabContents);
$('<div id="user-settings-tab-palette"></div>').appendTo(tabContents);
var tabs = RED.tabs.create({ var tabs = RED.tabs.create({
id: "user-settings-tabs", id: "user-settings-tabs",
vertical: true,
onchange: function(tab) { onchange: function(tab) {
$("#user-settings-tabs-content").children().hide(); $("#user-settings-tabs-content").children().hide();
$("#" + tab.id).show(); $("#" + tab.id).show();
@ -64,15 +68,31 @@ RED.userSettings = (function() {
}); });
tabs.addTab({ tabs.addTab({
id: "user-settings-tab-keyboard", id: "user-settings-tab-keyboard",
label: "Keyboard Shortcuts" label: "Keyboard"
}); });
tabs.addTab({ tabs.addTab({
id: "user-settings-tab-something", id: "user-settings-tab-palette",
label: "Something Else" label: "Palette"
}); });
if (initialTab) {
tabs.activateTab("user-settings-tab-"+initialTab)
}
}, },
close: function() { close: function() {
settingsVisible = false; settingsVisible = false;
viewSettings.forEach(function(section) {
section.options.forEach(function(opt) {
var input = $("#user-settings-"+opt.setting);
if (opt.toggle) {
setSelected(opt.setting,input.prop('checked'));
} else {
setSelected(opt.setting,input.val());
}
});
})
}, },
show: function() {} show: function() {}
} }
@ -82,10 +102,99 @@ RED.userSettings = (function() {
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }
var viewSettings = [
{
title: "Grid",
options: [
{setting:"view-show-grid",label:"menu.label.view.showGrid",toggle:true,onchange:"core:toggle-show-grid"},
{setting:"view-snap-grid",label:"menu.label.view.snapGrid",toggle:true,onchange:"core:toggle-snap-grid"},
{setting:"view-grid-size",label:"menu.label.view.gridSize",type:"number",default: 20, onchange:RED.view.gridSize}
]
},
{
title: "Nodes",
options: [
{setting:"view-node-status",label:"menu.label.displayStatus",toggle:true,onchange:"core:toggle-status", selected: true}
]
},
{
title: "Other",
options: [
{setting:"view-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"}
]
}
];
var allSettings = {};
function createViewPane() {
var pane = $('<div id="user-settings-tab-view" class="node-help"></div>');
viewSettings.forEach(function(section) {
$('<h3></h3>').text(section.title).appendTo(pane);
section.options.forEach(function(opt) {
var initialState = RED.settings.get(opt.setting);
var row = $('<div class="user-settings-row"></div>').appendTo(pane);
var input;
if (opt.toggle) {
input = $('<label for="user-settings-'+opt.setting+'"><input id="user-settings-'+opt.setting+'" type="checkbox"> '+RED._(opt.label)+'</label>').appendTo(row).find("input");
input.prop('checked',initialState);
} else {
$('<label for="user-settings-'+opt.setting+'">'+RED._(opt.label)+'</label>').appendTo(row);
$('<input id="user-settings-'+opt.setting+'" type="'+(opt.type||"text")+'">').appendTo(row).val(initialState);
}
});
})
return pane;
}
function setSelected(id, value) {
var opt = allSettings[id];
RED.settings.set(opt.setting,value);
var callback = opt.onchange;
if (typeof callback === 'string') {
callback = RED.actions.get(callback);
}
if (callback) {
callback.call(opt,value);
}
}
function toggle(id) {
var opt = allSettings[id];
var state = RED.settings.get(opt.setting);
setSelected(id,!state);
}
function init() { function init() {
RED.actions.add("core:show-user-settings",show); RED.actions.add("core:show-user-settings",show);
RED.actions.add("core:show-help", function() { show('keyboard')});
viewSettings.forEach(function(section) {
section.options.forEach(function(opt) {
allSettings[opt.setting] = opt;
if (opt.onchange) {
var value = RED.settings.get(opt.setting);
if (value === null && opt.hasOwnProperty('default')) {
value = opt.default;
RED.settings.set(opt.setting,value);
}
var callback = opt.onchange;
if (typeof callback === 'string') {
callback = RED.actions.get(callback);
}
if (callback) {
callback.call(opt,value);
}
}
});
});
} }
return { return {
init: init init: init,
toggle: toggle
}; };
})(); })();

View File

@ -239,6 +239,41 @@ RED.view = (function() {
}); });
grid.style("visibility","hidden"); grid.style("visibility","hidden");
updateGrid();
function updateGrid() {
grid.selectAll("line.horizontal").remove();
grid.selectAll("line.horizontal").data(gridScale.ticks(space_width/gridSize)).enter()
.append("line")
.attr(
{
"class":"horizontal",
"x1" : 0,
"x2" : space_width,
"y1" : function(d){ return gridScale(d);},
"y2" : function(d){ return gridScale(d);},
"fill" : "none",
"shape-rendering" : "crispEdges",
"stroke" : "#eee",
"stroke-width" : "1px"
});
grid.selectAll("line.vertical").remove();
grid.selectAll("line.vertical").data(gridScale.ticks(space_width/gridSize)).enter()
.append("line")
.attr(
{
"class":"vertical",
"y1" : 0,
"y2" : space_width,
"x1" : function(d){ return gridScale(d);},
"x2" : function(d){ return gridScale(d);},
"fill" : "none",
"shape-rendering" : "crispEdges",
"stroke" : "#eee",
"stroke-width" : "1px"
});
}
var dragGroup = vis.append("g"); var dragGroup = vis.append("g");
var drag_lines = []; var drag_lines = [];
@ -408,21 +443,21 @@ RED.view = (function() {
RED.actions.add("core:toggle-show-grid",function(state) { RED.actions.add("core:toggle-show-grid",function(state) {
if (state === undefined) { if (state === undefined) {
RED.menu.toggleSelected("menu-item-view-show-grid"); RED.userSettings.toggle("view-show-grid");
} else { } else {
toggleShowGrid(state); toggleShowGrid(state);
} }
}); });
RED.actions.add("core:toggle-snap-grid",function(state) { RED.actions.add("core:toggle-snap-grid",function(state) {
if (state === undefined) { if (state === undefined) {
RED.menu.toggleSelected("menu-item-view-snap-grid"); RED.userSettings.toggle("view-snap-grid");
} else { } else {
toggleSnapGrid(state); toggleSnapGrid(state);
} }
}); });
RED.actions.add("core:toggle-status",function(state) { RED.actions.add("core:toggle-status",function(state) {
if (state === undefined) { if (state === undefined) {
RED.menu.toggleSelected("menu-item-status"); RED.userSettings.toggle("view-node-status");
} else { } else {
toggleStatus(state); toggleStatus(state);
} }
@ -2743,6 +2778,14 @@ RED.view = (function() {
RED.sidebar.config.show(id); RED.sidebar.config.show(id);
} }
} }
},
gridSize: function(v) {
if (v === undefined) {
return gridSize;
} else {
gridSize = v;
updateGrid();
}
} }
}; };

View File

@ -46,6 +46,7 @@
overflow: auto; overflow: auto;
} }
.editor-tray-body { .editor-tray-body {
position: relative;
form { form {
margin: 20px; margin: 20px;
} }

View File

@ -19,31 +19,88 @@
padding-top: 10px; padding-top: 10px;
} }
#user-settings-tab-keyboard .red-ui-editableList-container {
border-radius: 0;
border: none;
padding: 0;
}
.keyboard-shortcut-entry.keyboard-shortcut-list-header { .keyboard-shortcut-entry.keyboard-shortcut-list-header {
padding:0 30px 0 5px; padding:0 5px 0 5px;
div { div {
color: #666 !important; color: #666 !important;
} }
.red-ui-searchBox-container {
width: calc(100% - 20px);
}
.keyboard-shortcut-entry-scope {
text-align: center;
}
} }
#keyboard-shortcut-list {
.keyboard-shortcut-list-header {
border-bottom: 1px solid $primary-border-color;
}
.keyboard-shortcut-list {
position: absolute; position: absolute;
top:30px; top:30px;
left:10px; left:10px;
right:10px; right:10px;
bottom:10px; bottom:10px;
li {
padding: 0;
.red-ui-editableList-item-content {
padding: 8px;
cursor: pointer;
}
}
li:hover {
background: #f6f6f6;
}
} }
.keyboard-shortcut-entry { .keyboard-shortcut-entry {
padding: 0px 20px 0 10px;
div { div {
display: inline-block; display: inline-block;
} }
// white-space: nowrap;
select {
margin: 0;
width: calc(100% - 30px);
font-size: 0.9em;
margin-right: 5px;
}
} }
.keyboard-shortcut-entry-key { .keyboard-shortcut-entry-key {
width:150px; width:160px;
vertical-align: middle;
input {
margin:0;
width: calc(100% - 5px);
}
}
.keyboard-shortcut-entry-text {
vertical-align: middle;
width: calc(100% - 160px - 100px - 10px);
overflow: hidden;
i {
color: #ccc;
margin-right: 5px;
}
} }
.keyboard-shortcut-entry-scope { .keyboard-shortcut-entry-scope {
float: right; width:100px;
color: #999; color: #999;
vertical-align: middle;
text-align: right;
}
.keyboard-shortcut-entry:not(.keyboard-shortcut-list-header) {
.keyboard-shortcut-entry-scope {
font-size: 0.8em;
}
} }
.keyboard-shortcut-entry-unassigned { .keyboard-shortcut-entry-unassigned {
color: #999; color: #999;
@ -51,7 +108,21 @@
font-style: italic; font-style: italic;
} }
} }
.keyboard-shortcut-entry-expanded {
.keyboard-shortcut-entry-key {
width: 150px;
}
.keyboard-shortcut-entry-text {
}
.keyboard-shortcut-entry-scope {
width: 110px;
}
span {
display: none;
}
}
.keyboard-shortcut-edit {
}
.help-key { .help-key {
border: 1px solid #ddd; border: 1px solid #ddd;
padding: 4px; padding: 4px;

View File

@ -80,12 +80,28 @@
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
.button-group-vertical & {
display: block;
min-width: 22px;
}
.button-group-vertical &:not(:first-child) {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.button-group-vertical &:not(:last-child) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
&:focus { &:focus {
outline: 1px solid $workspace-button-color-focus-outline; outline: 1px solid $workspace-button-color-focus-outline;
} }
} }
.button-group-vertical {
display: inline-block;
vertical-align: middle;
}
.button-group:not(:last-child) { .button-group:not(:last-child) {
margin-right: 10px; margin-right: 10px;
} }

View File

@ -45,6 +45,8 @@
@import "palette-editor"; @import "palette-editor";
@import "diff"; @import "diff";
@import "userSettings";
@import "ui/common/editableList"; @import "ui/common/editableList";
@import "ui/common/searchBox"; @import "ui/common/searchBox";

View File

@ -113,6 +113,50 @@
&.red-ui-tabs-add.red-ui-tabs-scrollable { &.red-ui-tabs-add.red-ui-tabs-scrollable {
padding-right: 59px; padding-right: 59px;
} }
&.red-ui-tabs-vertical {
box-sizing: border-box;
height: 100%;
border-right: 1px solid $primary-border-color;
margin: 0;
background: #f3f3f3;
overflow: visible;
.red-ui-tabs-scroll-container {
height: auto;
overflow-x:visible;
overflow-y: scroll;
}
& ul {
padding: 0;
height: auto;
border: none;
width: calc(100% + 1px);
li {
width: 100%;
display: block;
margin: 0;
border: none;
border-right: 1px solid $primary-border-color;
height: auto;
&:not(:first-child) {
border-top: 1px solid $secondary-border-color;
}
&:last-child {
border-bottom: 1px solid $secondary-border-color;
}
a.red-ui-tab-label {
padding: 9px;
}
&.active {
border-right: 1px solid #fff;
}
}
}
}
} }
.red-ui-tab-button { .red-ui-tab-button {
position: absolute; position: absolute;

View File

@ -0,0 +1,59 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
#user-settings-tabs-container {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 120px;
background: #f3f3f3;
}
#user-settings-tabs-content {
position: absolute;
top: 0;
left: 120px;
right: 0;
bottom: 0;
padding: 0;
h3:not(:first-child) {
border-top: 1px solid $secondary-border-color;
margin-top: 15px;
margin-bottom: 10px;
padding-top: 20px;
}
label {
display: inline-block;
min-width: 100px;
input {
vertical-align: top;
padding-bottom: 0;
}
}
input {
margin-bottom: 0;
}
input[type='number'] {
width: 60px;
}
}
#user-settings-tab-view {
padding: 8px 20px 20px;
}
.user-settings-row {
padding: 5px 10px 2px;
}

View File

@ -31,6 +31,7 @@
"view": "View", "view": "View",
"showGrid": "Show grid", "showGrid": "Show grid",
"snapGrid": "Snap to grid", "snapGrid": "Snap to grid",
"gridSize": "Grid size",
"textDir": "Text Direction", "textDir": "Text Direction",
"defaultDir": "Default", "defaultDir": "Default",
"ltr": "Left-to-right", "ltr": "Left-to-right",
@ -354,7 +355,8 @@
"info": "Information", "info": "Information",
"blank": "blank", "blank": "blank",
"null": "null", "null": "null",
"arrayItems": "__count__ items" "arrayItems": "__count__ items",
"showTips":"You can open the tips from the settings panel"
}, },
"config": { "config": {
"name": "Configuration nodes", "name": "Configuration nodes",

View File

@ -5,7 +5,7 @@
"tip2" : "{{core:toggle-sidebar}} will toggle the view of this sidebar", "tip2" : "{{core:toggle-sidebar}} will toggle the view of this sidebar",
"tip3" : "You can manage your palette of nodes with {{core:manage-palette}}", "tip3" : "You can manage your palette of nodes with {{core:manage-palette}}",
"tip4" : "Your flow configuration nodes are listed in the sidebar panel. It can been accessed from the menu or with {{core:show-config-tab}}", "tip4" : "Your flow configuration nodes are listed in the sidebar panel. It can been accessed from the menu or with {{core:show-config-tab}}",
"tip5" : "Enable or disable these tips from the option in the menu", "tip5" : "Enable or disable these tips from the option in the settings",
"tip6" : "Move the selected nodes using the [left] [up] [down] and [right] keys. Hold [shift] to nudge them further", "tip6" : "Move the selected nodes using the [left] [up] [down] and [right] keys. Hold [shift] to nudge them further",
"tip7" : "Dragging a node onto a wire will splice it into the link", "tip7" : "Dragging a node onto a wire will splice it into the link",
"tip8" : "Export the selected nodes, or the current tab with {{core:show-export-dialog}}", "tip8" : "Export the selected nodes, or the current tab with {{core:show-export-dialog}}",
@ -19,15 +19,5 @@
"tip16" : "Switch flow tabs with {{core:show-previous-tab}} and {{core:show-next-tab}}", "tip16" : "Switch flow tabs with {{core:show-previous-tab}} and {{core:show-next-tab}}",
"tip17" : "You can confirm your changes in the node edit tray with {{core:confirm-edit-tray}} or cancel them with {{core:cancel-edit-tray}}", "tip17" : "You can confirm your changes in the node edit tray with {{core:confirm-edit-tray}} or cancel them with {{core:cancel-edit-tray}}",
"tip18" : "Pressing {{core:edit-selected-node}} will edit the first node in the current selection" "tip18" : "Pressing {{core:edit-selected-node}} will edit the first node in the current selection"
},
"info-tbd": {
"tip1" : "Press the <code>Deploy</code> button above to start the flow running. You can choose to deploy the whole flow or just the changes.",
"tip2" : "Options like <b>Show grid</b> and <b>Snap to grid</b> are under the menu icon<br/><i class='fa fa-bars'></i> <i class='fa fa-caret-right'></i> <b>View</b>",
"tip4" : "<i class='fa fa-bars'></i> <i class='fa fa-caret-right'></i> <b>Manage palette</b> can be used to find, add and remove extra nodes.",
"tip5" : "Nodes may install examples under<br/><i class='fa fa-bars'></i> <i class='fa fa-caret-right'></i> <b>Import</b> <i class='fa fa-caret-right'></i> <b>Examples</b>",
"tip6" : "Lots of example flows can be found on <a href='http://flows.nodered.org' target='_blank'>flows.nodered.org</a><br/>They can then be imported by drag and drop to the workspace.",
"tip7" : "<b>Shift-click and drag</b> on a connector to move all the attached wires in one go.",
"tip8" : "The <b>Node-RED Dashboard</b> package can be used to create simple User Interfaces.",
"tip10": "Got a question?<br/>Join us on <a href='https://node-red.slack.com/' target='_blank'>Slack</a><br/>or the<br/><a href='https://groups.google.com/forum/#!forum/node-red' target='_blank'>Node-RED Google group</a>"
} }
} }