diff --git a/images/resources/META-INF/plugin.xml b/images/resources/META-INF/plugin.xml index 60a9d980caae..7801b010ae64 100644 --- a/images/resources/META-INF/plugin.xml +++ b/images/resources/META-INF/plugin.xml @@ -155,6 +155,8 @@ + + diff --git a/platform/platform-api/resources/messages/IdeBundle.properties b/platform/platform-api/resources/messages/IdeBundle.properties index 32a9f819710a..0e3de7d9ad0e 100644 --- a/platform/platform-api/resources/messages/IdeBundle.properties +++ b/platform/platform-api/resources/messages/IdeBundle.properties @@ -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. \ diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index cdb0051e613f..57f89d59433c 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -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; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/ChangeEditorSplitActions.kt b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ChangeEditorSplitActions.kt new file mode 100644 index 000000000000..f970420859ad --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ChangeEditorSplitActions.kt @@ -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) \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/TextEditorWithPreview.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/TextEditorWithPreview.java index b5cdc4649287..f8dce4dfec27 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/TextEditorWithPreview.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/TextEditorWithPreview.java @@ -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 myCondition; diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index ee2365921714..f0e78efd3176 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -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 diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index dd15e6b8286e..052d1d82a5c4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -339,6 +339,11 @@ + + + + +