Add declarative menu structure

This commit is contained in:
Nick O'Leary
2014-08-20 21:58:54 +01:00
parent 47b4ebc92f
commit 7176f3ee2b
10 changed files with 248 additions and 9723 deletions

View File

@@ -15,8 +15,6 @@
**/
var RED = (function() {
$('#btn-keyboard-shortcuts').click(function(){showHelp();});
function hideDropTarget() {
$("#dropTarget").hide();
RED.keyboard.remove(/* ESCAPE */ 27);
@@ -201,12 +199,9 @@ var RED = (function() {
});
}
$('#btn-node-status').click(function() {toggleStatus();});
var statusEnabled = false;
function toggleStatus() {
var btnStatus = $("#btn-node-status");
statusEnabled = btnStatus.toggleClass("active").hasClass("active");
function toggleStatus(state) {
statusEnabled = state;
RED.view.status(statusEnabled);
}
@@ -229,6 +224,36 @@ var RED = (function() {
}
$(function() {
RED.menu.init({id:"btn-sidemenu",
options: [
{id:"btn-sidebar",icon:"fa fa-columns",label:"Sidebar",toggle:true,onselect:RED.sidebar.toggleSidebar},
null,
{id:"btn-node-status",icon:"fa fa-info",label:"Node Status",toggle:true,onselect:toggleStatus},
null,
{id:"btn-import-menu",icon:"fa fa-sign-in",label:"Import...",options:[
{id:"btn-import-clipboard",icon:"fa fa-clipboard",label:"Clipboard...",onselect:RED.view.showImportNodesDialog},
{id:"btn-import-library",icon:"fa fa-book",label:"Library",options:[]}
]},
{id:"btn-export-menu",icon:"fa fa-sign-out",label:"Export...",disabled:true,options:[
{id:"btn-export-clipboard",icon:"fa fa-clipboard",label:"Clipboard...",disabled:true,onselect:RED.view.showExportNodesDialog},
{id:"btn-export-library",icon:"fa fa-book",label:"Library...",disabled:true,onselect:RED.view.showExportNodesLibraryDialog}
]},
null,
{id:"btn-config-nodes",icon:"fa fa-th-list",label:"Configuration nodes...",onselect:RED.sidebar.config.show},
null,
{id:"btn-workspace-menu",icon:"fa fa-th-large",label:"Workspaces",options:[
{id:"btn-workspace-add",icon:"fa fa-plus",label:"Add"},
{id:"btn-workspace-edit",icon:"fa fa-pencil",label:"Rename"},
{id:"btn-workspace-delete",icon:"fa fa-minus",label:"Delete"},
null
]},
null,
{id:"btn-keyboard-shortcuts",icon:"fa fa-keyboard-o",label:"Keyboard Shortcuts",onselect:showHelp},
{id:"btn-help",icon:"fa fa-question",label:"Help...", href:"http://node-red.github.io/docs"}
]
});
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
loadSettings();
RED.comms.connect();

View File

@@ -25,6 +25,7 @@ RED.library = (function() {
var li;
var a;
var ul = document.createElement("ul");
ul.id = "btn-import-library-submenu";
ul.className = "dropdown-menu";
if (data.d) {
for (i in data.d) {
@@ -61,7 +62,8 @@ RED.library = (function() {
return ul;
};
var menu = buildMenu(data,"");
$("#flow-menu-parent>ul").replaceWith(menu);
//TODO: need an api in RED.menu for this
$("#btn-import-library-submenu").replaceWith(menu);
});
}
loadFlowLibrary();

124
public/red/ui/menu.js Normal file
View File

@@ -0,0 +1,124 @@
/**
* Copyright 2014 IBM Corp.
*
* 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.
**/
RED.menu = (function() {
var menuItems = {};
function createMenuItem(opt) {
var item;
if (opt === null) {
item = $('<li class="divider"></li>');
} else {
item = $('<li></li>');
var link = $('<a '+(opt.id?'id="'+opt.id+'" ':'')+'tabindex="-1" href="#">'+
(opt.toggle?'<i class="fa fa-check pull-right"></i>':'')+
(opt.icon?'<i class="'+opt.icon+'"></i> ':'')+
opt.label+
'</a>').appendTo(item);
menuItems[opt.id] = opt;
if (opt.onselect) {
link.click(function() {
if ($(this).parent().hasClass("disabled")) {
return;
}
if (opt.toggle) {
setSelected(opt.id,!isSelected(opt.id));
} else {
opt.onselect.call(opt);
}
})
} else if (opt.href) {
link.attr("target","_blank").attr("href",opt.href);
}
if (opt.options) {
item.addClass("dropdown-submenu pull-left");
var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item);
for (var i=0;i<opt.options.length;i++) {
createMenuItem(opt.options[i]).appendTo(submenu);
}
}
if (opt.disabled) {
item.addClass("disabled");
}
}
return item;
}
function createMenu(options) {
var button = $("#"+options.id);
var topMenu = $("<ul/>",{class:"dropdown-menu"}).insertAfter(button);
for (var i=0;i<options.options.length;i++) {
var opt = options.options[i];
createMenuItem(opt).appendTo(topMenu);
}
}
function isSelected(id) {
return $("#"+id).hasClass("active");
}
function setSelected(id,state) {
if (isSelected(id) == state) {
return;
}
var opt = menuItems[id];
if (state) {
$("#"+id).addClass("active");
} else {
$("#"+id).removeClass("active");
}
if (opt.onselect) {
opt.onselect.call(opt,state);
}
}
function setDisabled(id,state) {
if (state) {
$("#"+id).parent().addClass("disabled");
} else {
$("#"+id).parent().removeClass("disabled");
}
}
function addItem(id,opt) {
createMenuItem(opt).appendTo("#"+id+"-submenu");
console.log(opt.id);
}
function removeItem(id) {
$("#"+id).parent().remove();
}
return {
init: createMenu,
setSelected: setSelected,
isSelected: isSelected,
setDisabled: setDisabled,
addItem: addItem,
removeItem: removeItem
//TODO: add an api for replacing a submenu - see library.js:loadFlowLibrary
}
})();

View File

@@ -33,9 +33,6 @@ RED.sidebar = (function() {
//content.style.position = "absolute";
//$('#sidebar').tabs("refresh");
}
$('#btn-sidebar').click(function() {toggleSidebar();});
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();});
var sidebarSeparator = {};
$("#sidebar-separator").draggable({
@@ -49,14 +46,14 @@ RED.sidebar = (function() {
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2;
if (!btnSidebar.hasClass("active")) {
if (!RED.menu.isSelected("btn-sidebar")) {
sidebarSeparator.opening = true;
var newChartRight = 15;
$("#sidebar").addClass("closing");
$("#workspace").css("right",newChartRight);
$("#chart-zoom-controls").css("right",newChartRight+20);
$("#sidebar").width(0);
toggleSidebar();
RED.menu.setSelected("btn-sidebar",true);
RED.view.resize();
}
@@ -106,7 +103,7 @@ RED.sidebar = (function() {
RED.view.resize();
if (sidebarSeparator.closing) {
$("#sidebar").removeClass("closing");
toggleSidebar();
RED.menu.setSelected("btn-sidebar",false);
if ($("#sidebar").width() < 180) {
$("#sidebar").width(180);
$("#workspace").css("right",208);
@@ -118,25 +115,16 @@ RED.sidebar = (function() {
}
});
var btnSidebar = $("#btn-sidebar");
function toggleSidebar() {
//if ($('#sidebar').tabs( "option", "active" ) === false) {
// $('#sidebar').tabs( "option", "active",0);
//}
btnSidebar.toggleClass("active");
if (!btnSidebar.hasClass("active")) {
function toggleSidebar(state) {
if (!state) {
$("#main-container").addClass("sidebar-closed");
} else {
$("#main-container").removeClass("sidebar-closed");
}
}
toggleSidebar();
function showSidebar(id) {
if (!$("#btn-sidebar").hasClass("active")) {
toggleSidebar();
}
RED.menu.setSelected("btn-sidebar",true);
sidebar_tabs.activateTab("tab-"+id);
}
@@ -144,10 +132,18 @@ RED.sidebar = (function() {
return sidebar_tabs.contains("tab-"+id);
}
$(function() {
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("btn-sidebar",!RED.menu.isSelected("btn-sidebar"));d3.event.preventDefault();});
showSidebar("info");
});
return {
addTab: addTab,
show: showSidebar,
containsTab: containsTab
containsTab: containsTab,
toggleSidebar: toggleSidebar
}
})();

View File

@@ -23,13 +23,13 @@ RED.sidebar.config = (function() {
var list = $("<ul>",{class:"tab-config-list"}).appendTo(content);
$("#btn-config-nodes").click(function(){
function show() {
if (!RED.sidebar.containsTab("config")) {
RED.sidebar.addTab("config",content,true);
}
refresh();
RED.sidebar.show("config");
});
}
function refresh() {
list.empty();
@@ -78,6 +78,7 @@ RED.sidebar.config = (function() {
});
}
return {
show:show,
refresh:refresh
}
})();

View File

@@ -268,29 +268,18 @@ RED.view = (function() {
showRenameWorkspaceDialog(tab.id);
},
onadd: function(tab) {
var menuli = $("<li/>");
var menuA = $("<a/>",{tabindex:"-1",href:"#"+tab.id}).appendTo(menuli);
menuA.html(tab.label);
menuA.on("click",function() {
workspace_tabs.activateTab(tab.id);
RED.menu.addItem("btn-workspace-menu",{
id:"btn-workspace-menu-"+tab.id.replace(".","-"),
label:tab.label,
onselect:function() {
workspace_tabs.activateTab(tab.id);
}
});
$('#workspace-menu-list').append(menuli);
if (workspace_tabs.count() == 1) {
$('#btn-workspace-delete').parent().addClass("disabled");
} else {
$('#btn-workspace-delete').parent().removeClass("disabled");
}
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
},
onremove: function(tab) {
if (workspace_tabs.count() == 1) {
$('#btn-workspace-delete').parent().addClass("disabled");
} else {
$('#btn-workspace-delete').parent().removeClass("disabled");
}
$('#workspace-menu-list a[href="#'+tab.id+'"]').parent().remove();
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
RED.menu.removeItem("btn-workspace-menu-"+tab.id.replace(".","-"));
}
});
@@ -309,13 +298,15 @@ RED.view = (function() {
RED.history.push({t:'add',workspaces:[ws],dirty:dirty});
RED.view.dirty(true);
}
$('#btn-workspace-add-tab').on("click",addWorkspace);
$('#btn-workspace-add').on("click",addWorkspace);
$('#btn-workspace-edit').on("click",function() {
showRenameWorkspaceDialog(activeWorkspace);
});
$('#btn-workspace-delete').on("click",function() {
deleteWorkspace(activeWorkspace);
$(function() {
$('#btn-workspace-add-tab').on("click",addWorkspace);
$('#btn-workspace-add').on("click",addWorkspace);
$('#btn-workspace-edit').on("click",function() {
showRenameWorkspaceDialog(activeWorkspace);
});
$('#btn-workspace-delete').on("click",function() {
deleteWorkspace(activeWorkspace);
});
});
function deleteWorkspace(id) {
@@ -641,13 +632,13 @@ RED.view = (function() {
function updateSelection() {
if (moving_set.length === 0) {
$("#li-menu-export").addClass("disabled");
$("#li-menu-export-clipboard").addClass("disabled");
$("#li-menu-export-library").addClass("disabled");
RED.menu.setDisabled("btn-export-menu",true);
RED.menu.setDisabled("btn-export-clipboard",true);
RED.menu.setDisabled("btn-export-library",true);
} else {
$("#li-menu-export").removeClass("disabled");
$("#li-menu-export-clipboard").removeClass("disabled");
$("#li-menu-export-library").removeClass("disabled");
RED.menu.setDisabled("btn-export-menu",false);
RED.menu.setDisabled("btn-export-clipboard",false);
RED.menu.setDisabled("btn-export-library",false);
}
if (moving_set.length === 0 && selected_link == null) {
RED.keyboard.remove(/* backspace */ 8);
@@ -1465,10 +1456,6 @@ RED.view = (function() {
}
}
$('#btn-import').click(function() {showImportNodesDialog();});
$('#btn-export-clipboard').click(function() {showExportNodesDialog();});
$('#btn-export-library').click(function() {showExportNodesLibraryDialog();});
function showExportNodesDialog() {
mouse_mode = RED.state.EXPORT;
var nns = RED.nodes.createExportableNodeSet(moving_set);
@@ -1638,6 +1625,11 @@ RED.view = (function() {
RED.nodes.eachNode(function(n) { n.dirty = true;});
//TODO: subscribe/unsubscribe here
redraw();
}
},
//TODO: should these move to an import/export module?
showImportNodesDialog: showImportNodesDialog,
showExportNodesDialog: showExportNodesDialog,
showExportNodesLibraryDialog: showExportNodesLibraryDialog
};
})();