00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_ComboBox.h"
00025 #include "MyGUI_ControllerManager.h"
00026 #include "MyGUI_InputManager.h"
00027 #include "MyGUI_WidgetManager.h"
00028 #include "MyGUI_Gui.h"
00029 #include "MyGUI_List.h"
00030 #include "MyGUI_Button.h"
00031 #include "MyGUI_ResourceSkin.h"
00032 #include "MyGUI_LayerManager.h"
00033
00034 namespace MyGUI
00035 {
00036
00037 const float COMBO_ALPHA_MAX = ALPHA_MAX;
00038 const float COMBO_ALPHA_MIN = ALPHA_MIN;
00039 const float COMBO_ALPHA_COEF = 4.0f;
00040
00041 ComboBox::ComboBox() :
00042 mButton(nullptr),
00043 mList(nullptr),
00044 mListShow(false),
00045 mMaxHeight(0),
00046 mItemIndex(ITEM_NONE),
00047 mModeDrop(false),
00048 mDropMouse(false),
00049 mShowSmooth(false),
00050 mManualList(true)
00051 {
00052 }
00053
00054 void ComboBox::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00055 {
00056 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00057
00058 initialiseWidgetSkin(_info);
00059 }
00060
00061 ComboBox::~ComboBox()
00062 {
00063 shutdownWidgetSkin();
00064 }
00065
00066 void ComboBox::baseChangeWidgetSkin(ResourceSkin* _info)
00067 {
00068 shutdownWidgetSkin();
00069 Base::baseChangeWidgetSkin(_info);
00070 initialiseWidgetSkin(_info);
00071 }
00072
00073 void ComboBox::initialiseWidgetSkin(ResourceSkin* _info)
00074 {
00075
00076 const MapString& properties = _info->getProperties();
00077 if (!properties.empty())
00078 {
00079 MapString::const_iterator iter = properties.find("HeightList");
00080 if (iter != properties.end()) mMaxHeight = utility::parseValue<int>(iter->second);
00081
00082 iter = properties.find("ListSmoothShow");
00083 if (iter != properties.end()) setSmoothShow(utility::parseBool(iter->second));
00084 }
00085
00086
00087 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00088 {
00089 if (*(*iter)->_getInternalData<std::string>() == "Button")
00090 {
00091 MYGUI_DEBUG_ASSERT( ! mButton, "widget already assigned");
00092 mButton = (*iter)->castType<Button>();
00093 mButton->eventMouseButtonPressed = newDelegate(this, &ComboBox::notifyButtonPressed);
00094 }
00095 else if (*(*iter)->_getInternalData<std::string>() == "List")
00096 {
00097 MYGUI_DEBUG_ASSERT( ! mList, "widget already assigned");
00098 mList = (*iter)->castType<List>();
00099 mList->setVisible(false);
00100 mList->eventKeyLostFocus = newDelegate(this, &ComboBox::notifyListLostFocus);
00101 mList->eventListSelectAccept = newDelegate(this, &ComboBox::notifyListSelectAccept);
00102 mList->eventListMouseItemActivate = newDelegate(this, &ComboBox::notifyListMouseItemActivate);
00103 mList->eventListChangePosition = newDelegate(this, &ComboBox::notifyListChangePosition);
00104 }
00105 }
00106
00107
00108
00109
00110
00111 mManualList = (mList == nullptr);
00112 if (mList == nullptr)
00113 {
00114 std::string list_skin;
00115 MapString::const_iterator iter = properties.find("ListSkin");
00116 if (iter != properties.end()) list_skin = iter->second;
00117 std::string list_layer;
00118 iter = properties.find("ListLayer");
00119 if (iter != properties.end()) list_layer = iter->second;
00120 mList = createWidget<MyGUI::List>(WidgetStyle::Popup, list_skin, IntCoord(), Align::Default, list_layer);
00121 mWidgetChild.pop_back();
00122
00123 mList->setVisible(false);
00124 mList->eventKeyLostFocus = newDelegate(this, &ComboBox::notifyListLostFocus);
00125 mList->eventListSelectAccept = newDelegate(this, &ComboBox::notifyListSelectAccept);
00126 mList->eventListMouseItemActivate = newDelegate(this, &ComboBox::notifyListMouseItemActivate);
00127 mList->eventListChangePosition = newDelegate(this, &ComboBox::notifyListChangePosition);
00128 }
00129
00130
00131
00132
00133
00134 if (mWidgetClient != nullptr)
00135 {
00136 mWidgetClient->eventMouseWheel = newDelegate(this, &ComboBox::notifyMouseWheel);
00137 mWidgetClient->eventMouseButtonPressed = newDelegate(this, &ComboBox::notifyMousePressed);
00138 }
00139
00140
00141 eventEditTextChange = newDelegate(this, &ComboBox::notifyEditTextChange);
00142 }
00143
00144 void ComboBox::shutdownWidgetSkin()
00145 {
00146 if (mManualList)
00147 {
00148 mWidgetChild.push_back(mList);
00149 WidgetManager::getInstance().destroyWidget(mList);
00150 }
00151 mList = nullptr;
00152 mButton = nullptr;
00153 }
00154
00155
00156 void ComboBox::notifyButtonPressed(Widget* _sender, int _left, int _top, MouseButton _id)
00157 {
00158 if (MouseButton::Left != _id) return;
00159
00160 mDropMouse = true;
00161
00162 if (mListShow) hideList();
00163 else showList();
00164 }
00165
00166 void ComboBox::notifyListLostFocus(Widget* _sender, Widget* _new)
00167 {
00168 if (mDropMouse)
00169 {
00170 mDropMouse = false;
00171 Widget* focus = InputManager::getInstance().getMouseFocusWidget();
00172
00173 if (focus == mButton) return;
00174
00175 if ( (mModeDrop) && (focus == mWidgetClient) ) return;
00176 }
00177
00178 hideList();
00179 }
00180
00181 void ComboBox::notifyListSelectAccept(List* _widget, size_t _position)
00182 {
00183 mItemIndex = _position;
00184 Base::setCaption(mItemIndex != ITEM_NONE ? mList->getItemNameAt(mItemIndex) : "");
00185
00186 mDropMouse = false;
00187 InputManager::getInstance().setKeyFocusWidget(this);
00188
00189 if (mModeDrop)
00190 {
00191 eventComboAccept.m_eventObsolete(this);
00192 eventComboAccept.m_event(this, mItemIndex);
00193 }
00194 }
00195
00196 void ComboBox::notifyListChangePosition(List* _widget, size_t _position)
00197 {
00198 mItemIndex = _position;
00199 eventComboChangePosition(this, _position);
00200 }
00201
00202 void ComboBox::onKeyButtonPressed(KeyCode _key, Char _char)
00203 {
00204 Base::onKeyButtonPressed(_key, _char);
00205
00206
00207 if (_key == KeyCode::ArrowDown)
00208 {
00209
00210 if (!InputManager::getInstance().isCaptureMouse())
00211 {
00212 showList();
00213 }
00214 }
00215
00216 else if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter))
00217 {
00218 eventComboAccept.m_eventObsolete(this);
00219 eventComboAccept.m_event(this, mItemIndex);
00220 }
00221
00222 }
00223
00224 void ComboBox::notifyListMouseItemActivate(List* _widget, size_t _position)
00225 {
00226 mItemIndex = _position;
00227 Base::setCaption(mItemIndex != ITEM_NONE ? mList->getItemNameAt(mItemIndex) : "");
00228
00229 InputManager::getInstance().setKeyFocusWidget(this);
00230
00231 if (mModeDrop)
00232 {
00233 eventComboAccept.m_eventObsolete(this);
00234 eventComboAccept.m_event(this, mItemIndex);
00235 }
00236 }
00237
00238 void ComboBox::notifyMouseWheel(Widget* _sender, int _rel)
00239 {
00240 if (mList->getItemCount() == 0) return;
00241 if (InputManager::getInstance().getKeyFocusWidget() != this) return;
00242 if (InputManager::getInstance().isCaptureMouse()) return;
00243
00244 if (_rel > 0)
00245 {
00246 if (mItemIndex != 0)
00247 {
00248 if (mItemIndex == ITEM_NONE) mItemIndex = 0;
00249 else mItemIndex --;
00250 Base::setCaption(mList->getItemNameAt(mItemIndex));
00251 mList->setIndexSelected(mItemIndex);
00252 mList->beginToItemAt(mItemIndex);
00253 eventComboChangePosition(this, mItemIndex);
00254 }
00255 }
00256 else if (_rel < 0)
00257 {
00258 if ((mItemIndex+1) < mList->getItemCount())
00259 {
00260 if (mItemIndex == ITEM_NONE) mItemIndex = 0;
00261 else mItemIndex ++;
00262 Base::setCaption(mList->getItemNameAt(mItemIndex));
00263 mList->setIndexSelected(mItemIndex);
00264 mList->beginToItemAt(mItemIndex);
00265 eventComboChangePosition(this, mItemIndex);
00266 }
00267 }
00268 }
00269
00270 void ComboBox::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
00271 {
00272
00273 Base::notifyMousePressed(_sender, _left, _top, _id);
00274
00275 mDropMouse = true;
00276
00277
00278 if (mModeDrop) notifyButtonPressed(nullptr, _left, _top, _id);
00279 }
00280
00281 void ComboBox::notifyEditTextChange(Edit* _sender)
00282 {
00283
00284 if (ITEM_NONE != mItemIndex)
00285 {
00286 mItemIndex = ITEM_NONE;
00287 mList->setIndexSelected(mItemIndex);
00288 mList->beginToItemFirst();
00289 eventComboChangePosition(this, mItemIndex);
00290 }
00291 }
00292
00293 void ComboBox::showList()
00294 {
00295
00296 if (mList->getItemCount() == 0) return;
00297
00298 mListShow = true;
00299
00300 int height = mList->getOptimalHeight();
00301 if (height > mMaxHeight) height = mMaxHeight;
00302
00303
00304 IntCoord coord = this->getAbsoluteCoord();
00305
00306
00307 if ((coord.top + coord.height + height) > Gui::getInstance().getViewSize().height)
00308 {
00309 coord.height = height;
00310 coord.top -= coord.height;
00311 }
00312
00313 else
00314 {
00315 coord.top += coord.height;
00316 coord.height = height;
00317 }
00318 mList->setCoord(coord);
00319
00320 if (mShowSmooth)
00321 {
00322 ControllerFadeAlpha* controller = createControllerFadeAlpha(COMBO_ALPHA_MAX, COMBO_ALPHA_COEF, true);
00323 ControllerManager::getInstance().addItem(mList, controller);
00324 }
00325 else
00326 {
00327 mList->setVisible(true);
00328 }
00329
00330 InputManager::getInstance().setKeyFocusWidget(mList);
00331 }
00332
00333 void ComboBox::actionWidgetHide(Widget* _widget)
00334 {
00335 _widget->setVisible(false);
00336 _widget->setEnabled(true);
00337 }
00338
00339 void ComboBox::hideList()
00340 {
00341 mListShow = false;
00342
00343 if (mShowSmooth)
00344 {
00345 ControllerFadeAlpha* controller = createControllerFadeAlpha(COMBO_ALPHA_MIN, COMBO_ALPHA_COEF, false);
00346 controller->eventPostAction = newDelegate(this, &ComboBox::actionWidgetHide);
00347 ControllerManager::getInstance().addItem(mList, controller);
00348 }
00349 else
00350 {
00351 mList->setVisible(false);
00352 }
00353 }
00354
00355 void ComboBox::setIndexSelected(size_t _index)
00356 {
00357 MYGUI_ASSERT_RANGE_AND_NONE(_index, mList->getItemCount(), "ComboBox::setIndexSelected");
00358 mItemIndex = _index;
00359 mList->setIndexSelected(_index);
00360 if (_index == ITEM_NONE)
00361 {
00362 Base::setCaption("");
00363 return;
00364 }
00365 Base::setCaption(mList->getItemNameAt(_index));
00366 Base::updateView();
00367 }
00368
00369 void ComboBox::setItemNameAt(size_t _index, const UString& _name)
00370 {
00371 mList->setItemNameAt(_index, _name);
00372 mItemIndex = ITEM_NONE;
00373 mList->setIndexSelected(mItemIndex);
00374 }
00375
00376 void ComboBox::setItemDataAt(size_t _index, Any _data)
00377 {
00378 mList->setItemDataAt(_index, _data);
00379 mItemIndex = ITEM_NONE;
00380 mList->setIndexSelected(mItemIndex);
00381 }
00382
00383 void ComboBox::insertItemAt(size_t _index, const UString& _item, Any _data)
00384 {
00385 mList->insertItemAt(_index, _item, _data);
00386 mItemIndex = ITEM_NONE;
00387 mList->setIndexSelected(mItemIndex);
00388 }
00389
00390 void ComboBox::removeItemAt(size_t _index)
00391 {
00392 mList->removeItemAt(_index);
00393 mItemIndex = ITEM_NONE;
00394 mList->clearIndexSelected();
00395 }
00396
00397 void ComboBox::removeAllItems()
00398 {
00399 mItemIndex = ITEM_NONE;
00400 mList->removeAllItems();
00401 }
00402
00403 void ComboBox::setComboModeDrop(bool _drop)
00404 {
00405 mModeDrop = _drop;
00406 setEditStatic(mModeDrop);
00407 }
00408
00409 ControllerFadeAlpha* ComboBox::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
00410 {
00411 ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName());
00412 ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
00413
00414 controller->setAlpha(_alpha);
00415 controller->setCoef(_coef);
00416 controller->setEnabled(_enable);
00417
00418 return controller;
00419 }
00420
00421 size_t ComboBox::findItemIndexWith(const UString& _name)
00422 {
00423 return mList->findItemIndexWith(_name);
00424 }
00425
00426 void ComboBox::setProperty(const std::string& _key, const std::string& _value)
00427 {
00428 if (_key == "ComboBox_ModeDrop") setComboModeDrop(utility::parseValue<bool>(_value));
00429 else if (_key == "ComboBox_AddItem") addItem(_value);
00430 else
00431 {
00432 Base::setProperty(_key, _value);
00433 return;
00434 }
00435 eventChangeProperty(this, _key, _value);
00436 }
00437
00438 }