001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.util;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
025import org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand;
026import org.pushingpixels.flamingo.api.ribbon.JFlowRibbonBand;
027import org.pushingpixels.flamingo.api.ribbon.JRibbon;
028import org.pushingpixels.flamingo.api.ribbon.JRibbonBand;
029import org.pushingpixels.flamingo.api.ribbon.RibbonElementPriority;
030import org.pushingpixels.flamingo.api.ribbon.RibbonTask;
031import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.FlowThreeRows;
032import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.FlowTwoRows;
033import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.High2Low;
034import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.High2Mid;
035import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.Low2Mid;
036import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.Mid2Low;
037import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.Mid2Mid;
038import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.Mirror;
039import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies.None;
040import org.pushingpixels.flamingo.api.ribbon.resize.IconRibbonBandResizePolicy;
041import org.pushingpixels.flamingo.api.ribbon.resize.RibbonBandResizePolicy;
042import org.pushingpixels.flamingo.internal.ui.ribbon.JBandControlPanel;
043import org.pushingpixels.flamingo.internal.ui.ribbon.JFlowBandControlPanel;
044
045import icy.util.StringUtil;
046
047/**
048 * @author Stephane
049 */
050public class RibbonUtil
051{
052    private static final int DEFAULT_HEIGHT = 48;
053    private static final int DEFAULT_GAP = 4;
054
055    // High2Low --> LOW, LOW, LOW
056    // High2Mid --> MED, LOW, LOW
057    // Mid2Low --> TOP, LOW, LOW
058    // Mirror --> TOP, MED, LOW
059    // Mid2Mid --> TOP, MED, MED
060    // Low2Mid --> TOP, TOP, MED
061    // None --> TOP, TOP, TOP
062
063    private static List<RibbonBandResizePolicy> getPermissiveResizePolicies(final JBandControlPanel controlPanel)
064    {
065        final ArrayList<RibbonBandResizePolicy> result = new ArrayList<RibbonBandResizePolicy>();
066
067        final None none = new None(controlPanel);
068        final Low2Mid low2Mid = new Low2Mid(controlPanel);
069        final Mid2Mid mid2Mid = new Mid2Mid(controlPanel);
070        final Mirror mirror = new Mirror(controlPanel);
071        final Mid2Low mid2Low = new Mid2Low(controlPanel);
072        final High2Mid high2Mid = new High2Mid(controlPanel);
073        final High2Low high2Low = new High2Low(controlPanel);
074        final IconRibbonBandResizePolicy icon = new IconRibbonBandResizePolicy(controlPanel);
075
076        final int noneW = none.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
077        final int low2MidW = low2Mid.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
078        final int mid2MidW = mid2Mid.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
079        final int mirrorW = mirror.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
080        final int mid2LowW = mid2Low.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
081        final int high2MidW = high2Mid.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
082        final int high2LowW = high2Low.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
083        final int iconW = icon.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
084
085        result.add(none);
086        if (low2MidW < noneW)
087            result.add(low2Mid);
088        if (mid2MidW < low2MidW)
089            result.add(mid2Mid);
090        if (mirrorW < mid2MidW)
091            result.add(mirror);
092        if (mid2LowW < mirrorW)
093            result.add(mid2Low);
094        if (high2MidW < mid2LowW)
095            result.add(high2Mid);
096        if (high2LowW < high2MidW)
097            result.add(high2Low);
098        // icon resize policy should be in last position
099        if (iconW < high2LowW)
100            result.add(icon);
101
102        return result;
103    }
104
105    private static List<RibbonBandResizePolicy> getRestrictiveResizePolicies(final JBandControlPanel controlPanel,
106            int gap)
107    {
108        final ArrayList<RibbonBandResizePolicy> result = new ArrayList<RibbonBandResizePolicy>();
109
110        final Mirror mirror = new Mirror(controlPanel);
111        final Mid2Low mid2Low = new Mid2Low(controlPanel);
112        final High2Mid high2Mid = new High2Mid(controlPanel);
113        final High2Low high2Low = new High2Low(controlPanel);
114        final IconRibbonBandResizePolicy icon = new IconRibbonBandResizePolicy(controlPanel);
115
116        final int mirrorW = mirror.getPreferredWidth(DEFAULT_HEIGHT, gap);
117        final int mid2LowW = mid2Low.getPreferredWidth(DEFAULT_HEIGHT, gap);
118        final int high2MidW = high2Mid.getPreferredWidth(DEFAULT_HEIGHT, gap);
119        final int high2LowW = high2Low.getPreferredWidth(DEFAULT_HEIGHT, gap);
120        final int iconW = icon.getPreferredWidth(DEFAULT_HEIGHT, gap);
121
122        result.add(mirror);
123        if (mid2LowW < mirrorW)
124            result.add(mid2Low);
125        if (high2MidW < mid2LowW)
126            result.add(high2Mid);
127        if (high2LowW < high2MidW)
128            result.add(high2Low);
129        // icon resize policy should be in last position
130        if (iconW < high2LowW)
131            result.add(icon);
132
133        return result;
134    }
135
136    private static List<RibbonBandResizePolicy> getFixedResizePolicies(JBandControlPanel controlPanel)
137    {
138        final ArrayList<RibbonBandResizePolicy> result = new ArrayList<RibbonBandResizePolicy>();
139
140        result.add(new Mirror(controlPanel));
141
142        return result;
143    }
144
145    private static List<RibbonBandResizePolicy> getRestrictiveResizePolicies(JFlowBandControlPanel controlPanel,
146            int step)
147    {
148        final ArrayList<RibbonBandResizePolicy> result = new ArrayList<RibbonBandResizePolicy>();
149
150        final FlowTwoRows twoRows = new FlowTwoRows(controlPanel);
151        final FlowThreeRows threeRows = new FlowThreeRows(controlPanel);
152        final IconRibbonBandResizePolicy icon = new IconRibbonBandResizePolicy(controlPanel);
153
154        final int twoRowsW = twoRows.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
155        final int threeRowsW = threeRows.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
156        final int iconW = twoRows.getPreferredWidth(DEFAULT_HEIGHT, DEFAULT_GAP);
157
158        if (twoRowsW > threeRowsW)
159        {
160            // add two rows policy first
161            for (int i = 0; i < step; i++)
162                result.add(new FlowTwoRows(controlPanel));
163            for (int i = 0; i < step; i++)
164                result.add(new FlowThreeRows(controlPanel));
165            // icon resize policy should be in last position
166            if (iconW < threeRowsW)
167                result.add(icon);
168        }
169        else
170        {
171            // add three rows policy first
172            for (int i = 0; i < step; i++)
173                result.add(new FlowThreeRows(controlPanel));
174            for (int i = 0; i < step; i++)
175                result.add(new FlowTwoRows(controlPanel));
176            // icon resize policy should be in last position
177            if (iconW < twoRowsW)
178                result.add(icon);
179        }
180
181        return result;
182    }
183
184    public static void setPermissiveResizePolicies(JRibbonBand band)
185    {
186        // equivalent to getCorePoliciesPermissive(band);
187        band.setResizePolicies(getPermissiveResizePolicies(band.getControlPanel()));
188    }
189
190    public static void setRestrictiveResizePolicies(JRibbonBand band)
191    {
192        setRestrictiveResizePolicies(band, DEFAULT_GAP);
193    }
194
195    public static void setRestrictiveResizePolicies(JRibbonBand band, int gap)
196    {
197        // equivalent to getCorePoliciesRestrictive(band);
198        band.setResizePolicies(getRestrictiveResizePolicies(band.getControlPanel(), gap));
199    }
200
201    public static void setFixedResizePolicies(JRibbonBand band)
202    {
203        // equivalent to getCorePoliciesNone(band);
204        band.setResizePolicies(getFixedResizePolicies(band.getControlPanel()));
205    }
206
207    public static void setRestrictiveResizePolicies(JFlowRibbonBand band, int step)
208    {
209        // equivalent to getCoreFlowPoliciesRestrictive(band, step);
210        band.setResizePolicies(getRestrictiveResizePolicies(band.getControlPanel(), step));
211    }
212
213    public static ArrayList<RibbonTask> getTasks(JRibbon ribbon)
214    {
215        final ArrayList<RibbonTask> result = new ArrayList<RibbonTask>();
216
217        if (ribbon != null)
218        {
219            final int taskCount = ribbon.getTaskCount();
220
221            for (int i = 0; i < taskCount; i++)
222                result.add(ribbon.getTask(i));
223        }
224
225        return result;
226    }
227
228    public static RibbonTask getTask(JRibbon ribbon, String name)
229    {
230        if (ribbon != null)
231        {
232            final int taskCount = ribbon.getTaskCount();
233
234            for (int i = 0; i < taskCount; i++)
235            {
236                final RibbonTask ribbonTask = ribbon.getTask(i);
237
238                if (StringUtil.equals(ribbonTask.getTitle(), name))
239                    return ribbonTask;
240            }
241        }
242
243        return null;
244    }
245
246    public static JRibbonBand getBand(RibbonTask ribbonTask, String name)
247    {
248        if (ribbonTask != null)
249        {
250            for (AbstractRibbonBand<?> ribbonBand : ribbonTask.getBands())
251            {
252                if (StringUtil.equals(ribbonBand.getTitle(), name))
253                    if (ribbonBand instanceof JRibbonBand)
254                        return (JRibbonBand) ribbonBand;
255            }
256        }
257
258        return null;
259    }
260
261    public static JFlowRibbonBand getFlowBand(RibbonTask ribbonTask, String name)
262    {
263        if (ribbonTask != null)
264        {
265            for (AbstractRibbonBand<?> ribbonBand : ribbonTask.getBands())
266            {
267                if (StringUtil.equals(ribbonBand.getTitle(), name))
268                    if (ribbonBand instanceof JFlowRibbonBand)
269                        return (JFlowRibbonBand) ribbonBand;
270            }
271        }
272
273        return null;
274    }
275
276    public static RibbonElementPriority getButtonPriority(JRibbonBand band, AbstractCommandButton button)
277    {
278        final RibbonElementPriority result = band.getControlPanel().getPriority(button);
279
280        if (result != null)
281            return result;
282
283        return RibbonElementPriority.LOW;
284    }
285
286    // public static int getButtonPosition(JRibbonBand band, AbstractCommandButton button)
287    // {
288    // int result = 0;
289    //
290    // final JBandControlPanel controlPanel = band.getControlPanel();
291    //
292    // if (controlPanel != null)
293    // {
294    // for (ControlPanelGroup panelGroup : controlPanel.getControlPanelGroups())
295    // {
296    // for (AbstractCommandButton b : panelGroup.getRibbonButtons(RibbonElementPriority.LOW))
297    // {
298    // if (b == button)
299    // return result;
300    // result++;
301    // }
302    //
303    // for (AbstractCommandButton b : panelGroup.getRibbonButtons(RibbonElementPriority.MEDIUM))
304    // {
305    // if (b == button)
306    // return result;
307    // result++;
308    // }
309    //
310    // for (AbstractCommandButton b : panelGroup.getRibbonButtons(RibbonElementPriority.TOP))
311    // {
312    // if (b == button)
313    // return result;
314    // result++;
315    // }
316    // }
317    // }
318    //
319    // // return -1 if not found
320    // return -1;
321    // }
322
323    public static List<AbstractCommandButton> getButtons(JRibbonBand band)
324    {
325        return band.getControlPanel().getAllCommandButtons();
326    }
327
328    public static AbstractCommandButton findButton(List<AbstractCommandButton> buttons, String name)
329    {
330        for (AbstractCommandButton button : buttons)
331            if (StringUtil.equals(button.getName(), name))
332                return button;
333
334        return null;
335    }
336
337    public static AbstractCommandButton findButton(JRibbonBand band, String name)
338    {
339        if (band != null)
340            return findButton(band.getControlPanel().getAllCommandButtons(), name);
341
342        return null;
343    }
344
345    /**
346     * ! Ribbon doesn't support button removing so use it at your own risk !
347     */
348    public static void removeButton(JRibbonBand band, String name)
349    {
350        band.removeCommandButton(findButton(band, name));
351    }
352}