From 019a70d9ee66cdd2f8de0dcb06e30e09e7da7538 Mon Sep 17 00:00:00 2001 From: Kirill Kirichenko Date: Mon, 1 Apr 2019 13:06:14 +0300 Subject: [PATCH] IDEA-200183 Add keys: row height for list and table --- .../searcheverywhere/SearchEverywhereUI.java | 17 ++++++- .../intellij/ui/ColoredListCellRenderer.java | 2 +- .../intellij/ui/GroupedElementsRenderer.java | 11 +++- .../intellij/ui/components/OnOffButton.java | 42 ++++++++++++---- .../src/com/intellij/ui/table/JBTable.java | 5 +- .../intellij/ide/ui/laf/LafManagerImpl.java | 4 +- .../ui/laf/darcula/ui/DarculaComboBoxUI.java | 50 +++++++++++++++++++ .../ui/NotificationsConfigurablePanel.java | 39 ++++++++++----- .../keymap/impl/ui/QuickListPanel.java | 8 ++- .../com/intellij/ui/plaf/beg/BegTableUI.java | 10 ++++ .../util/src/com/intellij/util/ui/UIUtil.java | 6 +++ 11 files changed, 163 insertions(+), 31 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java index 3bb3d42e2d1d..ca3ccf555446 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java @@ -43,6 +43,7 @@ import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBList; import com.intellij.ui.components.fields.ExtendableTextComponent; import com.intellij.ui.components.fields.ExtendableTextField; +import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.PopupUpdateProcessor; import com.intellij.usageView.UsageInfo; import com.intellij.usages.*; @@ -909,6 +910,13 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic .getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } + component = new NonOpaquePanel((JComponent)component) { + @Override + public Dimension getPreferredSize() { + return UIUtil.updateListRowHeight(super.getPreferredSize()); + } + }; + if (isAllTabSelected() && myListModel.isGroupFirstItem(index)) { component = groupTitleRenderer.withDisplayedData(contributor.getFullGroupName(), component); } @@ -916,14 +924,14 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic return wrap(component, 1, 0); } - private Component wrap(Component cmp, int verticalGap, int hotizontalGap) { + private Component wrap(Component cmp, int verticalGap, int horizontalGap) { JPanel panel = new JPanel(new BorderLayout()); panel.setOpaque(cmp.isOpaque()); if (cmp.isOpaque()) { panel.setBackground(cmp.getBackground()); } panel.add(cmp, BorderLayout.CENTER); - panel.setBorder(JBUI.Borders.empty(verticalGap, hotizontalGap)); + panel.setBorder(JBUI.Borders.empty(verticalGap, horizontalGap)); return panel; } } @@ -961,6 +969,11 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic setBackground(UIUtil.getListBackground(isSelected)); return this; } + + @Override + public Dimension getPreferredSize() { + return UIUtil.updateListRowHeight(super.getPreferredSize()); + } } private final GroupTitleRenderer groupTitleRenderer = new GroupTitleRenderer(); diff --git a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java index d2fd9694a872..3946a8bcd3fc 100644 --- a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java @@ -92,7 +92,7 @@ public abstract class ColoredListCellRenderer extends SimpleColoredComponent setFont(null); } - return result; + return UIUtil.updateListRowHeight(result); } protected abstract void customizeCellRenderer(@NotNull JList list, T value, int index, boolean selected, boolean hasFocus); diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java index ec2a985849da..d8f1670ba9e9 100644 --- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java @@ -13,6 +13,7 @@ // limitations under the License. package com.intellij.ui; +import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.components.panels.OpaquePanel; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.accessibility.AccessibleContextUtil; @@ -101,7 +102,15 @@ public abstract class GroupedElementsRenderer { @Override protected void layout() { myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH); - myRendererComponent.add(myComponent, BorderLayout.CENTER); + + JComponent centerComponent = new NonOpaquePanel(myComponent) { + @Override + public Dimension getPreferredSize() { + return UIUtil.updateListRowHeight(super.getPreferredSize()); + } + }; + + myRendererComponent.add(centerComponent, BorderLayout.CENTER); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java b/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java index 5a25af39aeba..0f54f1498861 100644 --- a/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java +++ b/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java @@ -74,7 +74,7 @@ public class OnOffButton extends JToggleButton { private static final Color BORDER_COLOR = JBColor.namedColor("ToggleButton.borderColor", new JBColor(Gray._192, Gray._80)); private static final Color BUTTON_COLOR = JBColor.namedColor("ToggleButton.buttonColor", new JBColor(Gray._200, Gray._100)); private static final Color ON_BACKGROUND = JBColor.namedColor("ToggleButton.onBackground", new JBColor(new Color(74, 146, 73), new Color(77, 105, 76))); - private static final Color ON_FOREGROUND = JBColor.namedColor("ToggleButton.onForeground", new JBColor(() -> UIUtil.getListForeground(true))); + private static final Color ON_FOREGROUND = JBColor.namedColor("ToggleButton.onForeground", new JBColor(() -> UIUtil.getListForeground(true, true))); private static final Color OFF_BACKGROUND = JBColor.namedColor("ToggleButton.offBackground", new JBColor(() -> UIUtil.getPanelBackground())); private static final Color OFF_FOREGROUND = JBColor.namedColor("ToggleButton.offForeground", new JBColor(() -> UIUtil.getLabelDisabledForeground())); @@ -108,7 +108,6 @@ public class OnOffButton extends JToggleButton { int buttonArc = JBUI.scale(5); int vGap = JBUI.scale(4); int hGap = JBUI.scale(3); - int border = 1; OnOffButton button = (OnOffButton)c; Dimension size = button.getSize(); @@ -119,7 +118,6 @@ public class OnOffButton extends JToggleButton { } Graphics2D g2 = (Graphics2D)g.create(); - try { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int xOff = (button.getWidth() - w) / 2; @@ -133,22 +131,46 @@ public class OnOffButton extends JToggleButton { g2.setColor(BORDER_COLOR); g2.drawRoundRect(0, 0, w, h, buttonArc, buttonArc); + int knobWidth = w - SwingUtilities.computeStringWidth(g2.getFontMetrics(), button.getOffText()) - JBUI.scale(2); + knobWidth = knobWidth > h ? h : knobWidth; + + int textAscent = g2.getFontMetrics().getAscent(); + + Rectangle viewRect = new Rectangle(); + Rectangle textRect = new Rectangle(); + Rectangle iconRect = new Rectangle(); + + g2.setColor(BUTTON_COLOR); if (selected) { - g2.setColor(BUTTON_COLOR); - g2.fillRoundRect(w - h, border, h, h - border, toggleArc, toggleArc); + g2.fillRoundRect(w - knobWidth, 0, knobWidth, h, toggleArc, toggleArc); + + viewRect.setBounds(0, 0, w - knobWidth, h); + SwingUtilities.layoutCompoundLabel(g2.getFontMetrics(), + button.getOnText(), + null, + SwingConstants.CENTER, SwingConstants.CENTER, + SwingConstants.CENTER, SwingConstants.CENTER, + viewRect, iconRect, textRect, 0); g2.setColor(ON_FOREGROUND); - g2.drawString(button.getOnText(), h / 2, h - vGap); + g2.drawString(button.getOnText(), textRect.x, textRect.y + textAscent); } else { + g2.fillRoundRect(0, 0, knobWidth, h, toggleArc, toggleArc); - g2.setColor(BUTTON_COLOR); - g2.fillRoundRect(0, 0, h, h, toggleArc, toggleArc); + viewRect.setBounds(knobWidth, 0, w - knobWidth, h); + SwingUtilities.layoutCompoundLabel(g2.getFontMetrics(), + button.getOffText(), + null, + SwingConstants.CENTER, SwingConstants.CENTER, + SwingConstants.CENTER, SwingConstants.CENTER, + viewRect, iconRect, textRect, 0); g2.setColor(OFF_FOREGROUND); - g2.drawString(button.getOffText(), h + vGap, h - vGap); + g2.drawString(button.getOffText(), textRect.x, textRect.y + textAscent); } - } finally { + } + finally { g2.dispose(); } } diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index dce29a0c57e8..ec5dd4e0aa63 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -176,8 +176,9 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component @Override public int getRowHeight() { + int height = super.getRowHeight(); if (myRowHeightIsComputing) { - return super.getRowHeight(); + return height; } if (myRowHeight < 0) { @@ -194,7 +195,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component myMinRowHeight = getFontMetrics(UIManager.getFont("Label.font")).getHeight(); } - return Math.max(myRowHeight, myMinRowHeight); + return Math.max(myRowHeight, Math.max(myMinRowHeight, height)); } protected int calculateRowHeight() { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index 2a6c3ee410ce..5c3263124de3 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -557,7 +557,9 @@ public final class LafManagerImpl extends LafManager implements PersistentStateC List myIntKeys = Arrays.asList("Tree.leftChildIndent", "Tree.rightChildIndent", - "Tree.rowHeight"); + "Tree.rowHeight", + "Table.rowHeight", + "List.rowHeight"); List myDimensionKeys = Arrays.asList("Slider.horizontalSize", "Slider.verticalSize", diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index 2c0e6f4b2f69..3edeae92a863 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -8,6 +8,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.EditorTextField; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -25,6 +26,7 @@ import java.awt.event.*; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import static com.intellij.ide.ui.laf.darcula.DarculaUIUtil.*; @@ -604,5 +606,53 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB } super.show(invoker, x, y); } + + @Override + protected void configureList() { + super.configureList(); + wrapRenderer(); + } + @Override + + protected PropertyChangeListener createPropertyChangeListener() { + PropertyChangeListener listener = super.createPropertyChangeListener(); + return new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + listener.propertyChange(evt); + if ("renderer".equals(evt.getPropertyName())) { + wrapRenderer(); + } + } + }; + } + + @SuppressWarnings("unchecked") + private void wrapRenderer() { + ListCellRenderer renderer = list.getCellRenderer(); + if (!(renderer instanceof ComboBoxRendererWrapper) && renderer != null) { + list.setCellRenderer(new ComboBoxRendererWrapper(renderer)); + } + } } + + private static class ComboBoxRendererWrapper implements ListCellRenderer { + private final ListCellRenderer myRenderer; + + ComboBoxRendererWrapper(@NotNull ListCellRenderer renderer) { + myRenderer = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = myRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + return new NonOpaquePanel((JComponent)c) { + @Override + public Dimension getPreferredSize() { + return UIUtil.updateListRowHeight(super.getPreferredSize()); + } + }; + } + } + } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java index 64ab18d7174c..96b49943b15e 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java @@ -19,6 +19,7 @@ import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.ui.treeStructure.treetable.TreeTableModel; import com.intellij.util.ObjectUtils; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.IndexTreePathState; import com.intellij.util.ui.tree.TreeUtil; @@ -189,13 +190,13 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable setSelectionMode(ListSelectionModel.SINGLE_SELECTION); getTree().setCellRenderer(new TreeColumnCellRenderer(this)); - final TableColumn idColumn = getColumnModel().getColumn(ID_COLUMN); - idColumn.setPreferredWidth(200); + initColumns(); + } - final TableColumn displayTypeColumn = getColumnModel().getColumn(DISPLAY_TYPE_COLUMN); - displayTypeColumn.setMaxWidth(300); - displayTypeColumn.setPreferredWidth(250); - displayTypeColumn.setCellRenderer(new ComboBoxTableRenderer(NotificationDisplayType.values()) { + private void initColumns() { + TableColumn displayTypeColumn = getColumnModel().getColumn(DISPLAY_TYPE_COLUMN); + ComboBoxTableRenderer displayTypeRenderer = + new ComboBoxTableRenderer(NotificationDisplayType.values()) { @Override protected void customizeComponent(NotificationDisplayType value, JTable table, boolean isSelected) { super.customizeComponent(myDisplayBalloons.isSelected() ? value : NotificationDisplayType.NONE, table, isSelected); @@ -209,7 +210,8 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable protected String getTextFor(@NotNull NotificationDisplayType value) { return value.getTitle(); } - }); + }; + displayTypeColumn.setCellRenderer(displayTypeRenderer); displayTypeColumn.setCellEditor(new ComboBoxTableRenderer(NotificationDisplayType.values()) { @Override @@ -240,14 +242,13 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable } }); - final TableColumn logColumn = getColumnModel().getColumn(LOG_COLUMN); - logColumn.setMaxWidth(logColumn.getPreferredWidth()); - logColumn.setCellRenderer(new BooleanTableCellRenderer()); + displayTypeColumn.setPreferredWidth(displayTypeRenderer.getPreferredSize().width); + displayTypeColumn.setMaxWidth(displayTypeRenderer.getMinimumSize().width); + + initBooleanColumn(LOG_COLUMN); if (SystemInfo.isMac) { - final TableColumn readAloudColumn = getColumnModel().getColumn(READ_ALOUD_COLUMN); - readAloudColumn.setMaxWidth(readAloudColumn.getPreferredWidth()); - readAloudColumn.setCellRenderer(new BooleanTableCellRenderer()); + initBooleanColumn(READ_ALOUD_COLUMN); } new TableSpeedSearch(this); @@ -255,6 +256,18 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable TreeUtil.expandAll(getTree()); } + private void initBooleanColumn(int columnIndex) { + TableColumn column = getColumnModel().getColumn(columnIndex); + BooleanTableCellRenderer renderer = new BooleanTableCellRenderer(); + column.setCellRenderer(renderer); + + Dimension headerSize = getTableHeader().getDefaultRenderer(). + getTableCellRendererComponent(this, getModel().getColumnName(columnIndex), false, false, 0, columnIndex). + getPreferredSize(); + + column.setMaxWidth(Math.max(JBUI.scale(65), Math.max(headerSize.width, renderer.getPreferredSize().width))); + } + @Override public Dimension getMinimumSize() { return calcSize(super.getMinimumSize()); diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java index 05c3c583c834..f048df568c2f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java @@ -29,6 +29,7 @@ import com.intellij.ui.CollectionListModel; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -172,5 +173,10 @@ class QuickListPanel { return this; } - } + + @Override + public Dimension getPreferredSize() { + return UIUtil.updateListRowHeight(super.getPreferredSize()); + } + } } diff --git a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java index 995cbb6e161c..7d03b2101bd9 100644 --- a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java +++ b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java @@ -46,6 +46,16 @@ public class BegTableUI extends BasicTableUI { c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("pressed ESCAPE"), "cancel"); } + @Override + public void installDefaults() { + super.installDefaults(); + + int rowHeight = UIManager.getInt("Table.rowHeight"); + if (rowHeight > 0) { + LookAndFeel.installProperty(table, "rowHeight", rowHeight); + } + } + @Override protected KeyListener createKeyListener() { return myAdapter; diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index e492465bd852..9d96233924a1 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -4612,6 +4612,12 @@ public class UIUtil { return isUnderDefaultMacTheme() && alpha >= 0 && alpha <= 1.0 ? ColorUtil.mix(Color.WHITE, color, alpha) : color; } + @NotNull + public static Dimension updateListRowHeight(@NotNull Dimension size) { + size.height = Math.max(size.height, UIManager.getInt("List.rowHeight")); + return size; + } + @NotNull public static Color getListBackground(boolean selected, boolean focused) { return !selected ? getListBackground() : getListSelectionBackground(focused);