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:
parent
8135da71bd
commit
5938143002
@ -171,10 +171,10 @@
|
||||
function loadEditor() {
|
||||
var menuOptions = [];
|
||||
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-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},
|
||||
null,
|
||||
// {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",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
|
||||
// {id:"menu-item-status",setting:"node-show-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true},
|
||||
//null,
|
||||
// {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-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")}}}
|
||||
// ]},
|
||||
// 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({id:"menu-item-import",label:RED._("menu.label.import"),options:[
|
||||
@ -217,7 +218,6 @@
|
||||
menuOptions.push(null);
|
||||
|
||||
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",
|
||||
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")
|
||||
|
@ -21,7 +21,7 @@ RED.actions = (function() {
|
||||
var result = [];
|
||||
Object.keys(actions).forEach(function(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;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@
|
||||
var that = this;
|
||||
var count = 0;
|
||||
if (!this.activeFilter) {
|
||||
this.element.children().show();
|
||||
return this.element.children().show();
|
||||
}
|
||||
var items = this.items();
|
||||
items.each(function (i,el) {
|
||||
|
@ -28,7 +28,17 @@ RED.menu = (function() {
|
||||
}
|
||||
|
||||
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) {
|
||||
link.addClass("active");
|
||||
triggerAction(opt.id,true);
|
||||
@ -176,18 +186,10 @@ RED.menu = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function isSavedStateActive(id) {
|
||||
return RED.settings.get("menu-" + id);
|
||||
}
|
||||
|
||||
function isSelected(id) {
|
||||
return $("#" + id).hasClass("active");
|
||||
}
|
||||
|
||||
function setSavedState(id, state) {
|
||||
RED.settings.set("menu-" + id, state);
|
||||
}
|
||||
|
||||
function setSelected(id,state) {
|
||||
if (isSelected(id) == state) {
|
||||
return;
|
||||
@ -201,7 +203,7 @@ RED.menu = (function() {
|
||||
if (opt && opt.onselect) {
|
||||
triggerAction(opt.id,state);
|
||||
}
|
||||
setSavedState(id, state);
|
||||
RED.settings.set(opt.setting||("menu-"+opt.id), state);
|
||||
}
|
||||
|
||||
function toggleSelected(id) {
|
||||
|
@ -26,6 +26,9 @@ RED.tabs = (function() {
|
||||
var wrapper = ul.wrap( "<div>" ).parent();
|
||||
var scrollContainer = ul.wrap( "<div>" ).parent();
|
||||
wrapper.addClass("red-ui-tabs");
|
||||
if (options.vertical) {
|
||||
wrapper.addClass("red-ui-tabs-vertical");
|
||||
}
|
||||
if (options.addButton && typeof options.addButton === 'function') {
|
||||
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);
|
||||
@ -146,6 +149,9 @@ RED.tabs = (function() {
|
||||
}
|
||||
|
||||
function updateTabWidths() {
|
||||
if (options.vertical) {
|
||||
return;
|
||||
}
|
||||
var tabs = ul.find("li.red-ui-tab");
|
||||
var width = wrapper.width();
|
||||
var tabCount = tabs.size();
|
||||
|
@ -48,6 +48,7 @@ RED.keyboard = (function() {
|
||||
93: true
|
||||
}
|
||||
var actionToKeyMap = {}
|
||||
var defaultKeyMap = {};
|
||||
|
||||
// FF generates some different keycodes because reasons.
|
||||
var firefoxKeyCodeMap = {
|
||||
@ -57,20 +58,45 @@ RED.keyboard = (function() {
|
||||
}
|
||||
|
||||
function init() {
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
$.getJSON("red/keymap.json",function(data) {
|
||||
for (var scope in data) {
|
||||
if (data.hasOwnProperty(scope)) {
|
||||
var keys = data[scope];
|
||||
for (var key in keys) {
|
||||
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) {
|
||||
var parts = key.toLowerCase().split("-");
|
||||
@ -126,10 +152,12 @@ RED.keyboard = (function() {
|
||||
if (partialState) {
|
||||
partialState = null;
|
||||
return resolveKeyEvent(evt);
|
||||
} else {
|
||||
} else if (Object.keys(handler).length > 0) {
|
||||
partialState = handler;
|
||||
evt.preventDefault();
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (handler.scope && handler.scope !== "*") {
|
||||
var target = evt.target;
|
||||
@ -174,6 +202,9 @@ RED.keyboard = (function() {
|
||||
if (typeof key === 'string') {
|
||||
if (typeof cbdown === 'string') {
|
||||
actionToKeyMap[cbdown] = {scope:scope,key:key};
|
||||
if (typeof ondown === 'boolean') {
|
||||
actionToKeyMap[cbdown].user = ondown;
|
||||
}
|
||||
}
|
||||
var parts = key.split(" ");
|
||||
for (i=0;i<parts.length;i++) {
|
||||
@ -181,7 +212,6 @@ RED.keyboard = (function() {
|
||||
if (parsedKey) {
|
||||
keys.push(parsedKey);
|
||||
} else {
|
||||
console.log("Unrecognised key specifier:",key)
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -217,7 +247,7 @@ RED.keyboard = (function() {
|
||||
var keys = [];
|
||||
var i=0;
|
||||
if (typeof key === 'string') {
|
||||
delete actionToKeyMap[key];
|
||||
|
||||
var parts = key.split(" ");
|
||||
for (i=0;i<parts.length;i++) {
|
||||
var parsedKey = parseKeySpecifier(parts[i]);
|
||||
@ -249,78 +279,19 @@ RED.keyboard = (function() {
|
||||
}
|
||||
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.ondown;
|
||||
}
|
||||
|
||||
var shortcutDialog = null;
|
||||
|
||||
var cmdCtrlKey = '<span class="help-key">'+(isMac?'⌘':'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) {
|
||||
var formattedKey = isMac?key.replace(/ctrl-?/,"⌘"):key;
|
||||
formattedKey = isMac?formattedKey.replace(/alt-?/,"⌥"):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>';
|
||||
}
|
||||
|
||||
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 {
|
||||
init: init,
|
||||
add: addHandler,
|
||||
@ -339,7 +510,10 @@ RED.keyboard = (function() {
|
||||
getShortcut: function(actionName) {
|
||||
return actionToKeyMap[actionName];
|
||||
},
|
||||
formatKey: formatKey
|
||||
revertToDefault: revertToDefault,
|
||||
formatKey: formatKey,
|
||||
validateKey: validateKey,
|
||||
getSettingsPane: getSettingsPane
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -74,7 +74,7 @@ RED.sidebar.info = (function() {
|
||||
tipClose.click(function(e) {
|
||||
e.preventDefault();
|
||||
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({
|
||||
@ -267,7 +267,7 @@ RED.sidebar.info = (function() {
|
||||
|
||||
RED.actions.add("core:toggle-show-tips",function(state) {
|
||||
if (state === undefined) {
|
||||
RED.menu.toggleSelected("menu-item-show-tips");
|
||||
RED.userSettings.toggle("view-show-tips");
|
||||
} else {
|
||||
enabled = state;
|
||||
if (enabled) {
|
||||
|
@ -16,14 +16,15 @@
|
||||
|
||||
RED.userSettings = (function() {
|
||||
|
||||
var trayWidth = null;
|
||||
var trayWidth = 700;
|
||||
var settingsVisible = false;
|
||||
|
||||
function show() {
|
||||
function show(initialTab) {
|
||||
if (settingsVisible) {
|
||||
return;
|
||||
}
|
||||
settingsVisible = true;
|
||||
var tabContainer;
|
||||
|
||||
var trayOptions = {
|
||||
title: "User Settings",
|
||||
@ -42,17 +43,20 @@ RED.userSettings = (function() {
|
||||
},
|
||||
open: function(tray) {
|
||||
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);
|
||||
|
||||
$('<div class="hide" id="user-settings-tab-view">View Tab</div>').appendTo(tabContents);
|
||||
$('<div class="hide" id="user-settings-tab-keyboard">Keyboard Tab</div>').appendTo(tabContents);
|
||||
$('<div class="hide" id="user-settings-tab-something">Something Tab</div>').appendTo(tabContents);
|
||||
createViewPane().hide().appendTo(tabContents);
|
||||
RED.keyboard.getSettingsPane().hide().appendTo(tabContents);
|
||||
|
||||
$('<div id="user-settings-tab-palette"></div>').appendTo(tabContents);
|
||||
|
||||
|
||||
var tabs = RED.tabs.create({
|
||||
id: "user-settings-tabs",
|
||||
vertical: true,
|
||||
onchange: function(tab) {
|
||||
$("#user-settings-tabs-content").children().hide();
|
||||
$("#" + tab.id).show();
|
||||
@ -64,15 +68,31 @@ RED.userSettings = (function() {
|
||||
});
|
||||
tabs.addTab({
|
||||
id: "user-settings-tab-keyboard",
|
||||
label: "Keyboard Shortcuts"
|
||||
label: "Keyboard"
|
||||
});
|
||||
tabs.addTab({
|
||||
id: "user-settings-tab-something",
|
||||
label: "Something Else"
|
||||
id: "user-settings-tab-palette",
|
||||
label: "Palette"
|
||||
});
|
||||
if (initialTab) {
|
||||
tabs.activateTab("user-settings-tab-"+initialTab)
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
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() {}
|
||||
}
|
||||
@ -82,10 +102,99 @@ RED.userSettings = (function() {
|
||||
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() {
|
||||
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 {
|
||||
init: init
|
||||
init: init,
|
||||
toggle: toggle
|
||||
};
|
||||
})();
|
||||
|
@ -239,6 +239,41 @@ RED.view = (function() {
|
||||
});
|
||||
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 drag_lines = [];
|
||||
|
||||
@ -408,21 +443,21 @@ RED.view = (function() {
|
||||
|
||||
RED.actions.add("core:toggle-show-grid",function(state) {
|
||||
if (state === undefined) {
|
||||
RED.menu.toggleSelected("menu-item-view-show-grid");
|
||||
RED.userSettings.toggle("view-show-grid");
|
||||
} else {
|
||||
toggleShowGrid(state);
|
||||
}
|
||||
});
|
||||
RED.actions.add("core:toggle-snap-grid",function(state) {
|
||||
if (state === undefined) {
|
||||
RED.menu.toggleSelected("menu-item-view-snap-grid");
|
||||
RED.userSettings.toggle("view-snap-grid");
|
||||
} else {
|
||||
toggleSnapGrid(state);
|
||||
}
|
||||
});
|
||||
RED.actions.add("core:toggle-status",function(state) {
|
||||
if (state === undefined) {
|
||||
RED.menu.toggleSelected("menu-item-status");
|
||||
RED.userSettings.toggle("view-node-status");
|
||||
} else {
|
||||
toggleStatus(state);
|
||||
}
|
||||
@ -2743,6 +2778,14 @@ RED.view = (function() {
|
||||
RED.sidebar.config.show(id);
|
||||
}
|
||||
}
|
||||
},
|
||||
gridSize: function(v) {
|
||||
if (v === undefined) {
|
||||
return gridSize;
|
||||
} else {
|
||||
gridSize = v;
|
||||
updateGrid();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -46,6 +46,7 @@
|
||||
overflow: auto;
|
||||
}
|
||||
.editor-tray-body {
|
||||
position: relative;
|
||||
form {
|
||||
margin: 20px;
|
||||
}
|
||||
|
@ -19,31 +19,88 @@
|
||||
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 {
|
||||
padding:0 30px 0 5px;
|
||||
padding:0 5px 0 5px;
|
||||
div {
|
||||
color: #666 !important;
|
||||
}
|
||||
.red-ui-searchBox-container {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
#keyboard-shortcut-list {
|
||||
.keyboard-shortcut-entry-scope {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.keyboard-shortcut-list-header {
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
|
||||
}
|
||||
.keyboard-shortcut-list {
|
||||
position: absolute;
|
||||
top:30px;
|
||||
left:10px;
|
||||
right:10px;
|
||||
bottom:10px;
|
||||
li {
|
||||
padding: 0;
|
||||
.red-ui-editableList-item-content {
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
li:hover {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
}
|
||||
.keyboard-shortcut-entry {
|
||||
padding: 0px 20px 0 10px;
|
||||
div {
|
||||
display: inline-block;
|
||||
}
|
||||
// white-space: nowrap;
|
||||
|
||||
select {
|
||||
margin: 0;
|
||||
width: calc(100% - 30px);
|
||||
font-size: 0.9em;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
float: right;
|
||||
width:100px;
|
||||
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 {
|
||||
color: #999;
|
||||
@ -51,7 +108,21 @@
|
||||
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 {
|
||||
border: 1px solid #ddd;
|
||||
padding: 4px;
|
||||
|
@ -80,12 +80,28 @@
|
||||
border-top-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 {
|
||||
outline: 1px solid $workspace-button-color-focus-outline;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group-vertical {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.button-group:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
@ -45,6 +45,8 @@
|
||||
@import "palette-editor";
|
||||
@import "diff";
|
||||
|
||||
@import "userSettings";
|
||||
|
||||
|
||||
@import "ui/common/editableList";
|
||||
@import "ui/common/searchBox";
|
||||
|
@ -113,6 +113,50 @@
|
||||
&.red-ui-tabs-add.red-ui-tabs-scrollable {
|
||||
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 {
|
||||
position: absolute;
|
||||
|
59
editor/sass/userSettings.scss
Normal file
59
editor/sass/userSettings.scss
Normal 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;
|
||||
}
|
@ -31,6 +31,7 @@
|
||||
"view": "View",
|
||||
"showGrid": "Show grid",
|
||||
"snapGrid": "Snap to grid",
|
||||
"gridSize": "Grid size",
|
||||
"textDir": "Text Direction",
|
||||
"defaultDir": "Default",
|
||||
"ltr": "Left-to-right",
|
||||
@ -354,7 +355,8 @@
|
||||
"info": "Information",
|
||||
"blank": "blank",
|
||||
"null": "null",
|
||||
"arrayItems": "__count__ items"
|
||||
"arrayItems": "__count__ items",
|
||||
"showTips":"You can open the tips from the settings panel"
|
||||
},
|
||||
"config": {
|
||||
"name": "Configuration nodes",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"tip2" : "{{core:toggle-sidebar}} will toggle the view of this sidebar",
|
||||
"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}}",
|
||||
"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",
|
||||
"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}}",
|
||||
@ -19,15 +19,5 @@
|
||||
"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}}",
|
||||
"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>"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user