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_ListCtrl.h"
00025 #include "MyGUI_Button.h"
00026 #include "MyGUI_VScroll.h"
00027 #include "MyGUI_HScroll.h"
00028 #include "MyGUI_ResourceSkin.h"
00029 #include "MyGUI_InputManager.h"
00030 #include "MyGUI_Gui.h"
00031 #include "MyGUI_WidgetTranslate.h"
00032 #include "MyGUI_WidgetManager.h"
00033
00034 namespace MyGUI
00035 {
00036
00037 ListCtrl::ListCtrl() :
00038 mIndexSelect(ITEM_NONE),
00039 mIndexActive(ITEM_NONE),
00040 mIndexAccept(ITEM_NONE),
00041 mIndexRefuse(ITEM_NONE),
00042 mIsFocus(false),
00043 mItemDrag(nullptr),
00044 mScrollViewPage(1)
00045 {
00046 mChangeContentByResize = true;
00047 }
00048
00049 void ListCtrl::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00050 {
00051 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00052
00053 initialiseWidgetSkin(_info);
00054 }
00055
00056 ListCtrl::~ListCtrl()
00057 {
00058 shutdownWidgetSkin();
00059 }
00060
00061 size_t ListCtrl::getHScrollPage()
00062 {
00063 return mScrollViewPage;
00064 }
00065
00066 size_t ListCtrl::getVScrollPage()
00067 {
00068 return mScrollViewPage;
00069 }
00070
00071 void ListCtrl::baseChangeWidgetSkin(ResourceSkin* _info)
00072 {
00073 shutdownWidgetSkin();
00074 Base::baseChangeWidgetSkin(_info);
00075 initialiseWidgetSkin(_info);
00076 }
00077
00078 void ListCtrl::initialiseWidgetSkin(ResourceSkin* _info)
00079 {
00080
00081 mNeedKeyFocus = true;
00082 mDragLayer = "DragAndDrop";
00083
00084 const MapString& properties = _info->getProperties();
00085 if (!properties.empty())
00086 {
00087 MapString::const_iterator iter = properties.end();
00088 iter = properties.find("DragLayer");
00089 if (iter != properties.end()) mDragLayer = iter->second;
00090 }
00091
00092 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00093 {
00094 if (*(*iter)->_getInternalData<std::string>() == "VScroll")
00095 {
00096 MYGUI_DEBUG_ASSERT( ! mVScroll, "widget already assigned");
00097 mVScroll = (*iter)->castType<VScroll>();
00098 mVScroll->eventScrollChangePosition = newDelegate(this, &ListCtrl::notifyScrollChangePosition);
00099 }
00100 if (*(*iter)->_getInternalData<std::string>() == "HScroll")
00101 {
00102 MYGUI_DEBUG_ASSERT( ! mHScroll, "widget already assigned");
00103 mHScroll = (*iter)->castType<HScroll>();
00104 mHScroll->eventScrollChangePosition = newDelegate(this, &ListCtrl::notifyScrollChangePosition);
00105 }
00106 else if (*(*iter)->_getInternalData<std::string>() == "Client")
00107 {
00108 MYGUI_DEBUG_ASSERT( ! mWidgetClient, "widget already assigned");
00109 mWidgetClient = (*iter);
00110 mWidgetClient->eventMouseWheel = newDelegate(this, &ListCtrl::notifyMouseWheel);
00111 mWidgetClient->eventMouseButtonPressed = newDelegate(this, &ListCtrl::notifyMouseButtonPressed);
00112 mClient = mWidgetClient;
00113 }
00114 }
00115
00116
00117
00118
00119 _getClientWidget()->_requestGetContainer = newDelegate(this, &ListCtrl::_requestGetContainer);
00120
00121 updateFromResize();
00122 }
00123
00124 void ListCtrl::shutdownWidgetSkin()
00125 {
00126 mVScroll = nullptr;
00127 mHScroll = nullptr;
00128 mClient = nullptr;
00129 mWidgetClient = nullptr;
00130 }
00131
00132 void ListCtrl::setPosition(const IntPoint& _point)
00133 {
00134 Base::setPosition(_point);
00135 }
00136
00137 void ListCtrl::setSize(const IntSize& _size)
00138 {
00139 Base::setSize(_size);
00140 updateFromResize();
00141 }
00142
00143 void ListCtrl::setCoord(const IntCoord& _coord)
00144 {
00145 Base::setCoord(_coord);
00146 updateFromResize();
00147 }
00148
00149 void ListCtrl::updateFromResize()
00150 {
00151 updateMetrics();
00152
00153 updateScrollSize();
00154 updateScrollPosition();
00155
00156 _updateAllVisible(ITEM_NONE, true, true);
00157 _resetContainer(true);
00158 }
00159
00160 void ListCtrl::_updateAllVisible(size_t _index, bool _needUpdateContetntSize, bool _update)
00161 {
00162
00163 bool change = false;
00164
00165 int top = 0;
00166 size_t widget_index = 0;
00167
00168 for (size_t index=0; index<mItemsInfo.size(); ++index)
00169 {
00170 ItemDataInfo& info = mItemsInfo[index];
00171
00172
00173 if ((top + info.size.height) < (mContentPosition.top))
00174 {
00175 }
00176
00177 else if (top > ((mContentPosition.top) + _getClientWidget()->getHeight()))
00178 {
00179 }
00180
00181 else
00182 {
00183 Widget* item = getItemWidget(widget_index);
00184 widget_index++;
00185
00186 if (index == _index || ITEM_NONE == _index)
00187 {
00188 item->_setInternalData((size_t)index);
00189
00190 item->setPosition(-mContentPosition.left, top - (mContentPosition.top));
00191 item->setVisible(true);
00192
00193 IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, _update, false);
00194
00195 IntCoord coord(IntPoint(), info.size);
00196 requestDrawItem(this, item, data, coord);
00197
00198 if (info.size != coord.size())
00199 change = true;
00200
00201 info.size = coord.size();
00202 item->setSize(mClient->getWidth(), info.size.height);
00203 }
00204
00205 }
00206
00207 top += info.size.height;
00208 }
00209
00210
00211 while (widget_index < mVectorItems.size())
00212 {
00213 Widget* item = mVectorItems[widget_index];
00214 widget_index ++;
00215
00216 item->setVisible(false);
00217 item->_setInternalData((size_t)ITEM_NONE);
00218 }
00219
00220 if (change && _needUpdateContetntSize)
00221 {
00222 updateMetrics();
00223
00224 updateScrollSize();
00225 updateScrollPosition();
00226 }
00227 }
00228
00229 Widget* ListCtrl::getItemWidget(size_t _index)
00230 {
00231
00232 if (_index == mVectorItems.size())
00233 {
00234
00235 Widget* item = _getClientWidget()->createWidget<Widget>("Default", IntCoord(), Align::Default);
00236
00237
00238 requestCreateWidgetItem(this, item);
00239
00240 item->eventMouseWheel = newDelegate(this, &ListCtrl::notifyMouseWheel);
00241 item->eventRootMouseChangeFocus = newDelegate(this, &ListCtrl::notifyRootMouseChangeFocus);
00242 item->eventMouseButtonPressed = newDelegate(this, &ListCtrl::notifyMouseButtonPressed);
00243 item->eventMouseButtonReleased = newDelegate(this, &ListCtrl::notifyMouseButtonReleased);
00244 item->eventMouseButtonDoubleClick = newDelegate(this, &ListCtrl::notifyMouseButtonDoubleClick);
00245 item->eventMouseDrag = newDelegate(this, &ListCtrl::notifyMouseDrag);
00246 item->_requestGetContainer = newDelegate(this, &ListCtrl::_requestGetContainer);
00247 item->eventKeyButtonPressed = newDelegate(this, &ListCtrl::notifyKeyButtonPressed);
00248 item->eventKeyButtonReleased = newDelegate(this, &ListCtrl::notifyKeyButtonReleased);
00249
00250 mVectorItems.push_back(item);
00251 }
00252
00253
00254 MYGUI_ASSERT_RANGE(_index, mVectorItems.size(), "ListCtrl::getItemWidget");
00255
00256 return mVectorItems[_index];
00257 }
00258
00259 void ListCtrl::onMouseWheel(int _rel)
00260 {
00261 notifyMouseWheel(nullptr, _rel);
00262
00263 Base::onMouseWheel(_rel);
00264 }
00265
00266 void ListCtrl::onKeySetFocus(Widget* _old)
00267 {
00268 mIsFocus = true;
00269 setState("pushed");
00270
00271 Base::onKeySetFocus(_old);
00272 }
00273
00274 void ListCtrl::onKeyLostFocus(Widget* _new)
00275 {
00276 mIsFocus = false;
00277 setState("normal");
00278
00279 Base::onKeyLostFocus(_new);
00280 }
00281
00282 void ListCtrl::resetCurrentActiveItem()
00283 {
00284
00285 if (mIndexActive != ITEM_NONE)
00286 {
00287
00288 size_t index = mIndexActive;
00289 mIndexActive = ITEM_NONE;
00290
00291
00292 _updateAllVisible(index, true, false);
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 }
00307 }
00308
00309 void ListCtrl::findCurrentActiveItem()
00310 {
00311 MYGUI_DEBUG_ASSERT(mIndexActive == ITEM_NONE, "use : resetCurrentActiveItem() before findCurrentActiveItem()");
00312
00313 const IntPoint& point = InputManager::getInstance().getMousePositionByLayer();
00314
00315
00316 const IntRect& rect = _getClientWidget()->getAbsoluteRect();
00317 if ((point.left < rect.left) || (point.left > rect.right) || (point.top < rect.top) || (point.top > rect.bottom))
00318 {
00319 return;
00320 }
00321
00322 for (size_t pos=0; pos<mVectorItems.size(); ++pos)
00323 {
00324 Widget* item = mVectorItems[pos];
00325 const IntRect& abs_rect = item->getAbsoluteRect();
00326 if ((point.left>= abs_rect.left) && (point.left <= abs_rect.right) && (point.top>= abs_rect.top) && (point.top <= abs_rect.bottom))
00327 {
00328
00329 size_t index = calcIndexByWidget(item);
00330
00331 if (index < mItemsInfo.size())
00332 {
00333
00334 mIndexActive = index;
00335
00336 _updateAllVisible(index, true, false);
00337
00338
00339
00340
00341
00342
00343 }
00344
00345 break;
00346 }
00347 }
00348 }
00349
00350 void ListCtrl::_requestGetContainer(Widget* _sender, Widget*& _container, size_t& _index)
00351 {
00352 if (_sender == _getClientWidget())
00353 {
00354 _container = this;
00355 _index = ITEM_NONE;
00356 }
00357 else
00358 {
00359 size_t index = calcIndexByWidget(_sender);
00360 if (index < mItemsInfo.size())
00361 {
00362 _container = this;
00363 _index = index;
00364 }
00365 }
00366 }
00367
00368 void ListCtrl::_setContainerItemInfo(size_t _index, bool _set, bool _accept)
00369 {
00370 if (_index == ITEM_NONE) return;
00371 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ListCtrl::_setContainerItemInfo");
00372
00373 mIndexAccept = (_set && _accept ) ? _index : ITEM_NONE;
00374 mIndexRefuse = (_set && !_accept) ? _index : ITEM_NONE;
00375
00376
00377 _updateAllVisible(_index, true, false);
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 }
00393
00394 void ListCtrl::setItemDataAt(size_t _index, Any _data)
00395 {
00396 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ListCtrl::setItemData");
00397 mItemsInfo[_index].data = _data;
00398
00399
00400 _updateAllVisible(_index, true, true);
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 _resetContainer(true);
00412 }
00413
00414 void ListCtrl::insertItemAt(size_t _index, Any _data)
00415 {
00416 MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "ListCtrl::insertItemAt");
00417 if (_index == ITEM_NONE) _index = mItemsInfo.size();
00418
00419 _resetContainer(false);
00420
00421 resetCurrentActiveItem();
00422
00423 mItemsInfo.insert(mItemsInfo.begin() + _index, ItemDataInfo(_data));
00424
00425
00426 if (mIndexSelect != ITEM_NONE)
00427 {
00428 if (mIndexSelect >= _index)
00429 {
00430 mIndexSelect ++;
00431 }
00432 }
00433
00434 updateScrollSize();
00435 updateScrollPosition();
00436
00437 findCurrentActiveItem();
00438
00439 _updateAllVisible(ITEM_NONE, true, true);
00440 }
00441
00442 void ListCtrl::removeItemAt(size_t _index)
00443 {
00444 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ListCtrl::removeItemAt");
00445
00446 _resetContainer(false);
00447 resetCurrentActiveItem();
00448
00449 mItemsInfo.erase(mItemsInfo.begin() + _index);
00450
00451
00452 if (mIndexSelect != ITEM_NONE)
00453 {
00454 if (mItemsInfo.empty())
00455 {
00456 mIndexSelect = ITEM_NONE;
00457 }
00458 else if ((mIndexSelect > _index) || (mIndexSelect == mItemsInfo.size()))
00459 {
00460 mIndexSelect --;
00461 }
00462 }
00463
00464 updateScrollSize();
00465 updateScrollPosition();
00466
00467 findCurrentActiveItem();
00468
00469 _updateAllVisible(ITEM_NONE, true, true);
00470 }
00471
00472 void ListCtrl::removeAllItems()
00473 {
00474 if (0 == mItemsInfo.size()) return;
00475 _resetContainer(false);
00476
00477 mItemsInfo.clear();
00478
00479 mIndexSelect = ITEM_NONE;
00480 mIndexActive = ITEM_NONE;
00481
00482 updateScrollSize();
00483 updateScrollPosition();
00484
00485 _updateAllVisible(ITEM_NONE, true, true);
00486 }
00487
00488 void ListCtrl::redrawItemAt(size_t _index)
00489 {
00490 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ListCtrl::redrawItemAt");
00491
00492
00493 _updateAllVisible(_index, true, true);
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504
00505 void ListCtrl::setIndexSelected(size_t _index)
00506 {
00507 MYGUI_ASSERT_RANGE_AND_NONE(_index, mItemsInfo.size(), "ListCtrl::setIndexSelected");
00508 if (_index == mIndexSelect) return;
00509
00510
00511
00512
00513 if (mIndexSelect != ITEM_NONE)
00514 {
00515
00516 size_t index = mIndexSelect;
00517 mIndexSelect = ITEM_NONE;
00518
00519
00520 _updateAllVisible(index, true, false);
00521
00522
00523
00524
00525
00526
00527
00528
00529 }
00530
00531 mIndexSelect = _index;
00532 if (mIndexSelect != ITEM_NONE)
00533 {
00534
00535
00536 _updateAllVisible(_index, true, false);
00537
00538
00539
00540
00541
00542
00543
00544
00545 }
00546
00547 }
00548
00549 void ListCtrl::notifyMouseButtonDoubleClick(Widget* _sender)
00550 {
00551 size_t index = getIndexByWidget(_sender);
00552
00553 eventSelectItemAccept(this, index);
00554 }
00555
00556 void ListCtrl::notifyKeyButtonPressed(Widget* _sender, KeyCode _key, Char _char)
00557 {
00558 eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::KeyPressed, _key, _char));
00559 }
00560
00561 void ListCtrl::notifyKeyButtonReleased(Widget* _sender, KeyCode _key)
00562 {
00563 eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::KeyReleased, _key));
00564 }
00565
00566 size_t ListCtrl::getIndexByWidget(Widget* _widget)
00567 {
00568 MYGUI_ASSERT(_widget, "ListCtrl::getIndexByWidget : Widget == nullptr");
00569 if (_widget == _getClientWidget()) return ITEM_NONE;
00570 MYGUI_ASSERT(_widget->getParent() == _getClientWidget(), "ListCtrl::getIndexByWidget : Widget is not child");
00571
00572 size_t index = calcIndexByWidget(_widget);
00573 MYGUI_ASSERT_RANGE(index, mItemsInfo.size(), "ListCtrl::getIndexByWidget");
00574
00575 return index;
00576 }
00577
00578 size_t ListCtrl::_getContainerIndex(const IntPoint& _point)
00579 {
00580 for (VectorWidgetPtr::iterator iter=mVectorItems.begin(); iter!=mVectorItems.end(); ++iter)
00581 {
00582 if ((*iter)->isVisible())
00583 {
00584 if ((*iter)->getAbsoluteRect().inside(_point))
00585 {
00586 return getIndexByWidget(*iter);
00587 }
00588 }
00589 }
00590 return ITEM_NONE;
00591 }
00592
00593 void ListCtrl::_resetContainer(bool _update)
00594 {
00595
00596 Base::_resetContainer(_update);
00597
00598 if ( ! _update)
00599 {
00600 WidgetManager& instance = WidgetManager::getInstance();
00601 for (VectorWidgetPtr::iterator iter=mVectorItems.begin(); iter!=mVectorItems.end(); ++iter)
00602 {
00603 instance.unlinkFromUnlinkers(*iter);
00604 }
00605 }
00606 }
00607
00608 Widget* ListCtrl::getWidgetByIndex(size_t _index)
00609 {
00610 for (VectorWidgetPtr::iterator iter=mVectorItems.begin(); iter!=mVectorItems.end(); ++iter)
00611 {
00612 if ((*iter)->isVisible())
00613 {
00614 size_t index = getIndexByWidget(*iter);
00615
00616 if (index == _index) return (*iter);
00617 }
00618 }
00619 return nullptr;
00620 }
00621
00622 void ListCtrl::onMouseButtonPressed(int _left, int _top, MouseButton _id)
00623 {
00624 Base::onMouseButtonPressed(_left, _top, _id);
00625 }
00626
00627 void ListCtrl::onMouseButtonReleased(int _left, int _top, MouseButton _id)
00628 {
00629 Base::onMouseButtonReleased(_left, _top, _id);
00630 }
00631
00632 void ListCtrl::onMouseDrag(int _left, int _top)
00633 {
00634 Base::onMouseDrag(_left, _top);
00635 }
00636
00637 void ListCtrl::removeDropItems()
00638 {
00639 if (mItemDrag) mItemDrag->setVisible(false);
00640 }
00641
00642 void ListCtrl::updateDropItems()
00643 {
00644 if (nullptr == mItemDrag)
00645 {
00646
00647 IntCoord coord(0, 0, 50, 50);
00648
00649
00650
00651 mPointDragOffset = coord.point();
00652
00653
00654 mItemDrag = Gui::getInstance().createWidget<Widget>("Default", IntCoord(0, 0, coord.width, coord.height), Align::Default, mDragLayer);
00655 requestCreateWidgetItem(this, mItemDrag);
00656 }
00657
00658 const IntPoint& point = InputManager::getInstance().getMousePositionByLayer();
00659
00660 mItemDrag->setPosition(point.left - mClickInWidget.left + mPointDragOffset.left, point.top - mClickInWidget.top + mPointDragOffset.top);
00661 mItemDrag->setVisible(true);
00662 }
00663
00664 void ListCtrl::updateDropItemsState(const DDWidgetState& _state)
00665 {
00666 IBDrawItemInfo data;
00667 data.drop_accept = _state.accept;
00668 data.drop_refuse = _state.refuse;
00669
00670 data.select = false;
00671 data.active = false;
00672
00673 data.index = mDropSenderIndex;
00674 data.update = _state.update;
00675 data.drag = true;
00676
00677 IntCoord coord;
00678
00679 requestDrawItem(this, mItemDrag, data, coord);
00680
00681 }
00682
00683 void ListCtrl::notifyMouseDrag(Widget* _sender, int _left, int _top)
00684 {
00685 mouseDrag();
00686 }
00687
00688 void ListCtrl::notifyMouseButtonPressed(Widget* _sender, int _left, int _top, MouseButton _id)
00689 {
00690 mouseButtonPressed(_id);
00691
00692 if ( MouseButton::Left == _id)
00693 {
00694 size_t old = mIndexSelect;
00695
00696 if (_sender == _getClientWidget())
00697 {
00698
00699 setIndexSelected(ITEM_NONE);
00700 }
00701 else
00702 {
00703
00704 mDropSenderIndex = getIndexByWidget(_sender);
00705
00706
00707 setIndexSelected(mDropSenderIndex);
00708 }
00709
00710
00711 mClickInWidget = InputManager::getInstance().getLastLeftPressed() - _sender->getAbsolutePosition();
00712
00713
00714 eventMouseItemActivate(this, mIndexSelect);
00715
00716 if (old != mIndexSelect) eventChangeItemPosition(this, mIndexSelect);
00717 }
00718
00719 eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::MousePressed, _left, _top, _id));
00720 }
00721
00722 void ListCtrl::notifyMouseButtonReleased(Widget* _sender, int _left, int _top, MouseButton _id)
00723 {
00724 mouseButtonReleased(_id);
00725 eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::MouseReleased, _left, _top, _id));
00726 }
00727
00728 void ListCtrl::notifyRootMouseChangeFocus(Widget* _sender, bool _focus)
00729 {
00730 size_t index = calcIndexByWidget(_sender);
00731 if (_focus)
00732 {
00733 MYGUI_ASSERT_RANGE(index, mItemsInfo.size(), "ListCtrl::notifyRootMouseChangeFocus");
00734
00735
00736 if (mIndexActive != ITEM_NONE)
00737 {
00738 size_t old_index = mIndexActive;
00739 mIndexActive = ITEM_NONE;
00740
00741
00742 _updateAllVisible(old_index, true, false);
00743
00744
00745
00746
00747
00748
00749 }
00750
00751 mIndexActive = index;
00752
00753
00754 _updateAllVisible(index, true, false);
00755
00756
00757
00758
00759
00760
00761 }
00762 else
00763 {
00764
00765
00766 if (index < mItemsInfo.size() && mIndexActive == index)
00767 {
00768 mIndexActive = ITEM_NONE;
00769
00770
00771 _updateAllVisible(index, true, false);
00772
00773
00774
00775
00776
00777
00778 }
00779 }
00780 }
00781
00782 void ListCtrl::updateMetrics()
00783 {
00784 IntSize size;
00785
00786 for (VectorItemInfo::const_iterator item=mItemsInfo.begin(); item!=mItemsInfo.end(); ++item)
00787 {
00788 if (size.width < item->size.width)
00789 size.width = item->size.width;
00790 size.height += item->size.height;
00791 }
00792
00793 mContentSize = size;
00794 }
00795
00796 void ListCtrl::notifyScrollChangePosition(VScroll* _sender, size_t _index)
00797 {
00798 if (_sender == mVScroll)
00799 {
00800 mContentPosition.top = (int)_index;
00801 }
00802 else if (_sender == mHScroll)
00803 {
00804 mContentPosition.left = (int)_index;
00805 }
00806
00807 setContentPosition(mContentPosition);
00808 }
00809
00810 void ListCtrl::setContentPosition(const IntPoint& _point)
00811 {
00812 mContentPosition = _point;
00813
00814 _updateAllVisible(ITEM_NONE, true, true);
00815 _resetContainer(true);
00816 }
00817
00818 void ListCtrl::notifyMouseWheel(Widget* _sender, int _rel)
00819 {
00820 if (mContentSize.height <= 0) return;
00821
00822 int offset = mContentPosition.top;
00823 if (_rel < 0) offset += mScrollViewPage;
00824 else offset -= mScrollViewPage;
00825
00826 if (mContentSize.height <= _getClientWidget()->getHeight()) return;
00827
00828 if (offset >= mContentSize.height - _getClientWidget()->getHeight()) offset = mContentSize.height - _getClientWidget()->getHeight();
00829 else if (offset < 0) offset = 0;
00830
00831 if (mContentPosition.top == offset) return;
00832
00833
00834
00835 resetCurrentActiveItem();
00836
00837 mContentPosition.top = offset;
00838
00839 setContentPosition(mContentPosition);
00840
00841
00842 if (!mNeedDrop)
00843 findCurrentActiveItem();
00844
00845 if (nullptr != mVScroll) mVScroll->setScrollPosition(mContentPosition.top);
00846 if (nullptr != mHScroll) mHScroll->setScrollPosition(mContentPosition.left);
00847 }
00848
00849 void ListCtrl::resetDrag()
00850 {
00851 endDrop(true);
00852 }
00853
00854 IntSize ListCtrl::getContentSize()
00855 {
00856 return mContentSize;
00857 }
00858
00859 IntPoint ListCtrl::getContentPosition()
00860 {
00861 return mContentPosition;
00862 }
00863
00864 IntSize ListCtrl::getViewSize() const
00865 {
00866 return _getClientWidget()->getSize();
00867 }
00868
00869 void ListCtrl::eraseContent()
00870 {
00871 _updateAllVisible(ITEM_NONE, false, true);
00872 updateMetrics();
00873 }
00874
00875 Align ListCtrl::getContentAlign()
00876 {
00877 return Align::Default;
00878 }
00879
00880 Widget* ListCtrl::_getClientWidget()
00881 {
00882 return mWidgetClient == nullptr ? this : mWidgetClient;
00883 }
00884
00885 const Widget* ListCtrl::_getClientWidget() const
00886 {
00887 return mWidgetClient == nullptr ? this : mWidgetClient;
00888 }
00889
00890 }