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