source: trunk/ardor3d-ui/src/main/java/com/ardor3d/extension/ui/UIComboBox.java @ 1586

Revision 1586, 7.6 KB checked in by ardorlabs, 15 months ago (diff)

Added combobox, and simple popup menu + skin updates.

Line 
1/**
2 * Copyright (c) 2008-2011 Ardor Labs, Inc.
3 *
4 * This file is part of Ardor3D.
5 *
6 * Ardor3D is free software: you can redistribute it and/or modify it
7 * under the terms of its license which may be found in the accompanying
8 * LICENSE file or at <http://www.ardor3d.com/LICENSE>.
9 */
10
11package com.ardor3d.extension.ui;
12
13import java.util.List;
14
15import com.ardor3d.extension.ui.event.ActionEvent;
16import com.ardor3d.extension.ui.event.ActionListener;
17import com.ardor3d.extension.ui.event.SelectionListener;
18import com.ardor3d.extension.ui.layout.BorderLayout;
19import com.ardor3d.extension.ui.layout.BorderLayoutData;
20import com.ardor3d.extension.ui.model.ComboBoxModel;
21import com.ardor3d.extension.ui.model.DefaultComboBoxModel;
22import com.ardor3d.extension.ui.skin.SkinningTask;
23import com.ardor3d.extension.ui.text.StyleConstants;
24import com.ardor3d.input.InputState;
25import com.ardor3d.input.MouseButton;
26import com.ardor3d.scenegraph.Spatial;
27import com.google.common.collect.Lists;
28
29/**
30 * A UI component that contains several possible choices, but shows only the currently selected one. Changing the
31 * selection is allowed via a popup menu shown when the component is clicked on.
32 */
33public class UIComboBox extends UIPanel {
34
35    protected ComboBoxModel _model;
36
37    protected UILabel _valueLabel;
38    protected UIButton _openButton;
39    protected UIPopupMenu _valuesMenu;
40
41    protected int _selectedIndex = 0;
42
43    private final List<SelectionListener<UIComboBox>> _listeners = Lists.newArrayList();
44
45    private SkinningTask _itemSkinCallback;
46
47    public UIComboBox() {
48        this(new DefaultComboBoxModel());
49    }
50
51    public UIComboBox(final ComboBoxModel model) {
52        super(new BorderLayout());
53        if (model == null) {
54            throw new IllegalArgumentException("model can not be null.");
55        }
56        _model = model;
57
58        _valueLabel = new UILabel(_model.size() > 0 ? _model.getViewAt(0) : "") {
59            @Override
60            public boolean mouseReleased(final MouseButton button, final InputState state) {
61                _openButton.doClick();
62                return true;
63            }
64        };
65        _valueLabel.setLayoutData(BorderLayoutData.CENTER);
66        add(_valueLabel);
67
68        _openButton = new UIButton("\\/");
69        _openButton.setLayoutData(BorderLayoutData.EAST);
70        add(_openButton);
71
72        _valuesMenu = new UIPopupMenu() {
73            @Override
74            public UIComponent getUIComponent(final int hudX, final int hudY) {
75                final UIComponent component = super.getUIComponent(hudX, hudY);
76                if (component != null) {
77                    if (component instanceof UIButton) {
78                        final UIButton over = (UIButton) component;
79                        final UIState state = over.getCurrentState();
80                        if (state == over.getDefaultState() || state == over.getSelectedState()) {
81                            clearOver();
82                        }
83                    }
84                }
85                return component;
86            }
87        };
88
89        _openButton.addActionListener(new ActionListener() {
90            @Override
91            public void actionPerformed(final ActionEvent event) {
92                if (!isEnabled()) {
93                    return;
94                }
95
96                if (_valuesMenu.isAttachedToHUD()) {
97                    _valuesMenu.getHud().closePopupMenus();
98                }
99
100                _valuesMenu.clearItems();
101                for (int i = 0; i < _model.size(); i++) {
102                    final UIMenuItem item = new UIMenuItem("" + _model.getValueAt(i));
103                    if (_itemSkinCallback != null) {
104                        _itemSkinCallback.skinComponent(item);
105                    }
106                    if (i == getSelectedIndex()) {
107                        item.addFontStyle(StyleConstants.KEY_BOLD, Boolean.TRUE);
108                    }
109                    final int index = i;
110                    item.addActionListener(new ActionListener() {
111                        @Override
112                        public void actionPerformed(final ActionEvent event) {
113                            setSelectedIndex(index);
114                        }
115                    });
116
117                    // Apply model for name and toolTipText
118                    item.setName(_model.getViewAt(i));
119                    item.setTooltipText(_model.getToolTipAt(i));
120                    _valuesMenu.addItem(item);
121                }
122
123                _valuesMenu.updateMinimumSizeFromContents();
124                _valuesMenu.pack();
125                if (_valuesMenu.getLocalComponentWidth() < UIComboBox.this.getLocalComponentWidth()) {
126                    _valuesMenu.setLocalComponentWidth(UIComboBox.this.getLocalComponentWidth());
127                }
128                _valuesMenu.layout();
129                getHud().closePopupMenus();
130                getHud().showSubPopupMenu(_valuesMenu);
131                _valuesMenu.showAt(_valueLabel.getHudX(), _valueLabel.getHudY());
132            }
133        });
134
135        applySkin();
136    }
137
138    protected void clearOver() {
139        _openButton.switchState(_openButton.getDefaultState());
140        for (int i = _valuesMenu.getNumberOfChildren(); --i >= 0;) {
141            final Spatial item = _valuesMenu.getChild(i);
142            if (item instanceof UIButton) {
143                final UIButton over = (UIButton) item;
144                over.switchState(over.getDefaultState());
145            }
146        }
147    }
148
149    public int getSelectedIndex() {
150        return _selectedIndex;
151    }
152
153    public Object getSelectedValue() {
154        return _model.getValueAt(getSelectedIndex());
155    }
156
157    public void setSelectedIndex(final int index) {
158        setSelectedIndex(index, true);
159    }
160
161    public void setSelectedIndex(final int index, final boolean fireEvent) {
162        if (index != _selectedIndex) {
163            _selectedIndex = index;
164            if (fireEvent) {
165                fireSelectionEvent();
166            }
167            fireComponentDirty();
168        }
169
170        if (index == -1 || _model == null || _model.size() == 0) {
171            _valueLabel.setText("");
172        } else {
173            _valueLabel.setText(_model.getViewAt(index));
174        }
175    }
176
177    protected void fireSelectionEvent() {
178        if (!isEnabled()) {
179            return;
180        }
181        for (final SelectionListener<UIComboBox> listener : _listeners) {
182            listener.selectionChanged(this, getSelectedValue());
183        }
184    }
185
186    @Override
187    public void setEnabled(final boolean enabled) {
188        super.setEnabled(enabled);
189        _valueLabel.setEnabled(enabled);
190        _openButton.setEnabled(enabled);
191    }
192
193    @Override
194    public String getTooltipText() {
195        if (_tooltipText == null) {
196            final String rVal = _model.getToolTipAt(_selectedIndex);
197            if (rVal != null) {
198                return rVal;
199            }
200        }
201        return super.getTooltipText();
202    }
203
204    public UILabel getValueLabel() {
205        return _valueLabel;
206    }
207
208    public ComboBoxModel getModel() {
209        return _model;
210    }
211
212    public UIButton getOpenButton() {
213        return _openButton;
214    }
215
216    public UIPopupMenu getValuesMenu() {
217        return _valuesMenu;
218    }
219
220    public void addSelectionListener(final SelectionListener<UIComboBox> listener) {
221        _listeners.add(listener);
222    }
223
224    public void removeSelectionListener(final SelectionListener<UIComboBox> listener) {
225        _listeners.remove(listener);
226    }
227
228    public void clearSelectionListeners() {
229        _listeners.clear();
230    }
231
232    public void setItemSkinCallback(final SkinningTask callback) {
233        _itemSkinCallback = callback;
234    }
235
236    public SkinningTask getItemSkinCallback() {
237        return _itemSkinCallback;
238    }
239}
Note: See TracBrowser for help on using the repository browser.