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