/*******************************************************************************
* Copyright (c) 2016
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*******************************************************************************/
package jsettlers.main.swing.lookandfeel.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.TexturePaint;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.plaf.PanelUI;
import jsettlers.main.swing.lookandfeel.DrawHelper;
import jsettlers.main.swing.lookandfeel.components.SplitedBackgroundPanel;
import jsettlers.main.swing.lookandfeel.ui.img.UiImageLoader;
/**
* Background Panel UI
*
* @author Andreas Butti
*/
public class BackgroundPanelUi extends PanelUI {
/**
* Background texture
*/
private final BufferedImage backgroundTextture = UiImageLoader.get("test-pattern-bg.jpg");
/**
* Background color image
*/
private final BufferedImage backgroundColor = UiImageLoader.get("stone-background-colors.jpg");
/**
* Border texture for the border line
*/
private final BufferedImage borderTexture = UiImageLoader.get("texture-border.png");
/**
* Leaf image at the right corner
*/
private final BufferedImage leaves1 = UiImageLoader.get("leaves1b.png");
/**
* Leaf image at the left side
*/
private final BufferedImage leaves2 = UiImageLoader.get("leaves2.png");
/**
* Leaf image at the bottom
*/
private final BufferedImage leaves3 = UiImageLoader.get("leaves3.png");
/**
* Current background cache
*/
private BufferedImage cachedBackground = null;
@Override
public void installUI(JComponent c) {
super.installUI(c);
c.setOpaque(false);
}
@Override
public void paint(Graphics graphics, JComponent component) {
super.paint(graphics, component);
Graphics2D graphics2D = DrawHelper.enableAntialiasing(graphics);
if (cachedBackground == null || cachedBackground.getWidth() != component.getWidth()
|| cachedBackground.getHeight() != component.getHeight()) {
recreateBackgroundImage(component);
}
graphics2D.drawImage(cachedBackground, 0, 0, component);
}
/**
* Recreate the cached background image, if needed
*
* @param component
* The component
*/
private void recreateBackgroundImage(JComponent component) {
final int width = component.getWidth();
final int height = component.getHeight();
cachedBackground = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = cachedBackground.createGraphics();
// scale the background color image
graphics.drawImage(backgroundColor, 0, 0, width, height, component);
for (int x = 0; x < width; x += backgroundTextture.getWidth()) {
for (int y = 0; y < height; y += backgroundTextture.getHeight()) {
multiplyImage(cachedBackground, backgroundTextture, x, y);
}
}
BorderDrawer border = new BorderDrawer(graphics, 3, 0, 0, width, height);
BufferedImage scaledTexture = DrawHelper.toBufferedImage(borderTexture.getScaledInstance(width, height, BufferedImage.SCALE_FAST));
TexturePaint tp = new TexturePaint(scaledTexture, new Rectangle2D.Float(0, 0, width, height));
border.setPaint(tp);
border.drawRect();
if (component instanceof SplitedBackgroundPanel) {
border.drawVertical(((SplitedBackgroundPanel) component).getSplitPosition(), true);
}
float factor = 0.2f;
graphics.drawImage(leaves1, width - 120, -30, (int) (leaves1.getWidth() * factor), (int) (leaves1.getHeight() * factor), component);
factor = 0.4f;
graphics.drawImage(leaves2, -35, 45, (int) (leaves2.getWidth() * factor), (int) (leaves2.getHeight() * factor), component);
factor = 0.3f;
graphics.drawImage(leaves3, 60, height - 60, (int) (leaves3.getWidth() * factor), (int) (leaves3.getHeight() * factor), component);
graphics.dispose();
}
/**
* Multiply two images, may can be done more efficient
*
* @param targetImage
* Source and target
* @param texture
* source
* @param targetX
* target start X coordinate
* @param targetY
* target start y coordinate
*/
private void multiplyImage(BufferedImage targetImage, BufferedImage texture, int targetX, int targetY) {
for (int x = 0; x < texture.getWidth(); x++) {
for (int y = 0; y < texture.getHeight(); y++) {
if (x + targetX >= targetImage.getWidth() || y + targetY >= targetImage.getHeight()) {
continue;
}
int rgb1 = targetImage.getRGB(x + targetX, y + targetY);
Color c1 = new Color(rgb1);
float r1 = c1.getRed() / 255f;
float g1 = c1.getGreen() / 255f;
float b1 = c1.getBlue() / 255f;
int rgb2 = texture.getRGB(x, y);
Color c2 = new Color(rgb2);
float addTexture = 0.15f;
float r2 = c2.getRed() / 255f + addTexture;
float g2 = c2.getGreen() / 255f + addTexture;
float b2 = c2.getBlue() / 255f + addTexture;
int r = (int) (Math.min(1.0f, r1 * r2) * 255f);
int g = (int) (Math.min(1.0f, g1 * g2) * 255f);
int b = (int) (Math.min(1.0f, b1 * b2) * 255f);
targetImage.setRGB(x + targetX, y + targetY, r << 16 | g << 8 | b);
}
}
}
}