001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance;
031:
032: import java.awt.*;
033:
034: import javax.swing.*;
035:
036: import org.jvnet.lafwidget.LafWidgetUtilities;
037: import org.jvnet.lafwidget.layout.TransitionLayout;
038: import org.jvnet.substance.painter.decoration.DecorationAreaType;
039: import org.jvnet.substance.painter.decoration.SubstanceDecorationUtilities;
040: import org.jvnet.substance.theme.SubstanceTheme;
041: import org.jvnet.substance.utils.*;
042:
043: /**
044: * Delegate for painting filled backgrounds.
045: *
046: * @author Kirill Grouchnikov
047: */
048: public class SubstanceFillBackgroundDelegate {
049: /**
050: * Alpha composite of <code>this</code> delegate. The default value is 1.0
051: * which results in completely opaque background. However, in some cases, we
052: * need to draw partially translucent background, as in menus.
053: */
054: private float watermarkAlpha;
055: /**
056: * Background delegate.
057: */
058: public static final SubstanceFillBackgroundDelegate GLOBAL_INSTANCE = new SubstanceFillBackgroundDelegate();
059:
060: /**
061: * Creates a new opaque fill background delegate.
062: */
063: public SubstanceFillBackgroundDelegate() {
064: this (1.0f);
065: }
066:
067: /**
068: * Creates a new translucent fill background delegate.
069: *
070: * @param watermarkAlpha
071: * Alpha composite of <code>this</code> delegate. The default
072: * value is 1.0 which results in completely opaque background.
073: * However, in some cases, we need to draw partially translucent
074: * background, as in menus.
075: */
076: public SubstanceFillBackgroundDelegate(float watermarkAlpha) {
077: this .watermarkAlpha = watermarkAlpha;
078: }
079:
080: // /**
081: // * Updates the background of the specified component on the specified
082: // * graphic context.
083: // *
084: // * @param g
085: // * Graphic context.
086: // * @param c
087: // * Component.
088: // */
089: // public void update(Graphics g, Component c) {
090: // this.update(g, c, SubstanceCoreUtilities.isInHeader(c));
091: // }
092: //
093: /**
094: * Updates the background of the specified component on the specified
095: * graphic context. The background is updated only if the component is
096: * opaque.
097: *
098: * @param g
099: * Graphic context.
100: * @param c
101: * Component.
102: */
103: public void updateIfOpaque(Graphics g, Component c) {
104: if (TransitionLayout.isOpaque(c))
105: this .update(g, c, false);
106: }
107:
108: /**
109: * Updates the background of the specified component on the specified
110: * graphic context.
111: *
112: * @param g
113: * Graphic context.
114: * @param c
115: * Component.
116: */
117: public void update(Graphics g, Component c, boolean force) {
118: // failsafe for LAF change
119: if (!(UIManager.getLookAndFeel() instanceof SubstanceLookAndFeel)) {
120: return;
121: }
122:
123: boolean isInCellRenderer = (c.getParent() instanceof CellRendererPane);
124: boolean isPreviewMode = false;
125: if (c instanceof JComponent) {
126: isPreviewMode = (Boolean.TRUE
127: .equals(((JComponent) c)
128: .getClientProperty(LafWidgetUtilities.PREVIEW_MODE)));
129: }
130: if (!force && !isPreviewMode && !c.isShowing()
131: && !isInCellRenderer) {
132: return;
133: }
134:
135: Graphics2D graphics = (Graphics2D) g.create();
136: // synchronized (c) {
137: // if (TransitionLayout.isOpaque(c)) {
138: // fill background
139: graphics.setComposite(TransitionLayout.getAlphaComposite(c, g));
140: // this.alphaComposite));
141:
142: DecorationAreaType decorationType = SubstanceDecorationUtilities
143: .getDecorationType(c);
144: SubstanceTheme componentTheme = SubstanceThemeUtilities
145: .getNonColorizedTheme(c, true);
146: if ((decorationType != null)
147: && (componentTheme
148: .toUseDecorationPainter(decorationType))) {
149: SubstanceDecorationUtilities.paintDecorationBackground(
150: graphics, c, force);
151: } else {
152: Color backgr = SubstanceCoreUtilities
153: .getBackgroundFillColor(c);
154: graphics.setColor(backgr);
155: graphics.fillRect(0, 0, c.getWidth(), c.getHeight());
156:
157: if (((c instanceof JToolBar) || (SwingUtilities
158: .getAncestorOfClass(JToolBar.class, c) != null))
159: && componentTheme.isPaintingToolbarDropShadows()) {
160: Color headerColor = SubstanceColorUtilities
161: .getBackgroundColor(
162: SubstanceLookAndFeel.getTheme())
163: .darker();
164:
165: // need to handle toolbars "embedded" in other toolbars
166: int dy = 0;
167: int totalOffsetY = 0;
168: Component comp = c;
169: while (comp.getParent() != null) {
170: Component parent = comp.getParent();
171: dy += comp.getY();
172: if (parent instanceof JToolBar) {
173: totalOffsetY += dy;
174: dy = 0;
175: }
176: comp = parent;
177: }
178:
179: graphics.translate(0, -totalOffsetY);
180: graphics.setPaint(new GradientPaint(0, 0,
181: SubstanceColorUtilities.getAlphaColor(
182: headerColor, 160), 0, 4,
183: SubstanceColorUtilities.getAlphaColor(
184: headerColor, 16)));
185: graphics.fillRect(0, 0, c.getWidth(), 4);
186: graphics.translate(0, totalOffsetY);
187: }
188:
189: if (!isPreviewMode
190: && !isInCellRenderer
191: && c.isShowing()
192: && (SubstanceCoreUtilities.toDrawWatermark(c) || SubstanceCoreUtilities
193: .toBleedWatermark(c))) {
194: SubstanceLookAndFeel.getCurrentWatermark()
195: .drawWatermarkImage(graphics, c, 0, 0,
196: c.getWidth(), c.getHeight());
197: }
198: }
199:
200: // TODO : drop shadows
201:
202: // JRootPane rootPane = SwingUtilities.getRootPane(c);
203: // SubstanceTitlePainter titlePainter = SubstanceCoreUtilities
204: // .getTitlePainter(rootPane);
205: // boolean shouldUseHeaderPainter = useHeaderPainter
206: // && (titlePainter instanceof SubstanceHeaderPainter);
207: // boolean paintDropShadow = false;
208: // if (shouldUseHeaderPainter
209: // && ((c instanceof JToolBar) || (SwingUtilities
210: // .getAncestorOfClass(JToolBar.class, c) != null))) {
211: // SubstanceHeaderPainter headerPainter = (SubstanceHeaderPainter)
212: // titlePainter;
213: // shouldUseHeaderPainter = headerPainter
214: // .isPaintingContainer((Container) c);
215: // paintDropShadow = shouldUseHeaderPainter ? false
216: // : headerPainter.isPaintingToolbarDropShadows();
217: // }
218: // Container headerParent = SubstanceCoreUtilities.getHeaderParent(c);
219: // if (shouldUseHeaderPainter
220: // && (SwingUtilities.getAncestorOfClass(JToolBar.class, c) != null)
221: // /* (headerParent instanceof JToolBar) */) {
222: // shouldUseHeaderPainter = ((SubstanceHeaderPainter) titlePainter)
223: // .isPaintingContainer((Container) c);
224: // }
225: //
226: // Window window = SwingUtilities.windowForComponent(c);
227: // boolean isSelected = (window == null) ? true : window.isActive();
228: // SubstanceTheme theme = isSelected ? SubstanceLookAndFeel.getTheme()
229: // .getActiveTitlePaneTheme() : SubstanceLookAndFeel
230: // .getTheme().getDefaultTitlePaneTheme();
231: //
232: // Component rpc = SwingUtilities.getAncestorOfClass(
233: // RootPaneContainer.class, c);
234: // if ((rpc != null) && SubstanceCoreUtilities.hasColorization(c)) {
235: // Color backgr = rpc.getBackground();
236: // if (!(backgr instanceof UIResource)) {
237: // double colorization = SubstanceCoreUtilities
238: // .getColorizationFactor(rpc);
239: // theme = SubstanceShiftTheme.getShiftedTheme(theme, backgr,
240: // colorization, null, 0.0);
241: // }
242: // }
243: //
244: // if (shouldUseHeaderPainter) {
245: //
246: // // if (c instanceof JMenuItem) {
247: // // System.out.println("Using " + theme.getDisplayName()
248: // // + " to paint " + ((JMenuItem) c).getText());
249: // // }
250: //
251: // SubstanceHeaderPainter headerPainter = (SubstanceHeaderPainter)
252: // titlePainter;
253: // // if (!(c instanceof JMenuItem)) {
254: // headerPainter.paintExtraBackground(graphics, headerParent, c, c
255: // .getWidth(), c.getHeight(), theme, false);
256: // // }
257: // } else {
258: // if (c instanceof JMenu) {
259: // Color headerBackgroundColor = SubstanceColorUtilities
260: // .getBackgroundColor(SubstanceLookAndFeel.getTheme()
261: // .getActiveTitlePaneTheme());
262: // if (shouldUseHeaderPainter
263: // && (c.getParent() instanceof JMenuBar))
264: // graphics.setColor(headerBackgroundColor);
265: // else
266: // graphics.setColor(SubstanceCoreUtilities
267: // .getBackgroundFillColor(c));
268: // } else {
269: // Color backgr = SubstanceCoreUtilities
270: // .getBackgroundFillColor(c);
271: // graphics.setColor(backgr);
272: // }
273: // // if (c instanceof JMenuItem) {
274: // // System.out.println("Filling " + ((JMenuItem) c).getText()
275: // // + "[" + ((JMenuItem) c).isEnabled() + "] with "
276: // // + graphics.getColor().getRed() + ":"
277: // // + graphics.getColor().getGreen() + ":"
278: // // + graphics.getColor().getBlue());
279: // // }
280: // graphics.fillRect(0, 0, c.getWidth(), c.getHeight());
281: // }
282: // if (paintDropShadow) {
283: // Color headerColor = SubstanceColorUtilities.getBackgroundColor(
284: // SubstanceLookAndFeel.getTheme()).darker();
285: // // theme.getDefaultColorScheme().getMidColor();
286: //
287: // // Color neg = SubstanceColorUtilities.getNegativeColor(c
288: // // .getBackground());
289: //
290: // // need to handle toolbars "embedded" in other toolbars
291: // int dy = 0;
292: // int totalOffsetY = 0;
293: // Component comp = c;
294: // while (comp.getParent() != null) {
295: // Component parent = comp.getParent();
296: // dy += comp.getY();
297: // if (parent instanceof JToolBar) {
298: // totalOffsetY += dy;
299: // dy = 0;
300: // }
301: // comp = parent;
302: // }
303: //
304: // graphics.translate(0, -totalOffsetY);
305: // graphics
306: // .setPaint(new GradientPaint(0, 0,
307: // SubstanceColorUtilities.getAlphaColor(
308: // headerColor, 160), 0, 4,
309: // SubstanceColorUtilities.getAlphaColor(
310: // headerColor, 16)));
311: // graphics.fillRect(0, 0, c.getWidth(), 4);
312: // graphics.translate(0, totalOffsetY);
313: // }
314: // // if (c.getClass().getName().contains("DesktopPanel"))
315: // // System.out.println("Painting DesktopPanel with color "
316: // // + c.getBackground()
317: // // + "["
318: // // + c.isOpaque()
319: // // + "]"
320: // // + " on "
321: // // + ((AlphaComposite) graphics.getComposite())
322: // // .getAlpha());
323: // // if (c instanceof JDesktopPane)
324: // // System.out.println("Painting JDesktopPane with color "
325: // // + c.getBackground()
326: // // + "["
327: // // + c.isOpaque()
328: // // + "]"
329: // // + " on "
330: // // + ((AlphaComposite) graphics.getComposite())
331: // // .getAlpha());
332: // // if (c.getClass().getName().contains("TextFieldsPanel"))
333: // // System.out.println("Painting TextFieldsPanel with color "
334: // // + c.getBackground()
335: // // + "["
336: // // + c.isOpaque()
337: // // + "]"
338: // // + " on "
339: // // + ((AlphaComposite) graphics.getComposite())
340: // // .getAlpha());
341: //
342: // graphics.setComposite(TransitionLayout.getAlphaComposite(c,
343: // this.alphaComposite, g));
344: // // graphics.setComposite(AlphaComposite.getInstance(
345: // // AlphaComposite.SRC_OVER, this.alphaComposite));
346: // // stamp watermark
347: // if (!isPreviewMode
348: // && !isInCellRenderer
349: // && c.isShowing()
350: // && (SubstanceCoreUtilities.toDrawWatermark(c) ||
351: // SubstanceCoreUtilities
352: // .toBleedWatermark(c))) {
353: // SubstanceLookAndFeel.getCurrentWatermark().drawWatermarkImage(
354: // graphics, c, 0, 0, c.getWidth(), c.getHeight());
355: //
356: // // paint the background second time with 50% translucency,
357: // // making the watermark 'bleed' through.
358: // if (shouldUseHeaderPainter) {
359: // // Window window = SwingUtilities.windowForComponent(c);
360: // // boolean isSelected = (window == null) ? true : window
361: // // .isActive();
362: // // SubstanceTheme theme = isSelected ? SubstanceLookAndFeel
363: // // .getTheme().getActiveTitlePaneTheme()
364: // // : SubstanceLookAndFeel.getTheme()
365: // // .getDefaultTitlePaneTheme();
366: //
367: // SubstanceHeaderPainter headerPainter = (SubstanceHeaderPainter)
368: // titlePainter;
369: // graphics.setComposite(TransitionLayout.getAlphaComposite(c,
370: // 0.5f * this.alphaComposite, g));
371: // headerPainter.paintExtraBackground(graphics, headerParent,
372: // c, c.getWidth(), c.getHeight(), theme, false);
373: // } else {
374: // // graphics.setColor(c.getBackground());
375: // // if (c instanceof JMenuItem) {
376: // // System.out.println("Filling "
377: // // + ((JMenuItem) c).getText() + " with "
378: // // + graphics.getColor().getRed() + ":"
379: // // + graphics.getColor().getGreen() + ":"
380: // // + graphics.getColor().getBlue());
381: // // }
382: // // graphics.fillRect(0, 0, c.getWidth(), c.getHeight());
383: // }
384: // // }
385: // }
386: // }
387: graphics.dispose();
388: }
389:
390: /**
391: * Updates the background of the specified component on the specified
392: * graphic context in the specified rectangle.
393: *
394: * @param g
395: * Graphic context.
396: * @param c
397: * Component.
398: * @param fillColor
399: * Fill color.
400: * @param rect
401: * The rectangle to fill.
402: */
403: public void fillAndWatermark(Graphics g, JComponent c,
404: Color fillColor, Rectangle rect) {
405: // failsafe for LAF change
406: if (!(UIManager.getLookAndFeel() instanceof SubstanceLookAndFeel)) {
407: return;
408: }
409:
410: boolean isInCellRenderer = (c.getParent() instanceof CellRendererPane);
411: if ((!c.isShowing()) && (!isInCellRenderer)) {
412: return;
413: }
414:
415: Graphics2D graphics = (Graphics2D) g.create();
416: synchronized (c) {
417: // if (TransitionLayout.isOpaque(c)) {
418: // fill background
419: graphics.setComposite(TransitionLayout.getAlphaComposite(c,
420: g));
421: graphics.setColor(fillColor);
422: graphics.fillRect(rect.x, rect.y, rect.width, rect.height);
423: graphics.setComposite(TransitionLayout.getAlphaComposite(c,
424: watermarkAlpha, g));
425: // stamp watermark
426: if (!isInCellRenderer
427: && c.isShowing()
428: && (SubstanceCoreUtilities.toDrawWatermark(c) || SubstanceCoreUtilities
429: .toBleedWatermark(c)))
430: SubstanceLookAndFeel.getCurrentWatermark()
431: .drawWatermarkImage(graphics, c, rect.x,
432: rect.y, rect.width, rect.height);
433: // }
434: }
435: graphics.dispose();
436: }
437:
438: /**
439: * Sets the watermark alpha (translucency) attribute for this delegate.
440: *
441: * @param watermarkAlpha
442: * Watermark alpha (translucency) attribute for this delegate.
443: */
444: public void setWatermarkAlpha(float watermarkAlpha) {
445: this.watermarkAlpha = watermarkAlpha;
446: }
447: }
|