Collapse sidebar tabs

This commit is contained in:
Nick O'Leary 2018-05-23 10:25:10 +01:00
parent 36105412b1
commit a4eb8e11c3
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
9 changed files with 269 additions and 42 deletions

View File

@ -19,12 +19,14 @@ RED.popover = (function() {
"default": { "default": {
top: 10, top: 10,
leftRight: 17, leftRight: 17,
leftLeft: 25 leftLeft: 25,
leftBottom: 8,
}, },
"small": { "small": {
top: 5, top: 5,
leftRight: 17, leftRight: 17,
leftLeft: 16 leftLeft: 16,
leftBottom: 3,
} }
} }
function createPopover(options) { function createPopover(options) {
@ -69,6 +71,8 @@ RED.popover = (function() {
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left+targetWidth+deltaSizes[size].leftRight}); div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left+targetWidth+deltaSizes[size].leftRight});
} else if (direction === 'left') { } else if (direction === 'left') {
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth}); div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth});
} else if (direction === 'bottom') {
div.css({top: targetPos.top+targetHeight+deltaSizes[size].top,left:targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom});
} }
if (instant) { if (instant) {
div.show(); div.show();

View File

@ -19,8 +19,10 @@
RED.tabs = (function() { RED.tabs = (function() {
function createTabs(options) { function createTabs(options) {
var tabs = {}; var tabs = {};
var pinnedTabsCount = 0;
var currentTabWidth; var currentTabWidth;
var currentActiveTabWidth = 0; var currentActiveTabWidth = 0;
var collapsibleMenu;
var ul = options.element || $("#"+options.id); var ul = options.element || $("#"+options.id);
var wrapper = ul.wrap( "<div>" ).parent(); var wrapper = ul.wrap( "<div>" ).parent();
@ -50,6 +52,55 @@ RED.tabs = (function() {
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a"); scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();}); scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();});
} }
if (options.collapsible) {
// var dropDown = $('<div>',{class:"red-ui-tabs-select"}).appendTo(wrapper);
// ul.hide();
wrapper.addClass("red-ui-tabs-collapsible");
var collapsedButtonsRow = $('<div class="red-ui-tab-link-buttons"></div>').appendTo(wrapper);
var selectButton = $('<a href="#"><i class="fa fa-caret-down"></i></a>').appendTo(collapsedButtonsRow);
selectButton.addClass("red-ui-tab-link-button-menu")
selectButton.click(function(evt) {
evt.preventDefault();
if (!collapsibleMenu) {
var pinnedOptions = [];
var options = [];
ul.children().each(function(i,el) {
var id = $(el).data('tabId');
var opt = {
id:"red-ui-tabs-menu-option-"+id,
label: tabs[id].name,
onselect: function() {
activateTab(id);
}
};
if (tabs[id].pinned) {
pinnedOptions.push(opt);
} else {
options.push(opt);
}
});
options = pinnedOptions.concat(options);
collapsibleMenu = RED.menu.init({id:"debug-message-option-menu",options: options});
collapsibleMenu.css({
position: "absolute"
})
collapsibleMenu.on('mouseleave', function(){ $(this).hide() });
collapsibleMenu.on('mouseup', function() { $(this).hide() });
collapsibleMenu.appendTo("body");
var elementPos = selectButton.offset();
collapsibleMenu.css({
top: (elementPos.top+selectButton.height()-20)+"px",
left: (elementPos.left - collapsibleMenu.width() + selectButton.width())+"px"
})
}
collapsibleMenu.toggle();
})
}
function scrollEventHandler(evt,dir) { function scrollEventHandler(evt,dir) {
evt.preventDefault(); evt.preventDefault();
if ($(this).hasClass('disabled')) { if ($(this).hasClass('disabled')) {
@ -118,6 +169,9 @@ RED.tabs = (function() {
ul.children().removeClass("active"); ul.children().removeClass("active");
ul.children().css({"transition": "width 100ms"}); ul.children().css({"transition": "width 100ms"});
link.parent().addClass("active"); link.parent().addClass("active");
var parentId = link.parent().attr('id');
wrapper.find(".red-ui-tab-link-button").removeClass("active");
$("#"+parentId+"-link-button").addClass("active");
if (options.scrollable) { if (options.scrollable) {
var pos = link.parent().position().left; var pos = link.parent().position().left;
if (pos-21 < 0) { if (pos-21 < 0) {
@ -155,41 +209,70 @@ RED.tabs = (function() {
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();
var tabWidth = (width-12-(tabCount*6))/tabCount; var tabWidth;
currentTabWidth = (100*tabWidth/width)+"%";
currentActiveTabWidth = currentTabWidth+"%"; if (options.collapsible) {
if (options.scrollable) { tabWidth = width - collapsedButtonsRow.width()-10;
tabWidth = Math.max(tabWidth,140); if (tabWidth < 198) {
currentTabWidth = tabWidth+"px"; var delta = 198 - tabWidth;
currentActiveTabWidth = 0; var b = collapsedButtonsRow.find("a:last").prev();
var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount); while (b.is(":not(:visible)")) {
ul.width(listWidth); b = b.prev();
updateScroll(); }
} else if (options.hasOwnProperty("minimumActiveTabWidth")) { if (!b.hasClass("red-ui-tab-link-button-pinned")) {
if (tabWidth < options.minimumActiveTabWidth) { b.hide();
tabCount -= 1; }
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount; tabWidth = width - collapsedButtonsRow.width()-10;
currentTabWidth = (100*tabWidth/width)+"%";
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
} else { } else {
currentActiveTabWidth = 0; var space = width - 198 - collapsedButtonsRow.width();
if (space > 40) {
collapsedButtonsRow.find("a:not(:visible):first").show();
tabWidth = width - collapsedButtonsRow.width()-10;
}
} }
} tabs.css({width:tabWidth});
tabs.css({width:currentTabWidth});
if (tabWidth < 50) {
ul.find(".red-ui-tab-close").hide();
ul.find(".red-ui-tab-icon").hide();
ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"})
} else { } else {
ul.find(".red-ui-tab-close").show(); var tabWidth = (width-12-(tabCount*6))/tabCount;
ul.find(".red-ui-tab-icon").show(); currentTabWidth = (100*tabWidth/width)+"%";
ul.find(".red-ui-tab-label").css({paddingLeft:""}) currentActiveTabWidth = currentTabWidth+"%";
} if (options.scrollable) {
if (currentActiveTabWidth !== 0) { tabWidth = Math.max(tabWidth,140);
ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth}); currentTabWidth = tabWidth+"px";
ul.find("li.red-ui-tab.active .red-ui-tab-close").show(); currentActiveTabWidth = 0;
ul.find("li.red-ui-tab.active .red-ui-tab-icon").show(); var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount);
ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""}) ul.width(listWidth);
updateScroll();
} else if (options.hasOwnProperty("minimumActiveTabWidth")) {
if (tabWidth < options.minimumActiveTabWidth) {
tabCount -= 1;
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount;
currentTabWidth = (100*tabWidth/width)+"%";
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
} else {
currentActiveTabWidth = 0;
}
}
if (options.collapsible) {
console.log(currentTabWidth);
}
tabs.css({width:currentTabWidth});
if (tabWidth < 50) {
ul.find(".red-ui-tab-close").hide();
ul.find(".red-ui-tab-icon").hide();
ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"})
} else {
ul.find(".red-ui-tab-close").show();
ul.find(".red-ui-tab-icon").show();
ul.find(".red-ui-tab-label").css({paddingLeft:""})
}
if (currentActiveTabWidth !== 0) {
ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth});
ul.find("li.red-ui-tab.active .red-ui-tab-close").show();
ul.find("li.red-ui-tab.active .red-ui-tab-icon").show();
ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""})
}
} }
} }
@ -210,11 +293,15 @@ RED.tabs = (function() {
activateTab(tab.find("a")); activateTab(tab.find("a"));
} }
li.remove(); li.remove();
if (tabs[id].pinned) {
pinnedTabsCount--;
}
if (options.onremove) { if (options.onremove) {
options.onremove(tabs[id]); options.onremove(tabs[id]);
} }
delete tabs[id]; delete tabs[id];
updateTabWidths(); updateTabWidths();
collapsibleMenu = null;
} }
return { return {
@ -223,13 +310,55 @@ RED.tabs = (function() {
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul); var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul);
li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-"))); li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-")));
li.data("tabId",tab.id); li.data("tabId",tab.id);
if (options.maximumTabWidth) {
li.css("maxWidth",options.maximumTabWidth+"px");
}
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li);
if (tab.icon) { if (tab.icon) {
$('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link); $('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link);
} else if (tab.iconClass) {
$('<i>',{class:"red-ui-tab-icon "+tab.iconClass}).appendTo(link);
} }
var span = $('<span/>',{class:"bidiAware"}).text(tab.label).appendTo(link); var span = $('<span/>',{class:"bidiAware"}).text(tab.label).appendTo(link);
span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label)); span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label));
if (options.collapsible) {
li.addClass("red-ui-tab-pinned");
var pinnedLink = $('<a href="#'+tab.id+'" class="red-ui-tab-link-button"></a>');
if (tab.pinned) {
if (pinnedTabsCount === 0) {
pinnedLink.prependTo(collapsedButtonsRow)
} else {
pinnedLink.insertAfter(collapsedButtonsRow.find("a.red-ui-tab-link-button-pinned:last"));
}
} else {
pinnedLink.insertBefore(collapsedButtonsRow.find("a:last"));
}
pinnedLink.attr('id',li.attr('id')+"-link-button");
if (tab.iconClass) {
$('<i>',{class:tab.iconClass}).appendTo(pinnedLink);
} else {
$('<i>',{class:"fa fa-lemon-o"}).appendTo(pinnedLink);
}
pinnedLink.click(function(evt) {
evt.preventDefault();
activateTab(tab.id);
});
if (tab.pinned) {
pinnedLink.addClass("red-ui-tab-link-button-pinned");
pinnedTabsCount++;
}
RED.popover.create({
target:$(pinnedLink),
trigger: "hover",
size: "small",
direction: "bottom",
content: tab.name,
delay: { show: 550, hide: 10 }
});
}
link.on("click",onTabClick); link.on("click",onTabClick);
link.on("dblclick",onTabDblClick); link.on("dblclick",onTabDblClick);
if (tab.closeable) { if (tab.closeable) {
@ -326,6 +455,7 @@ RED.tabs = (function() {
} }
}) })
} }
collapsibleMenu = null;
}, },
removeTab: removeTab, removeTab: removeTab,
activateTab: activateTab, activateTab: activateTab,

View File

@ -1003,6 +1003,8 @@ RED.sidebar.versionControl = (function() {
name: "Project History", name: "Project History",
content: sidebarContent, content: sidebarContent,
enableOnEdit: false, enableOnEdit: false,
pinned: true,
iconClass: "fa fa-code-fork",
onchange: function() { onchange: function() {
setTimeout(function() { setTimeout(function() {
sections.resize(); sections.resize();

View File

@ -35,7 +35,8 @@ RED.sidebar = (function() {
tab.onremove.call(tab); tab.onremove.call(tab);
} }
}, },
minimumActiveTabWidth: 70 // minimumActiveTabWidth: 70,
collapsible: true
// scrollable: true // scrollable: true
}); });
@ -59,6 +60,8 @@ RED.sidebar = (function() {
options = title; options = title;
} }
delete options.closeable;
options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#sidebar-content") options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#sidebar-content")
options.wrapper.append(options.content); options.wrapper.append(options.content);
options.wrapper.hide(); options.wrapper.hide();
@ -82,6 +85,8 @@ RED.sidebar = (function() {
group: "sidebar-tabs" group: "sidebar-tabs"
}); });
options.iconClass = options.iconClass || "fa fa-square-o"
knownTabs[options.id] = options; knownTabs[options.id] = options;
if (options.visible !== false) { if (options.visible !== false) {

View File

@ -221,8 +221,7 @@ RED.sidebar.config = (function() {
name: RED._("sidebar.config.name"), name: RED._("sidebar.config.name"),
content: content, content: content,
toolbar: toolbar, toolbar: toolbar,
closeable: true, iconClass: "fa fa-cog",
visible: false,
onchange: function() { refreshConfigNodeList(); } onchange: function() { refreshConfigNodeList(); }
}); });
RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')}); RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')});

View File

@ -83,7 +83,9 @@ RED.sidebar.info = (function() {
id: "info", id: "info",
label: RED._("sidebar.info.label"), label: RED._("sidebar.info.label"),
name: RED._("sidebar.info.name"), name: RED._("sidebar.info.name"),
iconClass: "fa fa-info",
content: content, content: content,
pinned: true,
enableOnEdit: true enableOnEdit: true
}); });
if (tips.enabled()) { if (tips.enabled()) {

View File

@ -30,7 +30,6 @@
} }
.red-ui-popover:after, .red-ui-popover:before { .red-ui-popover:after, .red-ui-popover:before {
top: 50%;
border: solid transparent; border: solid transparent;
content: " "; content: " ";
height: 0; height: 0;
@ -39,12 +38,18 @@
pointer-events: none; pointer-events: none;
} }
.red-ui-popover.red-ui-popover-right:after, .red-ui-popover.red-ui-popover-right:before { .red-ui-popover.red-ui-popover-right:after, .red-ui-popover.red-ui-popover-right:before {
top: 50%;
right: 100%; right: 100%;
} }
.red-ui-popover.red-ui-popover-left:after, .red-ui-popover.red-ui-popover-left:before { .red-ui-popover.red-ui-popover-left:after, .red-ui-popover.red-ui-popover-left:before {
top: 50%;
left: 100%; left: 100%;
} }
.red-ui-popover.red-ui-popover-bottom:after, .red-ui-popover.red-ui-popover-bottom:before {
bottom: 100%;
left: 50%;
}
.red-ui-popover.red-ui-popover-right:after { .red-ui-popover.red-ui-popover-right:after {
border-color: rgba(136, 183, 213, 0); border-color: rgba(136, 183, 213, 0);
@ -72,6 +77,21 @@
margin-top: -11px; margin-top: -11px;
} }
.red-ui-popover.red-ui-popover-bottom:after {
border-color: rgba(136, 183, 213, 0);
border-bottom-color: #fff;
border-width: 10px;
margin-left: -10px;
}
.red-ui-popover.red-ui-popover-bottom:before {
border-color: rgba(194, 225, 245, 0);
border-bottom-color: $primary-border-color;
border-width: 11px;
margin-left: -11px;
}
.red-ui-popover-size-small { .red-ui-popover-size-small {
font-size: 11px; font-size: 11px;
padding: 5px; padding: 5px;
@ -93,4 +113,12 @@
border-width: 6px; border-width: 6px;
margin-top: -6px; margin-top: -6px;
} }
&.red-ui-popover-bottom:after {
border-width: 5px;
margin-left: -5px;
}
&.red-ui-popover-bottom:before {
border-width: 6px;
margin-left: -6px;
}
} }

View File

@ -93,7 +93,7 @@
color: $workspace-button-color-hover; color: $workspace-button-color-hover;
} }
} }
.red-ui-tab-icon { img.red-ui-tab-icon {
opacity: 0.2; opacity: 0.2;
} }
} }
@ -113,6 +113,21 @@
&.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-collapsible {
li:not(.active) {
display: none;
&.red-ui-tab-pinned {
a {
padding-left: 0;
text-align: center;
}
span {
display: none;
}
width: 32px;
}
}
}
&.red-ui-tabs-vertical { &.red-ui-tabs-vertical {
box-sizing: border-box; box-sizing: border-box;
@ -157,6 +172,15 @@
} }
} }
} }
.red-ui-tabs-select {
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
opacity: 0.4;
background: red;
}
} }
.red-ui-tab-button { .red-ui-tab-button {
position: absolute; position: absolute;
@ -180,7 +204,33 @@
z-index: 2; z-index: 2;
} }
} }
.red-ui-tab-link-buttons {
position: absolute;
box-sizing: border-box;
top: 0;
right: 0;
height: 35px;
background: #fff;
border-bottom: 1px solid $primary-border-color;
z-index: 2;
a {
@include workspace-button;
line-height: 26px;
height: 28px;
width: 28px;
margin: 4px 3px 3px;
border: 1px solid $primary-border-color;
z-index: 2;
&.red-ui-tab-link-button {
&:not(.active) {
background: #eee;
}
}
&.red-ui-tab-link-button-menu {
border-color: white;
}
}
}
.red-ui-tab-scroll { .red-ui-tab-scroll {
width: 21px; width: 21px;
top: 0; top: 0;
@ -216,7 +266,7 @@
right: 38px; right: 38px;
} }
.red-ui-tab-icon { img.red-ui-tab-icon {
margin-left: -8px; margin-left: -8px;
margin-right: 3px; margin-right: 3px;
margin-top: -2px; margin-top: -2px;
@ -225,6 +275,11 @@
height: 20px; height: 20px;
vertical-align: middle; vertical-align: middle;
} }
i.red-ui-tab-icon {
opacity: 0.7;
width: 18px;
height: 20px;
}
.red-ui-tabs-badges { .red-ui-tabs-badges {
position: absolute; position: absolute;

View File

@ -154,7 +154,9 @@
name: this._("debug.sidebar.name"), name: this._("debug.sidebar.name"),
content: uiComponents.content, content: uiComponents.content,
toolbar: uiComponents.footer, toolbar: uiComponents.footer,
enableOnEdit: true enableOnEdit: true,
pinned: true,
iconClass: "fa fa-wrench"
}); });
RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug'); }); RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug'); });