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

« back to all changes in this revision

Viewing changes to substance-flamingo/src/main/java/org/pushingpixels/substance/flamingo/ribbon/ui/SubstanceRibbonUI.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 / 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 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.substance.flamingo.ribbon.ui;
 
31
 
 
32
import org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand;
 
33
import org.pushingpixels.flamingo.api.ribbon.RibbonContextualTaskGroup;
 
34
import org.pushingpixels.flamingo.api.ribbon.RibbonTask;
 
35
import org.pushingpixels.flamingo.internal.ui.ribbon.BasicRibbonUI;
 
36
import org.pushingpixels.flamingo.internal.ui.ribbon.JRibbonRootPane;
 
37
import org.pushingpixels.flamingo.internal.ui.ribbon.JRibbonTaskToggleButton;
 
38
import org.pushingpixels.flamingo.internal.utils.FlamingoUtilities;
 
39
import org.pushingpixels.substance.api.*;
 
40
import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter;
 
41
import org.pushingpixels.substance.internal.painter.BackgroundPaintingUtils;
 
42
import org.pushingpixels.substance.internal.painter.DecorationPainterUtils;
 
43
import org.pushingpixels.substance.internal.painter.SeparatorPainterUtils;
 
44
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
 
45
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
 
46
import org.pushingpixels.substance.internal.utils.SubstanceSizeUtils;
 
47
 
 
48
import javax.swing.*;
 
49
import javax.swing.plaf.ColorUIResource;
 
50
import javax.swing.plaf.ComponentUI;
 
51
import javax.swing.plaf.UIResource;
 
52
import java.awt.*;
 
53
import java.util.HashSet;
 
54
import java.util.Set;
 
55
 
 
56
/**
 
57
 * UI for ribbon in <b>Substance</b> look and feel.
 
58
 * 
 
59
 * @author Kirill Grouchnikov
 
60
 */
 
61
public class SubstanceRibbonUI extends BasicRibbonUI {
 
62
 
 
63
    /**
 
64
     * This component extends across the full width of the tab row
 
65
     * so that header backgrounds can be properly painted
 
66
     */
 
67
    protected JComponent tabPanelHeaderBackground;
 
68
 
 
69
        /**
 
70
         * Panel for hosting task toggle buttons.
 
71
         * 
 
72
         * @author Kirill Grouchnikov
 
73
         */
 
74
        protected class SubstanceTaskToggleButtonsHostPanel extends
 
75
                        TaskToggleButtonsHostPanel {
 
76
                @Override
 
77
                protected void paintContextualTaskGroupOutlines(Graphics g,
 
78
                                RibbonContextualTaskGroup group, Rectangle groupBounds) {
 
79
                        Graphics2D g2d = (Graphics2D) g.create();
 
80
 
 
81
                        // SubstanceColorScheme scheme = SubstanceColorSchemeUtilities
 
82
                        // .getBorderColorScheme(ribbon, ComponentState.DEFAULT);
 
83
 
 
84
                        g2d.translate(groupBounds.x, 0);
 
85
                        SeparatorPainterUtils.paintSeparator(ribbon, g2d, 2,
 
86
                                        groupBounds.height * 3 / 4, SwingConstants.VERTICAL, false,
 
87
                                        0, groupBounds.height / 3, true);
 
88
 
 
89
                        g2d.translate(groupBounds.width - 1, 0);
 
90
                        SeparatorPainterUtils.paintSeparator(ribbon, g2d, 2,
 
91
                                        groupBounds.height * 3 / 4, SwingConstants.VERTICAL, false,
 
92
                                        0, groupBounds.height / 3, true);
 
93
 
 
94
                        g2d.dispose();
 
95
                }
 
96
 
 
97
                @Override
 
98
                protected void paintTaskOutlines(Graphics g) {
 
99
                        Graphics2D g2d = (Graphics2D) g.create();
 
100
                        SubstanceColorScheme scheme = SubstanceColorSchemeUtilities
 
101
                                        .getColorScheme(ribbon,
 
102
                                                        ColorSchemeAssociationKind.SEPARATOR,
 
103
                                                        ComponentState.ENABLED);
 
104
 
 
105
                        Set<RibbonTask> tasksWithTrailingSeparators = new HashSet<RibbonTask>();
 
106
                        // add all regular tasks except the last
 
107
                        for (int i = 0; i < ribbon.getTaskCount() - 1; i++) {
 
108
                                RibbonTask task = ribbon.getTask(i);
 
109
                                tasksWithTrailingSeparators.add(task);
 
110
                                // System.out.println("Added " + task.getTitle());
 
111
                        }
 
112
                        // add all tasks of visible contextual groups except last task in
 
113
                        // each group
 
114
                        for (int i = 0; i < ribbon.getContextualTaskGroupCount(); i++) {
 
115
                                RibbonContextualTaskGroup group = ribbon
 
116
                                                .getContextualTaskGroup(i);
 
117
                                if (ribbon.isVisible(group)) {
 
118
                                        for (int j = 0; j < group.getTaskCount() - 1; j++) {
 
119
                                                RibbonTask task = group.getTask(j);
 
120
                                                tasksWithTrailingSeparators.add(task);
 
121
                                        }
 
122
                                }
 
123
                        }
 
124
 
 
125
                        for (RibbonTask taskWithTrailingSeparator : tasksWithTrailingSeparators) {
 
126
                                JRibbonTaskToggleButton taskToggleButton = taskToggleButtons
 
127
                                                .get(taskWithTrailingSeparator);
 
128
                                Rectangle bounds = taskToggleButton.getBounds();
 
129
                                int x = bounds.x + bounds.width + getTabButtonGap() / 2 - 1;
 
130
                                g2d.translate(x, 0);
 
131
                                SeparatorPainterUtils.paintSeparator(ribbon, g2d, scheme, 2,
 
132
                                                getHeight(), SwingConstants.VERTICAL, false,
 
133
                                                getHeight() / 3, 0, true);
 
134
                                g2d.translate(-x, 0);
 
135
                        }
 
136
 
 
137
                        g2d.dispose();
 
138
                }
 
139
        }
 
140
 
 
141
        /**
 
142
         * Panel for hosting ribbon bands.
 
143
         * 
 
144
         * @author Kirill Grouchnikov
 
145
         */
 
146
        protected class SubstanceBandHostPanel extends BandHostPanel {
 
147
                @Override
 
148
                protected void paintComponent(Graphics g) {
 
149
                        int dy = 0;
 
150
                        for (int i = 0; i < getComponentCount(); i++) {
 
151
                                Component child = getComponent(i);
 
152
                                if (child instanceof AbstractRibbonBand) {
 
153
                                        dy = child.getBounds().y;
 
154
                                        break;
 
155
                                }
 
156
                        }
 
157
                        SubstanceRibbonBandUI.paintRibbonBandBackground(g, this, 0.0f, dy);
 
158
                }
 
159
        }
 
160
 
 
161
    protected class SubstanceRibbonLayout extends BasicRibbonUI.RibbonLayout  {
 
162
 
 
163
        @Override
 
164
        public void layoutContainer(Container c) {
 
165
            super.layoutContainer(c);
 
166
 
 
167
            tabPanelHeaderBackground.setBounds(
 
168
                0, taskToggleButtonsScrollablePanel.getY(),
 
169
                ribbon.getWidth(), taskToggleButtonsScrollablePanel.getHeight()
 
170
            );
 
171
            ribbon.setComponentZOrder(tabPanelHeaderBackground, ribbon.getComponentCount() - 1);
 
172
        }
 
173
    }
 
174
 
 
175
        /*
 
176
         * (non-Javadoc)
 
177
         * 
 
178
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
179
         */
 
180
        public static ComponentUI createUI(JComponent comp) {
 
181
                SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
 
182
                return new SubstanceRibbonUI();
 
183
        }
 
184
 
 
185
        /*
 
186
         * (non-Javadoc)
 
187
         * 
 
188
         * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#installDefaults()
 
189
         */
 
190
        @Override
 
191
        protected void installDefaults() {
 
192
                super.installDefaults();
 
193
                SubstanceLookAndFeel.setDecorationType(this.ribbon,
 
194
                                DecorationAreaType.HEADER);
 
195
                Color backgr = this.ribbon.getBackground();
 
196
                if (backgr == null || backgr instanceof UIResource) {
 
197
                        Color toSet = SubstanceColorSchemeUtilities.getColorScheme(
 
198
                                        this.ribbon, ComponentState.ENABLED)
 
199
                                        .getBackgroundFillColor();
 
200
                        this.ribbon.setBackground(new ColorUIResource(toSet));
 
201
                }
 
202
        }
 
203
 
 
204
        /*
 
205
         * (non-Javadoc)
 
206
         * 
 
207
         * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#uninstallDefaults()
 
208
         */
 
209
        @Override
 
210
        protected void uninstallDefaults() {
 
211
                DecorationPainterUtils.clearDecorationType(this.ribbon);
 
212
                super.uninstallDefaults();
 
213
        }
 
214
 
 
215
        /*
 
216
         * (non-Javadoc)
 
217
         * 
 
218
         * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#installComponents()
 
219
         */
 
220
        @Override
 
221
        protected void installComponents() {
 
222
                super.installComponents();
 
223
 
 
224
        tabPanelHeaderBackground = new JPanel();
 
225
        ribbon.add(tabPanelHeaderBackground);
 
226
        SubstanceLookAndFeel.setDecorationType(this.tabPanelHeaderBackground,
 
227
                DecorationAreaType.HEADER);
 
228
 
 
229
                SubstanceLookAndFeel.setDecorationType(this.taskBarPanel,
 
230
                                DecorationAreaType.PRIMARY_TITLE_PANE);
 
231
                SubstanceLookAndFeel.setDecorationType(this.ribbon,
 
232
                                DecorationAreaType.HEADER);
 
233
                SubstanceLookAndFeel.setDecorationType(this.bandScrollablePanel,
 
234
                                DecorationAreaType.GENERAL);
 
235
        }
 
236
 
 
237
        @Override
 
238
        protected void uninstallComponents() {
 
239
        this.ribbon.remove(tabPanelHeaderBackground);
 
240
                DecorationPainterUtils.clearDecorationType(this.taskBarPanel);
 
241
                super.uninstallComponents();
 
242
        }
 
243
 
 
244
    @Override
 
245
    protected LayoutManager createLayoutManager() {
 
246
        return new SubstanceRibbonLayout();
 
247
    }
 
248
 
 
249
        /*
 
250
         * (non-Javadoc)
 
251
         * 
 
252
         * @see
 
253
         * org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#createTaskToggleButtonsHostPanel
 
254
         * ()
 
255
         */
 
256
        @Override
 
257
        protected TaskToggleButtonsHostPanel createTaskToggleButtonsHostPanel() {
 
258
                return new SubstanceTaskToggleButtonsHostPanel();
 
259
        }
 
260
 
 
261
        /*
 
262
         * (non-Javadoc)
 
263
         * 
 
264
         * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#createBandHostPanel()
 
265
         */
 
266
        @Override
 
267
        protected BandHostPanel createBandHostPanel() {
 
268
                return new SubstanceBandHostPanel();
 
269
        }
 
270
 
 
271
        /*
 
272
         * (non-Javadoc)
 
273
         * 
 
274
         * @see
 
275
         * org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#paintBackground(java.awt.Graphics
 
276
         * )
 
277
         */
 
278
        @Override
 
279
        protected void paintBackground(Graphics g) {
 
280
                BackgroundPaintingUtils.update(g, this.ribbon, false);
 
281
        }
 
282
 
 
283
        /*
 
284
         * (non-Javadoc)
 
285
         * 
 
286
         * @see
 
287
         * org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#paintTaskArea(java.awt.Graphics
 
288
         * , int, int, int, int)
 
289
         */
 
290
        @Override
 
291
        protected void paintTaskArea(Graphics g, int x, int y, int width, int height) {
 
292
                if (this.ribbon.getTaskCount() == 0)
 
293
                        return;
 
294
 
 
295
                Graphics2D g2d = (Graphics2D) g.create();
 
296
 
 
297
                RibbonTask selectedTask = this.ribbon.getSelectedTask();
 
298
                JRibbonTaskToggleButton selectedTaskButton = this.taskToggleButtons
 
299
                                .get(selectedTask);
 
300
                Rectangle selectedTaskButtonBounds = selectedTaskButton.getBounds();
 
301
                Point converted = SwingUtilities.convertPoint(selectedTaskButton
 
302
                                .getParent(), selectedTaskButtonBounds.getLocation(),
 
303
                                this.ribbon);
 
304
                float radius = SubstanceSizeUtils
 
305
                                .getClassicButtonCornerRadius(SubstanceSizeUtils
 
306
                                                .getComponentFontSize(this.ribbon));
 
307
 
 
308
                int borderDelta = (int) Math.floor(SubstanceSizeUtils
 
309
                                .getBorderStrokeWidth(SubstanceSizeUtils
 
310
                                                .getComponentFontSize(this.ribbon)) / 2.0);
 
311
 
 
312
                SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
 
313
                                .getBorderPainter(this.ribbon);
 
314
                int borderThickness = (int) SubstanceSizeUtils
 
315
                                .getBorderStrokeWidth(SubstanceSizeUtils
 
316
                                                .getComponentFontSize(this.ribbon));
 
317
 
 
318
                AbstractRibbonBand band = (selectedTask.getBandCount() == 0) ? null
 
319
                                : selectedTask.getBand(0);
 
320
                SubstanceColorScheme borderScheme = SubstanceColorSchemeUtilities
 
321
                                .getColorScheme(band, ColorSchemeAssociationKind.BORDER,
 
322
                                                ComponentState.ENABLED);
 
323
 
 
324
                Rectangle taskToggleButtonsViewportBounds = taskToggleButtonsScrollablePanel
 
325
                                .getView().getParent().getBounds();
 
326
                taskToggleButtonsViewportBounds.setLocation(SwingUtilities
 
327
                                .convertPoint(taskToggleButtonsScrollablePanel,
 
328
                                                taskToggleButtonsViewportBounds.getLocation(),
 
329
                                                this.ribbon));
 
330
                int startSelectedX = Math.max(converted.x + 1,
 
331
                                (int) taskToggleButtonsViewportBounds.getMinX());
 
332
                startSelectedX = Math.min(startSelectedX,
 
333
                                (int) taskToggleButtonsViewportBounds.getMaxX());
 
334
                int endSelectedX = Math.min(converted.x
 
335
                                + selectedTaskButtonBounds.width - 1,
 
336
                                (int) taskToggleButtonsViewportBounds.getMaxX());
 
337
                endSelectedX = Math.max(endSelectedX,
 
338
                                (int) taskToggleButtonsViewportBounds.getMinX());
 
339
 
 
340
                Shape outerContour = RibbonBorderShaper.getRibbonBorderOutline(
 
341
                                this.ribbon, x + borderDelta, x + width - 2 * borderDelta - 1,
 
342
                                startSelectedX + borderDelta, endSelectedX - 2 * borderDelta,
 
343
                                converted.y + borderDelta, y + borderDelta, y + height - 2
 
344
                                                * borderDelta, radius);
 
345
 
 
346
                Shape innerContour = RibbonBorderShaper.getRibbonBorderOutline(
 
347
                                this.ribbon, x + borderDelta + borderThickness, x + width - 2
 
348
                                                * (borderDelta + borderThickness) - 1, startSelectedX
 
349
                                                + borderDelta + borderThickness, endSelectedX - 2
 
350
                                                * (borderDelta + borderThickness), converted.y
 
351
                                                + borderDelta + borderThickness, y + borderDelta
 
352
                                                + borderThickness, y + height - 2
 
353
                                                * (borderDelta + borderThickness) + 1, radius);
 
354
 
 
355
                g2d.setColor(SubstanceColorSchemeUtilities.getColorScheme(band,
 
356
                                ComponentState.ENABLED).getBackgroundFillColor());
 
357
                g2d.clipRect(x, y, width, height + 2);
 
358
                g2d.fill(outerContour);
 
359
 
 
360
                borderPainter.paintBorder(g2d, this.ribbon, width, height
 
361
                                + selectedTaskButtonBounds.height + 1, outerContour,
 
362
                                innerContour, borderScheme);
 
363
 
 
364
                // check whether the currently selected task is a contextual task
 
365
                RibbonTask selected = selectedTask;
 
366
                RibbonContextualTaskGroup contextualGroup = selected
 
367
                                .getContextualGroup();
 
368
                if (contextualGroup != null) {
 
369
                        // paint a small gradient directly below the task area
 
370
                        Insets ins = this.ribbon.getInsets();
 
371
                        int topY = ins.top + getTaskbarHeight();
 
372
                        int bottomY = topY + 5;
 
373
                        Color hueColor = contextualGroup.getHueColor();
 
374
                        Paint paint = new GradientPaint(0, topY, FlamingoUtilities
 
375
                                        .getAlphaColor(hueColor,
 
376
                                                        (int) (255 * RibbonContextualTaskGroup.HUE_ALPHA)),
 
377
                                        0, bottomY, FlamingoUtilities.getAlphaColor(hueColor, 0));
 
378
                        g2d.setPaint(paint);
 
379
                        g2d.clip(outerContour);
 
380
                        g2d.fillRect(0, topY, width, bottomY - topY + 1);
 
381
                }
 
382
 
 
383
                // paint outlines of the contextual task groups
 
384
                // paintContextualTaskGroupsOutlines(g);
 
385
 
 
386
                g2d.dispose();
 
387
        }
 
388
 
 
389
        /*
 
390
         * (non-Javadoc)
 
391
         * 
 
392
         * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#getTabButtonGap()
 
393
         */
 
394
        @Override
 
395
        protected int getTabButtonGap() {
 
396
                return SubstanceSizeUtils.getAdjustedSize(SubstanceSizeUtils
 
397
                                .getComponentFontSize(this.ribbon), super.getTabButtonGap(), 3,
 
398
                                1, false);
 
399
        }
 
400
 
 
401
        /*
 
402
         * (non-Javadoc)
 
403
         * 
 
404
         * @see
 
405
         * org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#syncApplicationMenuRichTooltip
 
406
         * ()
 
407
         */
 
408
        @Override
 
409
        protected void syncApplicationMenuTips() {
 
410
                JRibbonRootPane ribbonRootPane = (JRibbonRootPane) SwingUtilities
 
411
                                .getRootPane(this.ribbon);
 
412
                if (ribbonRootPane == null)
 
413
                        return;
 
414
                SubstanceRibbonRootPaneUI ribbonRootPaneUI = (SubstanceRibbonRootPaneUI) ribbonRootPane
 
415
                                .getUI();
 
416
                ribbonRootPaneUI.syncApplicationMenuTips();
 
417
        }
 
418
 
 
419
        /*
 
420
         * (non-Javadoc)
 
421
         * 
 
422
         * @see
 
423
         * org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#paintMinimizedRibbonSeparator
 
424
         * (java.awt.Graphics)
 
425
         */
 
426
        @Override
 
427
        protected void paintMinimizedRibbonSeparator(Graphics g) {
 
428
                Graphics2D g2d = (Graphics2D) g.create();
 
429
                g2d.translate(0, this.ribbon.getHeight() - 1);
 
430
                SeparatorPainterUtils.paintSeparator(this.ribbon, g2d, this.ribbon
 
431
                                .getWidth(), 0, JSeparator.HORIZONTAL, false, 0);
 
432
                g2d.dispose();
 
433
        }
 
434
}