From e4626ee52b35debb73a92799d879e9f1010f03db Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Sep 2016 22:56:28 +0100 Subject: [PATCH] =?UTF-8?q?Scrollable=20tabs=20=F0=9F=91=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- editor/js/ui/common/tabs.js | 98 ++++++++++++-- editor/js/ui/workspaces.js | 7 +- editor/sass/tabs.scss | 255 +++++++++++++++++++++++------------- editor/sass/workspace.scss | 27 ---- editor/templates/index.mst | 1 - 5 files changed, 258 insertions(+), 130 deletions(-) diff --git a/editor/js/ui/common/tabs.js b/editor/js/ui/common/tabs.js index 5712ef15a..c95b34f4f 100644 --- a/editor/js/ui/common/tabs.js +++ b/editor/js/ui/common/tabs.js @@ -17,15 +17,58 @@ RED.tabs = (function() { - - function createTabs(options) { var tabs = {}; var currentTabWidth; var currentActiveTabWidth = 0; var ul = $("#"+options.id); - ul.addClass("red-ui-tabs"); + var wrapper = ul.wrap( "
" ).parent(); + var scrollContainer = ul.wrap( "
" ).parent(); + wrapper.addClass("red-ui-tabs"); + if (options.addButton && typeof options.addButton === 'function') { + wrapper.addClass("red-ui-tabs-add"); + var addButton = $('
').appendTo(wrapper); + addButton.find('a').click(function(evt) { + evt.preventDefault(); + options.addButton(); + }) + + } + var scrollLeft; + var scrollRight; + + if (options.scrollable) { + wrapper.addClass("red-ui-tabs-scrollable"); + scrollContainer.addClass("red-ui-tabs-scroll-container"); + scrollContainer.scroll(updateScroll); + scrollLeft = $('
').appendTo(wrapper).find("a"); + scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }); + scrollRight = $('
').appendTo(wrapper).find("a"); + scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }); + } + function scrollEventHandler(evt,dir) { + evt.preventDefault(); + if ($(this).hasClass('disabled')) { + return; + } + var currentScrollLeft = scrollContainer.scrollLeft(); + scrollContainer.animate( { scrollLeft: dir }, 300); + var interval = setInterval(function() { + var newScrollLeft = scrollContainer.scrollLeft() + if (newScrollLeft === currentScrollLeft) { + clearInterval(interval); + return; + } + currentScrollLeft = newScrollLeft; + scrollContainer.animate( { scrollLeft: dir }, 300); + },300); + $(this).one('mouseup',function() { + clearInterval(interval); + }) + } + + ul.children().first().addClass("active"); ul.children().addClass("red-ui-tab"); @@ -34,6 +77,23 @@ RED.tabs = (function() { return false; } + function updateScroll() { + if (ul.children().length !== 0) { + var sl = scrollContainer.scrollLeft(); + var scWidth = scrollContainer.width(); + var ulWidth = ul.width(); + if (sl === 0) { + scrollLeft.hide(); + } else { + scrollLeft.show(); + } + if (sl === ulWidth-scWidth) { + scrollRight.hide(); + } else { + scrollRight.show(); + } + } + } function onTabDblClick() { if (options.ondblclick) { options.ondblclick(tabs[$(this).attr('href').slice(1)]); @@ -49,6 +109,14 @@ RED.tabs = (function() { ul.children().removeClass("active"); ul.children().css({"transition": "width 100ms"}); link.parent().addClass("active"); + if (options.scrollable) { + var pos = link.parent().position().left; + if (pos-21 < 0) { + scrollContainer.animate( { scrollLeft: '+='+(pos-50) }, 300); + } else if (pos + 120 > scrollContainer.width()) { + scrollContainer.animate( { scrollLeft: '+='+(pos + 140-scrollContainer.width()) }, 300); + } + } if (options.onchange) { options.onchange(tabs[link.attr('href').slice(1)]); } @@ -61,23 +129,29 @@ RED.tabs = (function() { function updateTabWidths() { var tabs = ul.find("li.red-ui-tab"); - var width = ul.width(); + var width = wrapper.width(); var tabCount = tabs.size(); var tabWidth = (width-12-(tabCount*6))/tabCount; - currentTabWidth = 100*tabWidth/width; + currentTabWidth = (100*tabWidth/width)+"%"; currentActiveTabWidth = currentTabWidth+"%"; - - if (options.hasOwnProperty("minimumActiveTabWidth")) { + if (options.scrollable) { + tabWidth = Math.max(tabWidth,140); + currentTabWidth = tabWidth+"px"; + currentActiveTabWidth = 0; + var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount); + 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; + currentTabWidth = (100*tabWidth/width)+"%"; currentActiveTabWidth = options.minimumActiveTabWidth+"px"; } else { currentActiveTabWidth = 0; } } - tabs.css({width:currentTabWidth+"%"}); + tabs.css({width:currentTabWidth}); if (tabWidth < 50) { ul.find(".red-ui-tab-close").hide(); ul.find(".red-ui-tab-icon").hide(); @@ -97,7 +171,9 @@ RED.tabs = (function() { } ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick); - updateTabWidths(); + setTimeout(function() { + updateTabWidths(); + },0); function removeTab(id) { @@ -210,8 +286,6 @@ RED.tabs = (function() { break; } } - - // console.log(ui.position.left,ui.offset.left); }, stop: function(event,ui) { ul.children().css({position:"relative",left:"",transition:""}); diff --git a/editor/js/ui/workspaces.js b/editor/js/ui/workspaces.js index e6b5f5994..9817a5a11 100644 --- a/editor/js/ui/workspaces.js +++ b/editor/js/ui/workspaces.js @@ -166,13 +166,16 @@ RED.workspaces = (function() { RED.nodes.dirty(true); setWorkspaceOrder(newOrder); }, - minimumActiveTabWidth: 150 + minimumActiveTabWidth: 150, + scrollable: true, + addButton: function() { + addWorkspace(); + } }); } function init() { createWorkspaceTabs(); - $('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()}); RED.events.on("sidebar:resize",workspace_tabs.resize); RED.menu.setAction('menu-item-workspace-delete',function() { diff --git a/editor/sass/tabs.scss b/editor/sass/tabs.scss index b441d1550..c848459e2 100644 --- a/editor/sass/tabs.scss +++ b/editor/sass/tabs.scss @@ -1,5 +1,5 @@ /** - * Copyright 2015 IBM Corp. + * Copyright 2015, 2016 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,47 +14,174 @@ * limitations under the License. **/ -ul.red-ui-tabs { - list-style-type: none; - padding:0; - margin: 0; - display: block; - height: 35px; - box-sizing:border-box; - white-space: nowrap; - border-bottom: 1px solid $primary-border-color; - background: #fff; - @include disable-selection; -} - -ul.red-ui-tabs li { - box-sizing: border-box; - display: inline-block; - border-left: 1px solid $primary-border-color; - border-top: 1px solid $primary-border-color; - border-right: 1px solid $primary-border-color; - border-bottom: 1px solid $primary-border-color; - background: $tab-background-inactive; - margin: 3px 3px 0 3px; - height: 32px; - line-height: 29px; - max-width: 200px; - width: 14%; - overflow: hidden; - white-space: nowrap; -} - -ul.red-ui-tabs li a.red-ui-tab-label { - display: block; - font-size: 14px; - padding-left: 12px; - width: 100%; - height: 100%; - color: #666; -} -ul.red-ui-tabs li { +.red-ui-tabs { position: relative; + background: #fff; + overflow: hidden; + height: 35px; + box-sizing: border-box; + + .red-ui-tabs-scroll-container { + height: 60px; + overflow-x: scroll; + overflow-y: hidden; + &::-webkit-scrollbar { + display: none; + } + } + & ul { + //background: #9999ff; + list-style-type: none; + padding:0; + margin: 0; + display: block; + height: 35px; + box-sizing:border-box; + border-bottom: 1px solid $primary-border-color; + white-space: nowrap; + @include disable-selection; + + li { + box-sizing: border-box; + display: inline-block; + border-left: 1px solid $primary-border-color; + border-top: 1px solid $primary-border-color; + border-right: 1px solid $primary-border-color; + border-bottom: 1px solid $primary-border-color; + background: $tab-background-inactive; + margin: 3px 3px 0 3px; + height: 32px; + line-height: 29px; + max-width: 200px; + width: 14%; + overflow: hidden; + white-space: nowrap; + position: relative; + + a.red-ui-tab-label { + display: block; + font-size: 14px; + padding-left: 12px; + width: 100%; + height: 100%; + color: #666; + } + a:hover { + text-decoration: none; + } + a:focus { + text-decoration: none; + } + + &:not(.active) a:hover+a.red-ui-tab-close { + background: $tab-background-hover; + } + &.active { + background: $tab-background-active; + font-weight: bold; + border-bottom: 1px solid #fff; + z-index: 2; + + a { + color: #333; + } + a.red-ui-tab-close { + color: #aaa; + background: $tab-background-active; + &:hover { + background: $workspace-button-background-hover !important; + color: $workspace-button-color-hover; + } + } + .red-ui-tab-icon { + opacity: 0.2; + } + } + &:not(.active) a:hover { + color: $workspace-button-color-hover; + background: $tab-background-hover; + } + } + } + &.red-ui-tabs-scrollable { + padding-left: 21px; + padding-right: 21px; + } + &.red-ui-tabs-add { + padding-right: 35px; + } + &.red-ui-tabs-add.red-ui-tabs-scrollable { + padding-right: 59px; + } } +.red-ui-tab-button { + position: absolute; + box-sizing: border-box; + top: 0; + right: 0; + height: 35px; + background: #fff; + border-bottom: 1px solid $primary-border-color; + z-index: 3; + + a { + @include workspace-button; + line-height: 32px; + height: 32px; + width: 32px; + margin-top: 3px; + margin-right:3px; + margin-left:3px; + border: 1px solid $primary-border-color; + z-index: 3; + } +} + +.red-ui-tab-scroll { + width: 21px; + top: 0; + a { + height: 35px; + width: 21px; + display: block; + color: $link-color; + font-size: 22px; + text-align: center; + margin:0; + border-left: none; + border-right: none; + border-top: none; + } +} +.red-ui-tab-scroll-left { + left:0; + a { + border-right: 1px solid $primary-border-color; + // box-shadow: 8px 0px 5px -2px rgba(0,0,0,0.1); + } +} +.red-ui-tab-scroll-right { + right: 0px; + a { + border-left: 1px solid $primary-border-color; + // box-shadow: -8px 0px 5px -2px rgba(0,0,0,0.1); + } + +} +.red-ui-tabs.red-ui-tabs-add .red-ui-tab-scroll-right { + right: 38px; +} + +.red-ui-tab-icon { + margin-left: -8px; + margin-right: 3px; + margin-top: -2px; + opacity: 0.1; + width: 20px; + height: 20px; + vertical-align: middle; +} + .red-ui-tabs-badges { position: absolute; top:2px; @@ -96,51 +223,3 @@ ul.red-ui-tabs li { opacity: 1; } } -ul.red-ui-tabs li:not(.active) a:hover+a.red-ui-tab-close { - background: $tab-background-hover; -} - -ul.red-ui-tabs li.active a.red-ui-tab-close { - color: #aaa; - background: $tab-background-active; - &:hover { - background: $workspace-button-background-hover !important; - color: $workspace-button-color-hover; - } -} - -ul.red-ui-tabs li a:hover { - text-decoration: none; -} - -ul.red-ui-tabs li:not(.active) a:hover { - color: $workspace-button-color-hover; - background: $tab-background-hover; -} - -ul.red-ui-tabs li a:focus { - text-decoration: none; -} - -ul.red-ui-tabs li.active { - background: $tab-background-active; - font-weight: bold; - border-bottom: 1px solid #fff; - z-index: 2; -} -ul.red-ui-tabs li.active a { - color: #333; -} - -.red-ui-tab-icon { - margin-left: -8px; - margin-right: 3px; - margin-top: -2px; - opacity: 0.1; - width: 20px; - height: 20px; - vertical-align: middle; -} -ul.red-ui-tabs li.active .red-ui-tab-icon { - opacity: 0.2; -} diff --git a/editor/sass/workspace.scss b/editor/sass/workspace.scss index d23d5cb81..0d27a97f1 100644 --- a/editor/sass/workspace.scss +++ b/editor/sass/workspace.scss @@ -48,33 +48,6 @@ @include component-footer-button; } -#workspace-tabs { - margin-right: 35px; -} - - - -#workspace-add-tab { - position: absolute; - box-sizing: border-box; - top: 0; - right: 0; - height: 35px; - width: 35px; - background: #fff; - border-bottom: 1px solid $primary-border-color; -} - -#btn-workspace-add-tab { - @include workspace-button; - line-height: 32px; - height: 32px; - width: 32px; - margin-top: 3px; - margin-right:3px; - border: 1px solid $primary-border-color; -} - #workspace-footer { @include component-footer; } diff --git a/editor/templates/index.mst b/editor/templates/index.mst index 0d9bdb313..f3b7b22b9 100644 --- a/editor/templates/index.mst +++ b/editor/templates/index.mst @@ -45,7 +45,6 @@