/* * Copyright 2000-2012 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.darcula.ui; import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import org.intellij.lang.annotations.MagicConstant; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicSpinnerUI; import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; /** * @author Konstantin Bulenkov */ public class DarculaSpinnerUI extends BasicSpinnerUI { private FocusAdapter myFocusListener = new FocusAdapter() { @Override public void focusGained(FocusEvent e) { spinner.repaint(); } @Override public void focusLost(FocusEvent e) { spinner.repaint(); } }; @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) public static ComponentUI createUI(JComponent c) { return new DarculaSpinnerUI(); } @Override protected void replaceEditor(JComponent oldEditor, JComponent newEditor) { super.replaceEditor(oldEditor, newEditor); if (oldEditor != null) { oldEditor.getComponents()[0].removeFocusListener(myFocusListener); } if (newEditor != null) { newEditor.getComponents()[0].addFocusListener(myFocusListener); } } @Override protected JComponent createEditor() { final JComponent editor = super.createEditor(); editor.getComponents()[0].addFocusListener(myFocusListener); return editor; } @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); final Border border = spinner.getBorder(); if (border != null) { border.paintBorder(c, g, 0, 0, spinner.getWidth(), spinner.getHeight()); } } @Override protected Component createPreviousButton() { JButton button = createArrow(SwingConstants.SOUTH); button.setName("Spinner.previousButton"); button.setBorder(new EmptyBorder(1, 1, 1, 1)); installPreviousButtonListeners(button); return button; } @Override protected Component createNextButton() { JButton button = createArrow(SwingConstants.NORTH); button.setName("Spinner.nextButton"); button.setBorder(new EmptyBorder(1, 1, 1, 1)); installNextButtonListeners(button); return button; } @Override protected LayoutManager createLayout() { return new LayoutManagerDelegate(super.createLayout()) { @Override public void layoutContainer(Container parent) { super.layoutContainer(parent); final JComponent editor = spinner.getEditor(); if (editor != null) { final Rectangle bounds = editor.getBounds(); editor.setBounds(bounds.x, bounds.y, bounds.width - 6, bounds.height); } } }; } private JButton createArrow(@MagicConstant(intValues = {SwingConstants.NORTH, SwingConstants.SOUTH}) int direction) { final Color shadow = UIUtil.getPanelBackground(); final Color darkShadow = UIUtil.getLabelForeground(); JButton b = new BasicArrowButton(direction, shadow, shadow, darkShadow, shadow) { @Override public void paint(Graphics g) { int y = direction == NORTH ? getHeight() - 6 : 2; paintTriangle(g, 0, y, 0, direction, DarculaSpinnerUI.this.spinner.isEnabled()); } @Override public boolean isOpaque() { return false; } @Override public void paintTriangle(Graphics g, int x, int y, int size, int direction, boolean isEnabled) { final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); int mid; final int w = 8; final int h = 6; mid = w / 2; g.setColor(isEnabled ? darkShadow : darkShadow.darker()); g.translate(x, y); switch (direction) { case SOUTH: g.fillPolygon(new int[]{0, w, mid}, new int[]{1, 1, h}, 3); break; case NORTH: g.fillPolygon(new int[]{0, w, mid}, new int[]{h - 1, h - 1, 0}, 3); break; case WEST: case EAST: } g.translate(-x, -y); config.restore(); } }; Border buttonBorder = UIManager.getBorder("Spinner.arrowButtonBorder"); if (buttonBorder instanceof UIResource) { // Wrap the border to avoid having the UIResource be replaced by // the ButtonUI. This is the opposite of using BorderUIResource. b.setBorder(new CompoundBorder(buttonBorder, null)); } else { b.setBorder(buttonBorder); } b.setInheritsPopupMenu(true); return b; } static class LayoutManagerDelegate implements LayoutManager { protected final LayoutManager myDelegate; LayoutManagerDelegate(LayoutManager delegate) { myDelegate = delegate; } @Override public void addLayoutComponent(String name, Component comp) { myDelegate.addLayoutComponent(name, comp); } @Override public void removeLayoutComponent(Component comp) { myDelegate.removeLayoutComponent(comp); } @Override public Dimension preferredLayoutSize(Container parent) { return myDelegate.preferredLayoutSize(parent); } @Override public Dimension minimumLayoutSize(Container parent) { return myDelegate.minimumLayoutSize(parent); } @Override public void layoutContainer(Container parent) { myDelegate.layoutContainer(parent); } } }