Sunday, July 27, 2008

Pimp My LWUIT Part V: Shadowing Presence


Shadows are an unbelievable piece of "eye candy", when building a "proper" shadow in desktop OS's one often uses black with an opacity gradient that is then blurred. This creates the remarkable shadows that windows in modern operating systems enjoy. These are REALLY expensive to recreate without serious hardware acceleration, so we won't...
However, a simple translucent black background provides a shadow effect that looks pretty cool in a button and provides depth for a UI. Before we install the shadow we will also change the color scheme of the application since the shadow just won't look well with the old black theme of the "Pimp" series...

Regardless of some of the changes made to the theme notice the gorgeous drop shadow surrounding the gradient menu which gives it depth beyond the default look. This is done by extending the gradient border introduced previously to also draw a shadow with the border.
public class DropShadowRoundedBorderLinearGradient extends Border {
private int sourceColor;
private int destColor;
private boolean horizontal;
private Image cache;
private int arcWidth;
private int arcHeight;
private int borderColor;
private boolean noShadow;

public DropShadowRoundedBorderLinearGradient(int sourceColor, int destColor, boolean horizontal, int borderColor, int arcWidth, int arcHeight) {
this.sourceColor = sourceColor;
this.destColor = destColor;
this.horizontal = horizontal;
this.arcHeight = arcHeight;
this.arcWidth = arcWidth;
this.borderColor = borderColor;
}

public Border createPressedVersion() {
DropShadowRoundedBorderLinearGradient d = new DropShadowRoundedBorderLinearGradient(sourceColor, destColor, horizontal, borderColor, arcWidth, arcHeight);
d.noShadow = true;
return d;
}

public boolean isBackgroundPainter() {
return true;
}

public void paintBorderBackground(Graphics g, Component c) {
int x = c.getX();
int y = c.getY();
int height = c.getHeight();
int width = c.getWidth();
if(cache == null || width != cache.getWidth() || height != cache.getHeight()) {
cache = Image.createImage(width, height);
Graphics current = cache.getGraphics();
int shadow = 0x60000000;
if(noShadow) {
current.setColor(0);
current.fillRoundRect(4, 4, width - 5, height - 5, arcWidth, arcHeight);
} else {
current.setColor(0xcccccc);
current.fillRoundRect(4, 4, width - 5, height - 5, arcWidth, arcHeight);
current.setColor(0);
current.fillRoundRect(0, 0, width - 5, height - 5, arcWidth, arcHeight);
}
int[] rgb = cache.getRGB();
current.fillLinearGradient(sourceColor, destColor, 0, 0, width, height, horizontal);
int[] rgb2 = cache.getRGB();
int white = rgb[0];
int gray = rgb[rgb.length - width - width / 2];
if(noShadow) {
gray = 0xffffff;
}
for(int iter = 0 ; iter < rgb.length ; iter++) {
if(rgb[iter] == white) {
rgb2[iter] = 0;
continue;
}
if(rgb[iter] == gray) {
rgb2[iter] = shadow;
}
}
cache = Image.createImage(rgb2, width, height);
}
g.drawImage(cache, x, y);
}

public void paint(Graphics g, Component c) {
int oldColor = g.getColor();
g.setColor(borderColor);
if(noShadow) {
g.drawRoundRect(c.getX() + 4, c.getY() + 4, c.getWidth() - 5, c.getHeight() - 5, arcWidth, arcHeight);
} else {
g.drawRoundRect(c.getX(), c.getY(), c.getWidth() - 5, c.getHeight() - 5, arcWidth, arcHeight);
}
g.setColor(oldColor);
}
}

No comments:

Post a Comment