From 9d4f8920597b31b4b3149c5a0ec7849d4b2ed4be Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Tue, 20 Mar 2018 21:02:35 +0300 Subject: [PATCH] IDEA-186805 Rework plugin page for settings dialog: design review --- .../src/com/intellij/ui/SearchTextField.java | 4 + .../components/breadcrumbs/Breadcrumbs.java | 23 ++ .../fields/ExtendableTextField.java | 4 + .../plugins/PluginManagerConfigurableNew.java | 309 ++++++++++++------ .../ui/TextFieldWithPopupHandlerUI.java | 9 + .../options/newEditor/SettingsEditor.java | 25 +- .../src/META-INF/PlatformExtensions.xml | 2 +- 7 files changed, 260 insertions(+), 116 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/SearchTextField.java b/platform/platform-api/src/com/intellij/ui/SearchTextField.java index 2753ce1d7fe6..0aa61e136b26 100644 --- a/platform/platform-api/src/com/intellij/ui/SearchTextField.java +++ b/platform/platform-api/src/com/intellij/ui/SearchTextField.java @@ -127,6 +127,10 @@ public class SearchTextField extends JPanel { protected Rectangle getEmptyTextComponentBounds(Rectangle bounds) { if (isSearchControlUISupported()) { int offset = JBUI.scale(15); + Integer gap = (Integer)getClientProperty("JTextField.Search.Gap"); + if (gap != null) { + offset += gap; + } bounds.x += offset; bounds.width -= 2 * offset; } diff --git a/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java b/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java index 23812d79d8df..8c1c2d0a6cf1 100644 --- a/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java +++ b/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java @@ -133,6 +133,10 @@ public class Breadcrumbs extends JBPanelWithEmptyText { repaint(); } + public int getBaseline() { + return views.isEmpty() ? 0 : views.get(0).getBaseline(); + } + @Override public String getToolTipText(MouseEvent event) { return hovered == null ? null : hovered.getTooltip(); @@ -422,6 +426,25 @@ public class Breadcrumbs extends JBPanelWithEmptyText { return crumb != null && (path != null ? path.contains(x, y) : bounds.contains(x, y)); } + private int getBaseline() { + if (font == null) { + update(); + } + + FontMetrics fm = getFontMetrics(font); + if (fm != null) { + Rectangle textR = new Rectangle(); + int scale = getScale(); + String text = layout(fm, new Rectangle(), textR, getBounds(scale * LEFT_RIGHT, scale * TOP_BOTTOM)); + + if (!StringUtil.isEmpty(text)) { + return textR.y + fm.getAscent(); + } + } + + return 0; + } + private void paint(Graphics2D g) { int scale = getScale(); if (path != null) { diff --git a/platform/platform-api/src/com/intellij/ui/components/fields/ExtendableTextField.java b/platform/platform-api/src/com/intellij/ui/components/fields/ExtendableTextField.java index d4589a10d62a..21e76ee52a0f 100644 --- a/platform/platform-api/src/com/intellij/ui/components/fields/ExtendableTextField.java +++ b/platform/platform-api/src/com/intellij/ui/components/fields/ExtendableTextField.java @@ -96,6 +96,10 @@ public class ExtendableTextField extends JBTextField { return getIconGap() + Math.max(icon1.getIconWidth(), icon2.getIconWidth()); } + default int getBeforeIconOffset() { + return 0; + } + default boolean isIconBeforeText() { return false; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java index 3343add24b3a..abacf2358307 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java @@ -4,7 +4,6 @@ package com.intellij.ide.plugins; import com.intellij.icons.AllIcons; import com.intellij.ide.HelpTooltip; import com.intellij.ide.IdeBundle; -import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -24,6 +23,7 @@ import com.intellij.ui.components.JBOptionButton; import com.intellij.ui.components.JBPanelWithEmptyText; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.JBTextField; +import com.intellij.ui.components.breadcrumbs.Breadcrumbs; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; import com.intellij.ui.components.panels.NonOpaquePanel; @@ -53,8 +53,6 @@ import java.util.*; import java.util.List; import java.util.regex.Pattern; -import static java.lang.System.out; - /** * @author Alexander Lobas */ @@ -62,7 +60,6 @@ public class PluginManagerConfigurableNew extends BaseConfigurable implements SearchableConfigurable, Configurable.NoScroll, Configurable.NoMargin, Configurable.TopComponentProvider, OptionalConfigurable { public static final String ID = "preferences.pluginManager2"; - public static final String DISPLAY_NAME = "Plugins (New Design)"; //IdeBundle.message("title.plugins"); private static final String SELECTION_TAB_KEY = "PluginConfigurable.selectionTab"; @@ -70,8 +67,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable private static final DecimalFormat K_FORMAT = new DecimalFormat("###.#K"); private static final DecimalFormat M_FORMAT = new DecimalFormat("###.#M"); - private static final String LONG_LONG_DESCRIPTION = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."; + @SuppressWarnings("UseJBColor") + private static final Color MAIN_BG_COLOR = new JBColor(() -> JBColor.isBright() ? UIUtil.getListBackground() : new Color(0x313335)); private final TagBuilder myTagBuilder; @@ -89,6 +86,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @Override public TagComponent createTagComponent(@NotNull String tag) { Color color; + String tooltip = null; if ("graphics".equals(tag)) { color = new JBColor(0xEFE4CE, 0x5E584B); } @@ -97,12 +95,12 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } else if ("EAP".equals(tag)) { color = new JBColor(0xF2D2CF, 0xF2D2CF); + tooltip = "The EAP version does not guarantee the stability\nand availability of the plugin."; } else { color = new JBColor(0xEAEAEC, 0x4D4D4D); } - String tooltip = "The EAP version does not guarantee the stability\nand availability of the plugin."; return new TagComponent(tag, tooltip, color); } @@ -121,6 +119,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return size; } }; + mySearchTextField.getTextEditor().putClientProperty("JTextField.Search.Gap", JBUI.scale(8)); + mySearchTextField.getTextEditor().setBackground(MAIN_BG_COLOR); } @NotNull @@ -132,7 +132,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @Nls @Override public String getDisplayName() { - return DISPLAY_NAME; + return IdeBundle.message("title.plugins"); } @Override @@ -144,6 +144,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @Override public JComponent createComponent() { JPanel panel = new JPanel(new BorderLayout()); + panel.setMinimumSize(new Dimension(JBUI.scale(580), -1)); DefaultActionGroup actions = new DefaultActionGroup(); actions.add(new DumbAwareAction("Manage Plugin Repositories...") { @@ -305,26 +306,34 @@ public class PluginManagerConfigurableNew extends BaseConfigurable downloaded.descriptors.addAll(InstalledPluginsState.getInstance().getInstalledPlugins()); ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx(); + int bundledEnabled = 0; + int downloadedEnabled = 0; for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) { if (!appInfo.isEssentialPlugin(descriptor.getPluginId().getIdString())) { if (descriptor.isBundled()) { bundled.descriptors.add(descriptor); + if (descriptor.isEnabled()) { + bundledEnabled++; + } } else { downloaded.descriptors.add(descriptor); + if (descriptor.isEnabled()) { + downloadedEnabled++; + } } } } if (!downloaded.descriptors.isEmpty()) { downloaded.sortByName(); - downloaded.titleWithCount("Downloaded"); + downloaded.titleWithCount("Downloaded", downloadedEnabled); panel.addGroup(downloaded); } bundled.sortByName(); - bundled.titleWithCount("Bundled"); + bundled.titleWithCount("Bundled", bundledEnabled); panel.addGroup(bundled); return createScrollPane(panel); @@ -369,24 +378,26 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @NotNull private JComponent createDetailsPanel(@NotNull IdeaPluginDescriptor plugin, boolean update) { - JPanel panel = new OpaquePanel(new BorderLayout(0, offset5()), mySearchTextField.getTextEditor().getBackground()); - panel.setBorder(JBUI.Borders.empty(15, 20)); + JPanel panel = new OpaquePanel(new BorderLayout(0, JBUI.scale(32)), mySearchTextField.getTextEditor().getBackground()); + panel.setBorder(JBUI.Borders.empty(15, 20, 0, 0)); - JPanel header = new NonOpaquePanel(new BorderLayout(offset5(), 0)); + JPanel header = new NonOpaquePanel(new BorderLayout(JBUI.scale(20), 0)); + header.setBorder(JBUI.Borders.emptyRight(20)); - JLabel myIconLabel = new JLabel(AllIcons.Plugins.PluginLogo_80); - myIconLabel.setDisabledIcon(AllIcons.Plugins.PluginLogoDisabled_80); - myIconLabel.setVerticalAlignment(SwingConstants.TOP); - myIconLabel.setOpaque(false); - myIconLabel.setEnabled(plugin.isEnabled()); - header.add(myIconLabel, BorderLayout.WEST); + JLabel iconLabel = new JLabel(AllIcons.Plugins.PluginLogo_80); + iconLabel.setDisabledIcon(AllIcons.Plugins.PluginLogoDisabled_80); + iconLabel.setVerticalAlignment(SwingConstants.TOP); + iconLabel.setOpaque(false); + iconLabel.setEnabled(plugin.isEnabled()); + header.add(iconLabel, BorderLayout.WEST); JPanel centerPanel = new NonOpaquePanel(new VerticalLayout(offset5())); header.add(centerPanel); boolean bundled = plugin.isBundled(); - JPanel buttons = new NonOpaquePanel(new HorizontalLayout(offset5())); + JPanel buttons = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(6))); + buttons.setBorder(JBUI.Borders.emptyTop(1)); if (update) { buttons.add(new UpdateButton()); } @@ -394,13 +405,14 @@ public class PluginManagerConfigurableNew extends BaseConfigurable buttons.add(new InstallButton(true)); } else if (bundled) { - buttons.add(new JButton(plugin.isEnabled() ? "Disable" : "Enable")); + JButton button = new JButton(plugin.isEnabled() ? "Disable" : "Enable"); + setWidth72(button); + buttons.add(button); } else { AbstractAction enableDisableAction = new AbstractAction(plugin.isEnabled() ? "Disable" : "Enable") { @Override public void actionPerformed(ActionEvent e) { - out.println("d"); // TODO: Auto-generated method stub } }; @@ -413,9 +425,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable buttons.add(new MyOptionButton(enableDisableAction, uninstallAction)); } - Color background = UIUtil.getListBackground(); for (Component component : UIUtil.uiChildren(buttons)) { - component.setBackground(background); + component.setBackground(MAIN_BG_COLOR); } JPanel nameButtons = new NonOpaquePanel(new BorderLayout(offset5(), 0)); @@ -425,7 +436,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable nameComponent.setFont(font.deriveFont(Font.BOLD, 30)); } if (!plugin.isEnabled()) { - nameComponent.setForeground(DarculaButtonUI.getDisabledTextColor()); + nameComponent.setForeground(DisabledColor); } nameButtons.add(nameComponent, BorderLayout.WEST); nameButtons.add(buttons, BorderLayout.EAST); @@ -445,12 +456,12 @@ public class PluginManagerConfigurableNew extends BaseConfigurable int nameBaseline = nameComponent.getBaseline(nameComponent.getWidth(), nameComponent.getHeight()); int versionBaseline = versionComponent.getBaseline(versionComponent.getWidth(), versionComponent.getHeight()); - versionComponent.setBorder(JBUI.Borders.emptyTop(nameBaseline - versionBaseline + JBUI.scale(6))); + versionComponent.setBorder(JBUI.Borders.empty(nameBaseline - versionBaseline + JBUI.scale(6), 4, 0, 0)); } List tags = getTags(plugin); if (!tags.isEmpty()) { - NonOpaquePanel tagPanel = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(offset5()))); + NonOpaquePanel tagPanel = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(6))); centerPanel.add(tagPanel); for (String tag : tags) { @@ -465,7 +476,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable if (downloads != null || date != null || rating != null) { JPanel metrics = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(20))); - metrics.setBorder(JBUI.Borders.emptyTop(5)); + metrics.setBorder(JBUI.Borders.emptyTop(3)); centerPanel.add(metrics); if (date != null) { @@ -492,13 +503,16 @@ public class PluginManagerConfigurableNew extends BaseConfigurable panel.add(header, BorderLayout.NORTH); - String description = plugin.getDescription(); + String description = getDescriptionAndChangeNotes(plugin); String vendor = bundled ? null : plugin.getVendor(); String size = plugin instanceof PluginNode ? ((PluginNode)plugin).getSize() : null; if (!StringUtil.isEmptyOrSpaces(description) || !StringUtil.isEmptyOrSpaces(vendor) || !StringUtil.isEmptyOrSpaces(size)) { - JPanel bottomPanel = new OpaquePanel(new VerticalLayout(offset5()), background); + JPanel bottomPanel = new OpaquePanel(new VerticalLayout(offset5()), MAIN_BG_COLOR); + bottomPanel.setBorder(JBUI.Borders.emptyBottom(15)); + JBScrollPane scrollPane = new JBScrollPane(bottomPanel); + scrollPane.getVerticalScrollBar().setBackground(MAIN_BG_COLOR); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setBorder(null); panel.add(scrollPane); @@ -507,6 +521,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable JEditorPane descriptionComponent = new JEditorPane(); descriptionComponent.setEditorKit(UIUtil.getHTMLEditorKit()); descriptionComponent.setEditable(false); + descriptionComponent.setFocusable(false); descriptionComponent.setOpaque(false); descriptionComponent.setBorder(null); descriptionComponent.setText(XmlStringUtil.wrapInHtml(description)); @@ -544,6 +559,23 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return panel; } + @Nullable + private static String getDescriptionAndChangeNotes(@NotNull IdeaPluginDescriptor plugin) { + StringBuilder result = new StringBuilder(); + + String description = plugin.getDescription(); + if (!StringUtil.isEmptyOrSpaces(description)) { + result.append(description); + } + + String notes = plugin.getChangeNotes(); + if (!StringUtil.isEmptyOrSpaces(notes)) { + result.append("

Change Notes

").append(notes); + } + + return result.length() > 0 ? result.toString() : null; + } + @Override public boolean needDisplay() { return Registry.is("show.new.plugin.page"); // TODO: temp code for show page over registry @@ -612,7 +644,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return value < 1000000 ? K_FORMAT.format(value / 1000D) : M_FORMAT.format(value / 1000000D); } } - catch (NumberFormatException ignore) { } + catch (NumberFormatException ignore) { + } } return null; @@ -633,7 +666,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return StringUtil.trimEnd(rating, ".0"); } } - catch (NumberFormatException ignore) { } + catch (NumberFormatException ignore) { + } } return null; @@ -677,11 +711,13 @@ public class PluginManagerConfigurableNew extends BaseConfigurable private int mySelectionTab = -1; private int myHoverTab = -1; private SizeInfo mySizeInfo; + private int myBaselineY; + private Breadcrumbs myBreadcrumbs; public TabHeaderComponent(@NotNull DefaultActionGroup actions, @NotNull TabHeaderListener listener) { myListener = listener; add(myToolbarComponent = createToolbar(actions)); - setBackground(JBUI.CurrentTheme.ToolWindow.headerActiveBackground()); + setBackground(JBUI.CurrentTheme.ToolWindow.headerBackground()); setOpaque(true); MouseAdapter mouseHandler = new MouseAdapter() { @@ -744,7 +780,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable private int findTab(@NotNull MouseEvent event) { calculateSize(); - int x = (getWidth() - mySizeInfo.width) / 2; + int x = getStartX(); int height = getHeight(); int eventX = event.getX(); int eventY = event.getY(); @@ -770,16 +806,19 @@ public class PluginManagerConfigurableNew extends BaseConfigurable calculateSize(); FontMetrics fm = getFontMetrics(getFont()); - int x = (getWidth() - mySizeInfo.width) / 2; + int x = getStartX(); int height = getHeight(); int tabTitleY = fm.getAscent() + (height - fm.getHeight()) / 2; + if (myBreadcrumbs != null) { + tabTitleY = myBaselineY + myBreadcrumbs.getBaseline(); + } for (int i = 0, size = myTabs.size(); i < size; i++) { if (mySelectionTab == i || myHoverTab == i) { Rectangle bounds = mySizeInfo.tabs[i]; g.setColor(mySelectionTab == i - ? JBUI.CurrentTheme.ToolWindow.tabSelectedActiveBackground() - : JBUI.CurrentTheme.ToolWindow.tabHoveredActiveBackground()); + ? JBUI.CurrentTheme.ToolWindow.tabSelectedBackground() + : JBUI.CurrentTheme.ToolWindow.tabHoveredBackground()); g.fillRect(x + bounds.x, 0, bounds.width, height); g.setColor(getForeground()); } @@ -790,20 +829,32 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @Override public void setBounds(int x, int y, int width, int height) { - height = getParent().getHeight(); - super.setBounds(x, 0, width, height); + myBaselineY = y; + super.setBounds(x, 0, width, height += y); + + if (myBreadcrumbs == null) { + myBreadcrumbs = UIUtil.findComponentOfType((JComponent)getParent(), Breadcrumbs.class); + } calculateSize(); - int startX = (width - mySizeInfo.width) / 2; Dimension size = myToolbarComponent.getPreferredSize(); - myToolbarComponent.setBounds(startX + mySizeInfo.toolbarX, (height - size.height) / 2, size.width, size.height); + int toolbarY = (height - size.height) / 2; + if (myBreadcrumbs != null) { + toolbarY = (int)(myBaselineY + myBreadcrumbs.getBaseline() - size.height * 0.65); + } + + myToolbarComponent.setBounds(getStartX() + mySizeInfo.toolbarX, toolbarY, size.width, size.height); + } + + private int getStartX() { + return (getParent().getWidth() - mySizeInfo.width) / 2 - getX(); } @Override public Dimension getPreferredSize() { calculateSize(); - return new Dimension(mySizeInfo.width, JBUI.scale(35)); + return new Dimension(mySizeInfo.width, JBUI.scale(30)); } private void calculateSize() { @@ -817,7 +868,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable mySizeInfo.tabs = new Rectangle[size]; mySizeInfo.tabTitleX = new int[size]; - int offset = JBUI.scale(24); + int offset = JBUI.scale(22); int x = 0; FontMetrics fm = getFontMetrics(getFont()); @@ -829,8 +880,9 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } Dimension toolbarSize = myToolbarComponent.getPreferredSize(); - mySizeInfo.width = x + offset + toolbarSize.width + offset; - mySizeInfo.toolbarX = x + offset; + x += JBUI.scale(10); + mySizeInfo.width = x + toolbarSize.width; + mySizeInfo.toolbarX = x; } } @@ -843,7 +895,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable public int toolbarX; } - private class PluginsGroupComponent extends JBPanelWithEmptyText { + private static class PluginsGroupComponent extends JBPanelWithEmptyText { private final LinkListener myListener; private final Function myFunction; private final List myGroups = new ArrayList<>(); @@ -859,7 +911,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable myFunction = function; setOpaque(true); - setBackground(mySearchTextField.getTextEditor().getBackground()); + setBackground(MAIN_BG_COLOR); myMouseHandler = new MouseAdapter() { @Override @@ -914,8 +966,11 @@ public class PluginManagerConfigurableNew extends BaseConfigurable myGroups.add(uiGroup); OpaquePanel panel = new OpaquePanel(new BorderLayout(), new JBColor(0xF7F7F7, 0x3D3F41)); - panel.setBorder(JBUI.Borders.empty(4, 13, 5, 14)); - panel.add(new JLabel(group.title), BorderLayout.WEST); + panel.setBorder(JBUI.Borders.empty(4, 13)); + + JLabel title = new JLabel(group.title); + title.setForeground(new JBColor(0x787878, 0x999999)); + panel.add(title, BorderLayout.WEST); if (group.rightAction != null) { panel.add(group.rightAction, BorderLayout.EAST); @@ -930,12 +985,17 @@ public class PluginManagerConfigurableNew extends BaseConfigurable add(pluginComponent); pluginComponent.addMouseListeners(myMouseHandler); //noinspection unchecked + pluginComponent.myIconLabel.setListener(myListener, descriptor); + //noinspection unchecked pluginComponent.myName.setListener(myListener, descriptor); } } } private static class PluginsListLayout extends AbstractLayoutManager { + private final int myFirsVtOffset = JBUI.scale(6); + private final int myLastVOffset = JBUI.scale(18); + private int myLineHeight; @Override @@ -948,6 +1008,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable for (UIPluginGroup group : groups) { height += group.panel.getPreferredSize().height; height += group.plugins.size() * myLineHeight; + height += myFirsVtOffset + myLastVOffset; } return new Dimension(0, height); @@ -965,12 +1026,14 @@ public class PluginManagerConfigurableNew extends BaseConfigurable Component component = group.panel; int height = component.getPreferredSize().height; component.setBounds(0, y, width, height); - y += height; + y += height + myFirsVtOffset; for (CellPluginComponent plugin : group.plugins) { plugin.setBounds(0, y, width, myLineHeight); y += myLineHeight; } + + y += myLastVOffset; } } @@ -999,13 +1062,19 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } private static class PluginsGridLayout extends AbstractLayoutManager { + private final int myFirstVOffset = JBUI.scale(10); + private final int myMiddleVOffset = JBUI.scale(20); + private final int myLastVOffset = JBUI.scale(30); + private final int myMiddleHOffset = JBUI.scale(20); + private final Dimension myCellSize; @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") public PluginsGridLayout(@NotNull TagBuilder tagBuilder) { PluginNode pluginNode = new PluginNode(null, "Language Language Lang", null); - pluginNode.setDescription( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + pluginNode.setDescription("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " + + "incididunt ut labore et dolore magna aliqua Ut enim ad minim veniam, quis nostrud " + + "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); pluginNode.setCategory("languages"); pluginNode.setDate(String.valueOf(System.currentTimeMillis())); pluginNode.setDownloads("123456"); @@ -1014,19 +1083,18 @@ public class PluginManagerConfigurableNew extends BaseConfigurable component.doLayout(); myCellSize = component.getPreferredSize(); - myCellSize.height += offset5(); } @Override public Dimension preferredLayoutSize(Container parent) { int width = getParentWidth(parent); int cellWidth = myCellSize.width; - int columns = width / cellWidth; + int columns = width / (cellWidth + myMiddleHOffset); if (columns < 2) { columns = 2; } - width = columns * cellWidth; + width = columns * (cellWidth + myMiddleHOffset) - myMiddleHOffset; int height = 0; int cellHeight = myCellSize.height; @@ -1048,7 +1116,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } } - height += rows * cellHeight; + height += myFirstVOffset + rows * (cellHeight + myMiddleVOffset) - myMiddleVOffset + myLastVOffset; } return new Dimension(width, height); @@ -1065,7 +1133,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable Component component = group.panel; int height = component.getPreferredSize().height; component.setBounds(0, y, width, height); - y += height; + y += height + myFirstVOffset; y += layoutPlugins(group.plugins, y, columns); } } @@ -1077,17 +1145,19 @@ public class PluginManagerConfigurableNew extends BaseConfigurable int height = myCellSize.height; int column = 0; - for (int i = 0, size = plugins.size(); i < size; i++) { + for (int i = 0, size = plugins.size(), last = size - 1; i < size; i++) { plugins.get(i).setBounds(x, startY + y, width, height); - x += width; + x += width + myMiddleHOffset; - if (++column == columns || i == size - 1) { + if (++column == columns || i == last) { x = 0; - y += height; + y += height + myMiddleVOffset; column = 0; } } + y += (myLastVOffset - myMiddleVOffset); + return y; } } @@ -1121,6 +1191,10 @@ public class PluginManagerConfigurableNew extends BaseConfigurable title = text + " (" + descriptors.size() + ")"; } + public void titleWithCount(@NotNull String text, int enabled) { + title = text + " (" + enabled + " of " + descriptors.size() + " enabled)"; + } + public void sortByName() { ContainerUtil.sort(descriptors, Comparator.comparing(IdeaPluginDescriptor::getName)); } @@ -1134,7 +1208,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable private static abstract class CellPluginComponent extends JPanel { protected final IdeaPluginDescriptor myPlugin; - protected JLabel myIconLabel; + protected LinkLabel myIconLabel; protected LinkLabel myName; protected JEditorPane myDescription; @@ -1145,23 +1219,24 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } @NotNull - protected JPanel createPanel() { - return createPanel(this, this, 0); + protected JPanel createPanel(int offset) { + return createPanel(this, offset5(), offset, 0); } @NotNull - protected JPanel createPanel(@NotNull JPanel parent, @NotNull JPanel root, int width) { - parent.setLayout(new BorderLayout(offset5(), 0)); + protected JPanel createPanel(@NotNull JPanel parent, int hgap, int offset, int width) { + parent.setLayout(new BorderLayout(hgap, 0)); - myIconLabel = new JLabel(AllIcons.Plugins.PluginLogo_40); + myIconLabel = new LinkLabel(null, AllIcons.Plugins.PluginLogo_40); myIconLabel.setVerticalAlignment(SwingConstants.TOP); myIconLabel.setOpaque(false); parent.add(myIconLabel, BorderLayout.WEST); - JPanel centerPanel = new NonOpaquePanel(new VerticalLayout(offset5(), width)); + JPanel centerPanel = new NonOpaquePanel(new VerticalLayout(offset, width)); parent.add(centerPanel); - root.setOpaque(true); + setOpaque(true); + setBorder(JBUI.Borders.empty(10)); return centerPanel; } @@ -1190,9 +1265,9 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return new Dimension(width, height); } }; - myDescription.setEditorKit(UIUtil.getHTMLEditorKit()); myDescription.setEditorKit(new UIUtil.JBWordWrapHtmlEditorKit()); myDescription.setEditable(false); + myDescription.setFocusable(false); myDescription.setOpaque(false); myDescription.setBorder(null); myDescription.setText(XmlStringUtil.wrapInHtml(description)); @@ -1208,13 +1283,13 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return mySelection; } - private static final Color HOVER_COLOR = new JBColor(0xE9EEF5, 0xE9EEF5); + private static final Color HOVER_COLOR = new JBColor(0xE9EEF5, 0x464A4D); private static final Color GRAY_COLOR = new JBColor(Gray._130, Gray._120); public void setSelection(@NotNull SelectionType type) { mySelection = type; - updateColors(GRAY_COLOR, type == SelectionType.NONE ? UIUtil.getListBackground() : HOVER_COLOR); + updateColors(GRAY_COLOR, type == SelectionType.NONE ? MAIN_BG_COLOR : HOVER_COLOR); repaint(); } @@ -1229,6 +1304,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable public void addMouseListeners(@NotNull MouseAdapter listener) { addMouseListener(listener); addMouseMotionListener(listener); + myIconLabel.addMouseListener(listener); + myIconLabel.addMouseMotionListener(listener); myName.addMouseListener(listener); myName.addMouseMotionListener(listener); if (myDescription != null) { @@ -1240,6 +1317,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable public void removeMouseListeners(@NotNull MouseAdapter listener) { removeMouseListener(listener); removeMouseMotionListener(listener); + myIconLabel.removeMouseListener(listener); + myIconLabel.removeMouseMotionListener(listener); myName.removeMouseListener(listener); myName.removeMouseMotionListener(listener); if (myDescription != null) { @@ -1265,13 +1344,14 @@ public class PluginManagerConfigurableNew extends BaseConfigurable public ListPluginComponent(@NotNull IdeaPluginDescriptor plugin, boolean update) { super(plugin); - JPanel buttons = new NonOpaquePanel(new HorizontalLayout(offset5())); + JPanel buttons = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(6))); if (update) { myUpdateButton = new UpdateButton(); buttons.add(myUpdateButton); } if (plugin.isBundled()) { myEnableDisableButton = new JButton(plugin.isEnabled() ? "Disable" : "Enable"); + setWidth72(myEnableDisableButton); buttons.add(myEnableDisableButton); } else { @@ -1291,8 +1371,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable buttons.add(myEnableDisableUninstallButton); } - JPanel centerPanel = createPanel(); - setBorder(JBUI.Borders.empty(10)); + JPanel centerPanel = createPanel(0); JPanel nameButtons = new NonOpaquePanel(new BorderLayout()); nameButtons.add(buttons, BorderLayout.EAST); @@ -1301,6 +1380,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable myIconLabel.setDisabledIcon(AllIcons.Plugins.PluginLogoDisabled_40); addNameComponent(nameButtons, BorderLayout.WEST); + myName.setVerticalAlignment(SwingConstants.TOP); if (update) { addDescriptionComponent(centerPanel, getChangeNotes(plugin), pane -> { @@ -1326,7 +1406,6 @@ public class PluginManagerConfigurableNew extends BaseConfigurable }); } else { - addDescriptionComponent(centerPanel, getShortDescription(plugin), null); } @@ -1336,7 +1415,22 @@ public class PluginManagerConfigurableNew extends BaseConfigurable if (version != null || date != null) { int offset = JBUI.scale(8); - JPanel panel = new NonOpaquePanel(new HorizontalLayout(offset)); + JPanel panel = new NonOpaquePanel(new HorizontalLayout(offset) { + @Override + public void layoutContainer(Container parent) { + Insets insets = parent.getInsets(); + int x = insets.left; + int y = insets.top + myName.getBaseline(myName.getWidth(), myName.getHeight()); + int count = parent.getComponentCount(); + + for (int i = 0; i < count; i++) { + Component component = parent.getComponent(i); + Dimension size = component.getPreferredSize(); + component.setBounds(x, y - component.getBaseline(size.width, size.height), size.width, size.height); + x += size.width + offset; + } + } + }); panel.setBorder(JBUI.Borders.emptyLeft(offset)); nameButtons.add(panel, BorderLayout.CENTER); @@ -1376,10 +1470,9 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } if (mySelection == SelectionType.NONE && !myPlugin.isEnabled()) { - Color disabledColor = DarculaButtonUI.getDisabledTextColor(); - myName.setForeground(disabledColor); + myName.setForeground(DisabledColor); if (myDescription != null) { - myDescription.setForeground(disabledColor); + myDescription.setForeground(DisabledColor); } } @@ -1442,8 +1535,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable super(plugin); JPanel container = new NonOpaquePanel(); - JPanel centerPanel = createPanel(container, this, JBUI.scale(180)); - setBorder(JBUI.Borders.empty(10, 10, 20, 10)); + JPanel centerPanel = createPanel(container, JBUI.scale(10), offset5(), JBUI.scale(180)); addNameComponent(centerPanel, null); addTags(centerPanel, tagBuilder); @@ -1455,7 +1547,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable String rating = getRating(myPlugin); if (downloads != null || date != null || rating != null) { - JPanel panel = new NonOpaquePanel(new HorizontalLayout(offset5())); + JPanel panel = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(7))); centerPanel.add(panel); if (date != null) { @@ -1486,6 +1578,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable @Override public Dimension preferredLayoutSize(Container parent) { Dimension size = container.getPreferredSize(); + size.height += offset5(); size.height += myInstallButton.getPreferredSize().height; JBInsets.addTo(size, parent.getInsets()); return size; @@ -1503,7 +1596,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable Dimension buttonSize = myInstallButton.getPreferredSize(); Border border = myInstallButton.getBorder(); int borderOffset = border == null ? 0 : border.getBorderInsets(myInstallButton).left; - myInstallButton.setBounds(bounds.x + location.x - borderOffset, bounds.y + bounds.height, buttonSize.width, buttonSize.height); + myInstallButton + .setBounds(bounds.x + location.x - borderOffset, bounds.y + offset5() + bounds.height, buttonSize.width, buttonSize.height); } }); @@ -1516,7 +1610,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable return; } - NonOpaquePanel panel = new NonOpaquePanel(new HorizontalLayout(offset5())); + NonOpaquePanel panel = new NonOpaquePanel(new HorizontalLayout(JBUI.scale(6))); parent.add(panel); myTagComponents = new ArrayList<>(); @@ -1591,10 +1685,11 @@ public class PluginManagerConfigurableNew extends BaseConfigurable if (tooltip != null) { setToolTipText(tooltip); } + setForeground(new JBColor(0x787878, 0xBBBBBB)); setBackground(color); setPaintUnderline(false); setOpaque(true); - setBorder(JBUI.Borders.empty(2, 5)); + setBorder(JBUI.Borders.empty(2)); } } @@ -1606,16 +1701,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable private static class MyOptionButton extends JBOptionButton { public MyOptionButton(Action action, Action option) { super(action, new Action[]{option}); - } - - @Override - public Dimension getPreferredSize() { - Dimension size = super.getPreferredSize(); - Object width = getClientProperty("ExtraWidth"); - if (width instanceof Integer) { - size.width += (int)width; - } - return size; + setWidth72(this); } @Override @@ -1649,8 +1735,9 @@ public class PluginManagerConfigurableNew extends BaseConfigurable width += (count - 1) * myOffset; - Insets insets = parent.getInsets(); - return new Dimension(width, height + insets.top + insets.bottom); + Dimension size = new Dimension(width, height); + JBInsets.addTo(size, parent.getInsets()); + return size; } @Override @@ -1711,7 +1798,9 @@ public class PluginManagerConfigurableNew extends BaseConfigurable height += (count - 1) * myOffset; - return new Dimension(myWidth > 0 ? myWidth : width, height); + Dimension size = new Dimension(myWidth > 0 ? myWidth : width, height); + JBInsets.addTo(size, parent.getInsets()); + return size; } @Override @@ -1730,6 +1819,8 @@ public class PluginManagerConfigurableNew extends BaseConfigurable } } + private static final Color DisabledColor = new JBColor(0xC6C6C6, 0x575859); + @SuppressWarnings("UseJBColor") private static final Color WhiteForeground = new JBColor(Color.white, new Color(0xBBBBBB)); @SuppressWarnings("UseJBColor") @@ -1746,7 +1837,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable setBorderColor(BlueColor); setText("Update"); - addWidth(10); + setWidth72(this); } } @@ -1782,7 +1873,7 @@ public class PluginManagerConfigurableNew extends BaseConfigurable protected void setTextAndSize() { setText("Install"); - addWidth(20); + setWidth72(this); } } @@ -1814,11 +1905,21 @@ public class PluginManagerConfigurableNew extends BaseConfigurable protected final void setFocusedBorderColor(@NotNull Color color) { putClientProperty("JButton.focusedBorderColor", color); } + } - protected final void addWidth(int width) { - Dimension size = getPreferredSize(); - setPreferredSize(new Dimension(size.width + JBUI.scale(width), size.height)); + private static void setWidth72(@NotNull JButton button) { + int width = JBUI.scale(72); + if (button instanceof JBOptionButton && button.getComponentCount() == 2) { + width += button.getComponent(1).getPreferredSize().width; } + else { + Border border = button.getBorder(); + if (border != null) { + Insets insets = border.getBorderInsets(button); + width += insets.left + insets.right; + } + } + button.setPreferredSize(new Dimension(width, button.getPreferredSize().height)); } @Nullable diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java index 43b035c4f7a6..6c2782f0429e 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java @@ -146,6 +146,9 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple for (IconHolder holder : icons.values()) { int gap = holder.extension.getIconGap(); if (holder.extension.isIconBeforeText()) { + int offset = holder.extension.getBeforeIconOffset(); + bounds.x += offset; + bounds.width -= offset; holder.bounds.x = bounds.x; bounds.width -= holder.bounds.width + gap; bounds.x += holder.bounds.width + gap; @@ -569,6 +572,12 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple return getSearchIcon(hovered, null != getActionOnClick()); } + @Override + public int getBeforeIconOffset() { + Integer gap = (Integer)getComponent().getClientProperty("JTextField.Search.Gap"); + return gap == null ? 0 : gap; + } + @Override public int getIconGap() { return getSearchIconGap(); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java index 6d6551791b72..972db47eac6e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LoadingDecorator; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.OnePixelSplitter; @@ -214,17 +215,19 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { myBanner.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 10)); mySearch.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); mySearchPanel.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); - mySearchPanel.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent event) { - Dimension size = myBanner.getPreferredSize(); - size.height = mySearchPanel.getHeight() - 5; - myBanner.setPreferredSize(size); - myBanner.setSize(size); - myBanner.revalidate(); - myBanner.repaint(); - } - }); + if (!Registry.is("show.new.plugin.page")) { + mySearchPanel.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent event) { + Dimension size = myBanner.getPreferredSize(); + size.height = mySearchPanel.getHeight() - 5; + myBanner.setPreferredSize(size); + myBanner.setSize(size); + myBanner.revalidate(); + myBanner.repaint(); + } + }); + } JComponent left = new JPanel(new BorderLayout()); left.add(BorderLayout.NORTH, mySearchPanel); left.add(BorderLayout.CENTER, myTreeView); diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 6f3bc2a8649f..432f23cf39c8 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -320,7 +320,7 @@ + displayName="Plugins2"/>