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.component;
020
021import icy.gui.component.button.IcyToggleButton;
022import icy.gui.util.ComponentUtil;
023import icy.resource.ResourceUtil;
024import icy.resource.icon.IcyIcon;
025import icy.util.GraphicsUtil;
026
027import java.awt.BorderLayout;
028import java.awt.Dimension;
029import java.awt.Image;
030import java.awt.event.ActionEvent;
031import java.awt.event.ActionListener;
032import java.awt.geom.Rectangle2D;
033
034import javax.swing.BorderFactory;
035import javax.swing.Icon;
036import javax.swing.JPanel;
037import javax.swing.SwingConstants;
038
039/**
040 * @author Stephane
041 */
042public class PopupPanel extends JPanel
043{
044    private class PopupTitlePanel extends IcyToggleButton
045    {
046        /**
047         * 
048         */
049        private static final long serialVersionUID = -6311966421110920079L;
050
051        public PopupTitlePanel(String text, Image image)
052        {
053            super(text, new IcyIcon(image, 14));
054
055            setHorizontalAlignment(SwingConstants.LEADING);
056            setFocusPainted(false);
057
058            if (subPopupPanel)
059                ComponentUtil.setFixedHeight(this, getTextSize().height);
060            else
061                ComponentUtil.setFontBold(this);
062
063            addActionListener(new ActionListener()
064            {
065                @Override
066                public void actionPerformed(ActionEvent e)
067                {
068                    refresh();
069                }
070            });
071        }
072
073        @Override
074        public void setText(String text)
075        {
076            super.setText(text);
077
078            updateIconTextGap();
079        }
080
081        @Override
082        public void setIcon(Icon defaultIcon)
083        {
084            super.setIcon(defaultIcon);
085
086            updateIconTextGap();
087        }
088
089        @Override
090        public void setBounds(int x, int y, int width, int height)
091        {
092            super.setBounds(x, y, width, height);
093
094            updateIconTextGap();
095        }
096
097        private Dimension getTextSize()
098        {
099            final String text = getText();
100
101            if (text != null)
102            {
103                final Rectangle2D r = GraphicsUtil.getStringBounds(this, text);
104                return new Dimension((int) r.getWidth(), (int) r.getHeight());
105            }
106
107            return new Dimension(0, 0);
108        }
109
110        private void updateIconTextGap()
111        {
112            final int width = getWidth();
113            final Icon icon = getIcon();
114
115            if ((width != 0) && (icon != null))
116            {
117                // adjust icon gap to new width
118                int iconTextGap = (width - getTextSize().width) / 2;
119                iconTextGap -= (icon.getIconWidth() + 10);
120                setIconTextGap(iconTextGap);
121            }
122        }
123    }
124
125    /**
126     * 
127     */
128    private static final long serialVersionUID = -5208183544572376729L;
129
130    protected final PopupTitlePanel topPanel;
131    protected final JPanel mainPanel;
132
133    protected final boolean subPopupPanel;
134
135    /**
136     * @deprecated Use {@link #PopupPanel(String, boolean)} instead
137     */
138    @Deprecated
139    public PopupPanel(String title, int panelHeight, boolean subPopupPanel)
140    {
141        this(title, subPopupPanel);
142
143    }
144
145    /**
146     * @deprecated Use {@link #PopupPanel(String, boolean)} instead
147     */
148    @Deprecated
149    public PopupPanel(String title, int panelHeight)
150    {
151        this(title, false);
152    }
153
154    /**
155     * Create a new popup panel with specified title.
156     * 
157     * @param title
158     *        Panel title
159     * @panel panel internal panel
160     * @param subPanel
161     *        Determine if this is an embedded popup panel or a normal one.
162     */
163    public PopupPanel(String title, JPanel panel, boolean subPanel)
164    {
165        super();
166
167        topPanel = new PopupTitlePanel(title, ResourceUtil.ICON_PANEL_COLLAPSE);
168        mainPanel = panel;
169        // if (panelHeight != -1)
170        // ComponentUtil.setFixedHeight(mainPanel, panelHeight);
171        subPopupPanel = subPanel;
172
173        setBorder(BorderFactory.createRaisedBevelBorder());
174        setLayout(new BorderLayout());
175
176        add(topPanel, BorderLayout.NORTH);
177        add(mainPanel, BorderLayout.CENTER);
178
179        refresh();
180    }
181
182    /**
183     * Create a new popup panel with specified title.
184     * 
185     * @param title
186     *        Panel title
187     * @panel panel internal panel
188     */
189    public PopupPanel(String title, JPanel panel)
190    {
191        this(title, panel, false);
192    }
193
194    /**
195     * Create a new popup panel with specified title.
196     * 
197     * @param title
198     *        Panel title
199     * @param subPanel
200     *        Determine if this is an embedded popup panel or a normal one.
201     */
202    public PopupPanel(String title, boolean subPanel)
203    {
204        this(title, new JPanel(), subPanel);
205    }
206
207    /**
208     * Create a new popup panel with specified title.
209     */
210    public PopupPanel(String title)
211    {
212        this(title, false);
213    }
214
215    /**
216     * @deprecated Use {@link #PopupPanel(String)} instead.
217     */
218    @Deprecated
219    public PopupPanel()
220    {
221        this("no title", false);
222    }
223
224    public String getTitle()
225    {
226        return topPanel.getText();
227    }
228
229    public void setTitle(String value)
230    {
231        topPanel.setText(value);
232    }
233
234    /**
235     * @return the title panel
236     */
237    public PopupTitlePanel getTitlePanel()
238    {
239        return topPanel;
240    }
241
242    /**
243     * @return the mainPanel
244     */
245    public JPanel getMainPanel()
246    {
247        return mainPanel;
248    }
249
250    /**
251     * @return the collapsed
252     */
253    public boolean isCollapsed()
254    {
255        return !isExpanded();
256    }
257
258    /**
259     * @return the collapsed
260     */
261    public boolean isExpanded()
262    {
263        return topPanel.isSelected();
264    }
265
266    /**
267     * @param value
268     *        the collapsed to set
269     */
270    public void setExpanded(boolean value)
271    {
272        if (topPanel.isSelected() != value)
273        {
274            topPanel.setSelected(value);
275            refresh();
276        }
277    }
278
279    /**
280     * @return the subPopupPanel
281     */
282    public boolean isSubPopupPanel()
283    {
284        return subPopupPanel;
285    }
286
287    public void expand()
288    {
289        setExpanded(true);
290    }
291
292    public void collapse()
293    {
294        setExpanded(false);
295    }
296
297    void refresh()
298    {
299        if (subPopupPanel)
300        {
301            if (topPanel.isSelected())
302                topPanel.setIcon(new IcyIcon(ResourceUtil.ICON_NODE_EXPANDED, 10));
303            else
304                topPanel.setIcon(new IcyIcon(ResourceUtil.ICON_NODE_COLLAPSED, 10));
305        }
306        else
307        {
308            if (topPanel.isSelected())
309                topPanel.setIcon(new IcyIcon(ResourceUtil.ICON_NODE_EXPANDED, 14));
310            else
311                topPanel.setIcon(new IcyIcon(ResourceUtil.ICON_NODE_COLLAPSED, 14));
312        }
313
314        mainPanel.setVisible(topPanel.isSelected());
315    }
316}