IDEA-312553 Show all view mode actions in the editor tabs without dropdown

Split mode actions are moved to image editor toolbar.

GitOrigin-RevId: b7066c7466901d855028b118eb0eefe220e8b05d
This commit is contained in:
Konstantin Hudyakov
2023-02-06 18:36:38 +02:00
committed by intellij-monorepo-bot
parent 74d1b45ef4
commit d978adaf4c
7 changed files with 96 additions and 114 deletions

View File

@@ -155,6 +155,8 @@
<reference id="Images.Editor.FitZoomToWindow"/>
<reference id="ShowColorPicker"/>
<reference id="Images.ChangeBackground"/>
<separator/>
<reference id="TextEditorWithPreview.SplitGroup"/>
</group>
<group id="Images.EditorPopupMenu">
<reference id="CutCopyPasteGroup"/>

View File

@@ -2287,9 +2287,6 @@ tooltip.search.history.hotkey=Search History {0}
tab.title.editor.only=Editor
tab.title.preview.only=Preview
tab.title.editor.and.preview=Editor and Preview
tab.vertical.split=Vertical split
tab.horizontal.split=Horizontal split
tab.view.modes=View Modes
tab.title.text=Text
tooltip.hide=Hide
dialog.message.command.could.not.complete={0} could not complete successfully. \

View File

@@ -6,7 +6,6 @@ import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -32,7 +31,6 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBThinOverlappingScrollBar;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.hover.HoverListener;
import com.intellij.ui.paint.LinePainter2D;
import com.intellij.ui.popup.PopupState;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.ui.switcher.QuickActionProvider;
@@ -485,8 +483,7 @@ public class JBTabsImpl extends JComponent
}
private @NotNull ActionToolbar createToolbar(ActionGroup group) {
final ActionToolbar toolbar =
ActionManagerEx.getInstanceEx().createActionToolbar(ActionPlaces.TABS_MORE_TOOLBAR, group, true, text -> new ThinActionSeparator());
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TABS_MORE_TOOLBAR, group, true);
toolbar.setTargetComponent(this);
toolbar.getComponent().setBorder(JBUI.Borders.empty());
toolbar.getComponent().setOpaque(false);
@@ -2705,9 +2702,21 @@ public class JBTabsImpl extends JComponent
ActionGroup tabActionGroup = selectedInfo != null ? selectedInfo.getTabPaneActions() : null;
DefaultActionGroup entryPointActionGroup = getEntryPointActionGroup();
if (tabActionGroup != null || entryPointActionGroup != null) {
ActionGroup group = tabActionGroup != null && entryPointActionGroup != null
? new DefaultActionGroup(tabActionGroup, entryPointActionGroup)
: tabActionGroup != null ? tabActionGroup : entryPointActionGroup;
ActionGroup group;
if (tabActionGroup != null && entryPointActionGroup != null) {
if (!myMoreToolbar.getComponent().getBounds().isEmpty()
&& tabActionGroup.getChildren(null).length != 0
// check that more toolbar and entry point toolbar are in the same row
&& (!TabLayout.showPinnedTabsSeparately() || ContainerUtil.all(getTabs(), info -> !info.isPinned()))) {
group = new DefaultActionGroup(new FakeEmptyAction(), Separator.create(), tabActionGroup, Separator.create(), entryPointActionGroup);
}
else {
group = new DefaultActionGroup(tabActionGroup, Separator.create(), entryPointActionGroup);
}
}
else {
group = tabActionGroup != null ? tabActionGroup : entryPointActionGroup;
}
if (myEntryPointToolbar != null && myEntryPointToolbar.getActionGroup().equals(group)) {
// keep old toolbar to avoid blinking (actions need to be updated to be visible)
@@ -2734,17 +2743,20 @@ public class JBTabsImpl extends JComponent
: JBUI.Borders.empty(0, 5, 0, 8);
}
private static class ThinActionSeparator extends JComponent {
// Useful when you need to always show separator as first or last component of ActionToolbar
// Just put it as first or last action and any separator will not be counted as corner and will be shown
private static class FakeEmptyAction extends DumbAwareAction implements CustomComponentAction {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(JBUI.CurrentTheme.ActionButton.SEPARATOR_COLOR);
LinePainter2D.paint(g2d, 0, 0, 0, getHeight());
public void actionPerformed(@NotNull AnActionEvent e) {
// do nothing
}
@Override
public Dimension getPreferredSize() {
return new JBDimension(1, 14);
public @NotNull JComponent createCustomComponent(@NotNull Presentation presentation, @NotNull String place) {
JPanel panel = new JPanel();
Dimension size = new Dimension(0, 0);
panel.setPreferredSize(size);
return panel;
}
}

View File

@@ -0,0 +1,48 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.fileEditor
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
import com.intellij.openapi.project.DumbAwareToggleAction
class EditorSplitGroup : DefaultActionGroup() {
override fun update(e: AnActionEvent) {
val editor = e.getEditorWithPreview()
e.presentation.isEnabledAndVisible = editor != null
if (editor != null) {
e.presentation.icon = TextEditorWithPreview.getEditorWithPreviewIcon(editor.isVerticalSplit)
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
}
abstract class ChangeEditorSplitAction(private val myVerticalSplit: Boolean) : DumbAwareToggleAction() {
override fun isSelected(e: AnActionEvent): Boolean {
val editor = e.getEditorWithPreview() ?: return false
return editor.isVerticalSplit == myVerticalSplit
}
override fun setSelected(e: AnActionEvent, state: Boolean) {
if (state) {
val editor = e.getEditorWithPreview() ?: return
editor.isVerticalSplit = myVerticalSplit
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
}
private fun AnActionEvent.getEditorWithPreview(): TextEditorWithPreview? {
return getData(PlatformCoreDataKeys.FILE_EDITOR) as? TextEditorWithPreview
}
class SplitVerticallyAction : ChangeEditorSplitAction(false)
class SplitHorizontallyAction : ChangeEditorSplitAction(true)

View File

@@ -8,14 +8,11 @@ import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.impl.EditorComponentImpl;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.DumbAwareToggleAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
@@ -441,42 +438,12 @@ public class TextEditorWithPreview extends UserDataHolderBase implements TextEdi
@Override
public final @NotNull ActionGroup getTabActions() {
return new ConditionalActionGroup(createTabActions(), () -> isShowActionsInTabs());
AnAction[] actions = createTabActions();
return new ConditionalActionGroup(actions, () -> isShowActionsInTabs());
}
protected AnAction @NotNull [] createTabActions() {
return new AnAction[]{
//getSingleChangeViewModeAction(),
Separator.create(), //todo[konstantin.hudyakov] this separator will be hidden since toolbars can start with separator, but we need it according to mockups
getShowEditorAction(),
getShowEditorAndPreviewAction(),
getShowPreviewAction(),
Separator.create(),
//createTabViewModesPopupActionGroup()
};
}
private @NotNull ActionGroup createTabViewModesPopupActionGroup() {
ActionGroup group = createTabViewModesActionGroup();
group.setPopup(true);
Presentation presentation = group.getTemplatePresentation();
presentation.setText(IdeBundle.message("tab.view.modes"));
presentation.setIcon(AllIcons.General.ChevronDown);
presentation.putClientProperty(ActionButton.HIDE_DROPDOWN_ICON, Boolean.TRUE);
return group;
}
protected @NotNull ActionGroup createTabViewModesActionGroup() {
return new DefaultActionGroup(
createViewActionGroup(),
Separator.create(),
new ChangeEditorSplitAction(IdeBundle.message("tab.vertical.split"), false),
new ChangeEditorSplitAction(IdeBundle.message("tab.horizontal.split"), true)
);
}
protected @NotNull AnAction getSingleChangeViewModeAction() {
return new SingleChangeViewModeAction();
return createViewActionGroup().getChildren(null);
}
protected @NotNull ToggleAction getShowEditorAction() {
@@ -521,14 +488,18 @@ public class TextEditorWithPreview extends UserDataHolderBase implements TextEdi
if (this == SHOW_EDITOR) return AllIcons.General.LayoutEditorOnly;
if (this == SHOW_PREVIEW) return AllIcons.General.LayoutPreviewOnly;
boolean isVerticalSplit = editor != null && editor.myIsVerticalSplit;
if (ExperimentalUI.isNewUI()) {
return isVerticalSplit ? IconLoader.getIcon("expui/general/editorPreviewVertical.svg", AllIcons.class)
: IconLoader.getIcon("expui/general/editorPreview.svg", AllIcons.class);
}
return isVerticalSplit ? AllIcons.Actions.PreviewDetailsVertically : AllIcons.Actions.PreviewDetails;
return getEditorWithPreviewIcon(isVerticalSplit);
}
}
public static Icon getEditorWithPreviewIcon(boolean isVerticalSplit) {
if (ExperimentalUI.isNewUI()) {
return isVerticalSplit ? IconLoader.getIcon("expui/general/editorPreviewVertical.svg", AllIcons.class)
: IconLoader.getIcon("expui/general/editorPreview.svg", AllIcons.class);
}
return isVerticalSplit ? AllIcons.Actions.PreviewDetailsVertically : AllIcons.Actions.PreviewDetails;
}
private class ChangeViewModeAction extends ToggleAction implements DumbAware {
private final Layout myActionLayout;
@@ -566,62 +537,6 @@ public class TextEditorWithPreview extends UserDataHolderBase implements TextEdi
}
}
private class SingleChangeViewModeAction extends DumbAwareAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
setLayout(getTargetLayout());
}
@Override
public void update(@NotNull AnActionEvent e) {
Layout targetLayout = getTargetLayout();
Presentation presentation = e.getPresentation();
presentation.setIcon(targetLayout.getIcon(TextEditorWithPreview.this));
presentation.setText(targetLayout.getName());
presentation.setDescription(targetLayout.getName());
}
private @NotNull Layout getTargetLayout() {
Layout curLayout = getLayout();
return switch (curLayout) {
case SHOW_EDITOR, SHOW_PREVIEW -> Layout.SHOW_EDITOR_AND_PREVIEW;
case SHOW_EDITOR_AND_PREVIEW -> Layout.SHOW_EDITOR;
};
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
}
private class ChangeEditorSplitAction extends DumbAwareToggleAction {
private final boolean myVerticalSplit;
protected ChangeEditorSplitAction(@Nls String text, boolean isVerticalSplit) {
super(text);
myVerticalSplit = isVerticalSplit;
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
return TextEditorWithPreview.this.myIsVerticalSplit == myVerticalSplit;
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
if (state) {
TextEditorWithPreview.this.myIsVerticalSplit = myVerticalSplit;
mySplitter.setOrientation(myVerticalSplit);
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
}
private static class ConditionalActionGroup extends ActionGroup {
private final AnAction[] myActions;
private final Supplier<Boolean> myCondition;

View File

@@ -2065,6 +2065,9 @@ action.ToolwindowSwitcher.text=Toolwindow Switcher
action.QuickDocCopy.text=Copy Quick Doc
action.OpenElementInNewWindow.text=Open In New Editor Window
action.ForceRefresh.text=Force Refresh
group.TextEditorWithPreview.SplitGroup.text=Split Layout
action.TextEditorWithPreview.SplitVertically.text=Vertical layout
action.TextEditorWithPreview.SplitHorizontally.text=Horizontal layout
action.Diff.OpenDiffInEditor.text=Open Selected Diff Request as Editor Tab
action.Diff.ShowSettingsPopup.text=Show Diff Settings Popup...
action.Diff.ShowInExternalTool.text=Show Diff in External Tool

View File

@@ -339,6 +339,11 @@
<action id="Refresh" class="com.intellij.ide.actions.RefreshAction" icon="AllIcons.Actions.Refresh"/>
<action id="ForceRefresh" class="com.intellij.openapi.actionSystem.EmptyAction" icon="AllIcons.Actions.ForceRefresh"/>
<group id="TextEditorWithPreview.SplitGroup" popup="true" class="com.intellij.openapi.fileEditor.EditorSplitGroup">
<action id="TextEditorWithPreview.SplitVertically" class="com.intellij.openapi.fileEditor.SplitVerticallyAction"/>
<action id="TextEditorWithPreview.SplitHorizontally" class="com.intellij.openapi.fileEditor.SplitHorizontallyAction"/>
</group>
<group id="Diff.KeymapGroup" searchable="false">
<action id="Diff.ShowDiff" class="com.intellij.diff.actions.ShowDiffAction"
icon="AllIcons.Actions.Diff"/> <!-- CommonShortcuts.getDiff() -->