~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/common/popup/BasicCommandPopupMenuUI.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.common.popup;
 
31
 
 
32
import java.awt.*;
 
33
import java.awt.geom.AffineTransform;
 
34
 
 
35
import javax.swing.*;
 
36
import javax.swing.border.Border;
 
37
import javax.swing.border.EmptyBorder;
 
38
import javax.swing.event.ChangeEvent;
 
39
import javax.swing.event.ChangeListener;
 
40
import javax.swing.plaf.ComponentUI;
 
41
 
 
42
import org.pushingpixels.flamingo.api.common.*;
 
43
import org.pushingpixels.flamingo.api.common.popup.*;
 
44
import org.pushingpixels.flamingo.api.common.popup.PopupPanelManager.PopupEvent;
 
45
import org.pushingpixels.flamingo.internal.ui.common.BasicCommandButtonPanelUI;
 
46
import org.pushingpixels.flamingo.internal.ui.common.CommandButtonLayoutManagerMedium;
 
47
import org.pushingpixels.flamingo.internal.utils.FlamingoUtilities;
 
48
 
 
49
public class BasicCommandPopupMenuUI extends BasicPopupPanelUI {
 
50
        /**
 
51
         * The associated popup menu
 
52
         */
 
53
        protected JCommandPopupMenu popupMenu;
 
54
 
 
55
        protected ChangeListener popupMenuChangeListener;
 
56
 
 
57
        protected PopupPanelManager.PopupListener popupListener;
 
58
 
 
59
        protected ScrollableCommandButtonPanel commandButtonPanel;
 
60
 
 
61
        protected JScrollablePanel<JPanel> menuItemsPanel;
 
62
 
 
63
        public static final String FORCE_ICON = "flamingo.internal.commandButtonLayoutManagerMedium.forceIcon";
 
64
 
 
65
        protected static final CommandButtonDisplayState POPUP_MENU = new CommandButtonDisplayState(
 
66
                        "Popup menu", 16) {
 
67
                @Override
 
68
                public CommandButtonLayoutManager createLayoutManager(
 
69
                                AbstractCommandButton commandButton) {
 
70
                        return new CommandButtonLayoutManagerMedium() {
 
71
                                @Override
 
72
                                protected float getIconTextGapFactor() {
 
73
                                        return 2.0f;
 
74
                                }
 
75
                        };
 
76
                }
 
77
        };
 
78
 
 
79
        /**
 
80
         * Popup panel that hosts groups of icons.
 
81
         * 
 
82
         * @author Kirill Grouchnikov
 
83
         */
 
84
        protected static class ScrollableCommandButtonPanel extends JComponent {
 
85
                /**
 
86
                 * Maximum dimension of <code>this</code> popup gallery.
 
87
                 */
 
88
                protected Dimension maxDimension;
 
89
 
 
90
                /**
 
91
                 * The internal panel that hosts the icon command buttons. Is hosted in
 
92
                 * the {@link #scroll}.
 
93
                 */
 
94
                protected JCommandButtonPanel buttonPanel;
 
95
 
 
96
                /**
 
97
                 * The maximum number of visible button rows.
 
98
                 */
 
99
                protected int maxVisibleButtonRows;
 
100
 
 
101
                /**
 
102
                 * Scroll panel that hosts {@link #buttonPanel}.
 
103
                 */
 
104
                protected JScrollPane scroll;
 
105
 
 
106
                /**
 
107
                 * Creates new a icon popup panel.
 
108
                 * 
 
109
                 * @param iconPanel
 
110
                 *            The internal panel that hosts icon command buttons.
 
111
                 * @param maxButtonColumns
 
112
                 *            The maximum number of button columns.
 
113
                 * @param maxVisibleButtonRows
 
114
                 *            The maximum number of visible button rows.
 
115
                 */
 
116
                public ScrollableCommandButtonPanel(JCommandButtonPanel iconPanel,
 
117
                                int maxButtonColumns, int maxVisibleButtonRows) {
 
118
                        this.buttonPanel = iconPanel;
 
119
                        this.buttonPanel.setMaxButtonColumns(maxButtonColumns);
 
120
                        this.maxVisibleButtonRows = maxVisibleButtonRows;
 
121
 
 
122
                        int maxButtonWidth = 0;
 
123
                        int maxButtonHeight = 0;
 
124
                        int groupCount = iconPanel.getGroupCount();
 
125
                        for (int i = 0; i < groupCount; i++) {
 
126
                                for (AbstractCommandButton button : iconPanel
 
127
                                                .getGroupButtons(i)) {
 
128
                                        maxButtonWidth = Math.max(maxButtonWidth, button
 
129
                                                        .getPreferredSize().width);
 
130
                                        maxButtonHeight = Math.max(maxButtonHeight, button
 
131
                                                        .getPreferredSize().height);
 
132
                                }
 
133
                        }
 
134
 
 
135
                        updateMaxDimension();
 
136
 
 
137
                        this.scroll = new JScrollPane(this.buttonPanel,
 
138
                                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
 
139
                                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
 
140
                        this.scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
 
141
                        this.buttonPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
 
142
                        this.scroll.setOpaque(false);
 
143
                        this.scroll.getViewport().setOpaque(false);
 
144
                        this.setLayout(new IconPopupLayout());
 
145
 
 
146
                        this.add(this.scroll);
 
147
 
 
148
                        this.setBorder(new Border() {
 
149
                                @Override
 
150
                                public Insets getBorderInsets(Component c) {
 
151
                                        return new Insets(0, 0, 1, 0);
 
152
                                }
 
153
 
 
154
                                @Override
 
155
                                public boolean isBorderOpaque() {
 
156
                                        return true;
 
157
                                }
 
158
 
 
159
                                @Override
 
160
                                public void paintBorder(Component c, Graphics g, int x, int y,
 
161
                                                int width, int height) {
 
162
                                        g.setColor(FlamingoUtilities.getBorderColor());
 
163
                                        g.drawLine(x, y + height - 1, x + width, y + height - 1);
 
164
                                }
 
165
                        });
 
166
                }
 
167
 
 
168
                /**
 
169
                 * Updates the max dimension of this panel. This method is for internal
 
170
                 * use only.
 
171
                 */
 
172
                public void updateMaxDimension() {
 
173
                        if (this.buttonPanel == null)
 
174
                                return;
 
175
                        this.buttonPanel.setPreferredSize(null);
 
176
                        Dimension prefIconPanelDim = this.buttonPanel.getPreferredSize();
 
177
                        // fix for issue 13 - respect the gaps and insets
 
178
                        BasicCommandButtonPanelUI panelUI = (BasicCommandButtonPanelUI) buttonPanel
 
179
                                        .getUI();
 
180
                        int titlePanelCount = buttonPanel.isToShowGroupLabels() ? 1 : 0;
 
181
                        this.maxDimension = new Dimension(prefIconPanelDim.width, panelUI
 
182
                                        .getPreferredHeight(this.maxVisibleButtonRows,
 
183
                                                        titlePanelCount));
 
184
                        this.setPreferredSize(null);
 
185
                }
 
186
 
 
187
                /**
 
188
                 * Layout manager for <code>this</code> popup gallery.
 
189
                 * 
 
190
                 * @author Kirill Grouchnikov
 
191
                 */
 
192
                protected class IconPopupLayout implements LayoutManager {
 
193
                        /*
 
194
                         * (non-Javadoc)
 
195
                         * 
 
196
                         * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String,
 
197
                         * java.awt.Component)
 
198
                         */
 
199
                        @Override
 
200
            public void addLayoutComponent(String name, Component comp) {
 
201
                        }
 
202
 
 
203
                        /*
 
204
                         * (non-Javadoc)
 
205
                         * 
 
206
                         * @see
 
207
                         * java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
 
208
                         */
 
209
                        @Override
 
210
            public void removeLayoutComponent(Component comp) {
 
211
                        }
 
212
 
 
213
                        /*
 
214
                         * (non-Javadoc)
 
215
                         * 
 
216
                         * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
 
217
                         */
 
218
                        @Override
 
219
            public void layoutContainer(Container parent) {
 
220
                                Insets insets = parent.getInsets();
 
221
                                int left = insets.left;
 
222
                                int right = insets.right;
 
223
                                int top = insets.top;
 
224
                                int bottom = insets.bottom;
 
225
                                scroll.setBounds(left, top, parent.getWidth() - left - right,
 
226
                                                parent.getHeight() - top - bottom);
 
227
                        }
 
228
 
 
229
                        /*
 
230
                         * (non-Javadoc)
 
231
                         * 
 
232
                         * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
 
233
                         */
 
234
                        @Override
 
235
            public Dimension minimumLayoutSize(Container parent) {
 
236
                                return this.preferredLayoutSize(parent);
 
237
                        }
 
238
 
 
239
                        /*
 
240
                         * (non-Javadoc)
 
241
                         * 
 
242
                         * @see
 
243
                         * java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
 
244
                         */
 
245
                        @Override
 
246
            public Dimension preferredLayoutSize(Container parent) {
 
247
                                Insets insets = parent.getInsets();
 
248
                                int left = insets.left;
 
249
                                int right = insets.right;
 
250
                                int top = insets.top;
 
251
                                int bottom = insets.bottom;
 
252
                                Dimension controlPanelDim = buttonPanel.getPreferredSize();
 
253
                                if (controlPanelDim == null)
 
254
                                        controlPanelDim = new Dimension(0, 0);
 
255
                                int w = Math.min(controlPanelDim.width, maxDimension.width)
 
256
                                                + left + right;
 
257
                                int h = Math.min(controlPanelDim.height, maxDimension.height)
 
258
                                                + top + bottom;
 
259
                                if (h == (maxDimension.height + top + bottom)) {
 
260
                                        int scrollBarWidth = UIManager.getInt("ScrollBar.width");
 
261
                                        if (scrollBarWidth == 0) {
 
262
                                                // Nimbus
 
263
                                                scrollBarWidth = new JScrollBar(JScrollBar.VERTICAL)
 
264
                                                                .getPreferredSize().width;
 
265
                                        }
 
266
                                        w += scrollBarWidth;
 
267
                                        // h += 5;
 
268
                                }
 
269
                                return new Dimension(w, h);
 
270
                        }
 
271
                }
 
272
        }
 
273
 
 
274
        /*
 
275
         * (non-Javadoc)
 
276
         * 
 
277
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
278
         */
 
279
        public static ComponentUI createUI(JComponent c) {
 
280
                return new BasicCommandPopupMenuUI();
 
281
        }
 
282
 
 
283
        /*
 
284
         * (non-Javadoc)
 
285
         * 
 
286
         * @see
 
287
         * org.jvnet.flamingo.common.ui.BasicPopupPanelUI#installUI(javax.swing.
 
288
         * JComponent)
 
289
         */
 
290
        @Override
 
291
        public void installUI(JComponent c) {
 
292
                this.popupMenu = (JCommandPopupMenu) c;
 
293
                super.installUI(this.popupMenu);
 
294
 
 
295
                this.popupMenu.setLayout(this.createLayoutManager());
 
296
        }
 
297
 
 
298
        /*
 
299
         * (non-Javadoc)
 
300
         * 
 
301
         * @see org.jvnet.flamingo.common.ui.BasicPopupPanelUI#installComponents()
 
302
         */
 
303
        @Override
 
304
        protected void installComponents() {
 
305
                super.installComponents();
 
306
 
 
307
                syncComponents();
 
308
        }
 
309
 
 
310
        protected void syncComponents() {
 
311
                if (this.popupMenu.hasCommandButtonPanel()) {
 
312
                        this.commandButtonPanel = createScrollableButtonPanel();
 
313
                        this.popupMenu.add(this.commandButtonPanel);
 
314
                }
 
315
 
 
316
                final JPanel menuPanel = this.createMenuPanel();
 
317
                menuPanel.setLayout(new LayoutManager() {
 
318
                        @Override
 
319
                        public void addLayoutComponent(String name, Component comp) {
 
320
                        }
 
321
 
 
322
                        @Override
 
323
                        public void removeLayoutComponent(Component comp) {
 
324
                        }
 
325
 
 
326
                        @Override
 
327
                        public Dimension preferredLayoutSize(Container parent) {
 
328
                                int height = 0;
 
329
                                int width = 0;
 
330
                                for (int i = 0; i < parent.getComponentCount(); i++) {
 
331
                                        Dimension pref = parent.getComponent(i).getPreferredSize();
 
332
                                        height += pref.height;
 
333
                                        width = Math.max(width, pref.width);
 
334
                                }
 
335
 
 
336
                                Insets ins = parent.getInsets();
 
337
                                return new Dimension(width + ins.left + ins.right, height
 
338
                                                + ins.top + ins.bottom);
 
339
                        }
 
340
 
 
341
                        @Override
 
342
                        public Dimension minimumLayoutSize(Container parent) {
 
343
                                return preferredLayoutSize(parent);
 
344
                        }
 
345
 
 
346
                        @Override
 
347
                        public void layoutContainer(Container parent) {
 
348
                                Insets ins = parent.getInsets();
 
349
 
 
350
                                int topY = ins.top;
 
351
                                for (int i = 0; i < parent.getComponentCount(); i++) {
 
352
                                        Component comp = parent.getComponent(i);
 
353
                                        Dimension pref = comp.getPreferredSize();
 
354
                                        comp.setBounds(ins.left, topY, parent.getWidth() - ins.left
 
355
                                                        - ins.right, pref.height);
 
356
                                        topY += pref.height;
 
357
                                }
 
358
                        }
 
359
                });
 
360
 
 
361
                this.popupMenu.putClientProperty(BasicCommandPopupMenuUI.FORCE_ICON,
 
362
                                null);
 
363
                java.util.List<Component> menuComponents = this.popupMenu
 
364
                                .getMenuComponents();
 
365
                if (menuComponents != null) {
 
366
                        for (Component menuComponent : menuComponents) {
 
367
                                menuPanel.add(menuComponent);
 
368
                        }
 
369
 
 
370
                        boolean atLeastOneButtonHasIcon = false;
 
371
                        for (Component menuComponent : menuComponents) {
 
372
                                if (menuComponent instanceof JCommandMenuButton) {
 
373
                                        JCommandMenuButton menuButton = (JCommandMenuButton) menuComponent;
 
374
                                        if (menuButton.getIcon() != null) {
 
375
                                                atLeastOneButtonHasIcon = true;
 
376
                                        }
 
377
                                }
 
378
                                if (menuComponent instanceof JCommandToggleMenuButton) {
 
379
                                        atLeastOneButtonHasIcon = true;
 
380
                                }
 
381
                        }
 
382
 
 
383
                        this.popupMenu.putClientProperty(
 
384
                                        BasicCommandPopupMenuUI.FORCE_ICON,
 
385
                                        atLeastOneButtonHasIcon ? Boolean.TRUE : null);
 
386
                        for (Component menuComponent : menuComponents) {
 
387
                                if (menuComponent instanceof JCommandMenuButton) {
 
388
                                        JCommandMenuButton menuButton = (JCommandMenuButton) menuComponent;
 
389
                                        menuButton.putClientProperty(
 
390
                                                        BasicCommandPopupMenuUI.FORCE_ICON,
 
391
                                                        atLeastOneButtonHasIcon ? Boolean.TRUE : null);
 
392
                                        menuButton.setDisplayState(POPUP_MENU);
 
393
                                }
 
394
                                if (menuComponent instanceof JCommandToggleMenuButton) {
 
395
                                        JCommandToggleMenuButton menuButton = (JCommandToggleMenuButton) menuComponent;
 
396
                                        menuButton.putClientProperty(
 
397
                                                        BasicCommandPopupMenuUI.FORCE_ICON, Boolean.TRUE);
 
398
                                        menuButton.setDisplayState(POPUP_MENU);
 
399
                                }
 
400
                        }
 
401
                }
 
402
 
 
403
                this.menuItemsPanel = new JScrollablePanel<JPanel>(menuPanel,
 
404
                                JScrollablePanel.ScrollType.VERTICALLY);
 
405
                final LayoutManager scrollableLm = this.menuItemsPanel.getLayout();
 
406
                this.menuItemsPanel.setLayout(new LayoutManager() {
 
407
                        @Override
 
408
                        public void addLayoutComponent(String name, Component comp) {
 
409
                                scrollableLm.addLayoutComponent(name, comp);
 
410
                        }
 
411
 
 
412
                        @Override
 
413
                        public void removeLayoutComponent(Component comp) {
 
414
                                scrollableLm.removeLayoutComponent(comp);
 
415
                        }
 
416
 
 
417
                        @Override
 
418
                        public Dimension preferredLayoutSize(Container parent) {
 
419
                                Dimension result = menuPanel.getPreferredSize();
 
420
                                int maxMenuButtonCount = popupMenu.getMaxVisibleMenuButtons();
 
421
                                if ((maxMenuButtonCount < 0)
 
422
                                                || (maxMenuButtonCount >= menuPanel.getComponentCount())) {
 
423
                                        return result;
 
424
                                }
 
425
                                // the assumption is that all menu buttons have the
 
426
                                // same height.
 
427
                                int singleHeight = menuPanel.getComponent(0).getPreferredSize().height;
 
428
                                int width = 0;
 
429
                                for (int i = 0; i < menuPanel.getComponentCount(); i++) {
 
430
                                        width = Math.max(width, menuPanel.getComponent(i)
 
431
                                                        .getPreferredSize().width);
 
432
                                }
 
433
                                Insets ins = parent.getInsets();
 
434
                                // add two for scroller buttons
 
435
                                return new Dimension(width + ins.left + ins.right, singleHeight
 
436
                                                * (maxMenuButtonCount + 2) + ins.top + ins.bottom);
 
437
                        }
 
438
 
 
439
                        @Override
 
440
                        public Dimension minimumLayoutSize(Container parent) {
 
441
                                return this.preferredLayoutSize(parent);
 
442
                        }
 
443
 
 
444
                        @Override
 
445
                        public void layoutContainer(Container parent) {
 
446
                                scrollableLm.layoutContainer(parent);
 
447
                        }
 
448
                });
 
449
                this.popupMenu.add(this.menuItemsPanel);
 
450
        }
 
451
 
 
452
        protected ScrollableCommandButtonPanel createScrollableButtonPanel() {
 
453
                return new ScrollableCommandButtonPanel(this.popupMenu
 
454
                                .getMainButtonPanel(), this.popupMenu.getMaxButtonColumns(),
 
455
                                this.popupMenu.getMaxVisibleButtonRows());
 
456
        }
 
457
 
 
458
        /*
 
459
         * (non-Javadoc)
 
460
         * 
 
461
         * @see org.jvnet.flamingo.common.ui.BasicPopupPanelUI#uninstallComponents()
 
462
         */
 
463
        @Override
 
464
        protected void uninstallComponents() {
 
465
                this.popupMenu.removeAll();
 
466
                super.uninstallComponents();
 
467
        }
 
468
 
 
469
        @Override
 
470
        protected void installListeners() {
 
471
                super.installListeners();
 
472
 
 
473
                this.popupMenuChangeListener = new ChangeListener() {
 
474
                        @Override
 
475
                        public void stateChanged(ChangeEvent e) {
 
476
                                popupMenu.removeAll();
 
477
                                syncComponents();
 
478
                        }
 
479
                };
 
480
                this.popupMenu.addChangeListener(this.popupMenuChangeListener);
 
481
 
 
482
                this.popupListener = new PopupPanelManager.PopupListener() {
 
483
                        @Override
 
484
                        public void popupShown(PopupEvent event) {
 
485
                        }
 
486
 
 
487
                        @Override
 
488
                        public void popupHidden(PopupEvent event) {
 
489
                                if (event.getSource() instanceof JColorSelectorPopupMenu) {
 
490
                                        ((JColorSelectorPopupMenu) event.getSource())
 
491
                                                        .getColorSelectorCallback().onColorRollover(null);
 
492
                                }
 
493
                        }
 
494
                };
 
495
                PopupPanelManager.defaultManager().addPopupListener(this.popupListener);
 
496
        }
 
497
 
 
498
        /*
 
499
         * (non-Javadoc)
 
500
         * 
 
501
         * @see org.jvnet.flamingo.common.ui.BasicPopupPanelUI#uninstallListeners()
 
502
         */
 
503
        @Override
 
504
        protected void uninstallListeners() {
 
505
                this.popupMenu.removeChangeListener(this.popupMenuChangeListener);
 
506
                this.popupMenuChangeListener = null;
 
507
 
 
508
                PopupPanelManager.defaultManager().addPopupListener(this.popupListener);
 
509
                this.popupListener = null;
 
510
 
 
511
                super.uninstallListeners();
 
512
        }
 
513
 
 
514
        protected JPanel createMenuPanel() {
 
515
                return new MenuPanel();
 
516
        }
 
517
 
 
518
        protected LayoutManager createLayoutManager() {
 
519
                return new PopupMenuLayoutManager();
 
520
        }
 
521
 
 
522
        protected class PopupMenuLayoutManager implements LayoutManager {
 
523
                @Override
 
524
                public void addLayoutComponent(String name, Component comp) {
 
525
                }
 
526
 
 
527
                @Override
 
528
                public void removeLayoutComponent(Component comp) {
 
529
                }
 
530
 
 
531
                @Override
 
532
                public Dimension minimumLayoutSize(Container parent) {
 
533
                        return null;
 
534
                }
 
535
 
 
536
                @Override
 
537
                public Dimension preferredLayoutSize(Container parent) {
 
538
                        int height = 0;
 
539
                        int width = 0;
 
540
 
 
541
                        if (commandButtonPanel != null) {
 
542
                                width = commandButtonPanel.getPreferredSize().width;
 
543
                                height = commandButtonPanel.getPreferredSize().height;
 
544
                        }
 
545
                        Dimension menuItemsPref = (popupMenu.getMaxVisibleMenuButtons() > 0) ? menuItemsPanel
 
546
                                        .getPreferredSize()
 
547
                                        : menuItemsPanel.getView().getPreferredSize();
 
548
                        width = Math.max(menuItemsPref.width, width);
 
549
                        height += menuItemsPref.height;
 
550
 
 
551
                        Insets ins = parent.getInsets();
 
552
                        return new Dimension(width + ins.left + ins.right, height + ins.top
 
553
                                        + ins.bottom);
 
554
                }
 
555
 
 
556
                @Override
 
557
                public void layoutContainer(Container parent) {
 
558
                        Insets ins = parent.getInsets();
 
559
 
 
560
                        int bottomY = parent.getHeight() - ins.bottom;
 
561
                        Dimension menuItemsPref = (popupMenu.getMaxVisibleMenuButtons() > 0) ? menuItemsPanel
 
562
                                        .getPreferredSize()
 
563
                                        : menuItemsPanel.getView().getPreferredSize();
 
564
 
 
565
            int menuHeight = Math.min(menuItemsPref.height, parent.getHeight());
 
566
                        menuItemsPanel.setBounds(ins.left, bottomY - menuHeight,
 
567
                                        parent.getWidth() - ins.left - ins.right,
 
568
                                        menuHeight);
 
569
                        menuItemsPanel.doLayout();
 
570
                        bottomY -= menuHeight;
 
571
 
 
572
                        if (commandButtonPanel != null) {
 
573
                                commandButtonPanel.setBounds(ins.left, ins.top, parent
 
574
                                                .getWidth()
 
575
                                                - ins.left - ins.right, bottomY - ins.top);
 
576
                                commandButtonPanel.invalidate();
 
577
                                commandButtonPanel.validate();
 
578
                                commandButtonPanel.doLayout();
 
579
                        }
 
580
                }
 
581
        }
 
582
 
 
583
        protected static class MenuPanel extends JPanel {
 
584
                @Override
 
585
                public void paintComponent(Graphics g) {
 
586
                        super.paintComponent(g);
 
587
                        JCommandPopupMenu menu = (JCommandPopupMenu) SwingUtilities
 
588
                                        .getAncestorOfClass(JCommandPopupMenu.class, this);
 
589
                        if (Boolean.TRUE.equals(menu.getClientProperty(FORCE_ICON))) {
 
590
                                this.paintIconGutterBackground(g);
 
591
                                this.paintIconGutterSeparator(g);
 
592
                        }
 
593
                }
 
594
 
 
595
                protected int getSeparatorX() {
 
596
                        JCommandPopupMenu menu = (JCommandPopupMenu) SwingUtilities
 
597
                                        .getAncestorOfClass(JCommandPopupMenu.class, this);
 
598
                        if (!Boolean.TRUE.equals(menu.getClientProperty(FORCE_ICON))) {
 
599
                                return -1;
 
600
                        }
 
601
                        java.util.List<Component> menuComponents = menu.getMenuComponents();
 
602
                        if (menuComponents != null) {
 
603
                                for (Component menuComponent : menuComponents) {
 
604
                                        if (menuComponent instanceof JCommandMenuButton
 
605
                                                        || menuComponent instanceof JCommandToggleMenuButton) {
 
606
                                                AbstractCommandButton button = (AbstractCommandButton) menuComponent;
 
607
                                                if (!Boolean.TRUE.equals(button
 
608
                                                                .getClientProperty(FORCE_ICON))) {
 
609
                                                        continue;
 
610
                                                }
 
611
                                                boolean ltr = button.getComponentOrientation()
 
612
                                                                .isLeftToRight();
 
613
                                                CommandButtonLayoutManager.CommandButtonLayoutInfo layoutInfo = button
 
614
                                                                .getUI().getLayoutInfo();
 
615
                                                if (ltr) {
 
616
                                                        int iconRight = layoutInfo.iconRect.x
 
617
                                                                        + layoutInfo.iconRect.width;
 
618
                                                        int textLeft = button.getWidth();
 
619
                                                        for (CommandButtonLayoutManager.TextLayoutInfo tli : layoutInfo.textLayoutInfoList) {
 
620
                                                                textLeft = Math.min(textLeft, tli.textRect.x);
 
621
                                                        }
 
622
                                                        return (iconRight + textLeft) / 2;
 
623
                                                } else {
 
624
                                                        int iconLeft = layoutInfo.iconRect.x;
 
625
                                                        int textRight = 0;
 
626
                                                        for (CommandButtonLayoutManager.TextLayoutInfo tli : layoutInfo.textLayoutInfoList) {
 
627
                                                                textRight = Math.max(textRight, tli.textRect.x
 
628
                                                                                + tli.textRect.width);
 
629
                                                        }
 
630
                                                        return (iconLeft + textRight) / 2;
 
631
                                                }
 
632
                                        }
 
633
                                }
 
634
                        }
 
635
                        throw new IllegalStateException(
 
636
                                        "Menu marked to show icons but no menu buttons in it");
 
637
                }
 
638
 
 
639
                protected void paintIconGutterSeparator(Graphics g) {
 
640
                        CellRendererPane buttonRendererPane = new CellRendererPane();
 
641
                        JSeparator rendererSeparator = new JSeparator(JSeparator.VERTICAL);
 
642
 
 
643
                        buttonRendererPane.setBounds(0, 0, this.getWidth(), this
 
644
                                        .getHeight());
 
645
                        int sepX = this.getSeparatorX();
 
646
                        if (this.getComponentOrientation().isLeftToRight()) {
 
647
                                buttonRendererPane.paintComponent(g, rendererSeparator, this,
 
648
                                                sepX, 2, 2, this.getHeight() - 4, true);
 
649
                        } else {
 
650
                                buttonRendererPane.paintComponent(g, rendererSeparator, this,
 
651
                                                sepX, 2, 2, this.getHeight() - 4, true);
 
652
                        }
 
653
                }
 
654
 
 
655
                protected void paintIconGutterBackground(Graphics g) {
 
656
                        Graphics2D g2d = (Graphics2D) g.create();
 
657
                        g2d.setComposite(AlphaComposite.SrcOver.derive(0.7f));
 
658
 
 
659
                        int sepX = this.getSeparatorX();
 
660
                        if (this.getComponentOrientation().isLeftToRight()) {
 
661
                                g2d.clipRect(0, 0, sepX + 2, this.getHeight());
 
662
                                AffineTransform at = AffineTransform.getTranslateInstance(0,
 
663
                                                this.getHeight());
 
664
                                at.rotate(-Math.PI / 2);
 
665
                                g2d.transform(at);
 
666
 
 
667
                                FlamingoUtilities.renderSurface(g2d, this, new Rectangle(0, 0,
 
668
                                                this.getHeight(), 50), false, false, false);
 
669
                        } else {
 
670
                                g2d.clipRect(this.getWidth() - sepX, 0, sepX + 2, this
 
671
                                                .getHeight());
 
672
                                AffineTransform at = AffineTransform.getTranslateInstance(0,
 
673
                                                this.getHeight());
 
674
                                at.rotate(-Math.PI / 2);
 
675
                                g2d.transform(at);
 
676
 
 
677
                                FlamingoUtilities.renderSurface(g2d, this, new Rectangle(0,
 
678
                                                sepX, this.getHeight(), this.getWidth() - sepX), false,
 
679
                                                false, false);
 
680
                        }
 
681
 
 
682
                        g2d.dispose();
 
683
                }
 
684
        }
 
685
}
 
 
b'\\ No newline at end of file'