Editor tabs: option to switch layout (compressible <-> scrollable)
authorVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Fri, 27 Feb 2015 19:04:13 +0000 (22:04 +0300)
committerVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Fri, 27 Feb 2015 19:05:17 +0000 (22:05 +0300)
Preferences -> Editor -> General -> Editor Tabs -> Hide tabs if there is no space (it's not checked by default to promote new "compressible" layout)

platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form
platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java
platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
platform/platform-resources-en/src/messages/ApplicationBundle.properties
platform/util/resources/misc/registry.properties

index 5b0d6fae19803523ad80145b7fbfd65e4c80f17d..1932622b89968352f323bde9e6ca5817178f71a9 100644 (file)
@@ -86,6 +86,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
   public boolean ALWAYS_SHOW_WINDOW_BUTTONS = false;
   public boolean CYCLE_SCROLLING = true;
   public boolean SCROLL_TAB_LAYOUT_IN_EDITOR = true;
+  public boolean HIDE_TABS_IF_NEED = false;
   public boolean SHOW_CLOSE_BUTTON = true;
   public int EDITOR_TAB_PLACEMENT = 1;
   public boolean HIDE_KNOWN_EXTENSION_IN_TABS = false;
index 4453eb04716314e78d3a5a24615a31f4fe03395a..e3992ac1a93798fa7f5ffb1e79fee3ceef274d9d 100644 (file)
@@ -8,7 +8,7 @@
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="ed507" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="ed507" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
           <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="9" fill="3" indent="0" use-parent-layout="false"/>
@@ -30,7 +30,7 @@
           <grid id="861f5" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
             <margin top="0" left="5" bottom="0" right="0"/>
             <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+              <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties/>
             <border type="none"/>
@@ -61,7 +61,7 @@
           </grid>
           <component id="50eb7" class="javax.swing.JCheckBox" binding="myShowCloseButtonOnCheckBox" default-binding="true">
             <constraints>
-              <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text resource-bundle="messages/ApplicationBundle" key="checkbox.editor.tabs.show.close.button"/>
@@ -69,7 +69,7 @@
           </component>
           <component id="e9bec" class="javax.swing.JCheckBox" binding="myCbModifiedTabsMarkedWithAsterisk">
             <constraints>
-              <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
+              <grid row="6" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
                 <preferred-size width="239" height="20"/>
               </grid>
             </constraints>
@@ -79,7 +79,7 @@
           </component>
           <component id="2ecb5" class="javax.swing.JCheckBox" binding="myHideKnownExtensions">
             <constraints>
-              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text resource-bundle="messages/ApplicationBundle" key="checkbox.hide.file.extension.in.editor.tabs"/>
@@ -87,7 +87,7 @@
           </component>
           <component id="66205" class="javax.swing.JCheckBox" binding="myShowDirectoryInTabCheckBox">
             <constraints>
-              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text value="Show directory in editor tabs for non-unique filenames"/>
           </component>
           <component id="9c802" class="javax.swing.JCheckBox" binding="myShowTabsTooltipsCheckBox" default-binding="true">
             <constraints>
-              <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="7" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text resource-bundle="messages/ApplicationBundle" key="checkbox.show.tabs.tooltips"/>
             </properties>
           </component>
+          <component id="85614" class="javax.swing.JCheckBox" binding="myHideTabsCheckbox">
+            <constraints>
+              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/ApplicationBundle" key="checkbox.editor.scroll.if.need"/>
+            </properties>
+          </component>
         </children>
       </grid>
       <vspacer id="651b4">
index 2947712039a669f41b2fb31e0f0258ccf0c7c12e..edcb1e05d1f7aa5114e2f86c295a5e5a8fed2fbe 100644 (file)
@@ -24,6 +24,8 @@ import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 
@@ -45,6 +47,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
   private JCheckBox myShowCloseButtonOnCheckBox;
   private JCheckBox myShowDirectoryInTabCheckBox;
   private JRadioButton myActivateRightNeighbouringTabRadioButton;
+  private JCheckBox myHideTabsCheckbox;
 
   public EditorTabsConfigurable() {
     myEditorTabPlacement.setModel(new DefaultComboBoxModel(new Object[]{
@@ -63,6 +66,12 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
     });
 
     revalidateSingleRowCheckbox();
+    myScrollTabLayoutInEditorCheckBox.addChangeListener(new ChangeListener() {
+      @Override
+      public void stateChanged(ChangeEvent event) {
+        myHideTabsCheckbox.setEnabled(myScrollTabLayoutInEditorCheckBox.isSelected());
+      }
+    });
   }
 
   private void revalidateSingleRowCheckbox() {
@@ -107,6 +116,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
     myCbModifiedTabsMarkedWithAsterisk.setSelected(uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK);
     myShowTabsTooltipsCheckBox.setSelected(uiSettings.SHOW_TABS_TOOLTIPS);
     myScrollTabLayoutInEditorCheckBox.setSelected(uiSettings.SCROLL_TAB_LAYOUT_IN_EDITOR);
+    myHideTabsCheckbox.setSelected(uiSettings.HIDE_TABS_IF_NEED);
     myEditorTabPlacement.setSelectedItem(uiSettings.EDITOR_TAB_PLACEMENT);
     myHideKnownExtensions.setSelected(uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS);
     myShowDirectoryInTabCheckBox.setSelected(uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES);
@@ -143,6 +153,9 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
     if (isModified(myScrollTabLayoutInEditorCheckBox, uiSettings.SCROLL_TAB_LAYOUT_IN_EDITOR)) uiSettingsChanged = true;
     uiSettings.SCROLL_TAB_LAYOUT_IN_EDITOR = myScrollTabLayoutInEditorCheckBox.isSelected();
 
+    if (isModified(myHideTabsCheckbox, uiSettings.HIDE_TABS_IF_NEED)) uiSettingsChanged = true;
+    uiSettings.HIDE_TABS_IF_NEED = myHideTabsCheckbox.isSelected();
+
     if (isModified(myShowCloseButtonOnCheckBox, uiSettings.SHOW_CLOSE_BUTTON)) uiSettingsChanged = true;
     uiSettings.SHOW_CLOSE_BUTTON = myShowCloseButtonOnCheckBox.isSelected();
 
@@ -191,6 +204,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
     isModified |= myShowDirectoryInTabCheckBox.isSelected() != uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES;
 
     isModified |= myScrollTabLayoutInEditorCheckBox.isSelected() != uiSettings.SCROLL_TAB_LAYOUT_IN_EDITOR;
+    isModified |= myHideTabsCheckbox.isSelected() != uiSettings.HIDE_TABS_IF_NEED;
     isModified |= myShowCloseButtonOnCheckBox.isSelected() != uiSettings.SHOW_CLOSE_BUTTON;
 
     isModified |= isModified(myCloseNonModifiedFilesFirstRadio, uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST);
index 4f81f3cbf4e18d016545e100078c256cee103119..bcaa5245a91547be0b5868fe112e638abc89959d 100644 (file)
@@ -55,7 +55,7 @@ public class JBEditorTabs extends JBTabsImpl {
 
   @Override
   protected SingleRowLayout createSingleRowLayout() {
-    if (Registry.is("editor.use.compressible.tabs")) {
+    if (!UISettings.getInstance().HIDE_TABS_IF_NEED) {
       return new CompressibleSingleRowLayout(this);
     }
     else if (ApplicationManager.getApplication().isInternal() || Registry.is("editor.use.scrollable.tabs")) {
index a3e0d7ec1452879d3af7b2de8b87c913a1dde755..8843c6c12ec903d1604131eea86fe528a0cc96e0 100644 (file)
@@ -32,6 +32,7 @@ import com.intellij.ui.switcher.QuickActionProvider;
 import com.intellij.ui.switcher.SwitchProvider;
 import com.intellij.ui.switcher.SwitchTarget;
 import com.intellij.ui.tabs.*;
+import com.intellij.ui.tabs.impl.singleRow.ScrollableSingleRowLayout;
 import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout;
 import com.intellij.ui.tabs.impl.singleRow.SingleRowPassInfo;
 import com.intellij.ui.tabs.impl.table.TableLayout;
@@ -103,7 +104,7 @@ public class JBTabsImpl extends JComponent
 
   private final WeakHashMap<Component, Component> myDeferredToRemove = new WeakHashMap<Component, Component>();
 
-  private final SingleRowLayout mySingleRowLayout;
+  private SingleRowLayout mySingleRowLayout;
   private final TableLayout myTableLayout = new TableLayout(this);
 
 
@@ -253,6 +254,22 @@ public class JBTabsImpl extends JComponent
           entry.getKey().revalidate();
           entry.getValue().setInactiveStateImage(null);
         }
+        boolean oldHideTabsIfNeed = mySingleRowLayout instanceof ScrollableSingleRowLayout;
+        boolean newHideTabsIfNeed = UISettings.getInstance().HIDE_TABS_IF_NEED;
+        boolean wasSingleRow = isSingleRow();
+        if (oldHideTabsIfNeed != newHideTabsIfNeed) {
+          if (mySingleRowLayout != null) {
+            remove(mySingleRowLayout.myLeftGhost);
+            remove(mySingleRowLayout.myRightGhost);
+          }
+          mySingleRowLayout = createSingleRowLayout();
+          if (wasSingleRow) {
+            myLayout = mySingleRowLayout;
+          }
+          add(mySingleRowLayout.myLeftGhost);
+          add(mySingleRowLayout.myRightGhost);
+          relayout(true, true);
+        }
       }
     }, this);
 
@@ -2521,7 +2538,7 @@ public class JBTabsImpl extends JComponent
     }
 
     revalidateAndRepaint(true);
-    
+
     fireTabRemoved(info);
 
     return result;
index 8bbd94030fb358adde033d73995ffb47164b94db..e55bc1ffb73fbc777aa80b3c3276354a3597a953 100644 (file)
@@ -22,7 +22,6 @@ import com.intellij.openapi.actionSystem.ActionPlaces;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import com.intellij.openapi.util.Pass;
 import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.registry.Registry;
 import com.intellij.ui.*;
 import com.intellij.ui.components.panels.Wrapper;
 import com.intellij.ui.tabs.JBTabsPosition;
@@ -126,7 +125,7 @@ public class TabLabel extends JPanel {
 
       @Override
       protected void doPaint(Graphics2D g) {
-        if (!Registry.is("editor.use.compressible.tabs") || tabs.getTabsPosition() == JBTabsPosition.left || tabs.getTabsPosition() == JBTabsPosition.right) {
+        if (UISettings.getInstance().HIDE_TABS_IF_NEED || tabs.getTabsPosition() == JBTabsPosition.left || tabs.getTabsPosition() == JBTabsPosition.right) {
           super.doPaint(g);
           return;
         }
@@ -156,7 +155,7 @@ public class TabLabel extends JPanel {
     };
     label.setOpaque(false);
     label.setBorder(null);
-    label.setIconTextGap(tabs.isEditorTabs() ? (Registry.is("editor.use.compressible.tabs") ? 4 : 2) : new JLabel().getIconTextGap());
+    label.setIconTextGap(tabs.isEditorTabs() ? (!UISettings.getInstance().HIDE_TABS_IF_NEED ? 4 : 2) : new JLabel().getIconTextGap());
     label.setIconOpaque(false);
     label.setIpad(new Insets(0, 0, 0, 0));
 
@@ -167,7 +166,7 @@ public class TabLabel extends JPanel {
   public Insets getInsets() {
     Insets insets = super.getInsets();
     if (myTabs.isEditorTabs()) {
-      if (!Registry.is("editor.use.compressible.tabs")) {
+      if (UISettings.getInstance().HIDE_TABS_IF_NEED) {
         if (UISettings.getInstance().SHOW_CLOSE_BUTTON) insets.right = 3;
       }
       else {
index 2492ff570e48e062d08f096094bc27ea1ee21172..64bea2106837c93eb0aa0590112535f5390a13dd 100644 (file)
@@ -37,7 +37,6 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Queryable;
 import com.intellij.openapi.ui.ShadowAction;
 import com.intellij.openapi.util.*;
-import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.*;
 import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
@@ -101,7 +100,7 @@ public final class EditorTabbedContainer implements Disposable, CloseAction.Clos
       @Override
       @NotNull
       public UiDecoration getDecoration() {
-        int sideInset = Registry.is("editor.use.compressible.tabs") ? 2 : 10;
+        int sideInset = !UISettings.getInstance().HIDE_TABS_IF_NEED ? 2 : 10;
         return new UiDecoration(null, new Insets(TabsUtil.TAB_VERTICAL_PADDING, sideInset, TabsUtil.TAB_VERTICAL_PADDING, sideInset));
       }
     }).setTabLabelActionsMouseDeadzone(TimedDeadzone.NULL).setGhostsAlwaysVisible(true).setTabLabelActionsAutoHide(false)
index a85e03f3a7e323e2247dd6cfda244d1f1cda27b6..36dcd15efdc0329276abdf7bebb3950e44850385 100644 (file)
@@ -72,7 +72,7 @@ public class EditorWindow {
   protected JPanel myPanel;
   private EditorTabbedContainer myTabbedPane;
   private final EditorsSplitters myOwner;
-  private static final Icon MODIFIED_ICON = Registry.is("editor.use.compressible.tabs") ? new Icon() {
+  private static final Icon MODIFIED_ICON = !UISettings.getInstance().HIDE_TABS_IF_NEED ? new Icon() {
     @Override
     public void paintIcon(Component c, Graphics g, int x, int y) {
       GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
@@ -975,7 +975,7 @@ public class EditorWindow {
     }
 
     final Icon modifiedIcon;
-    if (UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK || Registry.is("editor.use.compressible.tabs")) {
+    if (UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK || !UISettings.getInstance().HIDE_TABS_IF_NEED) {
       modifiedIcon =
         UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK && composite != null && composite.isModified() ? MODIFIED_ICON : GAP_ICON;
       count++;
@@ -988,7 +988,7 @@ public class EditorWindow {
 
     int i = 0;
     final LayeredIcon result = new LayeredIcon(count);
-    int xShift = Registry.is("editor.use.compressible.tabs") ? 4 : 0;
+    int xShift = !UISettings.getInstance().HIDE_TABS_IF_NEED ? 4 : 0;
     result.setIcon(baseIcon, i++, xShift, 0);
     if (pinIcon != null) result.setIcon(pinIcon, i++, xShift, 0);
     if (modifiedIcon != null) result.setIcon(modifiedIcon, i++);
index cdc6d54177804a2efd8e20fb0dfdf5a83c174b3f..e3916e2b8327b230e84909bd6c88a2e07ad66c80 100644 (file)
@@ -379,6 +379,7 @@ editbox.tab.limit=Tab limit:
 combobox.editor.tab.placement=Placement:
 checkbox.editor.tabs.in.single.row=Show tabs in single row
 checkbox.editor.tabs.show.close.button=Show "close" button on editor tabs
+checkbox.editor.scroll.if.need=Hide tabs if there is no space
 checkbox.hide.file.extension.in.editor.tabs=Hide file extension in editor tabs
 group.tab.closing.policy=Tab Closing Policy
 radio.activate.most.recently.opened.tab=<html>Activate most recently opened tab</html>
index 26124eeecf2561decfac060c6d1b8055a0f11e8e..00a33510ac9166b96f323e69f3d2728629cc6037 100644 (file)
@@ -126,7 +126,6 @@ editor.mouseSelectionStateResetTimeout=1000
 editor.mouseSelectionStateResetDeadZone=4
 editor.use.new.tabs=true
 editor.use.scrollable.tabs=true
-editor.use.compressible.tabs=true
 editor.smarterSelectionQuoting=true
 editor.skip.copy.and.cut.for.empty.selection=false
 editor.distraction.free.mode=false