new Yosemite ComboBox

This commit is contained in:
Konstantin Bulenkov
2015-06-12 03:37:27 +02:00
parent 956beb41cc
commit 993340662c
@@ -0,0 +1,284 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.ui.laf.intellij;
import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.ui.JBUI;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxUI;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* @author Konstantin Bulenkov
*/
public class MacIntelliJComboBoxUI extends BasicComboBoxUI implements Border, UIResource {
private static final Icon COMBOBOX = DarculaLaf.loadIcon("/com/intellij/ide/ui/laf/icons/comboboxMac.png");
private static final Icon COMBOBOX_LEFT = DarculaLaf.loadIcon("/com/intellij/ide/ui/laf/icons/comboboxLeft.png");
private static final Icon COMBOBOX_TOP_BOTTOM = DarculaLaf.loadIcon("/com/intellij/ide/ui/laf/icons/comboboxTopBottom.png");
private final JComboBox myComboBox;
public MacIntelliJComboBoxUI(JComboBox comboBox) {
myComboBox = comboBox;
myComboBox.setBorder(this);
currentValuePane = new CellRendererPane() {
@Override
public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) {
c.setBackground(Color.WHITE);
super.paintComponent(g, c, p, x, y, w, h, shouldValidate);
}
};
}
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new MacIntelliJComboBoxUI((JComboBox)c);
}
@Override
protected JButton createArrowButton() {
final Color bg = myComboBox.getBackground();
final Color fg = myComboBox.getForeground();
JButton button = new BasicArrowButton(SwingConstants.SOUTH, bg, fg, fg, fg) {
@Override
public void paint(Graphics g2) {
Icon icon = myComboBox.isEnabled() ? COMBOBOX : IconLoader.getDisabledIcon(COMBOBOX);
icon.paintIcon(this, g2, 0, 0);
}
@Override
public Dimension getPreferredSize() {
return JBUI.size(COMBOBOX.getIconWidth(), COMBOBOX.getIconWidth());
}
};
button.setBorder(BorderFactory.createEmptyBorder());
button.setOpaque(false);
return button;
}
@Override
public Dimension getMinimumSize(JComponent c) {
return getSizeWithIcon(super.getMinimumSize(c));
}
private Dimension getSizeWithIcon(Dimension d) {
Insets insets = getBorderInsets(myComboBox);
return new Dimension(Math.max(d.width + insets.left + insets.right, COMBOBOX.getIconWidth()), Math.max(d.height,
COMBOBOX.getIconHeight()));
}
@Override
public Dimension getPreferredSize(JComponent c) {
return getSizeWithIcon(super.getPreferredSize(c));
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
}
@Override
protected ComboBoxEditor createEditor() {
final ComboBoxEditor comboBoxEditor = new BasicComboBoxEditor.UIResource() {
@Override
protected JTextField createEditorComponent() {
return new JTextField() {
{
setOpaque(false);
setBorder(new Border() {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
}
@Override
public Insets getBorderInsets(Component c) {
return JBUI.insets(2, 6, 2, 6);
}
@Override
public boolean isBorderOpaque() {
return false;
}
});
}
public void setText(String s) {
if (getText().equals(s)) {
return;
}
super.setText(s);
}
public void setBorder(Border b) {
super.setBorder(b);
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
return new Dimension(size.width, COMBOBOX.getIconHeight() - 2);
}
};
}
};
if (comboBoxEditor.getEditorComponent() != null) {
comboBoxEditor.getEditorComponent().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
process(e);
}
@Override
public void keyReleased(KeyEvent e) {
process(e);
}
private void process(KeyEvent e) {
final int code = e.getKeyCode();
if ((code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN) && e.getModifiers() == 0) {
comboBox.dispatchEvent(e);
}
}
});
comboBoxEditor.getEditorComponent().addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
update();
}
@Override
public void focusLost(FocusEvent e) {
update();
}
void update() {
if (comboBox != null) {
comboBox.revalidate();
comboBox.repaint();
}
}
});
}
return comboBoxEditor;
}
@Override
protected Rectangle rectangleForCurrentValue() {
Rectangle rect = super.rectangleForCurrentValue();
rect.y+=2;
rect.x+=5;
rect.height-=4;
return rect;
}
@Override
public Insets getBorderInsets(Component c) {
return JBUI.insets(0, 5, 0, 0);
}
@Override
protected LayoutManager createLayoutManager() {
return new LayoutManager() {
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return null;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return null;
}
@Override
public void layoutContainer(Container parent) {
JComboBox cb = (JComboBox)parent;
int width = cb.getWidth();
int height = cb.getHeight();
Insets insets = getInsets();
int buttonHeight = height - (insets.top + insets.bottom);
int buttonWidth = buttonHeight;
if (arrowButton != null) {
Insets arrowInsets = arrowButton.getInsets();
buttonWidth = arrowButton.getPreferredSize().width + arrowInsets.left + arrowInsets.right;
}
Rectangle cvb;
if (arrowButton != null) {
arrowButton.setBounds(width - (insets.right + buttonWidth),
insets.top, buttonWidth, buttonHeight);
}
if ( editor != null ) {
cvb = rectangleForCurrentValue();
editor.setBounds(cvb);
}
}
};
}
@Override
public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean hasFocus) {
g.setColor(Color.WHITE);
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
int stop = arrowButton.getBounds().x;
g.setClip(0,0, stop, COMBOBOX.getIconHeight());
COMBOBOX_LEFT.paintIcon(c,g,0,0);
int x = COMBOBOX_LEFT.getIconWidth();
while (x < stop) {
COMBOBOX_TOP_BOTTOM.paintIcon(c, g, x, 0);
x+=COMBOBOX_TOP_BOTTOM.getIconWidth();
}
((Graphics2D)g).scale(0.5d, 0.5d);
g.setColor(Color.WHITE);
g.drawLine(COMBOBOX_LEFT.getIconWidth() * 2, 3, stop * 2, 3);
g.drawLine(COMBOBOX_LEFT.getIconWidth() * 2, 40, stop * 2, 40);
((Graphics2D)g).scale(2d, 2d);
}
@Override
public boolean isBorderOpaque() {
return false;
}
}