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

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/internal/ui/SubstanceToggleButtonUI.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.ui;
 
31
 
 
32
import java.awt.Component;
 
33
import java.awt.Dimension;
 
34
import java.awt.Font;
 
35
import java.awt.FontMetrics;
 
36
import java.awt.Graphics;
 
37
import java.awt.Graphics2D;
 
38
import java.awt.Insets;
 
39
import java.awt.Rectangle;
 
40
import java.awt.event.MouseEvent;
 
41
import java.beans.PropertyChangeEvent;
 
42
import java.beans.PropertyChangeListener;
 
43
 
 
44
import javax.swing.AbstractButton;
 
45
import javax.swing.Icon;
 
46
import javax.swing.JCheckBox;
 
47
import javax.swing.JComponent;
 
48
import javax.swing.JRadioButton;
 
49
import javax.swing.JToggleButton;
 
50
import javax.swing.LookAndFeel;
 
51
import javax.swing.SwingUtilities;
 
52
import javax.swing.border.Border;
 
53
import javax.swing.plaf.ComponentUI;
 
54
import javax.swing.plaf.basic.BasicButtonListener;
 
55
import javax.swing.plaf.basic.BasicHTML;
 
56
import javax.swing.plaf.basic.BasicToggleButtonUI;
 
57
import javax.swing.text.View;
 
58
 
 
59
import org.pushingpixels.lafwidget.LafWidgetUtilities;
 
60
import org.pushingpixels.lafwidget.animation.AnimationConfigurationManager;
 
61
import org.pushingpixels.lafwidget.animation.AnimationFacet;
 
62
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
 
63
import org.pushingpixels.substance.api.shaper.SubstanceButtonShaper;
 
64
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
 
65
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
 
66
import org.pushingpixels.substance.internal.utils.ButtonBackgroundDelegate;
 
67
import org.pushingpixels.substance.internal.utils.ButtonVisualStateTracker;
 
68
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
 
69
import org.pushingpixels.substance.internal.utils.SubstanceSizeUtils;
 
70
import org.pushingpixels.substance.internal.utils.SubstanceTextUtilities;
 
71
import org.pushingpixels.substance.internal.utils.border.SubstanceButtonBorder;
 
72
import org.pushingpixels.substance.internal.utils.icon.GlowingIcon;
 
73
 
 
74
/**
 
75
 * UI for toggle buttons in <b>Substance</b> look and feel.
 
76
 * 
 
77
 * @author Kirill Grouchnikov
 
78
 */
 
79
public class SubstanceToggleButtonUI extends BasicToggleButtonUI implements
 
80
                TransitionAwareUI {
 
81
        /**
 
82
         * Painting delegate.
 
83
         */
 
84
        private ButtonBackgroundDelegate delegate;
 
85
 
 
86
        /**
 
87
         * The matching glowing icon. Is used only when
 
88
         * {@link AnimationConfigurationManager#isAnimationAllowed(AnimationFacet, Component)}
 
89
         * returns true on {@link AnimationFacet#ICON_GLOW}.
 
90
         */
 
91
        protected GlowingIcon glowingIcon;
 
92
 
 
93
        /**
 
94
         * Property change listener. Listens on changes to the
 
95
         * {@link SubstanceLookAndFeel#BUTTON_SHAPER_PROPERTY} property and
 
96
         * {@link AbstractButton#MODEL_CHANGED_PROPERTY} property.
 
97
         */
 
98
        protected PropertyChangeListener substancePropertyListener;
 
99
 
 
100
        /**
 
101
         * Tracker for visual state transitions.
 
102
         */
 
103
        protected ButtonVisualStateTracker substanceVisualStateTracker;
 
104
 
 
105
        protected JToggleButton toggleButton;
 
106
 
 
107
        private Rectangle viewRect = new Rectangle();
 
108
 
 
109
        private Rectangle iconRect = new Rectangle();
 
110
 
 
111
        private Rectangle textRect = new Rectangle();
 
112
 
 
113
        /*
 
114
         * (non-Javadoc)
 
115
         * 
 
116
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
117
         */
 
118
        public static ComponentUI createUI(JComponent comp) {
 
119
                SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
 
120
                return new SubstanceToggleButtonUI((JToggleButton) comp);
 
121
        }
 
122
 
 
123
        /**
 
124
         * Simple constructor.
 
125
         */
 
126
        public SubstanceToggleButtonUI(JToggleButton toggleButton) {
 
127
                this.toggleButton = toggleButton;
 
128
                this.delegate = new ButtonBackgroundDelegate();
 
129
        }
 
130
 
 
131
        /*
 
132
         * (non-Javadoc)
 
133
         * 
 
134
         * @seejavax.swing.plaf.basic.BasicButtonUI#installDefaults(javax.swing.
 
135
         * AbstractButton)
 
136
         */
 
137
        @Override
 
138
        public void installDefaults(AbstractButton b) {
 
139
                super.installDefaults(b);
 
140
                if (b.getClientProperty(SubstanceButtonUI.BORDER_ORIGINAL) == null)
 
141
                        b.putClientProperty(SubstanceButtonUI.BORDER_ORIGINAL, b
 
142
                                        .getBorder());
 
143
 
 
144
                if (b.getClientProperty(SubstanceButtonUI.BORDER_ORIGINAL) == null)
 
145
                        b.putClientProperty(SubstanceButtonUI.BORDER_ORIGINAL, b
 
146
                                        .getBorder());
 
147
 
 
148
                SubstanceButtonShaper shaper = SubstanceCoreUtilities
 
149
                                .getButtonShaper(b);
 
150
 
 
151
                if (b.getClientProperty(SubstanceButtonUI.BORDER_COMPUTED) == null) {
 
152
                        b.setBorder(shaper.getButtonBorder(b));
 
153
                } else {
 
154
                        Border currBorder = b.getBorder();
 
155
                        if (!(currBorder instanceof SubstanceButtonBorder)) {
 
156
                                b.setBorder(shaper.getButtonBorder(b));
 
157
                        } else {
 
158
                                SubstanceButtonBorder sbCurrBorder = (SubstanceButtonBorder) currBorder;
 
159
                                if (shaper.getClass() != sbCurrBorder.getButtonShaperClass())
 
160
                                        b.setBorder(shaper.getButtonBorder(b));
 
161
                        }
 
162
                }
 
163
                b.putClientProperty(SubstanceButtonUI.OPACITY_ORIGINAL, b.isOpaque());
 
164
                // fix for defect 140
 
165
                b.setOpaque(false);
 
166
 
 
167
                b.setRolloverEnabled(true);
 
168
 
 
169
                LookAndFeel.installProperty(b, "iconTextGap", SubstanceSizeUtils
 
170
                                .getTextIconGap(SubstanceSizeUtils.getComponentFontSize(b)));
 
171
        }
 
172
 
 
173
        /*
 
174
         * (non-Javadoc)
 
175
         * 
 
176
         * @seejavax.swing.plaf.basic.BasicButtonUI#uninstallDefaults(javax.swing.
 
177
         * AbstractButton)
 
178
         */
 
179
        @Override
 
180
        public void uninstallDefaults(AbstractButton b) {
 
181
                super.uninstallDefaults(b);
 
182
 
 
183
                b.setBorder((Border) b
 
184
                                .getClientProperty(SubstanceButtonUI.BORDER_ORIGINAL));
 
185
                b.setOpaque((Boolean) b
 
186
                                .getClientProperty(SubstanceButtonUI.OPACITY_ORIGINAL));
 
187
                b.putClientProperty(SubstanceButtonUI.OPACITY_ORIGINAL, null);
 
188
        }
 
189
 
 
190
        /*
 
191
         * (non-Javadoc)
 
192
         * 
 
193
         * @see
 
194
         * javax.swing.plaf.basic.BasicButtonUI#createButtonListener(javax.swing
 
195
         * .AbstractButton)
 
196
         */
 
197
        @Override
 
198
        protected BasicButtonListener createButtonListener(AbstractButton b) {
 
199
                return null;
 
200
        }
 
201
 
 
202
        /*
 
203
         * (non-Javadoc)
 
204
         * 
 
205
         * @seejavax.swing.plaf.basic.BasicButtonUI#installListeners(javax.swing.
 
206
         * AbstractButton)
 
207
         */
 
208
        @Override
 
209
        protected void installListeners(final AbstractButton b) {
 
210
                super.installListeners(b);
 
211
 
 
212
                this.substanceVisualStateTracker = new ButtonVisualStateTracker();
 
213
                this.substanceVisualStateTracker.installListeners(b, true);
 
214
 
 
215
                this.trackGlowingIcon();
 
216
 
 
217
                this.substancePropertyListener = new PropertyChangeListener() {
 
218
                        @Override
 
219
            public void propertyChange(PropertyChangeEvent evt) {
 
220
                                if (AbstractButton.ICON_CHANGED_PROPERTY.equals(evt
 
221
                                                .getPropertyName())) {
 
222
                                        trackGlowingIcon();
 
223
                                }
 
224
                        }
 
225
                };
 
226
                b.addPropertyChangeListener(this.substancePropertyListener);
 
227
        }
 
228
 
 
229
        /*
 
230
         * (non-Javadoc)
 
231
         * 
 
232
         * @seejavax.swing.plaf.basic.BasicButtonUI#uninstallListeners(javax.swing.
 
233
         * AbstractButton)
 
234
         */
 
235
        @Override
 
236
        protected void uninstallListeners(AbstractButton b) {
 
237
                this.substanceVisualStateTracker.uninstallListeners(b);
 
238
                this.substanceVisualStateTracker = null;
 
239
 
 
240
                b.removePropertyChangeListener(this.substancePropertyListener);
 
241
                this.substancePropertyListener = null;
 
242
 
 
243
                super.uninstallListeners(b);
 
244
        }
 
245
 
 
246
        /*
 
247
         * (non-Javadoc)
 
248
         * 
 
249
         * @see javax.swing.plaf.basic.BasicToggleButtonUI#paint(java.awt.Graphics,
 
250
         * javax.swing.JComponent)
 
251
         */
 
252
        @Override
 
253
        public void paint(Graphics g, JComponent c) {
 
254
                final AbstractButton b = (AbstractButton) c;
 
255
 
 
256
                FontMetrics fm = g.getFontMetrics();
 
257
 
 
258
                Insets i = c.getInsets();
 
259
 
 
260
                viewRect.x = i.left;
 
261
                viewRect.y = i.top;
 
262
                viewRect.width = b.getWidth() - (i.right + viewRect.x);
 
263
                viewRect.height = b.getHeight() - (i.bottom + viewRect.y);
 
264
 
 
265
                textRect.x = textRect.y = textRect.width = textRect.height = 0;
 
266
                iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
 
267
 
 
268
                Font f = c.getFont();
 
269
 
 
270
                // layout the text and icon
 
271
                String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b
 
272
                                .getIcon(), b.getVerticalAlignment(), b
 
273
                                .getHorizontalAlignment(), b.getVerticalTextPosition(), b
 
274
                                .getHorizontalTextPosition(), viewRect, iconRect, textRect, b
 
275
                                .getText() == null ? 0 : b.getIconTextGap());
 
276
 
 
277
                Graphics2D g2d = (Graphics2D) g.create();
 
278
 
 
279
                View v = (View) c.getClientProperty(BasicHTML.propertyKey);
 
280
                g2d.setFont(f);
 
281
 
 
282
                this.delegate.updateBackground(g2d, b);
 
283
                if (v != null) {
 
284
                        v.paint(g2d, textRect);
 
285
                } else {
 
286
                        this.paintButtonText(g2d, b, textRect, text);
 
287
                }
 
288
 
 
289
                // Paint the Icon
 
290
                if (b.getIcon() != null) {
 
291
                        paintIcon(g2d, b, iconRect);
 
292
                }
 
293
 
 
294
                if (b.isFocusPainted()) {
 
295
                        SubstanceCoreUtilities.paintFocus(g, b, b, this, null, textRect,
 
296
                                        1.0f, SubstanceSizeUtils
 
297
                                                        .getFocusRingPadding(SubstanceSizeUtils
 
298
                                                                        .getComponentFontSize(b)));
 
299
                }
 
300
        }
 
301
 
 
302
        /*
 
303
         * (non-Javadoc)
 
304
         * 
 
305
         * @see
 
306
         * javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent)
 
307
         */
 
308
        @Override
 
309
        public Dimension getPreferredSize(JComponent c) {
 
310
                AbstractButton button = (AbstractButton) c;
 
311
                SubstanceButtonShaper shaper = SubstanceCoreUtilities
 
312
                                .getButtonShaper(button);
 
313
 
 
314
                // fix for defect 263
 
315
                Dimension superPref = super.getPreferredSize(button);
 
316
                if (superPref == null)
 
317
                        return null;
 
318
 
 
319
                if (shaper == null)
 
320
                        return superPref;
 
321
 
 
322
                return shaper.getPreferredSize(button, superPref);
 
323
        }
 
324
 
 
325
        /*
 
326
         * (non-Javadoc)
 
327
         * 
 
328
         * @see javax.swing.plaf.ComponentUI#contains(javax.swing.JComponent, int,
 
329
         * int)
 
330
         */
 
331
        @Override
 
332
        public boolean contains(JComponent c, int x, int y) {
 
333
                return ButtonBackgroundDelegate.contains((JToggleButton) c, x, y);
 
334
        }
 
335
 
 
336
        /*
 
337
         * (non-Javadoc)
 
338
         * 
 
339
         * @see
 
340
         * javax.swing.plaf.basic.BasicToggleButtonUI#paintIcon(java.awt.Graphics,
 
341
         * javax.swing.AbstractButton, java.awt.Rectangle)
 
342
         */
 
343
        @Override
 
344
        protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect) {
 
345
                Graphics2D graphics = (Graphics2D) g.create();
 
346
                // We have three types of icons:
 
347
                // 1. The original button icon
 
348
                // 2. The themed version of 1.
 
349
                // 3. The glowing version of 1.
 
350
                Icon originalIcon = SubstanceCoreUtilities.getOriginalIcon(b, b
 
351
                                .getIcon());
 
352
                Icon themedIcon = (!(b instanceof JRadioButton)
 
353
                                && !(b instanceof JCheckBox) && SubstanceCoreUtilities
 
354
                                .useThemedDefaultIcon(b)) ? SubstanceCoreUtilities
 
355
                                .getThemedIcon(b, originalIcon) : originalIcon;
 
356
 
 
357
                graphics.setComposite(LafWidgetUtilities.getAlphaComposite(b, g));
 
358
                float activeAmount = this.substanceVisualStateTracker
 
359
                                .getStateTransitionTracker().getActiveStrength();
 
360
                if (activeAmount >= 0.0f) {
 
361
                        if (AnimationConfigurationManager.getInstance().isAnimationAllowed(
 
362
                                        AnimationFacet.ICON_GLOW, b)
 
363
                                        && this.substanceVisualStateTracker
 
364
                                                        .getStateTransitionTracker().getIconGlowTracker()
 
365
                                                        .isPlaying()) {
 
366
                                this.glowingIcon.paintIcon(b, graphics, iconRect.x, iconRect.y);
 
367
                        } else {
 
368
                                themedIcon.paintIcon(b, graphics, iconRect.x, iconRect.y);
 
369
                                graphics.setComposite(LafWidgetUtilities.getAlphaComposite(b,
 
370
                                                activeAmount, g));
 
371
                                originalIcon.paintIcon(b, graphics, iconRect.x, iconRect.y);
 
372
                        }
 
373
                } else {
 
374
                        originalIcon.paintIcon(b, graphics, iconRect.x, iconRect.y);
 
375
                }
 
376
 
 
377
                graphics.dispose();
 
378
        }
 
379
 
 
380
        /**
 
381
         * Paints the text.
 
382
         * 
 
383
         * @param g
 
384
         *            Graphic context
 
385
         * @param button
 
386
         *            Button
 
387
         * @param textRect
 
388
         *            Text rectangle
 
389
         * @param text
 
390
         *            Text to paint
 
391
         */
 
392
        protected void paintButtonText(Graphics g, AbstractButton button,
 
393
                        Rectangle textRect, String text) {
 
394
                SubstanceTextUtilities.paintText(g, button, textRect, text, (button)
 
395
                                .getDisplayedMnemonicIndex());
 
396
        }
 
397
 
 
398
        /**
 
399
         * Tracks possible usage of glowing icon.
 
400
         * 
 
401
         */
 
402
        protected void trackGlowingIcon() {
 
403
                Icon currIcon = this.toggleButton.getIcon();
 
404
                if (currIcon instanceof GlowingIcon)
 
405
                        return;
 
406
                if (currIcon == null)
 
407
                        return;
 
408
                this.glowingIcon = new GlowingIcon(currIcon,
 
409
                                this.substanceVisualStateTracker.getStateTransitionTracker()
 
410
                                                .getIconGlowTracker());
 
411
        }
 
412
 
 
413
        /*
 
414
         * (non-Javadoc)
 
415
         * 
 
416
         * @see javax.swing.plaf.ComponentUI#update(java.awt.Graphics,
 
417
         * javax.swing.JComponent)
 
418
         */
 
419
        @Override
 
420
        public void update(Graphics g, JComponent c) {
 
421
                this.paint(g, c);
 
422
        }
 
423
 
 
424
        @Override
 
425
        public boolean isInside(MouseEvent me) {
 
426
                return this.contains(this.toggleButton, me.getX(), me.getY());
 
427
        }
 
428
 
 
429
        @Override
 
430
        public StateTransitionTracker getTransitionTracker() {
 
431
                return this.substanceVisualStateTracker.getStateTransitionTracker();
 
432
        }
 
433
}
 
 
b'\\ No newline at end of file'