mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-178632 Switching Default/Darcula themes on mac breaks combobox borders
This commit is contained in:
@@ -15,19 +15,15 @@
|
||||
*/
|
||||
package com.intellij.openapi.ui;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.components.JBTextField;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.MacUIUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.plaf.ComboBoxUI;
|
||||
@@ -37,8 +33,6 @@ import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
@@ -47,22 +41,10 @@ import java.lang.reflect.Method;
|
||||
* User: spLeaner
|
||||
*/
|
||||
public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
public static final Border EDITOR_BORDER = new MacComboBoxEditorBorder(false);
|
||||
public static final Border DISABLED_EDITOR_BORDER = new MacComboBoxEditorBorder(true);
|
||||
|
||||
@NotNull private final JBTextField myField;
|
||||
@NotNull
|
||||
private final JBTextField myField = UIUtil.isUnderDefaultMacTheme() ? new MacComboBoxTextField() : new JBTextField();
|
||||
private Object oldValue;
|
||||
|
||||
public FixedComboBoxEditor() {
|
||||
if (SystemInfo.isMac && (UIUtil.isUnderAquaLookAndFeel() || UIUtil.isUnderIntelliJLaF())) {
|
||||
myField = new MacComboBoxTextField();
|
||||
}
|
||||
else {
|
||||
myField = new JBTextField();
|
||||
myField.setBorder(null);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JBTextField getField() {
|
||||
return myField;
|
||||
@@ -95,8 +77,8 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
// Must take the value from the editor and get the value and cast it to the new type.
|
||||
Class cls = oldValue.getClass();
|
||||
try {
|
||||
Method method = cls.getMethod("valueOf", new Class[]{String.class});
|
||||
newValue = method.invoke(oldValue, new Object[]{myField.getText()});
|
||||
Method method = cls.getMethod("valueOf", String.class);
|
||||
newValue = method.invoke(oldValue, myField.getText());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Fail silently and return the newValue (a String object)
|
||||
@@ -108,22 +90,16 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
|
||||
public void selectAll() {
|
||||
myField.selectAll();
|
||||
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> {
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(myField, true);
|
||||
});
|
||||
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(myField, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActionListener(ActionListener l) {
|
||||
}
|
||||
@Override public void addActionListener(ActionListener l) {}
|
||||
|
||||
@Override
|
||||
public void removeActionListener(ActionListener l) {
|
||||
}
|
||||
@Override public void removeActionListener(ActionListener l) {}
|
||||
|
||||
@Nullable
|
||||
private static ComboPopup getComboboxPopup(final JComboBox comboBox) {
|
||||
final ComboBoxUI ui = comboBox.getUI();
|
||||
private static ComboPopup getComboboxPopup(JComboBox comboBox) {
|
||||
ComboBoxUI ui = comboBox.getUI();
|
||||
ComboPopup popup = null;
|
||||
if (ui instanceof BasicComboBoxUI) {
|
||||
popup = ReflectionUtil.getField(BasicComboBoxUI.class, ui, ComboPopup.class, "popup");
|
||||
@@ -134,7 +110,7 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
|
||||
private class MacComboBoxTextField extends JBTextField implements DocumentListener, FocusListener {
|
||||
private MacComboBoxTextField() {
|
||||
final InputMap inputMap = getInputMap();
|
||||
InputMap inputMap = getInputMap();
|
||||
|
||||
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "aquaSelectNext");
|
||||
inputMap.put(KeyStroke.getKeyStroke("KP_DOWN"), "aquaSelectNext");
|
||||
@@ -149,42 +125,12 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
inputMap.put(KeyStroke.getKeyStroke("ENTER"), "aquaEnterPressed");
|
||||
inputMap.put(KeyStroke.getKeyStroke("SPACE"), "aquaSpacePressed");
|
||||
|
||||
//getActionMap().put("macEnterPressed", macEnterPressedAction);
|
||||
//getDocument().addDocumentListener(this);
|
||||
|
||||
addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if ("enabled".equals(evt.getPropertyName())) {
|
||||
if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) {
|
||||
//ignore
|
||||
} else {
|
||||
setBorder(Boolean.TRUE.equals(evt.getNewValue()) ? EDITOR_BORDER : DISABLED_EDITOR_BORDER);
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addFocusListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
|
||||
if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) {
|
||||
setBorder(JBUI.Borders.empty());
|
||||
setOpaque(false);
|
||||
} else {
|
||||
setBorder(isEnabled() ? EDITOR_BORDER : DISABLED_EDITOR_BORDER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFocus() {
|
||||
final Container parent = getParent();
|
||||
Container parent = getParent();
|
||||
if (parent instanceof ComboBox && ((ComboBox)parent).myPaintingNow) {
|
||||
return false; // to disable focus painting around combobox button
|
||||
}
|
||||
@@ -196,40 +142,25 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
repaintCombobox();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
repaintCombobox();
|
||||
}
|
||||
|
||||
private void repaintCombobox() {
|
||||
final Container parent = getParent();
|
||||
if (parent == null) return;
|
||||
if (parent instanceof JComponent && Boolean.TRUE == ((JComponent)parent).getClientProperty("JComboBox.isTableCellEditor")) return;
|
||||
final Container grandParent = parent.getParent();
|
||||
Container parent = getParent();
|
||||
|
||||
if (parent == null || parent instanceof JComponent && Boolean.TRUE == ((JComponent)parent).getClientProperty("JComboBox.isTableCellEditor")) return;
|
||||
|
||||
Container grandParent = parent.getParent();
|
||||
if (grandParent != null) {
|
||||
grandParent.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
repaintCombobox();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
final Dimension minimumSize = super.getMinimumSize();
|
||||
return new Dimension(minimumSize.width, minimumSize.height + 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(final int x, final int y, final int width, final int height) {
|
||||
UIUtil.setComboBoxEditorBounds(x, y, width, height, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) {
|
||||
if (UIUtil.isUnderDefaultMacTheme()) {
|
||||
Container parent = getParent();
|
||||
if (parent != null && !parent.isEnabled()) {
|
||||
return Gray.xF8;
|
||||
@@ -254,18 +185,18 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
}
|
||||
|
||||
private void textChanged() {
|
||||
final Container ancestor = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
|
||||
Container ancestor = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
|
||||
if (ancestor == null || !ancestor.isVisible()) return;
|
||||
|
||||
final JComboBox comboBox = (JComboBox)ancestor;
|
||||
JComboBox comboBox = (JComboBox)ancestor;
|
||||
if (!comboBox.isPopupVisible()) return;
|
||||
|
||||
final ComboPopup popup = getComboboxPopup(comboBox);
|
||||
ComboPopup popup = getComboboxPopup(comboBox);
|
||||
if (popup == null) return;
|
||||
|
||||
String s = myField.getText();
|
||||
|
||||
final ListModel listmodel = comboBox.getModel();
|
||||
ListModel listmodel = comboBox.getModel();
|
||||
int i = listmodel.getSize();
|
||||
if (s.length() > 0) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
@@ -283,65 +214,4 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
popup.getList().clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MacComboBoxEditorBorder implements Border {
|
||||
|
||||
private boolean myDisabled;
|
||||
|
||||
public MacComboBoxEditorBorder(final boolean disabled) {
|
||||
myDisabled = disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
|
||||
Color topColor;
|
||||
Color secondTopColor;
|
||||
Color leftRightColor;
|
||||
Color bottomColor;
|
||||
|
||||
if (myDisabled) {
|
||||
topColor = Gray._200;
|
||||
secondTopColor = Gray._250;
|
||||
leftRightColor = Gray._205;
|
||||
bottomColor = Gray._220;
|
||||
}
|
||||
else {
|
||||
topColor = Gray._150;
|
||||
secondTopColor = Gray._230;
|
||||
leftRightColor = Gray._175;
|
||||
bottomColor = Gray._200;
|
||||
}
|
||||
|
||||
int _y = y + MacUIUtil.MAC_COMBO_BORDER_V_OFFSET;
|
||||
|
||||
g.setColor(topColor);
|
||||
g.drawLine(x + 3, _y + 3, x + width - 1, _y + 3);
|
||||
|
||||
g.setColor(secondTopColor);
|
||||
g.drawLine(x + 3, _y + 4, x + width - 1, _y + 4);
|
||||
|
||||
g.setColor(leftRightColor);
|
||||
g.drawLine(x + 3, _y + 4, x + 3, _y + height - 4);
|
||||
g.drawLine(x + width - 1, _y + 4, x + width - 1, _y + height - 4);
|
||||
|
||||
g.setColor(bottomColor);
|
||||
g.drawLine(x + 4, _y + height - 4, x + width - 2, _y + height - 4);
|
||||
|
||||
g.setColor(UIUtil.getPanelBackground());
|
||||
|
||||
g.fillRect(x, y, width, 3 + (SystemInfo.isMacOSLion ? 1 : 0));
|
||||
g.fillRect(x, _y, 3, height);
|
||||
g.fillRect(x, _y + height - 3, width, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(final Component c) {
|
||||
return new Insets(6, 6, 4, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -21,7 +21,6 @@ import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBGradientPaint;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import sun.swing.SwingUtilities2;
|
||||
@@ -95,7 +94,6 @@ public class DarculaRadioButtonUI extends MetalRadioButtonUI {
|
||||
JBGradientPaint ijGradient = new JBGradientPaint(c, new Color(0x4985e4), new Color(0x4074c9));
|
||||
|
||||
//setup AA for lines
|
||||
GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
|
||||
boolean focus = c.hasFocus();
|
||||
boolean selected = ((AbstractButton)c).isSelected();
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ public class MacComboBoxBorder extends MacIntelliJTextBorder {
|
||||
} else {
|
||||
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
|
||||
path.moveTo(i.left + VALUE_OFFSET, i.top);
|
||||
path.lineTo(i.left + VALUE_OFFSET, c.getHeight() - i.bottom);
|
||||
path.lineTo(i.left + arc, c.getHeight() - i.bottom);
|
||||
path.quadTo(i.left, c.getHeight() - i.bottom, i.left, c.getHeight() - arc - i.bottom);
|
||||
path.lineTo(i.left + VALUE_OFFSET, height - i.bottom);
|
||||
path.lineTo(i.left + arc, height - i.bottom);
|
||||
path.quadTo(i.left, height - i.bottom, i.left, height - arc - i.bottom);
|
||||
path.lineTo(i.left, arc + i.top);
|
||||
path.quadTo(i.left, i.top, arc + i.left, i.top);
|
||||
path.closePath();
|
||||
@@ -82,13 +82,13 @@ public class MacComboBoxBorder extends MacIntelliJTextBorder {
|
||||
Path2D border = new Path2D.Double(Path2D.WIND_EVEN_ODD);
|
||||
float lw = JBUI.scale(UIUtil.isRetina(g2) ? 0.5f : 1.0f);
|
||||
border.append(new RoundRectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
|
||||
c.getWidth() - JBUI.scale(3)*2,
|
||||
c.getHeight() - JBUI.scale(3)*2,
|
||||
width - JBUI.scale(3)*2,
|
||||
height - JBUI.scale(3)*2,
|
||||
arc, arc), false);
|
||||
float innerArc = JBUI.scale(arc > 0 ? arc - lw : 0.0f);
|
||||
border.append(new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
|
||||
c.getWidth() - (JBUI.scale(3) + lw) * 2,
|
||||
c.getHeight() - (JBUI.scale(3) + lw) * 2,
|
||||
width - (JBUI.scale(3) + lw) * 2,
|
||||
height - (JBUI.scale(3) + lw) * 2,
|
||||
innerArc, innerArc), false);
|
||||
g2.setColor(Gray.xBC);
|
||||
g2.fill(border);
|
||||
|
||||
+2
-1
@@ -54,11 +54,12 @@ public class MacIntelliJComboBoxUI extends BasicComboBoxUI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(final JComponent c) {
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
|
||||
DEFAULT_ICON = EmptyIcon.create(MacIntelliJIconCache.getIcon("comboRight", comboBox.isEditable(), false, false, true));
|
||||
comboBox.setOpaque(false);
|
||||
comboBox.setBorder(new MacComboBoxBorder());
|
||||
|
||||
myEditorBorderChangeListener = (evt) -> {
|
||||
Object value = evt.getNewValue();
|
||||
|
||||
@@ -21,33 +21,16 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.FocusChangeListener;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.FixedComboBoxEditor;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import java.awt.*;
|
||||
|
||||
public class ComboboxEditorTextField extends EditorTextField {
|
||||
|
||||
public static final Border EDITOR_TEXTFIELD_BORDER = new FixedComboBoxEditor.MacComboBoxEditorBorder(false) {
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return JBUI.insets(5, 6, 5, 3);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Border EDITOR_TEXTFIELD_DISABLED_BORDER = new FixedComboBoxEditor.MacComboBoxEditorBorder(true) {
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return JBUI.insets(5, 6, 5, 3);
|
||||
}
|
||||
};
|
||||
|
||||
public ComboboxEditorTextField(@NotNull String text, Project project, FileType fileType) {
|
||||
super(text, project, fileType);
|
||||
setOneLineMode(true);
|
||||
@@ -69,20 +52,11 @@ public class ComboboxEditorTextField extends EditorTextField {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height) {
|
||||
UIUtil.setComboBoxEditorBounds(x, y, width, height, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateBorder(@NotNull final EditorEx editor) {
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
editor.setBorder(isEnabled() ? EDITOR_TEXTFIELD_BORDER : EDITOR_TEXTFIELD_DISABLED_BORDER);
|
||||
}
|
||||
}
|
||||
protected void updateBorder(@NotNull EditorEx editor) {}
|
||||
|
||||
@Override
|
||||
protected EditorEx createEditor() {
|
||||
final EditorEx result = super.createEditor();
|
||||
EditorEx result = super.createEditor();
|
||||
|
||||
result.addFocusListener(new FocusChangeListener() {
|
||||
@Override
|
||||
@@ -106,22 +80,10 @@ public class ComboboxEditorTextField extends EditorTextField {
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
final Dimension preferredSize = super.getPreferredSize();
|
||||
Dimension preferredSize = super.getPreferredSize();
|
||||
return new Dimension(preferredSize.width, UIUtil.fixComboBoxHeight(preferredSize.height));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
final Editor editor = getEditor();
|
||||
if (editor != null) {
|
||||
editor.setBorder(enabled ? EDITOR_TEXTFIELD_BORDER : EDITOR_TEXTFIELD_DISABLED_BORDER);
|
||||
}
|
||||
}
|
||||
|
||||
super.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private void repaintComboBox() {
|
||||
// TODO:
|
||||
if (UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF() || (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel())) {
|
||||
|
||||
Reference in New Issue
Block a user