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

« back to all changes in this revision

Viewing changes to flamingo/src/main/java/org/pushingpixels/flamingo/internal/ui/ribbon/BasicRibbonComponentUI.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 Flamingo 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 Flamingo 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.flamingo.internal.ui.ribbon;
 
31
 
 
32
import java.awt.*;
 
33
import java.awt.color.ColorSpace;
 
34
import java.awt.image.ColorConvertOp;
 
35
import java.beans.PropertyChangeEvent;
 
36
import java.beans.PropertyChangeListener;
 
37
 
 
38
import javax.swing.*;
 
39
import javax.swing.plaf.ComponentUI;
 
40
 
 
41
import org.pushingpixels.flamingo.api.common.HorizontalAlignment;
 
42
import org.pushingpixels.flamingo.api.common.icon.FilteredResizableIcon;
 
43
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;
 
44
import org.pushingpixels.flamingo.api.ribbon.JRibbonComponent;
 
45
import org.pushingpixels.flamingo.api.ribbon.RibbonElementPriority;
 
46
 
 
47
public class BasicRibbonComponentUI extends RibbonComponentUI {
 
48
        /**
 
49
         * The associated ribbon component.
 
50
         */
 
51
        protected JRibbonComponent ribbonComponent;
 
52
 
 
53
        protected JLabel captionLabel;
 
54
 
 
55
        protected PropertyChangeListener propertyChangeListener;
 
56
 
 
57
        protected ResizableIcon disabledIcon;
 
58
 
 
59
        /*
 
60
         * (non-Javadoc)
 
61
         * 
 
62
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
63
         */
 
64
        public static ComponentUI createUI(JComponent c) {
 
65
                return new BasicRibbonComponentUI();
 
66
        }
 
67
 
 
68
        /*
 
69
         * (non-Javadoc)
 
70
         * 
 
71
         * @see javax.swing.plaf.ComponentUI#installUI(javax.swing.JComponent)
 
72
         */
 
73
        @Override
 
74
        public void installUI(JComponent c) {
 
75
                this.ribbonComponent = (JRibbonComponent) c;
 
76
                installDefaults();
 
77
                installComponents();
 
78
                installListeners();
 
79
                c.setLayout(createLayoutManager());
 
80
        }
 
81
 
 
82
        /*
 
83
         * (non-Javadoc)
 
84
         * 
 
85
         * @see javax.swing.plaf.ComponentUI#uninstallUI(javax.swing.JComponent)
 
86
         */
 
87
        @Override
 
88
        public void uninstallUI(JComponent c) {
 
89
                c.setLayout(null);
 
90
                uninstallListeners();
 
91
                uninstallDefaults();
 
92
                uninstallComponents();
 
93
        }
 
94
 
 
95
        /**
 
96
         * Installs default parameters on the associated ribbon component.
 
97
         */
 
98
        protected void installDefaults() {
 
99
                if (!this.ribbonComponent.isSimpleWrapper()) {
 
100
                        ResizableIcon icon = this.ribbonComponent.getIcon();
 
101
                        if (icon != null) {
 
102
                                icon.setDimension(new Dimension(16, 16));
 
103
                                this.disabledIcon = createDisabledIcon();
 
104
                        }
 
105
                }
 
106
 
 
107
                this.ribbonComponent.getMainComponent().setOpaque(false);
 
108
                this.ribbonComponent.setOpaque(false);
 
109
        }
 
110
 
 
111
        /**
 
112
         * Installs subcomponents on the associated ribbon component.
 
113
         */
 
114
        protected void installComponents() {
 
115
                this.captionLabel = new JLabel(this.ribbonComponent.getCaption());
 
116
                this.captionLabel.setEnabled(this.ribbonComponent.isEnabled());
 
117
                this.ribbonComponent.add(this.captionLabel);
 
118
 
 
119
                JComponent mainComponent = this.ribbonComponent.getMainComponent();
 
120
                this.ribbonComponent.add(mainComponent);
 
121
        }
 
122
 
 
123
        /**
 
124
         * Installs listeners on the associated ribbon component.
 
125
         */
 
126
        protected void installListeners() {
 
127
                this.propertyChangeListener = new PropertyChangeListener() {
 
128
                        @Override
 
129
                        public void propertyChange(PropertyChangeEvent evt) {
 
130
                                if ("enabled".equals(evt.getPropertyName())) {
 
131
                                        boolean isEnabled = (Boolean) evt.getNewValue();
 
132
                                        ribbonComponent.getMainComponent().setEnabled(isEnabled);
 
133
                                        if (!ribbonComponent.isSimpleWrapper()) {
 
134
                                                captionLabel.setEnabled(isEnabled);
 
135
                                        }
 
136
                                        ribbonComponent.repaint();
 
137
                                }
 
138
                                if ("caption".equals(evt.getPropertyName())) {
 
139
                                        captionLabel.setText((String) evt.getNewValue());
 
140
                                }
 
141
                                if ("displayPriority".equals(evt.getPropertyName())) {
 
142
                                        ribbonComponent.revalidate();
 
143
                                        ribbonComponent.doLayout();
 
144
                                }
 
145
                        }
 
146
                };
 
147
                this.ribbonComponent
 
148
                                .addPropertyChangeListener(this.propertyChangeListener);
 
149
 
 
150
        }
 
151
 
 
152
        /**
 
153
         * Uninstalls default parameters from the associated ribbon component.
 
154
         */
 
155
        protected void uninstallDefaults() {
 
156
        }
 
157
 
 
158
        /**
 
159
         * Uninstalls components from the associated ribbon component.
 
160
         */
 
161
        protected void uninstallComponents() {
 
162
                JComponent mainComponent = this.ribbonComponent.getMainComponent();
 
163
                this.ribbonComponent.remove(mainComponent);
 
164
 
 
165
                this.ribbonComponent.remove(this.captionLabel);
 
166
                this.captionLabel = null;
 
167
        }
 
168
 
 
169
        /**
 
170
         * Uninstalls listeners from the associated ribbon component.
 
171
         */
 
172
        protected void uninstallListeners() {
 
173
                this.ribbonComponent
 
174
                                .removePropertyChangeListener(this.propertyChangeListener);
 
175
                this.propertyChangeListener = null;
 
176
        }
 
177
 
 
178
        @Override
 
179
        public Point getKeyTipAnchorCenterPoint() {
 
180
                if (this.ribbonComponent.isSimpleWrapper()) {
 
181
                        return new Point(
 
182
                                        this.ribbonComponent.getMainComponent().getX() + 10,
 
183
                                        this.ribbonComponent.getHeight());
 
184
                } else {
 
185
                        return new Point(this.captionLabel.getX(), this.ribbonComponent
 
186
                                        .getHeight());
 
187
                }
 
188
        }
 
189
 
 
190
        protected LayoutManager createLayoutManager() {
 
191
                return new ExtComponentLayout();
 
192
        }
 
193
 
 
194
        protected class ExtComponentLayout implements LayoutManager {
 
195
                @Override
 
196
                public void addLayoutComponent(String name, Component comp) {
 
197
                }
 
198
 
 
199
                @Override
 
200
                public void removeLayoutComponent(Component comp) {
 
201
                }
 
202
 
 
203
                @Override
 
204
                public Dimension minimumLayoutSize(Container parent) {
 
205
                        Insets ins = ribbonComponent.getInsets();
 
206
                        JComponent mainComponent = ribbonComponent.getMainComponent();
 
207
                        Dimension minMain = mainComponent.getMinimumSize();
 
208
 
 
209
                        int width = ins.left;
 
210
                        int height = minMain.height;
 
211
                        if (isIconVisible(ribbonComponent.getDisplayPriority())) {
 
212
                                ResizableIcon icon = ribbonComponent.getIcon();
 
213
                                if (icon != null) {
 
214
                                        width += (icon.getIconWidth() + getLayoutGap());
 
215
                                        height = Math.max(height, icon.getIconHeight());
 
216
                                }
 
217
                        }
 
218
                        if (isCaptionVisible(ribbonComponent.getDisplayPriority())) {
 
219
                                Dimension minCaption = captionLabel.getMinimumSize();
 
220
                                width += (minCaption.width + getLayoutGap());
 
221
                                height = Math.max(height, minCaption.height);
 
222
                        }
 
223
                        width += minMain.width;
 
224
                        width += ins.right;
 
225
                        height += (ins.top + ins.bottom);
 
226
 
 
227
                        return new Dimension(width, height);
 
228
                }
 
229
 
 
230
                @Override
 
231
                public Dimension preferredLayoutSize(Container parent) {
 
232
                        return getPreferredSize(ribbonComponent.getDisplayPriority());
 
233
                }
 
234
 
 
235
                @Override
 
236
                public void layoutContainer(Container parent) {
 
237
                        JRibbonComponent ribbonComp = (JRibbonComponent) parent;
 
238
                        Insets ins = ribbonComp.getInsets();
 
239
                        int gap = getLayoutGap();
 
240
                        int availableHeight = ribbonComp.getHeight() - ins.top - ins.bottom;
 
241
                        int availableWidth = ribbonComp.getWidth() - ins.left - ins.right;
 
242
 
 
243
                        HorizontalAlignment horizAlignment = ribbonComp
 
244
                                        .getHorizontalAlignment();
 
245
                        JComponent mainComp = ribbonComp.getMainComponent();
 
246
                        Dimension prefMainDim = mainComp.getPreferredSize();
 
247
                        int prefMainWidth = prefMainDim.width;
 
248
                        int finalHeight = Math.min(prefMainDim.height, availableHeight);
 
249
                        boolean ltr = ribbonComp.getComponentOrientation().isLeftToRight();
 
250
 
 
251
                        if (ribbonComp.isSimpleWrapper()) {
 
252
                                int finalMainWidth = Math.min(availableWidth, prefMainWidth);
 
253
                                int offset = availableWidth - prefMainWidth;
 
254
                                int topMain = ins.top + (availableHeight - finalHeight) / 2;
 
255
                                int x = ltr ? ins.left : ribbonComp.getWidth() - ins.right;
 
256
                                switch (horizAlignment) {
 
257
                                case LEADING:
 
258
                                        if (ltr) {
 
259
                                                mainComp.setBounds(x, topMain, finalMainWidth,
 
260
                                                                finalHeight);
 
261
                                        } else {
 
262
                                                mainComp.setBounds(x - finalMainWidth, topMain,
 
263
                                                                finalMainWidth, finalHeight);
 
264
                                        }
 
265
                                        break;
 
266
                                case TRAILING:
 
267
                                        if (ltr) {
 
268
                                                mainComp.setBounds(x + offset, topMain, finalMainWidth,
 
269
                                                                finalHeight);
 
270
                                        } else {
 
271
                                                mainComp.setBounds(x - finalMainWidth - offset,
 
272
                                                                topMain, finalMainWidth, finalHeight);
 
273
                                        }
 
274
                                        break;
 
275
                                case CENTER:
 
276
                                        if (ltr) {
 
277
                                                mainComp.setBounds(x + offset / 2, topMain,
 
278
                                                                finalMainWidth, finalHeight);
 
279
                                        } else {
 
280
                                                mainComp.setBounds(x - finalMainWidth - offset / 2,
 
281
                                                                topMain, finalMainWidth, finalHeight);
 
282
                                        }
 
283
                                        break;
 
284
                                case FILL:
 
285
                                        if (ltr) {
 
286
                                                mainComp.setBounds(x, topMain, availableWidth,
 
287
                                                                finalHeight);
 
288
                                        } else {
 
289
                                                mainComp.setBounds(x - availableWidth, topMain,
 
290
                                                                availableWidth, finalHeight);
 
291
                                        }
 
292
                                        break;
 
293
                                }
 
294
                                mainComp.doLayout();
 
295
                        } else {
 
296
                                int x = ltr ? ins.left : ribbonComp.getWidth() - ins.right;
 
297
                                if (isIconVisible(ribbonComponent.getDisplayPriority())) {
 
298
                                        if (ribbonComp.getIcon() != null) {
 
299
                                                // icon is painted separately
 
300
                                                int iconW = ribbonComp.getIcon().getIconWidth();
 
301
                                                x = ltr ? x + iconW + gap : x - iconW - gap;
 
302
                                        }
 
303
                                }
 
304
 
 
305
                                if (isCaptionVisible(ribbonComponent.getDisplayPriority())) {
 
306
                                        captionLabel.setVisible(true);
 
307
                                        Dimension prefCaptionDim = captionLabel.getPreferredSize();
 
308
                                        if (ltr) {
 
309
                                                captionLabel
 
310
                                                                .setBounds(
 
311
                                                                                x,
 
312
                                                                                ins.top
 
313
                                                                                                + (availableHeight - prefCaptionDim.height)
 
314
                                                                                                / 2, prefCaptionDim.width,
 
315
                                                                                prefCaptionDim.height);
 
316
                                                x += (prefCaptionDim.width + gap);
 
317
                                        } else {
 
318
                                                captionLabel
 
319
                                                                .setBounds(
 
320
                                                                                x - prefCaptionDim.width,
 
321
                                                                                ins.top
 
322
                                                                                                + (availableHeight - prefCaptionDim.height)
 
323
                                                                                                / 2, prefCaptionDim.width,
 
324
                                                                                prefCaptionDim.height);
 
325
                                                x -= (prefCaptionDim.width + gap);
 
326
                                        }
 
327
                                } else {
 
328
                                        captionLabel.setVisible(false);
 
329
                                }
 
330
 
 
331
                                int topMain = ins.top + (availableHeight - finalHeight) / 2;
 
332
                                int finalMainWidth = ltr ? Math.min(ribbonComp.getWidth()
 
333
                                                - ins.right - x, prefMainWidth) : Math.min(
 
334
                                                x - ins.left, prefMainWidth);
 
335
                                int offset = ltr ? ribbonComp.getWidth() - ins.right - x
 
336
                                                - prefMainWidth : x - prefMainWidth - ins.left;
 
337
 
 
338
                                switch (horizAlignment) {
 
339
                                case LEADING:
 
340
                                        if (ltr) {
 
341
                                                mainComp.setBounds(x, topMain, finalMainWidth,
 
342
                                                                finalHeight);
 
343
                                        } else {
 
344
                                                mainComp.setBounds(x - finalMainWidth, topMain,
 
345
                                                                finalMainWidth, finalHeight);
 
346
                                        }
 
347
                                        break;
 
348
                                case TRAILING:
 
349
                                        if (ltr) {
 
350
                                                mainComp.setBounds(x + offset, topMain, finalMainWidth,
 
351
                                                                finalHeight);
 
352
                                        } else {
 
353
                                                mainComp.setBounds(x - finalMainWidth - offset,
 
354
                                                                topMain, finalMainWidth, finalHeight);
 
355
                                        }
 
356
                                        break;
 
357
                                case CENTER:
 
358
                                        if (ltr) {
 
359
                                                mainComp.setBounds(x + offset / 2, topMain,
 
360
                                                                finalMainWidth, finalHeight);
 
361
                                        } else {
 
362
                                                mainComp.setBounds(x - finalMainWidth - offset / 2,
 
363
                                                                topMain, finalMainWidth, finalHeight);
 
364
                                        }
 
365
                                        break;
 
366
                                case FILL:
 
367
                                        if (ltr) {
 
368
                                                mainComp.setBounds(x, topMain, ribbonComp.getWidth()
 
369
                                                                - ins.right - x, finalHeight);
 
370
                                        } else {
 
371
                                                mainComp.setBounds(ins.left, topMain, x - ins.left,
 
372
                                                                finalHeight);
 
373
                                        }
 
374
                                        break;
 
375
                                }
 
376
                                mainComp.doLayout();
 
377
                        }
 
378
                }
 
379
        }
 
380
 
 
381
        @Override
 
382
        public void paint(Graphics g, JComponent c) {
 
383
                JRibbonComponent ribbonComp = (JRibbonComponent) c;
 
384
                if (isIconVisible(this.ribbonComponent.getDisplayPriority())) {
 
385
                        Insets ins = ribbonComp.getInsets();
 
386
                        ResizableIcon icon = ribbonComp.isEnabled() ? ribbonComp.getIcon()
 
387
                                        : this.disabledIcon;
 
388
                        if (icon != null) {
 
389
                                int availableHeight = ribbonComp.getHeight() - ins.top
 
390
                                                - ins.bottom;
 
391
                                int iconY = Math.max(0, ins.top
 
392
                                                + (availableHeight - icon.getIconHeight()) / 2);
 
393
                                if (ribbonComp.getComponentOrientation().isLeftToRight()) {
 
394
                                        paintIcon(g, ribbonComp, icon, ins.left, iconY);
 
395
                                } else {
 
396
                                        paintIcon(g, ribbonComp, icon, ribbonComp.getWidth()
 
397
                                                        - ins.right - icon.getIconWidth(), iconY);
 
398
                                }
 
399
                        }
 
400
                }
 
401
        }
 
402
 
 
403
        protected void paintIcon(Graphics g, JRibbonComponent ribbonComp,
 
404
                        Icon icon, int x, int y) {
 
405
                icon.paintIcon(ribbonComp, g, x, y);
 
406
        }
 
407
 
 
408
        protected int getLayoutGap() {
 
409
                return 4;
 
410
        }
 
411
 
 
412
        protected ResizableIcon createDisabledIcon() {
 
413
                return new FilteredResizableIcon(this.ribbonComponent.getIcon(),
 
414
                                new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY),
 
415
                                                null));
 
416
        }
 
417
 
 
418
        protected boolean isIconVisible(RibbonElementPriority displayPriority) {
 
419
                if (this.ribbonComponent.isSimpleWrapper())
 
420
                        return false;
 
421
                return (displayPriority == RibbonElementPriority.TOP)
 
422
                                || (displayPriority == RibbonElementPriority.MEDIUM);
 
423
        }
 
424
 
 
425
        protected boolean isCaptionVisible(RibbonElementPriority displayPriority) {
 
426
                if (this.ribbonComponent.isSimpleWrapper())
 
427
                        return false;
 
428
                return (displayPriority == RibbonElementPriority.TOP);
 
429
        }
 
430
 
 
431
        @Override
 
432
        public Dimension getPreferredSize(RibbonElementPriority priority) {
 
433
                Insets ins = ribbonComponent.getInsets();
 
434
                JComponent mainComponent = ribbonComponent.getMainComponent();
 
435
                Dimension prefMain = mainComponent.getPreferredSize();
 
436
 
 
437
                int width = ins.left;
 
438
                int height = prefMain.height;
 
439
                if (isIconVisible(priority)) {
 
440
                        ResizableIcon icon = ribbonComponent.getIcon();
 
441
                        if (icon != null) {
 
442
                                width += (icon.getIconWidth() + getLayoutGap());
 
443
                                height = Math.max(height, icon.getIconHeight());
 
444
                        }
 
445
                }
 
446
                if (isCaptionVisible(priority)) {
 
447
                        Dimension prefCaption = captionLabel.getPreferredSize();
 
448
                        width += (prefCaption.width + getLayoutGap());
 
449
                        height = Math.max(height, prefCaption.height);
 
450
                }
 
451
                width += prefMain.width;
 
452
                width += ins.right;
 
453
                height += (ins.top + ins.bottom);
 
454
 
 
455
                return new Dimension(width, height);
 
456
        }
 
457
}