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_Common.h"
00025 #include "MyGUI_List.h"
00026 #include "MyGUI_Button.h"
00027 #include "MyGUI_VScroll.h"
00028 #include "MyGUI_ResourceSkin.h"
00029 #include "MyGUI_InputManager.h"
00030
00031 namespace MyGUI
00032 {
00033
00034 List::List() :
00035 mWidgetScroll(nullptr),
00036 mTopIndex(0),
00037 mOffsetTop(0),
00038 mRangeIndex(-1),
00039 mLastRedrawLine(0),
00040 mIndexSelect(ITEM_NONE),
00041 mLineActive(ITEM_NONE),
00042 mIsFocus(false),
00043 mNeedVisibleScroll(true)
00044 {
00045 }
00046
00047 void List::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, WidgetPtr _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00048 {
00049 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00050
00051 initialiseWidgetSkin(_info);
00052 }
00053
00054 List::~List()
00055 {
00056 shutdownWidgetSkin();
00057 }
00058
00059 void List::baseChangeWidgetSkin(ResourceSkin* _info)
00060 {
00061 shutdownWidgetSkin();
00062 Base::baseChangeWidgetSkin(_info);
00063 initialiseWidgetSkin(_info);
00064 }
00065
00066 void List::initialiseWidgetSkin(ResourceSkin* _info)
00067 {
00068
00069 mNeedKeyFocus = true;
00070
00071 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) {
00072 if (*(*iter)->_getInternalData<std::string>() == "VScroll") {
00073 MYGUI_DEBUG_ASSERT( ! mWidgetScroll, "widget already assigned");
00074 mWidgetScroll = (*iter)->castType<VScroll>();
00075 mWidgetScroll->eventScrollChangePosition = newDelegate(this, &List::notifyScrollChangePosition);
00076 mWidgetScroll->eventMouseButtonPressed = newDelegate(this, &List::notifyMousePressed);
00077 }
00078 else if (*(*iter)->_getInternalData<std::string>() == "Client") {
00079 MYGUI_DEBUG_ASSERT( ! mWidgetClient, "widget already assigned");
00080 mWidgetClient = (*iter);
00081 mWidgetClient->eventMouseButtonPressed = newDelegate(this, &List::notifyMousePressed);
00082 }
00083 }
00084 MYGUI_ASSERT(nullptr != mWidgetScroll, "Child VScroll not found in skin (List must have VScroll)");
00085 MYGUI_ASSERT(nullptr != mWidgetClient, "Child Widget Client not found in skin (List must have Client)");
00086
00087
00088 const MapString& properties = _info->getProperties();
00089 MapString::const_iterator iterS = properties.find("SkinLine");
00090 if (iterS != properties.end()) mSkinLine = iterS->second;
00091 MYGUI_ASSERT(false == mSkinLine.empty(), "SkinLine property not found (List must have SkinLine property)");
00092
00093 iterS = properties.find("HeightLine");
00094 if (iterS != properties.end()) mHeightLine = utility::parseInt(iterS->second);
00095 if (mHeightLine < 1) mHeightLine = 1;
00096
00097
00098 mWidgetScroll->setScrollPage((size_t)mHeightLine);
00099 mWidgetScroll->setScrollViewPage((size_t)mHeightLine);
00100
00101 updateScroll();
00102 updateLine();
00103
00104 }
00105
00106 void List::shutdownWidgetSkin()
00107 {
00108 mWidgetScroll = nullptr;
00109 mWidgetClient = nullptr;
00110 }
00111
00112 void List::onMouseWheel(int _rel)
00113 {
00114 notifyMouseWheel(nullptr, _rel);
00115
00116 Base::onMouseWheel(_rel);
00117 }
00118
00119 void List::onKeySetFocus(WidgetPtr _old)
00120 {
00121 mIsFocus = true;
00122 _updateState();
00123
00124 Base::onKeySetFocus(_old);
00125 }
00126
00127 void List::onKeyLostFocus(WidgetPtr _new)
00128 {
00129 mIsFocus = false;
00130 _updateState();
00131
00132 Base::onKeyLostFocus(_new);
00133 }
00134
00135 void List::onKeyButtonPressed(KeyCode _key, Char _char)
00136 {
00137 if (getItemCount() == 0) {
00138
00139 Base::onKeyButtonPressed(_key, _char);
00140 return;
00141 }
00142
00143
00144 size_t sel = mIndexSelect;
00145
00146 if (_key == KeyCode::ArrowUp) {
00147
00148 if (sel != 0) {
00149 if (sel == ITEM_NONE) sel = 0;
00150 else sel --;
00151 }
00152
00153 }
00154 else if (_key == KeyCode::ArrowDown) {
00155
00156 if (sel == ITEM_NONE) sel = 0;
00157 else sel ++;
00158
00159 if (sel >= getItemCount()) {
00160
00161 sel = mIndexSelect;
00162 }
00163
00164 }
00165 else if (_key == KeyCode::Home) {
00166
00167 if (sel != 0) sel = 0;
00168
00169 }
00170 else if (_key == KeyCode::End) {
00171
00172 if (sel != (getItemCount() - 1)) {
00173 sel = getItemCount() - 1;
00174 }
00175
00176 }
00177 else if (_key == KeyCode::PageUp) {
00178
00179 if (sel != 0) {
00180 if (sel == ITEM_NONE) sel = 0;
00181 else {
00182 size_t page = mWidgetClient->getHeight() / mHeightLine;
00183 if (sel <= page) sel = 0;
00184 else sel -= page;
00185 }
00186 }
00187
00188 }
00189 else if (_key == KeyCode::PageDown) {
00190
00191 if (sel != (getItemCount() - 1)) {
00192 if (sel == ITEM_NONE) sel = 0;
00193 else {
00194 sel += mWidgetClient->getHeight() / mHeightLine;
00195 if (sel >= getItemCount()) sel = getItemCount() - 1;
00196 }
00197 }
00198
00199 }
00200 else if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter)) {
00201 if (sel != ITEM_NONE) {
00202
00203 eventListSelectAccept(this, sel);
00204
00205 Base::onKeyButtonPressed(_key, _char);
00206
00207 return;
00208 }
00209
00210 }
00211
00212 if (sel != mIndexSelect) {
00213 if ( false == isItemVisibleAt(sel)) {
00214 beginToItemAt(sel);
00215 _sendEventChangeScroll(mWidgetScroll->getScrollPosition());
00216 }
00217 setIndexSelected(sel);
00218
00219
00220
00221 eventListChangePosition(this, mIndexSelect);
00222 }
00223
00224 Base::onKeyButtonPressed(_key, _char);
00225 }
00226
00227 void List::notifyMouseWheel(WidgetPtr _sender, int _rel)
00228 {
00229 if (mRangeIndex <= 0) return;
00230
00231 int offset = (int)mWidgetScroll->getScrollPosition();
00232 if (_rel < 0) offset += mHeightLine;
00233 else offset -= mHeightLine;
00234
00235 if (offset >= mRangeIndex) offset = mRangeIndex;
00236 else if (offset < 0) offset = 0;
00237
00238 if ((int)mWidgetScroll->getScrollPosition() == offset) return;
00239
00240 mWidgetScroll->setScrollPosition(offset);
00241 _setScrollView(offset);
00242 _sendEventChangeScroll(offset);
00243 }
00244
00245 void List::notifyScrollChangePosition(VScrollPtr _sender, size_t _position)
00246 {
00247 _setScrollView(_position);
00248 _sendEventChangeScroll(_position);
00249 }
00250
00251 void List::notifyMousePressed(WidgetPtr _sender, int _left, int _top, MouseButton _id)
00252 {
00253 if (MouseButton::Left != _id) return;
00254
00255 if (_sender == mWidgetScroll) return;
00256
00257
00258 if (_sender == mWidgetClient) {
00259
00260 if (mIndexSelect != ITEM_NONE) {
00261 _selectIndex(mIndexSelect, false);
00262 mIndexSelect = ITEM_NONE;
00263 eventListChangePosition(this, mIndexSelect);
00264 }
00265 eventListMouseItemActivate(this, mIndexSelect);
00266
00267
00268 }
00269
00270 else if (_sender->isVisible()) {
00271
00272 #if MYGUI_DEBUG_MODE == 1
00273 _checkMapping("List::notifyMousePressed");
00274 MYGUI_ASSERT_RANGE(*_sender->_getInternalData<size_t>(), mWidgetLines.size(), "List::notifyMousePressed");
00275 MYGUI_ASSERT_RANGE(*_sender->_getInternalData<size_t>() + mTopIndex, mItemsInfo.size(), "List::notifyMousePressed");
00276 #endif
00277
00278 size_t index = *_sender->_getInternalData<size_t>() + mTopIndex;
00279
00280 if (mIndexSelect != index) {
00281 _selectIndex(mIndexSelect, false);
00282 _selectIndex(index, true);
00283 mIndexSelect = index;
00284 eventListChangePosition(this, mIndexSelect);
00285 }
00286 eventListMouseItemActivate(this, mIndexSelect);
00287
00288 }
00289 }
00290
00291 void List::notifyMouseDoubleClick(WidgetPtr _sender)
00292 {
00293 if (mIndexSelect != ITEM_NONE)
00294 eventListSelectAccept(this, mIndexSelect);
00295 }
00296
00297 void List::setPosition(const IntPoint& _point)
00298 {
00299 Base::setPosition(_point);
00300 }
00301
00302 void List::setSize(const IntSize& _size)
00303 {
00304 Base::setSize(_size);
00305
00306 updateScroll();
00307 updateLine();
00308 }
00309
00310 void List::setCoord(const IntCoord& _coord)
00311 {
00312 Base::setCoord(_coord);
00313
00314 updateScroll();
00315 updateLine();
00316 }
00317
00318 void List::updateScroll()
00319 {
00320 mRangeIndex = (mHeightLine * (int)mItemsInfo.size()) - mWidgetClient->getHeight();
00321
00322 if ( (false == mNeedVisibleScroll) || (mRangeIndex < 1) || (mWidgetScroll->getLeft() <= mWidgetClient->getLeft()) )
00323 {
00324 if (mWidgetScroll->isVisible()) {
00325 mWidgetScroll->setVisible(false);
00326
00327 mWidgetClient->setSize(mWidgetClient->getWidth() + mWidgetScroll->getWidth(), mWidgetClient->getHeight());
00328 }
00329 }
00330 else if (false == mWidgetScroll->isVisible())
00331 {
00332 mWidgetClient->setSize(mWidgetClient->getWidth() - mWidgetScroll->getWidth(), mWidgetClient->getHeight());
00333 mWidgetScroll->setVisible(true);
00334 }
00335
00336 mWidgetScroll->setScrollRange(mRangeIndex + 1);
00337 if ((int)mItemsInfo.size()) mWidgetScroll->setTrackSize( mWidgetScroll->getLineSize() * mWidgetClient->getHeight() / mHeightLine / (int)mItemsInfo.size() );
00338 }
00339
00340 void List::updateLine(bool _reset)
00341 {
00342
00343 if (_reset) {
00344 mOldSize.clear();
00345 mLastRedrawLine = 0;
00346 }
00347
00348
00349 int position = mTopIndex * mHeightLine + mOffsetTop;
00350
00351
00352 if (mOldSize.height < mCoord.height) {
00353
00354 int height = (int)mWidgetLines.size() * mHeightLine - mOffsetTop;
00355
00356
00357 while ( (height <= (mWidgetClient->getHeight() + mHeightLine)) && (mWidgetLines.size() < mItemsInfo.size()) ) {
00358
00359 WidgetPtr line = mWidgetClient->createWidgetT("Button", mSkinLine, 0, height, mWidgetClient->getWidth(), mHeightLine, Align::Top | Align::HStretch);
00360
00361 line->eventMouseButtonPressed = newDelegate(this, &List::notifyMousePressed);
00362 line->eventMouseButtonDoubleClick = newDelegate(this, &List::notifyMouseDoubleClick);
00363 line->eventMouseWheel = newDelegate(this, &List::notifyMouseWheel);
00364 line->eventMouseSetFocus = newDelegate(this, &List::notifyMouseSetFocus);
00365 line->eventMouseLostFocus = newDelegate(this, &List::notifyMouseLostFocus);
00366
00367 line->_setInternalData((size_t)mWidgetLines.size());
00368
00369 mWidgetLines.push_back(line);
00370 height += mHeightLine;
00371 };
00372
00373
00374 if (position >= mRangeIndex) {
00375
00376
00377 if (mRangeIndex <= 0) {
00378
00379
00380 if (position || mOffsetTop || mTopIndex) {
00381
00382 position = 0;
00383 mTopIndex = 0;
00384 mOffsetTop = 0;
00385 mLastRedrawLine = 0;
00386
00387
00388 int offset = 0;
00389 for (size_t pos=0; pos<mWidgetLines.size(); pos++) {
00390 mWidgetLines[pos]->setPosition(0, offset);
00391 offset += mHeightLine;
00392 }
00393 }
00394
00395 }
00396 else {
00397
00398
00399 int count = mWidgetClient->getHeight() / mHeightLine;
00400 mOffsetTop = mHeightLine - (mWidgetClient->getHeight() % mHeightLine);
00401
00402 if (mOffsetTop == mHeightLine) {
00403 mOffsetTop = 0;
00404 count --;
00405 }
00406
00407 int top = (int)mItemsInfo.size() - count - 1;
00408
00409
00410 int offset = 0 - mOffsetTop;
00411 for (size_t pos=0; pos<mWidgetLines.size(); pos++) {
00412 mWidgetLines[pos]->setPosition(0, offset);
00413 offset += mHeightLine;
00414 }
00415
00416
00417 position = top * mHeightLine + mOffsetTop;
00418
00419
00420 if (top != mTopIndex) {
00421 mTopIndex = top;
00422 _redrawItemRange();
00423 }
00424
00425 }
00426 }
00427
00428
00429 _redrawItemRange(mLastRedrawLine);
00430
00431 }
00432
00433
00434 mWidgetScroll->setScrollPosition(position);
00435
00436 mOldSize.width = mCoord.width;
00437 mOldSize.height = mCoord.height;
00438
00439 #if MYGUI_DEBUG_MODE == 1
00440 _checkMapping("List::updateLine");
00441 #endif
00442
00443 }
00444
00445 void List::_redrawItemRange(size_t _start)
00446 {
00447
00448 size_t pos = _start;
00449 for (; pos<mWidgetLines.size(); pos++) {
00450
00451 size_t index = pos + (size_t)mTopIndex;
00452
00453
00454 if (index >= mItemsInfo.size()) {
00455
00456 mLastRedrawLine = pos;
00457 break;
00458 }
00459 if (mWidgetLines[pos]->getTop() > mWidgetClient->getHeight()) {
00460
00461 mLastRedrawLine = pos;
00462 break;
00463 }
00464
00465
00466 mWidgetLines[pos]->setVisible(true);
00467
00468 mWidgetLines[pos]->setCaption(mItemsInfo[index].first);
00469
00470
00471 static_cast<ButtonPtr>(mWidgetLines[pos])->setButtonPressed(index == mIndexSelect);
00472 }
00473
00474
00475 if (pos >= mWidgetLines.size()) mLastRedrawLine = pos;
00476 else {
00477
00478 for (; pos<mWidgetLines.size(); pos++) {
00479 static_cast<ButtonPtr>(mWidgetLines[pos])->setButtonPressed(false);
00480 static_cast<ButtonPtr>(mWidgetLines[pos])->setVisible(false);
00481
00482 }
00483 }
00484
00485 #if MYGUI_DEBUG_MODE == 1
00486 _checkMapping("List::_redrawItemRange");
00487 #endif
00488
00489 }
00490
00491
00492 void List::_redrawItem(size_t _index)
00493 {
00494
00495 if (_index < (size_t)mTopIndex) return;
00496 _index -= (size_t)mTopIndex;
00497
00498 if (_index >= mLastRedrawLine) return;
00499
00500 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::_redrawItem");
00501
00502 mWidgetLines[_index]->setCaption(mItemsInfo[_index + mTopIndex].first);
00503
00504 #if MYGUI_DEBUG_MODE == 1
00505 _checkMapping("List::_redrawItem");
00506 #endif
00507
00508 }
00509
00510 void List::insertItemAt(size_t _index, const UString& _name, Any _data)
00511 {
00512 MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "List::insertItemAt");
00513 if (_index == ITEM_NONE) _index = mItemsInfo.size();
00514
00515
00516 mItemsInfo.insert(mItemsInfo.begin() + _index, PairItem(_name, _data));
00517
00518
00519 if ( (mIndexSelect != ITEM_NONE) && (_index <= mIndexSelect) ) mIndexSelect++;
00520
00521
00522 if ( (_index <= (size_t)mTopIndex) && (mRangeIndex > 0) ) {
00523 mTopIndex ++;
00524
00525 mWidgetScroll->setScrollRange(mWidgetScroll->getScrollRange() + mHeightLine);
00526 if ((int)mItemsInfo.size()) mWidgetScroll->setTrackSize( mWidgetScroll->getLineSize() * mWidgetClient->getHeight() / mHeightLine / (int)mItemsInfo.size() );
00527 mWidgetScroll->setScrollPosition(mTopIndex * mHeightLine + mOffsetTop);
00528 mRangeIndex += mHeightLine;
00529
00530 }
00531 else {
00532
00533
00534 int offset = ((int)_index - mTopIndex) * mHeightLine - mOffsetTop;
00535
00536
00537 if (mWidgetClient->getHeight() < (offset - mHeightLine)) {
00538
00539 mWidgetScroll->setScrollRange(mWidgetScroll->getScrollRange() + mHeightLine);
00540 if ((int)mItemsInfo.size()) mWidgetScroll->setTrackSize( mWidgetScroll->getLineSize() * mWidgetClient->getHeight() / mHeightLine / (int)mItemsInfo.size() );
00541 mWidgetScroll->setScrollPosition(mTopIndex * mHeightLine + mOffsetTop);
00542 mRangeIndex += mHeightLine;
00543
00544
00545 } else {
00546
00547
00548 updateScroll();
00549 updateLine(true);
00550
00551
00552 }
00553 }
00554
00555 #if MYGUI_DEBUG_MODE == 1
00556 _checkMapping("List::insertItemAt");
00557 #endif
00558
00559 }
00560
00561 void List::removeItemAt(size_t _index)
00562 {
00563 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::removeItemAt");
00564
00565
00566 mItemsInfo.erase(mItemsInfo.begin() + _index);
00567
00568
00569 if (mItemsInfo.empty()) mIndexSelect = ITEM_NONE;
00570 else if (mIndexSelect != ITEM_NONE) {
00571 if (_index < mIndexSelect) mIndexSelect--;
00572 else if ( (_index == mIndexSelect) && (mIndexSelect == (mItemsInfo.size())) ) mIndexSelect--;
00573 }
00574
00575
00576 if (mWidgetLines.size() > mItemsInfo.size()) {
00577 mWidgetLines[mItemsInfo.size()]->setVisible(false);
00578 }
00579
00580
00581 if (_index < (size_t)mTopIndex) {
00582 mTopIndex --;
00583
00584 mWidgetScroll->setScrollRange(mWidgetScroll->getScrollRange() - mHeightLine);
00585 if ((int)mItemsInfo.size()) mWidgetScroll->setTrackSize( mWidgetScroll->getLineSize() * mWidgetClient->getHeight() / mHeightLine / (int)mItemsInfo.size() );
00586 mWidgetScroll->setScrollPosition(mTopIndex * mHeightLine + mOffsetTop);
00587 mRangeIndex -= mHeightLine;
00588
00589 }
00590 else {
00591
00592
00593 int offset = ((int)_index - mTopIndex) * mHeightLine - mOffsetTop;
00594
00595
00596 if (mWidgetClient->getHeight() < offset) {
00597
00598 mWidgetScroll->setScrollRange(mWidgetScroll->getScrollRange() - mHeightLine);
00599 if ((int)mItemsInfo.size()) mWidgetScroll->setTrackSize( mWidgetScroll->getLineSize() * mWidgetClient->getHeight() / mHeightLine / (int)mItemsInfo.size() );
00600 mWidgetScroll->setScrollPosition(mTopIndex * mHeightLine + mOffsetTop);
00601 mRangeIndex -= mHeightLine;
00602
00603
00604 }
00605 else {
00606
00607
00608 updateScroll();
00609 updateLine(true);
00610
00611
00612 }
00613 }
00614
00615 #if MYGUI_DEBUG_MODE == 1
00616 _checkMapping("List::removeItemAt");
00617 #endif
00618
00619 }
00620
00621 void List::setIndexSelected(size_t _index)
00622 {
00623 MYGUI_ASSERT_RANGE_AND_NONE(_index, mItemsInfo.size(), "List::setIndexSelected");
00624 if (mIndexSelect != _index) {
00625 _selectIndex(mIndexSelect, false);
00626 _selectIndex(_index, true);
00627 mIndexSelect = _index;
00628 }
00629 }
00630
00631 void List::_selectIndex(size_t _index, bool _select)
00632 {
00633 if (_index == ITEM_NONE) return;
00634
00635 if (_index < (size_t)mTopIndex) return;
00636
00637 int offset = ((int)_index - mTopIndex) * mHeightLine - mOffsetTop;
00638
00639 if (mWidgetClient->getHeight() < offset) return;
00640
00641 static_cast<ButtonPtr>(mWidgetLines[_index-mTopIndex])->setButtonPressed(_select);
00642
00643 #if MYGUI_DEBUG_MODE == 1
00644 _checkMapping("List::_selectIndex");
00645 #endif
00646
00647 }
00648
00649 void List::beginToItemAt(size_t _index)
00650 {
00651 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::beginToItemAt");
00652 if (mRangeIndex <= 0) return;
00653
00654 int offset = (int)_index * mHeightLine;
00655 if (offset >= mRangeIndex) offset = mRangeIndex;
00656
00657 if ((int)mWidgetScroll->getScrollPosition() == offset) return;
00658
00659 mWidgetScroll->setScrollPosition(offset);
00660 notifyScrollChangePosition(nullptr, offset);
00661
00662 #if MYGUI_DEBUG_MODE == 1
00663 _checkMapping("List::beginToItemAt");
00664 #endif
00665
00666 }
00667
00668
00669 bool List::isItemVisibleAt(size_t _index, bool _fill)
00670 {
00671
00672 if (_index >= mItemsInfo.size()) return false;
00673
00674 if (mRangeIndex <= 0) return true;
00675
00676
00677 if (_index < (size_t)mTopIndex) return false;
00678
00679
00680 if (_index == (size_t)mTopIndex) {
00681 if ( (mOffsetTop != 0) && (_fill) ) return false;
00682 return true;
00683 }
00684
00685
00686 int offset = ((int)_index - mTopIndex) * mHeightLine - mOffsetTop;
00687
00688
00689 if (mWidgetClient->getHeight() < offset) return false;
00690
00691
00692 if ((mWidgetClient->getHeight() < (offset + mHeightLine)) && (_fill) ) return false;
00693
00694 return true;
00695 }
00696
00697 void List::removeAllItems()
00698 {
00699 mTopIndex = 0;
00700 mIndexSelect = ITEM_NONE;
00701 mOffsetTop = 0;
00702
00703 mItemsInfo.clear();
00704
00705 int offset = 0;
00706 for (size_t pos=0; pos<mWidgetLines.size(); pos++)
00707 {
00708 mWidgetLines[pos]->setVisible(false);
00709 mWidgetLines[pos]->setPosition(0, offset);
00710 offset += mHeightLine;
00711 }
00712
00713
00714 updateScroll();
00715 updateLine(true);
00716
00717 #if MYGUI_DEBUG_MODE == 1
00718 _checkMapping("List::removeAllItems");
00719 #endif
00720
00721 }
00722
00723 void List::setItemNameAt(size_t _index, const UString& _name)
00724 {
00725 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::setItemNameAt");
00726 mItemsInfo[_index].first =_name;
00727 _redrawItem(_index);
00728 }
00729
00730 void List::setItemDataAt(size_t _index, Any _data)
00731 {
00732 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::setItemDataAt");
00733 mItemsInfo[_index].second = _data;
00734 _redrawItem(_index);
00735 }
00736
00737 const UString& List::getItemNameAt(size_t _index)
00738 {
00739 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "List::getItemNameAt");
00740 return mItemsInfo[_index].first;
00741 }
00742
00743 void List::notifyMouseSetFocus(WidgetPtr _sender, WidgetPtr _old)
00744 {
00745
00746 #if MYGUI_DEBUG_MODE == 1
00747 MYGUI_ASSERT_RANGE(*_sender->_getInternalData<size_t>(), mWidgetLines.size(), "List::notifyMouseSetFocus");
00748 #endif
00749
00750 mLineActive = *_sender->_getInternalData<size_t>();
00751 eventListMouseItemFocus(this, mLineActive);
00752 }
00753
00754 void List::notifyMouseLostFocus(WidgetPtr _sender, WidgetPtr _new)
00755 {
00756 if ((nullptr == _new) || (_new->getParent() != mWidgetClient)) {
00757 mLineActive = ITEM_NONE;
00758 eventListMouseItemFocus(this, ITEM_NONE);
00759 }
00760 }
00761
00762 void List::_setItemFocus(size_t _index, bool _focus)
00763 {
00764 MYGUI_ASSERT_RANGE(_index, mWidgetLines.size(), "List::_setItemFocus");
00765 static_cast<ButtonPtr>(mWidgetLines[_index])->_setMouseFocus(_focus);
00766 }
00767
00768 void List::setScrollVisible(bool _visible)
00769 {
00770 if (mNeedVisibleScroll == _visible) return;
00771 mNeedVisibleScroll = _visible;
00772 updateScroll();
00773 }
00774
00775 void List::setScrollPosition(size_t _position)
00776 {
00777 if (mWidgetScroll->getScrollRange() > _position) {
00778 mWidgetScroll->setScrollPosition(_position);
00779 _setScrollView(_position);
00780 }
00781 }
00782
00783 void List::_setScrollView(size_t _position)
00784 {
00785 mOffsetTop = ((int)_position % mHeightLine);
00786
00787
00788 int offset = 0 - mOffsetTop;
00789
00790 for (size_t pos=0; pos<mWidgetLines.size(); pos++) {
00791 mWidgetLines[pos]->setPosition(IntPoint(0, offset));
00792 offset += mHeightLine;
00793 }
00794
00795
00796 int top = ((int)_position / mHeightLine);
00797 if (top != mTopIndex) {
00798 mTopIndex = top;
00799 _redrawItemRange();
00800 }
00801
00802
00803 _redrawItemRange(mLastRedrawLine);
00804 }
00805
00806 void List::_sendEventChangeScroll(size_t _position)
00807 {
00808 eventListChangeScroll(this, _position);
00809 if (ITEM_NONE != mLineActive) eventListMouseItemFocus(this, mLineActive);
00810 }
00811
00812 void List::swapItemsAt(size_t _index1, size_t _index2)
00813 {
00814 MYGUI_ASSERT_RANGE(_index1, mItemsInfo.size(), "List::swapItemsAt");
00815 MYGUI_ASSERT_RANGE(_index2, mItemsInfo.size(), "List::swapItemsAt");
00816
00817 if (_index1 == _index2) return;
00818
00819 std::swap(mItemsInfo[_index1], mItemsInfo[_index2]);
00820
00821 _redrawItem(_index1);
00822 _redrawItem(_index2);
00823 }
00824
00825 void List::_checkMapping(const std::string& _owner)
00826 {
00827 size_t count_pressed = 0;
00828 size_t count_show = 0;
00829
00830 for (size_t pos=0; pos<mWidgetLines.size(); pos++) {
00831 MYGUI_ASSERT(pos == *mWidgetLines[pos]->_getInternalData<size_t>(), _owner);
00832 static_cast<ButtonPtr>(mWidgetLines[pos])->getButtonPressed() ? count_pressed ++ : 0;
00833 static_cast<ButtonPtr>(mWidgetLines[pos])->isVisible() ? count_show ++ : 0;
00834 }
00835 MYGUI_ASSERT(count_pressed < 2, _owner);
00836
00837 }
00838
00839 void List::_checkAlign()
00840 {
00841
00842 int max_height = mItemsInfo.size() * mHeightLine;
00843
00844 int visible_height = mWidgetClient->getHeight();
00845
00846
00847 if (visible_height >= max_height)
00848 {
00849 MYGUI_ASSERT(mTopIndex == 0, "mTopIndex == 0");
00850 MYGUI_ASSERT(mOffsetTop == 0, "mOffsetTop == 0");
00851 int height = 0;
00852 for (size_t pos=0; pos<mWidgetLines.size(); pos++) {
00853 if (pos >= mItemsInfo.size()) break;
00854 MYGUI_ASSERT(mWidgetLines[pos]->getTop() == height, "mWidgetLines[pos]->getTop() == height");
00855 height += mWidgetLines[pos]->getHeight();
00856 }
00857 }
00858 }
00859
00860 size_t List::findItemIndexWith(const UString& _name)
00861 {
00862 for (size_t pos=0; pos<mItemsInfo.size(); pos++)
00863 {
00864 if (mItemsInfo[pos].first == _name) return pos;
00865 }
00866 return ITEM_NONE;
00867 }
00868
00869 size_t List::getOptimalHeight()
00870 {
00871 return (mCoord.height - mWidgetClient->getHeight()) + (mItemsInfo.size() * mHeightLine);
00872 }
00873
00874 void List::setProperty(const std::string& _key, const std::string& _value)
00875 {
00876 if (_key == "List_AddItem") addItem(_value);
00877 else Base::setProperty(_key, _value);
00878 }
00879
00880 }