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