refactor shadow painter

This commit is contained in:
Konstantin Bulenkov
2016-03-05 20:42:00 +01:00
parent 7afb6d14c2
commit 1d754b329a
2 changed files with 127 additions and 72 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.ui.impl;
import com.intellij.icons.AllIcons;
import com.intellij.ui.Gray;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import org.jdesktop.swingx.graphics.ShadowRenderer;
@@ -28,78 +29,36 @@ import java.awt.image.BufferedImage;
* @author Konstantin Bulenkov
*/
public class ShadowBorderPainter {
private static final Icon TOP = AllIcons.Ide.Shadow.Top;
private static final Icon TOP_RIGHT = AllIcons.Ide.Shadow.Top_right;
private static final Icon RIGHT = AllIcons.Ide.Shadow.Right;
private static final Icon BOTTOM_RIGHT = AllIcons.Ide.Shadow.Bottom_right;
private static final Icon BOTTOM = AllIcons.Ide.Shadow.Bottom;
private static final Icon BOTTOM_LEFT = AllIcons.Ide.Shadow.Bottom_left;
private static final Icon LEFT = AllIcons.Ide.Shadow.Left;
private static final Icon TOP_LEFT = AllIcons.Ide.Shadow.Top_left;
public static final ShadowPainter ourPopupShadowPainter = new ShadowPainter(AllIcons.Ide.Shadow.Popup.Top,
AllIcons.Ide.Shadow.Popup.Top_right,
AllIcons.Ide.Shadow.Popup.Right,
AllIcons.Ide.Shadow.Popup.Bottom_right,
AllIcons.Ide.Shadow.Popup.Bottom,
AllIcons.Ide.Shadow.Popup.Bottom_left,
AllIcons.Ide.Shadow.Popup.Left,
AllIcons.Ide.Shadow.Popup.Top_left,
Gray.x00.withAlpha(30));
public static final int SIDE_SIZE = 35;
public static final int TOP_SIZE = 20;
public static final int BOTTOM_SIZE = 49;
public static final ShadowPainter ourShadowPainter = new ShadowPainter(AllIcons.Ide.Shadow.Top,
AllIcons.Ide.Shadow.Top_right,
AllIcons.Ide.Shadow.Right,
AllIcons.Ide.Shadow.Bottom_right,
AllIcons.Ide.Shadow.Bottom,
AllIcons.Ide.Shadow.Bottom_left,
AllIcons.Ide.Shadow.Left,
AllIcons.Ide.Shadow.Top_left,
Gray.x00.withAlpha(30));
private static final Icon POPUP_TOP = AllIcons.Ide.Shadow.Popup.Top;
private static final Icon POPUP_TOP_RIGHT = AllIcons.Ide.Shadow.Popup.Top_right;
private static final Icon POPUP_RIGHT = AllIcons.Ide.Shadow.Popup.Right;
private static final Icon POPUP_BOTTOM_RIGHT = AllIcons.Ide.Shadow.Popup.Bottom_right;
private static final Icon POPUP_BOTTOM = AllIcons.Ide.Shadow.Popup.Bottom;
private static final Icon POPUP_BOTTOM_LEFT = AllIcons.Ide.Shadow.Popup.Bottom_left;
private static final Icon POPUP_LEFT = AllIcons.Ide.Shadow.Popup.Left;
private static final Icon POPUP_TOP_LEFT = AllIcons.Ide.Shadow.Popup.Top_left;
public static final int POPUP_SIDE_SIZE = 7;
public static final int POPUP_TOP_SIZE = 4;
public static final int POPUP_BOTTOM_SIZE = 10;
private ShadowBorderPainter() {
}
public static BufferedImage createShadow(final JComponent c, final int width, final int height, boolean isPopup) {
final GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
return getPainter(isPopup).createShadow(c, width, height);
}
final BufferedImage image = graphicsConfiguration.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
final Graphics2D g = image.createGraphics();
final Icon topLeft = isPopup ? POPUP_TOP_LEFT : TOP_LEFT;
final Icon topRight = isPopup ? POPUP_TOP_RIGHT : TOP_RIGHT;
final Icon bottom = isPopup ? POPUP_BOTTOM : BOTTOM;
final Icon top = isPopup ? POPUP_TOP : TOP;
final Icon bottomRight = isPopup ? POPUP_BOTTOM_RIGHT : BOTTOM_RIGHT;
final Icon bottomLeft = isPopup ? POPUP_BOTTOM_LEFT : BOTTOM_LEFT;
final Icon left = isPopup ? POPUP_LEFT : LEFT;
final Icon right = isPopup ? POPUP_RIGHT : RIGHT;
final int sideSize = isPopup ? POPUP_SIDE_SIZE : SIDE_SIZE;
final int bottomSize = isPopup ? POPUP_BOTTOM_SIZE : BOTTOM_SIZE;
topLeft.paintIcon(c, g, 0, 0);
topRight.paintIcon(c, g, width - topRight.getIconWidth(), 0);
bottomRight.paintIcon(c, g, width - bottomRight.getIconWidth(), height - bottomRight.getIconHeight());
bottomLeft.paintIcon(c, g, 0, height - bottomLeft.getIconHeight());
for (int _x = topLeft.getIconWidth(); _x < width - topRight.getIconWidth(); _x++) {
top.paintIcon(c, g, _x, 0);
}
for (int _x = bottomLeft.getIconWidth(); _x < width - bottomLeft.getIconWidth(); _x++) {
bottom.paintIcon(c, g, _x, height - bottomSize);
}
for (int _y = topLeft.getIconHeight(); _y < height - bottomLeft.getIconHeight(); _y++) {
left.paintIcon(c, g, 0, _y);
}
for (int _y = topRight.getIconHeight(); _y < height - bottomRight.getIconHeight(); _y++) {
right.paintIcon(c, g, width - sideSize, _y);
}
g.setColor(new Color(0, 0, 0, 30));
g.drawRect(SIDE_SIZE - 1, TOP_SIZE - 1,
width - SIDE_SIZE * 2 + 1, height - TOP_SIZE - BOTTOM_SIZE + 1);
g.dispose();
return image;
private static ShadowPainter getPainter(boolean isPopup) {
return isPopup ? ourPopupShadowPainter : ourShadowPainter;
}
public static BufferedImage createShadow(final JComponent c, final int width, final int height) {
@@ -111,12 +70,11 @@ public class ShadowBorderPainter {
}
public static Shadow createShadow(Image source, int x, int y, boolean paintSource, int shadowSize) {
int size = shadowSize;
final float w = source.getWidth(null);
final float h = source.getHeight(null);
float ratio = w / h;
float deltaX = size;
float deltaY = size / ratio;
float deltaX = shadowSize;
float deltaY = shadowSize / ratio;
final Image scaled = source.getScaledInstance((int)(w + deltaX), (int)(h + deltaY), Image.SCALE_SMOOTH);
@@ -126,14 +84,14 @@ public class ShadowBorderPainter {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.drawImage(scaled, 0, 0, null);
final BufferedImage shadow = new ShadowRenderer(size, .25f, Color.black).createShadow(s);
final BufferedImage shadow = new ShadowRenderer(shadowSize, .25f, Gray.x00).createShadow(s);
if (paintSource) {
final Graphics imgG = shadow.getGraphics();
final double d = size * 0.5;
imgG.drawImage(source, (int)(size + d), (int)(size + d / ratio), null);
final double d = shadowSize * 0.5;
imgG.drawImage(source, (int)(shadowSize + d), (int)(shadowSize + d / ratio), null);
}
return new Shadow(shadow, x - size - 5, y - size + 2);
return new Shadow(shadow, x - shadowSize - 5, y - shadowSize + 2);
}
@@ -0,0 +1,97 @@
/*
* Copyright 2000-2016 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.openapi.ui.impl;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* @author Konstantin Bulenkov
*/
public class ShadowPainter {
private final Icon myTop;
private final Icon myTopRight;
private final Icon myRight;
private final Icon myBottomRight;
private final Icon myBottom;
private final Icon myBottomLeft;
private final Icon myLeft;
private final Icon myTopLeft;
@Nullable
private Color myBorderColor;
ShadowPainter(Icon top, Icon topRight, Icon right, Icon bottomRight, Icon bottom, Icon bottomLeft, Icon left, Icon topLeft) {
myTop = top;
myTopRight = topRight;
myRight = right;
myBottomRight = bottomRight;
myBottom = bottom;
myBottomLeft = bottomLeft;
myLeft = left;
myTopLeft = topLeft;
}
ShadowPainter(Icon top, Icon topRight, Icon right, Icon bottomRight, Icon bottom, Icon bottomLeft, Icon left, Icon topLeft, Color borderColor) {
this(top, topRight, right, bottomRight, bottom, bottomLeft, left, topLeft);
myBorderColor = borderColor;
}
public void setBorderColor(@Nullable Color borderColor) {
myBorderColor = borderColor;
}
public BufferedImage createShadow(final JComponent c, final int width, final int height) {
final GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
final BufferedImage image = graphicsConfiguration.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
final Graphics2D g = image.createGraphics();
final int sideSize = myLeft.getIconWidth();
final int bottomSize = myBottom.getIconHeight();
final int topSize = myTop.getIconHeight();
myTopLeft.paintIcon(c, g, 0, 0);
myTopRight.paintIcon(c, g, width - myTopRight.getIconWidth(), 0);
myBottomRight.paintIcon(c, g, width - myBottomRight.getIconWidth(), height - myBottomRight.getIconHeight());
myBottomLeft.paintIcon(c, g, 0, height - myBottomLeft.getIconHeight());
for (int _x = myTopLeft.getIconWidth(); _x < width - myTopRight.getIconWidth(); _x++) {
myTop.paintIcon(c, g, _x, 0);
}
for (int _x = myBottomLeft.getIconWidth(); _x < width - myBottomLeft.getIconWidth(); _x++) {
myBottom.paintIcon(c, g, _x, height - bottomSize);
}
for (int _y = myTopLeft.getIconHeight(); _y < height - myBottomLeft.getIconHeight(); _y++) {
myLeft.paintIcon(c, g, 0, _y);
}
for (int _y = myTopRight.getIconHeight(); _y < height - myBottomRight.getIconHeight(); _y++) {
myRight.paintIcon(c, g, width - sideSize, _y);
}
if (myBorderColor != null) {
g.setColor(myBorderColor);
g.drawRect(sideSize - 1, topSize - 1, width - sideSize * 2 + 1, height - topSize - bottomSize + 1);
}
g.dispose();
return image;
}
}