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