diff --git a/editor/js/history.js b/editor/js/history.js index f2bfb4cd0..265c365bf 100644 --- a/editor/js/history.js +++ b/editor/js/history.js @@ -273,6 +273,10 @@ RED.history = (function() { RED.nodes.addLink(ev.removedLinks[i]); } } + } else if (ev.t == "reorder") { + if (ev.order) { + RED.workspaces.order(ev.order); + } } Object.keys(modifiedTabs).forEach(function(id) { var subflow = RED.nodes.subflow(id); diff --git a/editor/js/nodes.js b/editor/js/nodes.js index 7bc8911e0..72053e549 100644 --- a/editor/js/nodes.js +++ b/editor/js/nodes.js @@ -21,6 +21,7 @@ RED.nodes = (function() { var links = []; var defaultWorkspace; var workspaces = {}; + var workspacesOrder =[]; var subflows = {}; var dirty = false; @@ -271,12 +272,15 @@ RED.nodes = (function() { function addWorkspace(ws) { workspaces[ws.id] = ws; + workspacesOrder.push(ws.id); } function getWorkspace(id) { return workspaces[id]; } function removeWorkspace(id) { delete workspaces[id]; + workspacesOrder.splice(workspacesOrder.indexOf(id),1); + var removedNodes = []; var removedLinks = []; var n; @@ -539,11 +543,9 @@ RED.nodes = (function() { function createCompleteNodeSet() { var nns = []; var i; - for (i in workspaces) { - if (workspaces.hasOwnProperty(i)) { - if (workspaces[i].type == "tab") { - nns.push(workspaces[i]); - } + for (i=0;i",{class:"red-ui-tab"}).appendTo(ul); + li.data("tabId",tab.id); var link = $("",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); if (tab.icon) { $('').appendTo(link); @@ -142,6 +143,85 @@ RED.tabs = (function() { if (ul.find("li.red-ui-tab").size() == 1) { activateTab(link); } + if (options.onreorder) { + var originalTabOrder; + var tabDragIndex; + var tabElements = []; + var startDragIndex; + + li.draggable({ + axis:"x", + distance: 20, + start: function(event,ui) { + originalTabOrder = []; + tabElements = []; + ul.children().each(function(i) { + tabElements[i] = { + el:$(this), + text: $(this).text(), + left: $(this).position().left, + width: $(this).width() + }; + if ($(this).is(li)) { + tabDragIndex = i; + startDragIndex = i; + } + originalTabOrder.push($(this).data("tabId")); + }); + ul.children().each(function(i) { + if (i!==tabDragIndex) { + $(this).css({ + position: 'absolute', + left: tabElements[i].left+"px", + width: tabElements[i].width+2, + transition: "left 0.3s" + }); + } + + }) + if (!li.hasClass('active')) { + li.css({'zIndex':1}); + } + }, + drag: function(event,ui) { + ui.position.left += tabElements[tabDragIndex].left; + var tabCenter = ui.position.left + tabElements[tabDragIndex].width/2; + for (var i=0;i tabElements[i].left && tabCenter < tabElements[i].left+tabElements[i].width) { + if (i < tabDragIndex) { + tabElements[i].left += tabElements[tabDragIndex].width+8; + tabElements[tabDragIndex].el.detach().insertBefore(tabElements[i].el); + } else { + tabElements[i].left -= tabElements[tabDragIndex].width+8; + tabElements[tabDragIndex].el.detach().insertAfter(tabElements[i].el); + } + tabElements[i].el.css({left:tabElements[i].left+"px"}); + + tabElements.splice(i, 0, tabElements.splice(tabDragIndex, 1)[0]); + + tabDragIndex = i; + break; + } + } + + // console.log(ui.position.left,ui.offset.left); + }, + stop: function(event,ui) { + ul.children().css({position:"relative",left:"",transition:""}); + if (!li.hasClass('active')) { + li.css({zIndex:""}); + } + updateTabWidths(); + if (startDragIndex !== tabDragIndex) { + options.onreorder(originalTabOrder, $.makeArray(ul.children().map(function() { return $(this).data('tabId');}))); + } + activateTab(tabElements[tabDragIndex].el.data('tabId')); + } + }) + } }, removeTab: removeTab, activateTab: activateTab, @@ -158,6 +238,30 @@ RED.tabs = (function() { tab.attr("title",label); tab.find("span").text(label); updateTabWidths(); + }, + order: function(order) { + var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); + if (existingTabOrder.length !== order.length) { + return + } + var i; + var match = true; + for (i=0;i