cache toolwindow header painting + ui polishing + reset navbar caches on laf change

This commit is contained in:
Alexey Pegov
2011-11-28 18:18:23 +04:00
parent 2dd7d09467
commit 201324fa52
6 changed files with 194 additions and 102 deletions
@@ -67,6 +67,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.PanelUI;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.event.MouseAdapter;
@@ -169,6 +170,12 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
getNavBarUI().clearItems();
}
@Override
public void setUI(PanelUI ui) {
getNavBarUI().clearItems();
super.setUI(ui);
}
public NavBarUpdateQueue getUpdateQueue() {
return myUpdateQueue;
}
@@ -38,8 +38,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.plaf.PanelUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -63,6 +65,8 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable {
private ToolWindow myToolWindow;
private WindowInfoImpl myInfo;
private final ToolWindowHeader.ActionButton myHideButton;
private BufferedImage myImage;
private BufferedImage myActiveImage;
public ToolWindowHeader(final ToolWindowImpl toolWindow, WindowInfoImpl info, @NotNull final Producer<ActionGroup> gearProducer) {
setLayout(new BorderLayout());
@@ -213,40 +217,80 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable {
@Override
protected void paintComponent(Graphics g) {
Rectangle r = getBounds();
Graphics2D g2d = (Graphics2D)g;
Shape clip = g2d.getClip();
g2d.setColor(UIUtil.getPanelBackground());
g2d.fill(clip);
g2d.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 5), 0, r.height, new Color(0, 0, 0, 20)));
g2d.fill(clip);
g2d.setColor(new Color(0, 0, 0, 90));
g2d.drawLine(r.x, r.y, r.width - 1, r.y);
g2d.drawLine(r.x, r.height - 1, r.width - 1, r.height - 1);
g2d.setColor(new Color(255, 255, 255, 100));
g2d.drawLine(r.x, r.y + 1, r.width - 1, r.y + 1);
Image image;
if (isActive()) {
g2d.setColor(new Color(100, 150, 230, 50));
g2d.fill(clip);
if (myActiveImage == null || myActiveImage.getHeight() != r.height) {
myActiveImage = drawToBuffer(true, r.height);
}
image = myActiveImage;
} else {
if (myImage == null || myImage.getHeight() != r.height) {
myImage = drawToBuffer(false, r.height);
}
image = myImage;
}
Rectangle clipBounds = clip.getBounds();
for (int x = clipBounds.x; x < clipBounds.x + clipBounds.width; x+=150) {
g2d.drawImage(image, x, 0, null);
}
}
private static BufferedImage drawToBuffer(boolean active, int height) {
final int width = 150;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D _g = image.createGraphics();
_g.setColor(UIUtil.getPanelBackground());
_g.fillRect(0, 0, width, height);
_g.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 5), 0, height, new Color(0, 0, 0, 20)));
_g.fillRect(0, 0, width, height);
_g.setColor(new Color(0, 0, 0, 90));
_g.drawLine(0, 0, width, 0);
_g.drawLine(0, height - 1, width, height - 1);
_g.setColor(new Color(255, 255, 255, 100));
_g.drawLine(0, 1, width, 1);
if (active) {
_g.setColor(new Color(100, 150, 230, 50));
_g.fillRect(0, 0, width, height);
}
_g.dispose();
return image;
}
@Override
public void setUI(PanelUI ui) {
myImage = null;
myActiveImage = null;
super.setUI(ui);
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D graphics = (Graphics2D) g.create();
UIUtil.applyRenderingHints(graphics);
super.paintChildren(graphics);
Rectangle r = getBounds();
Graphics2D g2d = (Graphics2D)g;
if (!isActive()) {
g2d.setColor(new Color(255, 255, 255, 30));
g2d.fill(r);
graphics.setColor(new Color(255, 255, 255, 30));
graphics.fill(r);
}
graphics.dispose();
}
protected abstract boolean isActive();
@@ -21,11 +21,13 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManagerEvent;
import java.awt.*;
import java.awt.image.BufferedImage;
class ComboContentLayout extends ContentLayout {
BaseLabel myIdLabel;
ContentComboLabel myComboLabel;
private BufferedImage myImage;
ComboContentLayout(ToolWindowContentUi ui) {
super(ui);
@@ -43,6 +45,7 @@ class ComboContentLayout extends ContentLayout {
public void reset() {
myIdLabel = null;
myComboLabel = null;
myImage = null;
}
@Override
@@ -71,25 +74,28 @@ class ComboContentLayout extends ContentLayout {
public void paintComponent(Graphics g) {
if (!isToDrawCombo()) return;
final Graphics2D g2d = (Graphics2D)g;
final GraphicsConfig c = new GraphicsConfig(g);
c.setAntialiasing(true);
Rectangle r = myComboLabel.getBounds();
//g2d.setPaint(new GradientPaint(r.x, r.y, new SameColor(200), r.x, r.y + r.height, new SameColor(190)));
g2d.setPaint(new GradientPaint(r.x, r.y, new Color(0, 0, 0, 10), r.x, r.y + r.height, new Color(0, 0, 0, 30)));
g2d.fillRect(r.x, r.y, r.width, r.height);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.x, r.y, r.x, r.y + r.height);
g2d.drawLine(r.x + r.width - 1, r.y, r.x + r.width - 1, r.y + r.height);
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(r.x + 1, r.y, r.width - 3, r.height - 1);
c.restore();
if (myImage == null || myImage.getHeight() != r.height || myImage.getWidth() != r.width) {
myImage = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2d = myImage.createGraphics();
final GraphicsConfig c = new GraphicsConfig(g);
c.setAntialiasing(true);
g2d.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 10), 0, r.height, new Color(0, 0, 0, 30)));
g2d.fillRect(0, 0, r.width, r.height);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(0, 0, 0, r.height);
g2d.drawLine(r.width - 1, 0, r.width - 1, r.height);
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(1, 0, r.width - 3, r.height - 1);
g2d.dispose();
}
g.drawImage(myImage, r.x, r.y, null);
}
@Override
@@ -132,6 +138,11 @@ class ComboContentLayout extends ContentLayout {
public void contentRemoved(ContentManagerEvent event) {
}
@Override
public boolean shouldDrawDecorations() {
return isToDrawCombo();
}
@Override
public void showContentPopup(ListPopup listPopup) {
listPopup.setMinimumSize(new Dimension(myComboLabel.getPreferredSize().width, 0));
@@ -63,8 +63,10 @@ abstract class ContentLayout {
public abstract void contentRemoved(ContentManagerEvent event);
public abstract boolean shouldDrawDecorations();
protected void updateIdLabel(BaseLabel label) {
label.setText(myUi.myWindow.getId());
label.setText(myUi.myWindow.getId() + (shouldDrawDecorations() ? ":" : ""));
label.setBorder(new EmptyBorder(0, 2, 0, 8));
if (myUi.myManager.getContentCount() == 1) {
@@ -79,7 +79,7 @@ class ContentTabLabel extends BaseLabel {
@Override
protected Color getPassiveFg(boolean selected) {
if (contentManager().getContentCount() > 1) {
return selected ? new SameColor(220) : super.getPassiveFg(selected);
return selected ? new SameColor(255) : super.getPassiveFg(selected);
}
return super.getPassiveFg(selected);
}
@@ -95,7 +95,7 @@ class ContentTabLabel extends BaseLabel {
@Override
protected Graphics _getGraphics(Graphics2D g) {
if (isSelected() && contentManager().getContentCount() > 1) {
return new EngravedTextGraphics(g, 1, 1, myUi.myWindow.isActive() ? new Color(0, 0, 0, 200) : new Color(0, 0, 0, 130));
return new EngravedTextGraphics(g, 1, 1, myUi.myWindow.isActive() ? new Color(0, 0, 0, 120) : new Color(0, 0, 0, 130));
}
return super._getGraphics(g);
@@ -30,6 +30,7 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -45,6 +46,8 @@ class TabContentLayout extends ContentLayout {
ArrayList<ContentTabLabel> myTabs = new ArrayList<ContentTabLabel>();
final Map<Content, ContentTabLabel> myContent2Tabs = new HashMap<Content, ContentTabLabel>();
private Map<String, BufferedImage> myCached = new com.intellij.util.containers.HashMap<String, BufferedImage>();
BaseLabel myIdLabel;
private final MoreIcon myMoreIcon = new MoreIcon() {
@@ -247,7 +250,6 @@ class TabContentLayout extends ContentLayout {
myLastLayout = data;
}
static void dropTab(final LayoutData data, final ContentTabLabel toDropLabel) {
data.requiredWidth -= (toDropLabel.getPreferredSize().width + 1);
data.toDrop.add(toDropLabel);
@@ -287,76 +289,91 @@ class TabContentLayout extends ContentLayout {
public void paintComponent(Graphics g) {
if (!isToDrawTabs()) return;
final Graphics2D g2d = (Graphics2D)g;
final GraphicsConfig c = new GraphicsConfig(g);
c.setAntialiasing(true);
boolean prevSelected = false;
for (int i = 0; i < myTabs.size(); i++) {
boolean last = i == myTabs.size() - 1;
ContentTabLabel each = myTabs.get(i);
Rectangle r = each.getBounds();
StringBuilder key = new StringBuilder().append(i);
if (each.isSelected()) key.append('s');
if (prevSelected) key.append('p');
if (last) key.append('l');
if (myUi.myWindow.isActive()) key.append('a');
BufferedImage image = myCached.get(key.toString());
if (image == null || image.getWidth() != r.width || image.getHeight() != r.height) {
image = drawToBuffer(r, each.isSelected(), last, prevSelected, myUi.myWindow.isActive());
myCached.put(key.toString(), image);
}
if (each.isSelected()) {
g2d.setColor(new Color(0, 0, 0, 150));
g2d.fillRect(r.x, r.y, r.width, r.height);
g2d.setColor(new Color(0, 0, 0, 90));
g2d.drawLine(r.x, r.y, r.x + r.width - 1, r.y);
g2d.drawLine(r.x, r.y + 1, r.x, r.y + r.height - 1);
g2d.setColor(new Color(0, 0, 0, 20));
g2d.drawLine(r.x + 1, r.y + 1, r.x + r.width - 1, r.y + 1);
g2d.drawLine(r.x + 1, r.y + 2, r.x + 1, r.y + r.height - 2);
g2d.setColor(new Color(0, 0, 0, 20));
g2d.drawLine(r.x + r.width - 1, r.y + 2, r.x + r.width - 1, r.y + r.height - 2);
g2d.drawLine(r.x + 1, r.y + r.height - 1, r.x + r.width - 1, r.y + r.height - 1);
if (myUi.myWindow.isActive()) {
g2d.setColor(new Color(100, 150, 230, 50));
g2d.fill(r);
}
}
else {
g2d.setPaint(new GradientPaint(r.x, r.y, new Color(0, 0, 0, 10), r.x, r.y + r.height, new Color(0, 0, 0, 30)));
g2d.fillRect(r.x, r.y, r.width, r.height);
if (last) {
if (prevSelected) {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(r.x, r.y, r.width - 1, r.height - 1);
} else {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(r.x + 1, r.y, r.width - 2, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.x, r.y, r.x, r.y + r.height);
}
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.x + r.width, r.y, r.x + r.width, r.y + r.height);
} else {
if (prevSelected) {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(r.x, r.y, r.width - 1, r.height - 1);
}
else {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(r.x + 1, r.y, r.width - 2, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.x, r.y, r.x, r.y + r.height);
}
}
}
g.drawImage(image, r.x, r.y, null);
prevSelected = each.isSelected();
}
}
private static BufferedImage drawToBuffer(Rectangle r, boolean selected, boolean last, boolean prevSelected, boolean active) {
BufferedImage image = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (selected) {
g2d.setColor(active ? new Color(0, 0, 0, 70) : new Color(0, 0, 0, 90));
g2d.fillRect(0, 0, r.width, r.height);
c.restore();
g2d.setColor(new Color(0, 0, 0, 140));
g2d.drawLine(0, 0, r.width - 1, 0);
g2d.drawLine(0, 1, 0, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 20));
g2d.drawLine(1, 1, r.width - 1, 1);
g2d.drawLine(1, 2, 1, r.height - 2);
g2d.drawLine(1, r.height - 1, r.width - 1, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.width - 1, 1, r.width - 1, r.height - 2);
if (active) {
g2d.setColor(new Color(100, 150, 230, 50));
g2d.fill(new Rectangle(0, 0, r.width, r.height));
}
}
else {
g2d.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 10), 0, r.height, new Color(0, 0, 0, 30)));
g2d.fillRect(0, 0, r.width, r.height);
if (last) {
if (prevSelected) {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(0, 0, r.width - 2, r.height - 1);
} else {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(1, 0, r.width - 3, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(0, 0, 0, r.height);
}
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(r.width - 1, 0, r.width - 1, r.height);
} else {
if (prevSelected) {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(0, 0, r.width - 1, r.height - 1);
}
else {
g2d.setColor(new Color(255, 255, 255, 80));
g2d.drawRect(1, 0, r.width - 2, r.height - 1);
g2d.setColor(new Color(0, 0, 0, 60));
g2d.drawLine(0, 0, 0, r.height);
}
}
}
g2d.dispose();
return image;
}
@Override
@@ -388,6 +405,8 @@ class TabContentLayout extends ContentLayout {
myUi.add(each);
myUi.initMouseListeners(each, myUi);
}
myCached.clear();
}
@Override
@@ -395,6 +414,8 @@ class TabContentLayout extends ContentLayout {
final ContentTabLabel tab = new ContentTabLabel(event.getContent(), this);
myTabs.add(event.getIndex(), tab);
myContent2Tabs.put(event.getContent(), tab);
myCached.clear();
}
@Override
@@ -404,6 +425,13 @@ class TabContentLayout extends ContentLayout {
myTabs.remove(tab);
myContent2Tabs.remove(event.getContent());
}
myCached.clear();
}
@Override
public boolean shouldDrawDecorations() {
return isToDrawTabs();
}
@Override