~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/internal/utils/ButtonBackgroundDelegate.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 *  o Redistributions of source code must retain the above copyright notice,
 
8
 *    this list of conditions and the following disclaimer.
 
9
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
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.
 
29
 */
 
30
package org.pushingpixels.substance.internal.utils;
 
31
 
 
32
import java.awt.AlphaComposite;
 
33
import java.awt.Graphics;
 
34
import java.awt.Graphics2D;
 
35
import java.awt.Insets;
 
36
import java.awt.Shape;
 
37
import java.awt.image.BufferedImage;
 
38
import java.util.Map;
 
39
import java.util.Set;
 
40
 
 
41
import javax.swing.AbstractButton;
 
42
import javax.swing.ButtonModel;
 
43
import javax.swing.JButton;
 
44
 
 
45
import org.pushingpixels.lafwidget.LafWidgetUtilities;
 
46
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
 
47
import org.pushingpixels.substance.api.ComponentState;
 
48
import org.pushingpixels.substance.api.SubstanceColorScheme;
 
49
import org.pushingpixels.substance.api.SubstanceConstants;
 
50
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
 
51
import org.pushingpixels.substance.api.SubstanceConstants.Side;
 
52
import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter;
 
53
import org.pushingpixels.substance.api.painter.fill.SubstanceFillPainter;
 
54
import org.pushingpixels.substance.api.shaper.RectangularButtonShaper;
 
55
import org.pushingpixels.substance.api.shaper.StandardButtonShaper;
 
56
import org.pushingpixels.substance.api.shaper.SubstanceButtonShaper;
 
57
import org.pushingpixels.substance.internal.animation.ModificationAwareUI;
 
58
import org.pushingpixels.substance.internal.animation.RootPaneDefaultButtonTracker;
 
59
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
 
60
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
 
61
import org.pushingpixels.trident.Timeline;
 
62
import org.pushingpixels.trident.Timeline.TimelineState;
 
63
 
 
64
/**
 
65
 * Delegate class for painting backgrounds of buttons in <b>Substance </b> look
 
66
 * and feel. This class is <b>for internal use only</b>.
 
67
 * 
 
68
 * @author Kirill Grouchnikov
 
69
 */
 
70
public class ButtonBackgroundDelegate {
 
71
        /**
 
72
         * Cache for background images. Each time
 
73
         * {@link #getFullAlphaBackground(javax.swing.AbstractButton, javax.swing.ButtonModel, org.pushingpixels.substance.api.shaper.SubstanceButtonShaper, org.pushingpixels.substance.api.painter.fill.SubstanceFillPainter, org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter, int, int)}
 
74
         * is called, it checks <code>this</code> map to see if it already contains
 
75
         * such background. If so, the background from the map is returned.
 
76
         */
 
77
        private static LazyResettableHashMap<BufferedImage> regularBackgrounds = new LazyResettableHashMap<BufferedImage>(
 
78
                        "ButtonBackgroundDelegate");
 
79
 
 
80
        /**
 
81
         * Retrieves the background for the specified button.
 
82
         * 
 
83
         * @param button
 
84
         *            Button.
 
85
         * @param model
 
86
         *            Button model.
 
87
         * @param shaper
 
88
         *            Button shaper.
 
89
         * @param fillPainter
 
90
         *            Button fill painter.
 
91
         * @param borderPainter
 
92
         *            Button border painter.
 
93
         * @param width
 
94
         *            Button width.
 
95
         * @param height
 
96
         *            Button height.
 
97
         * @return Button background.
 
98
         */
 
99
        public static BufferedImage getFullAlphaBackground(AbstractButton button,
 
100
                        ButtonModel model, SubstanceButtonShaper shaper,
 
101
                        SubstanceFillPainter fillPainter,
 
102
                        SubstanceBorderPainter borderPainter, int width, int height) {
 
103
                TransitionAwareUI transitionAwareUI = (TransitionAwareUI) button
 
104
                                .getUI();
 
105
                StateTransitionTracker.ModelStateInfo modelStateInfo = transitionAwareUI
 
106
                                .getTransitionTracker().getModelStateInfo();
 
107
 
 
108
                ComponentState currState = modelStateInfo.getCurrModelState();
 
109
 
 
110
                // ComponentState prevState = stateTransitionModel.getPrevModelState();
 
111
 
 
112
                // System.out.println(button.getText() + ": " + prevState.name() +
 
113
                // " -> "
 
114
                // + state.name() + " at "
 
115
                // + stateTransitionModel.getTransitionPosition());
 
116
 
 
117
                // compute cycle count (for animation)
 
118
                float cyclePos = 0.0f;// currState.getCyclePosition();
 
119
                // boolean isPulsating = false;
 
120
                if (button instanceof JButton) {
 
121
                        JButton jb = (JButton) button;
 
122
                        if (RootPaneDefaultButtonTracker.isPulsating(jb)
 
123
                                        && (currState != ComponentState.PRESSED_SELECTED)
 
124
                                        && (currState != ComponentState.PRESSED_UNSELECTED)) {
 
125
                                // isPulsating = true;
 
126
                                cyclePos = RootPaneDefaultButtonTracker.getTimelinePosition(jb);
 
127
                        }
 
128
                }
 
129
 
 
130
                // compute the straight sides
 
131
                Set<SubstanceConstants.Side> straightSides = SubstanceCoreUtilities
 
132
                                .getSides(button, SubstanceLookAndFeel.BUTTON_SIDE_PROPERTY);
 
133
 
 
134
                boolean isRoundButton = StandardButtonShaper.isRoundButton(button);
 
135
                float radius = 0.0f;
 
136
                if (shaper instanceof RectangularButtonShaper) {
 
137
                        radius = ((RectangularButtonShaper) shaper).getCornerRadius(button,
 
138
                                        null);
 
139
                }
 
140
 
 
141
                Set<Side> openSides = SubstanceCoreUtilities.getSides(button,
 
142
                                SubstanceLookAndFeel.BUTTON_OPEN_SIDE_PROPERTY);
 
143
                // String openKey = "";
 
144
                // for (Side oSide : openSides) {
 
145
                // openKey += oSide.name() + "-";
 
146
                // }
 
147
                // String extraModelKey = "";
 
148
                // for (String modelKey : extraModelKeys) {
 
149
                // extraModelKey += (modelKey + "-");
 
150
                // }
 
151
                boolean isContentAreaFilled = button.isContentAreaFilled();
 
152
                boolean isBorderPainted = button.isBorderPainted();
 
153
 
 
154
                // compute color scheme
 
155
                SubstanceColorScheme baseBorderScheme = SubstanceColorSchemeUtilities
 
156
                                .getColorScheme(button, ColorSchemeAssociationKind.BORDER,
 
157
                                                currState);
 
158
 
 
159
                // see if need to use attention-drawing animation
 
160
                // boolean isWindowModified = false;
 
161
                if (button.getUI() instanceof ModificationAwareUI) {
 
162
                        ModificationAwareUI modificationAwareUI = (ModificationAwareUI) button
 
163
                                        .getUI();
 
164
                        Timeline modificationTimeline = modificationAwareUI
 
165
                                        .getModificationTimeline();
 
166
                        if (modificationTimeline != null) {
 
167
                                if (modificationTimeline.getState() != TimelineState.IDLE) {
 
168
                                        // isWindowModified = true;
 
169
                                        SubstanceColorScheme colorScheme2 = SubstanceColorSchemeUtilities.YELLOW;
 
170
                                        SubstanceColorScheme colorScheme = SubstanceColorSchemeUtilities.ORANGE;
 
171
                                        cyclePos = modificationTimeline.getTimelinePosition();
 
172
 
 
173
                                        HashMapKey key1 = SubstanceCoreUtilities.getHashKey(width,
 
174
                                                        height, colorScheme.getDisplayName(),
 
175
                                                        baseBorderScheme.getDisplayName(), shaper
 
176
                                                                        .getDisplayName(), fillPainter
 
177
                                                                        .getDisplayName(), borderPainter
 
178
                                                                        .getDisplayName(), straightSides,
 
179
                                                        openSides, button.getClass().getName(),
 
180
                                                        isRoundButton, radius, isContentAreaFilled,
 
181
                                                        isBorderPainted, SubstanceSizeUtils
 
182
                                                                        .getComponentFontSize(button));
 
183
                                        BufferedImage layer1 = regularBackgrounds.get(key1);
 
184
                                        if (layer1 == null) {
 
185
                                                layer1 = createBackgroundImage(button, shaper,
 
186
                                                                fillPainter, borderPainter, width, height,
 
187
                                                                colorScheme, baseBorderScheme, openSides,
 
188
                                                                isContentAreaFilled, isBorderPainted);
 
189
 
 
190
                                                regularBackgrounds.put(key1, layer1);
 
191
                                        }
 
192
                                        HashMapKey key2 = SubstanceCoreUtilities.getHashKey(width,
 
193
                                                        height, colorScheme2.getDisplayName(),
 
194
                                                        baseBorderScheme.getDisplayName(), shaper
 
195
                                                                        .getDisplayName(), fillPainter
 
196
                                                                        .getDisplayName(), borderPainter
 
197
                                                                        .getDisplayName(), straightSides,
 
198
                                                        openSides, button.getClass().getName(),
 
199
                                                        isRoundButton, radius, isContentAreaFilled,
 
200
                                                        isBorderPainted, SubstanceSizeUtils
 
201
                                                                        .getComponentFontSize(button));
 
202
                                        BufferedImage layer2 = regularBackgrounds.get(key2);
 
203
                                        if (layer2 == null) {
 
204
                                                layer2 = createBackgroundImage(button, shaper,
 
205
                                                                fillPainter, borderPainter, width, height,
 
206
                                                                colorScheme2, baseBorderScheme, openSides,
 
207
                                                                isContentAreaFilled, isBorderPainted);
 
208
 
 
209
                                                regularBackgrounds.put(key2, layer2);
 
210
                                        }
 
211
 
 
212
                                        BufferedImage result = SubstanceCoreUtilities
 
213
                                                        .getBlankImage(width, height);
 
214
                                        Graphics2D g2d = result.createGraphics();
 
215
                                        if (cyclePos < 1.0f)
 
216
                                                g2d.drawImage(layer1, 0, 0, null);
 
217
                                        if (cyclePos > 0.0f) {
 
218
                                                g2d.setComposite(AlphaComposite.SrcOver
 
219
                                                                .derive(cyclePos));
 
220
                                                g2d.drawImage(layer2, 0, 0, null);
 
221
                                        }
 
222
                                        g2d.dispose();
 
223
                                        return result;
 
224
                                }
 
225
                        }
 
226
                }
 
227
 
 
228
                // see if need to use transition animation. Important - don't do it
 
229
                // on pulsating buttons (such as default or close buttons
 
230
                // of modified frames).
 
231
 
 
232
                Map<ComponentState, StateTransitionTracker.StateContributionInfo> activeStates = modelStateInfo
 
233
                                .getStateContributionMap();
 
234
 
 
235
                SubstanceColorScheme baseFillScheme = SubstanceColorSchemeUtilities
 
236
                                .getColorScheme(button, currState);
 
237
                HashMapKey keyBase = SubstanceCoreUtilities.getHashKey(width, height,
 
238
                                baseFillScheme.getDisplayName(), baseBorderScheme
 
239
                                                .getDisplayName(), shaper.getDisplayName(), fillPainter
 
240
                                                .getDisplayName(), borderPainter.getDisplayName(),
 
241
                                straightSides, openSides, button.getClass().getName(),
 
242
                                isRoundButton, (int) (1000 * radius), isContentAreaFilled,
 
243
                                isBorderPainted, SubstanceSizeUtils
 
244
                                                .getComponentFontSize(button));
 
245
                BufferedImage layerBase = regularBackgrounds.get(keyBase);
 
246
                if (layerBase == null) {
 
247
                        layerBase = createBackgroundImage(button, shaper, fillPainter,
 
248
                                        borderPainter, width, height, baseFillScheme,
 
249
                                        baseBorderScheme, openSides, isContentAreaFilled,
 
250
                                        isBorderPainted);
 
251
                        regularBackgrounds.put(keyBase, layerBase);
 
252
                }
 
253
                if (currState.isDisabled() || (activeStates.size() == 1)) {
 
254
                        return layerBase;
 
255
                }
 
256
 
 
257
                BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
 
258
                                height);
 
259
                Graphics2D g2d = result.createGraphics();
 
260
                // draw the base layer
 
261
                g2d.drawImage(layerBase, 0, 0, null);
 
262
                // System.out.println("\nPainting base state " + currState);
 
263
 
 
264
                // draw the other active layers
 
265
                for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : activeStates
 
266
                                .entrySet()) {
 
267
                        ComponentState activeState = activeEntry.getKey();
 
268
                        // System.out.println("Painting state " + activeState + "[curr is "
 
269
                        // + currState + "] with " + activeEntry.getValue());
 
270
                        if (activeState == currState)
 
271
                                continue;
 
272
 
 
273
                        float stateContribution = activeEntry.getValue().getContribution();
 
274
                        if (stateContribution > 0.0f) {
 
275
                                g2d.setComposite(AlphaComposite.SrcOver
 
276
                                                .derive(stateContribution));
 
277
 
 
278
                                SubstanceColorScheme fillScheme = SubstanceColorSchemeUtilities
 
279
                                                .getColorScheme(button, activeState);
 
280
                                SubstanceColorScheme borderScheme = SubstanceColorSchemeUtilities
 
281
                                                .getColorScheme(button,
 
282
                                                                ColorSchemeAssociationKind.BORDER, activeState);
 
283
                                HashMapKey key = SubstanceCoreUtilities.getHashKey(width,
 
284
                                                height, fillScheme.getDisplayName(), borderScheme
 
285
                                                                .getDisplayName(), shaper.getDisplayName(),
 
286
                                                fillPainter.getDisplayName(), borderPainter
 
287
                                                                .getDisplayName(), straightSides, openSides,
 
288
                                                button.getClass().getName(), isRoundButton,
 
289
                                                (int) (1000 * radius), isContentAreaFilled,
 
290
                                                isBorderPainted, SubstanceSizeUtils
 
291
                                                                .getComponentFontSize(button));
 
292
                                BufferedImage layer = regularBackgrounds.get(key);
 
293
                                if (layer == null) {
 
294
                                        layer = createBackgroundImage(button, shaper, fillPainter,
 
295
                                                        borderPainter, width, height, fillScheme,
 
296
                                                        borderScheme, openSides, isContentAreaFilled,
 
297
                                                        isBorderPainted);
 
298
                                        regularBackgrounds.put(key, layer);
 
299
                                }
 
300
                                g2d.drawImage(layer, 0, 0, null);
 
301
                        }
 
302
                }
 
303
                g2d.dispose();
 
304
                return result;
 
305
        }
 
306
 
 
307
        private static BufferedImage createBackgroundImage(AbstractButton button,
 
308
                        SubstanceButtonShaper shaper, SubstanceFillPainter fillPainter,
 
309
                        SubstanceBorderPainter borderPainter, int width, int height,
 
310
                        SubstanceColorScheme colorScheme,
 
311
                        SubstanceColorScheme borderScheme, Set<Side> openSides,
 
312
                        boolean isContentAreaFilled, boolean isBorderPainted) {
 
313
                int openDelta = (int) (Math.ceil(3.0 * SubstanceSizeUtils
 
314
                                .getBorderStrokeWidth(SubstanceSizeUtils
 
315
                                                .getComponentFontSize(button))));
 
316
                int deltaLeft = ((openSides != null) && openSides.contains(Side.LEFT)) ? openDelta
 
317
                                : 0;
 
318
                int deltaRight = ((openSides != null) && openSides.contains(Side.RIGHT)) ? openDelta
 
319
                                : 0;
 
320
                int deltaTop = ((openSides != null) && openSides.contains(Side.TOP)) ? openDelta
 
321
                                : 0;
 
322
                int deltaBottom = ((openSides != null) && openSides
 
323
                                .contains(Side.BOTTOM)) ? openDelta : 0;
 
324
 
 
325
                // System.err.println(key);
 
326
                int borderDelta = (int) Math.floor(SubstanceSizeUtils
 
327
                                .getBorderStrokeWidth(SubstanceSizeUtils
 
328
                                                .getComponentFontSize(button)) / 2.0);
 
329
                Shape contour = shaper.getButtonOutline(button, new Insets(borderDelta,
 
330
                                borderDelta, borderDelta, borderDelta), width + deltaLeft
 
331
                                + deltaRight, height + deltaTop + deltaBottom, false);
 
332
 
 
333
                BufferedImage newBackground = SubstanceCoreUtilities.getBlankImage(
 
334
                                width, height);
 
335
                Graphics2D finalGraphics = (Graphics2D) newBackground.getGraphics();
 
336
                finalGraphics.translate(-deltaLeft, -deltaTop);
 
337
                if (isContentAreaFilled) {
 
338
                        fillPainter.paintContourBackground(finalGraphics, button, width
 
339
                                        + deltaLeft + deltaRight, height + deltaTop + deltaBottom,
 
340
                                        contour, false, colorScheme, true);
 
341
                }
 
342
 
 
343
                if (isBorderPainted) {
 
344
                        int borderThickness = (int) SubstanceSizeUtils
 
345
                                        .getBorderStrokeWidth(SubstanceSizeUtils
 
346
                                                        .getComponentFontSize(button));
 
347
                        Shape contourInner = borderPainter.isPaintingInnerContour() ? shaper
 
348
                                        .getButtonOutline(button, new Insets(borderDelta
 
349
                                                        + borderThickness, borderDelta + borderThickness,
 
350
                                                        borderDelta + borderThickness, borderDelta
 
351
                                                                        + borderThickness), width + deltaLeft
 
352
                                                        + deltaRight, height + deltaTop + deltaBottom, true)
 
353
                                        : null;
 
354
                        borderPainter.paintBorder(finalGraphics, button, width + deltaLeft
 
355
                                        + deltaRight, height + deltaTop + deltaBottom, contour,
 
356
                                        contourInner, borderScheme);
 
357
                }
 
358
                return newBackground;
 
359
        }
 
360
 
 
361
        /**
 
362
         * Simple constructor.
 
363
         */
 
364
        public ButtonBackgroundDelegate() {
 
365
                super();
 
366
        }
 
367
 
 
368
        /**
 
369
         * Updates background of the specified button.
 
370
         * 
 
371
         * @param g
 
372
         *            Graphic context.
 
373
         * @param button
 
374
         *            Button to update.
 
375
         */
 
376
        public void updateBackground(Graphics g, AbstractButton button) {
 
377
                // failsafe for LAF change
 
378
                if (!SubstanceLookAndFeel.isCurrentLookAndFeel())
 
379
                        return;
 
380
 
 
381
                if (SubstanceCoreUtilities.isButtonNeverPainted(button))
 
382
                        return;
 
383
 
 
384
                int width = button.getWidth();
 
385
                int height = button.getHeight();
 
386
                int y = 0;
 
387
                if (SubstanceCoreUtilities.isScrollButton(button)
 
388
                                || SubstanceCoreUtilities.isSpinnerButton(button)) {
 
389
                        Sideable sideable = (Sideable) button;
 
390
                        PairwiseButtonBackgroundDelegate.updatePairwiseBackground(g,
 
391
                                        button, width, height, sideable.getSide(), false);
 
392
                        return;
 
393
                }
 
394
 
 
395
                SubstanceFillPainter fillPainter = SubstanceCoreUtilities
 
396
                                .getFillPainter(button);
 
397
                SubstanceButtonShaper shaper = SubstanceCoreUtilities
 
398
                                .getButtonShaper(button);
 
399
                SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
 
400
                                .getBorderPainter(button);
 
401
 
 
402
                BufferedImage bgImage = getFullAlphaBackground(button, button
 
403
                                .getModel(), shaper, fillPainter, borderPainter, width, height);
 
404
 
 
405
                TransitionAwareUI transitionAwareUI = (TransitionAwareUI) button
 
406
                                .getUI();
 
407
                StateTransitionTracker stateTransitionTracker = transitionAwareUI
 
408
                                .getTransitionTracker();
 
409
                StateTransitionTracker.ModelStateInfo modelStateInfo = stateTransitionTracker
 
410
                                .getModelStateInfo();
 
411
                Map<ComponentState, StateTransitionTracker.StateContributionInfo> activeStates = modelStateInfo
 
412
                                .getStateContributionMap();
 
413
 
 
414
                // Two special cases here:
 
415
                // 1. Button has flat appearance.
 
416
                // 2. Button is disabled.
 
417
                // For both cases, we need to set custom translucency.
 
418
                boolean isFlat = SubstanceCoreUtilities.hasFlatAppearance(button);
 
419
                boolean isSpecial = isFlat || !button.isEnabled();
 
420
                float extraAlpha = 1.0f;
 
421
                if (isSpecial) {
 
422
                        if (isFlat) {
 
423
                                // Special handling of flat buttons
 
424
                                extraAlpha = 0.0f;
 
425
                                for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : activeStates
 
426
                                                .entrySet()) {
 
427
                                        ComponentState activeState = activeEntry.getKey();
 
428
                                        if (activeState.isDisabled())
 
429
                                                continue;
 
430
                                        if (activeState == ComponentState.ENABLED)
 
431
                                                continue;
 
432
                                        extraAlpha += activeEntry.getValue().getContribution();
 
433
                                }
 
434
                        } else {
 
435
                                if (!button.isEnabled()) {
 
436
                                        extraAlpha = SubstanceColorSchemeUtilities.getAlpha(button,
 
437
                                                        modelStateInfo.getCurrModelState());
 
438
                                }
 
439
                        }
 
440
                }
 
441
                if (extraAlpha > 0.0f) {
 
442
                        Graphics2D graphics = (Graphics2D) g.create();
 
443
                        graphics.setComposite(LafWidgetUtilities.getAlphaComposite(button,
 
444
                                        extraAlpha, g));
 
445
                        graphics.drawImage(bgImage, 0, y, null);
 
446
                        graphics.dispose();
 
447
                }
 
448
        }
 
449
 
 
450
        /**
 
451
         * Checks whether the specified button has round corners.
 
452
         * 
 
453
         * @param button
 
454
         *            Button to check.
 
455
         * @return <code>true</code> if the specified button has round corners,
 
456
         *         <code>false</code> otherwise.
 
457
         */
 
458
        public static boolean isRoundButton(AbstractButton button) {
 
459
                return (!SubstanceCoreUtilities.isComboBoxButton(button))
 
460
                                && (!SubstanceCoreUtilities.isScrollButton(button))
 
461
                                && SubstanceCoreUtilities.hasText(button);
 
462
        }
 
463
 
 
464
        /**
 
465
         * Returns <code>true</code> if the specified <i>x,y </i> location is
 
466
         * contained within the look and feel's defined shape of the specified
 
467
         * component. <code>x</code> and <code>y</code> are defined to be relative
 
468
         * to the coordinate system of the specified component.
 
469
         * 
 
470
         * @param button
 
471
         *            the component where the <i>x,y </i> location is being queried;
 
472
         * @param x
 
473
         *            the <i>x </i> coordinate of the point
 
474
         * @param y
 
475
         *            the <i>y </i> coordinate of the point
 
476
         * @return <code>true</code> if the specified <i>x,y </i> location is
 
477
         *         contained within the look and feel's defined shape of the
 
478
         *         specified component, <code>false</code> otherwise.
 
479
         */
 
480
        public static boolean contains(AbstractButton button, int x, int y) {
 
481
                // failsafe for LAF change
 
482
                if (!SubstanceLookAndFeel.isCurrentLookAndFeel()) {
 
483
                        return false;
 
484
                }
 
485
                SubstanceButtonShaper shaper = SubstanceCoreUtilities
 
486
                                .getButtonShaper(button);
 
487
                if (shaper == null)
 
488
                        return false;
 
489
                Shape contour = shaper.getButtonOutline(button, null,
 
490
                                button.getWidth(), button.getHeight(), false);
 
491
                return contour.contains(x, y);
 
492
        }
 
493
 
 
494
        /**
 
495
         * Returns the memory usage string.
 
496
         * 
 
497
         * @return Memory usage string.
 
498
         */
 
499
        static String getMemoryUsage() {
 
500
                StringBuffer sb = new StringBuffer();
 
501
                sb.append("SubstanceBackgroundDelegate: \n");
 
502
                sb.append("\t" + regularBackgrounds.size() + " regular");
 
503
                // + pairwiseBackgrounds.size() + " pairwise");
 
504
                return sb.toString();
 
505
        }
 
506
 
 
507
}