2
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Substance Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.substance.api.painter.decoration;
33
import java.awt.image.BufferedImage;
34
import java.util.LinkedHashMap;
37
import org.pushingpixels.lafwidget.LafWidgetUtilities;
38
import org.pushingpixels.substance.api.*;
39
import org.pushingpixels.substance.api.painter.SubstancePainterUtils;
40
import org.pushingpixels.substance.internal.utils.SubstanceImageCreator;
43
* Implementation of {@link SubstanceDecorationPainter} that uses brushed metal
44
* painting on decoration areas.
46
* @author Kirill Grouchnikov
49
public abstract class ImageWrapperDecorationPainter implements
50
SubstanceDecorationPainter {
52
* Contains the original (not colorized) image of this painter.
54
protected Image originalTile = null;
57
* The base decoration painter - the colorized image tiles are painted over
58
* the painting of this painter. Can be <code>null</code>.
60
protected SubstanceDecorationPainter baseDecorationPainter;
63
* Map of colorized tiles.
65
protected LinkedHashMap<String, Image> colorizedTileMap;
68
* Alpha channel for the texture image (colorized tiles applied on top of
69
* the {@link #baseDecorationPainter} painting).
71
protected float textureAlpha;
74
* Creates a new image wrapper decoration painter.
76
public ImageWrapperDecorationPainter() {
77
this.textureAlpha = 0.3f;
79
this.colorizedTileMap = new LinkedHashMap<String, Image>() {
81
protected boolean removeEldestEntry(Map.Entry<String, Image> eldest) {
82
return this.size() > 10;
96
* @seeorg.pushingpixels.substance.painter.decoration.SubstanceDecorationPainter
97
* # paintDecorationArea(java.awt.Graphics2D, java.awt.Component,
98
* org.pushingpixels.substance.painter.decoration.DecorationAreaType, int,
99
* int, org.pushingpixels.substance.api.SubstanceSkin)
102
public void paintDecorationArea(Graphics2D graphics, Component comp,
103
DecorationAreaType decorationAreaType, int width, int height,
104
SubstanceSkin skin) {
105
if ((decorationAreaType == DecorationAreaType.PRIMARY_TITLE_PANE)
106
|| (decorationAreaType == DecorationAreaType.SECONDARY_TITLE_PANE)) {
107
this.paintTitleBackground(graphics, comp, decorationAreaType,
108
width, height, skin);
110
this.paintExtraBackground(graphics, comp, decorationAreaType,
111
width, height, skin);
116
* Paints the title background.
122
* @param decorationAreaType
123
* Decoration area type. Must not be <code>null</code>.
129
* Skin for painting the title background.
131
private void paintTitleBackground(Graphics2D graphics, Component comp,
132
DecorationAreaType decorationAreaType, int width, int height,
133
SubstanceSkin skin) {
135
SubstanceColorScheme tileScheme = skin
136
.getBackgroundColorScheme(decorationAreaType);
137
if (this.baseDecorationPainter == null) {
138
graphics.setColor(tileScheme.getMidColor());
139
graphics.fillRect(0, 0, width, height);
141
this.baseDecorationPainter.paintDecorationArea(graphics, comp,
142
decorationAreaType, width, height, skin);
145
Graphics2D temp = (Graphics2D) graphics.create();
146
this.tileArea(temp, comp, tileScheme, 0, 0, 0, 0, width, height);
151
* Paints the background of non-title decoration areas.
157
* @param decorationAreaType
158
* Decoration area type. Must not be <code>null</code>.
164
* Skin for painting the background of non-title decoration
167
private void paintExtraBackground(Graphics2D graphics, Component comp,
168
DecorationAreaType decorationAreaType, int width, int height,
169
SubstanceSkin skin) {
171
Point offset = SubstancePainterUtils.getOffsetInRootPaneCoords(comp);
173
SubstanceColorScheme tileScheme = skin
174
.getBackgroundColorScheme(decorationAreaType);
175
if (this.baseDecorationPainter != null) {
176
this.baseDecorationPainter.paintDecorationArea(graphics, comp,
177
decorationAreaType, width, height, skin);
179
graphics.setColor(tileScheme.getMidColor());
180
graphics.fillRect(0, 0, width, height);
182
Graphics2D temp = (Graphics2D) graphics.create();
183
this.tileArea(temp, comp, tileScheme, offset.x, offset.y, 0, 0, width,
189
* Tiles the specified area with colorized version of the image tile. This
190
* is called after the {@link #baseDecorationPainter} has painted the area.
191
* This method should respect the current {@link #textureAlpha} value.
198
* Scheme for the tile colorization.
199
* @param offsetTextureX
200
* X offset for the tiling.
201
* @param offsetTextureY
202
* Y offset for the tiling.
204
* X coordinate of the tiling region.
206
* Y coordinate of the tiling region.
208
* Width of the tiling region.
210
* Height of the tiling region.
212
protected void tileArea(Graphics2D g, Component comp,
213
SubstanceColorScheme tileScheme, int offsetTextureX,
214
int offsetTextureY, int x, int y, int width, int height) {
216
Graphics2D graphics = (Graphics2D) g.create();
217
graphics.setComposite(LafWidgetUtilities.getAlphaComposite(comp,
218
this.textureAlpha, g));
220
Image colorizedTile = this.getColorizedTile(tileScheme);
221
int tileWidth = colorizedTile.getWidth(null);
222
int tileHeight = colorizedTile.getHeight(null);
224
offsetTextureX = offsetTextureX % tileWidth;
225
offsetTextureY = offsetTextureY % tileHeight;
226
int currTileTop = -offsetTextureY;
228
int currTileLeft = -offsetTextureX;
230
graphics.drawImage(colorizedTile, currTileLeft, currTileTop,
232
currTileLeft += tileWidth;
233
} while (currTileLeft < width);
234
currTileTop += tileHeight;
235
} while (currTileTop < height);
241
* Sets the base decoration painter.
243
* @param baseDecorationPainter
244
* Base decoration painter.
246
public void setBaseDecorationPainter(
247
SubstanceDecorationPainter baseDecorationPainter) {
248
this.baseDecorationPainter = baseDecorationPainter;
252
* Sets the alpha channel for the image texture.
254
* @param textureAlpha
255
* Alpha channel for the image texture.
257
public void setTextureAlpha(float textureAlpha) {
258
this.textureAlpha = textureAlpha;
262
* Returns a colorized image tile.
265
* Color scheme for the colorization.
266
* @return Colorized tile.
268
protected Image getColorizedTile(SubstanceColorScheme scheme) {
269
Image result = this.colorizedTileMap.get(scheme.getDisplayName());
270
if (result == null) {
271
BufferedImage tileBi = new BufferedImage(this.originalTile
272
.getWidth(null), this.originalTile.getHeight(null),
273
BufferedImage.TYPE_INT_ARGB);
274
tileBi.getGraphics().drawImage(this.originalTile, 0, 0, null);
275
result = SubstanceImageCreator.getColorSchemeImage(tileBi, scheme,
277
this.colorizedTileMap.put(scheme.getDisplayName(), result);