• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_ItemBox.cpp

Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_Common.h"
00025 #include "MyGUI_ItemBox.h"
00026 #include "MyGUI_Button.h"
00027 #include "MyGUI_VScroll.h"
00028 #include "MyGUI_HScroll.h"
00029 #include "MyGUI_ResourceSkin.h"
00030 #include "MyGUI_InputManager.h"
00031 #include "MyGUI_Gui.h"
00032 #include "MyGUI_WidgetTranslate.h"
00033 #include "MyGUI_WidgetManager.h"
00034 
00035 namespace MyGUI
00036 {
00037 
00038     ItemBox::ItemBox() :
00039         mFirstVisibleIndex(0),
00040         mFirstOffsetIndex(0),
00041         mIndexSelect(ITEM_NONE),
00042         mIndexActive(ITEM_NONE),
00043         mIndexAccept(ITEM_NONE),
00044         mIndexRefuse(ITEM_NONE),
00045         mIsFocus(false),
00046         mItemDrag(nullptr),
00047         mAlignVert(true)
00048     {
00049         mChangeContentByResize = true;
00050     }
00051 
00052     void ItemBox::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, WidgetPtr _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00053     {
00054         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00055 
00056         initialiseWidgetSkin(_info);
00057     }
00058 
00059     ItemBox::~ItemBox()
00060     {
00061         shutdownWidgetSkin();
00062     }
00063 
00064     void ItemBox::baseChangeWidgetSkin(ResourceSkin* _info)
00065     {
00066         shutdownWidgetSkin();
00067         Base::baseChangeWidgetSkin(_info);
00068         initialiseWidgetSkin(_info);
00069     }
00070 
00071     void ItemBox::initialiseWidgetSkin(ResourceSkin* _info)
00072     {
00073         // нам нужен фокус клавы
00074         mNeedKeyFocus = true;
00075         mDragLayer = "DragAndDrop";
00076 
00077         const MapString& properties = _info->getProperties();
00078         if (false == properties.empty())
00079         {
00080             MapString::const_iterator iter = properties.find("AlignVert");
00081             if (iter != properties.end()) mAlignVert = utility::parseBool(iter->second);
00082             iter = properties.find("DragLayer");
00083             if (iter != properties.end()) mDragLayer = iter->second;
00084         }
00085 
00086         for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00087         {
00088             if (*(*iter)->_getInternalData<std::string>() == "VScroll")
00089             {
00090                 MYGUI_DEBUG_ASSERT( ! mVScroll, "widget already assigned");
00091                 mVScroll = (*iter)->castType<VScroll>();
00092                 mVScroll->eventScrollChangePosition = newDelegate(this, &ItemBox::notifyScrollChangePosition);
00093             }
00094             if (*(*iter)->_getInternalData<std::string>() == "HScroll")
00095             {
00096                 MYGUI_DEBUG_ASSERT( ! mHScroll, "widget already assigned");
00097                 mHScroll = (*iter)->castType<HScroll>();
00098                 mHScroll->eventScrollChangePosition = newDelegate(this, &ItemBox::notifyScrollChangePosition);
00099             }
00100             else if (*(*iter)->_getInternalData<std::string>() == "Client")
00101             {
00102                 MYGUI_DEBUG_ASSERT( ! mWidgetClient, "widget already assigned");
00103                 mWidgetClient = (*iter);
00104                 mWidgetClient->eventMouseWheel = newDelegate(this, &ItemBox::notifyMouseWheel);
00105                 mWidgetClient->eventMouseButtonPressed = newDelegate(this, &ItemBox::notifyMouseButtonPressed);
00106                 mClient = mWidgetClient;
00107             }
00108         }
00109         // сли нет скрола, то клиенская зона не обязательно
00110         MYGUI_ASSERT(nullptr != mWidgetClient, "Child Widget Client not found in skin (ItemBox must have Client) skin ='" << _info->getSkinName() << "'");
00111 
00112         // подписываем клиент для драгэндропа
00113         mWidgetClient->_requestGetContainer = newDelegate(this, &ItemBox::_requestGetContainer);
00114 
00115         requestItemSize();
00116 
00117         updateScrollSize();
00118         updateScrollPosition();
00119     }
00120 
00121     void ItemBox::shutdownWidgetSkin()
00122     {
00123         mVScroll = nullptr;
00124         mHScroll = nullptr;
00125         mClient = nullptr;
00126         mWidgetClient = nullptr;
00127     }
00128 
00129     void ItemBox::setPosition(const IntPoint& _point)
00130     {
00131         Base::setPosition(_point);
00132     }
00133 
00134     void ItemBox::setSize(const IntSize& _size)
00135     {
00136         Base::setSize(_size);
00137         updateFromResize();
00138     }
00139 
00140     void ItemBox::setCoord(const IntCoord& _coord)
00141     {
00142         Base::setCoord(_coord);
00143         updateFromResize();
00144     }
00145 
00146     void ItemBox::requestItemSize()
00147     {
00148         IntCoord coord(0, 0, 1, 1);
00149 
00150         // спрашиваем размер иконок
00151         requestCoordItem(this, coord, false);
00152 
00153         mSizeItem = coord.size();
00154         MYGUI_ASSERT((mSizeItem.width > 0 && mSizeItem.height > 0), "(mSizeItem.width > 0 && mSizeItem.height > 0)  at requestCoordWidgetItem");
00155     }
00156 
00157     void ItemBox::updateFromResize()
00158     {
00159         requestItemSize();
00160 
00161         updateScrollSize();
00162         updateScrollPosition();
00163 
00164         _updateAllVisible(true);
00165         _resetContainer(true);
00166     }
00167 
00168     void ItemBox::_updateAllVisible(bool _redraw)
00169     {
00170         int count_visible = 0;
00171         if (mAlignVert)
00172         {
00173             count_visible = (mWidgetClient->getHeight() / mSizeItem.height) + 2;
00174         }
00175         else
00176         {
00177             count_visible = (mWidgetClient->getWidth() / mSizeItem.width) + 2;
00178         }
00179 
00180         size_t start = (mFirstVisibleIndex * mCountItemInLine);
00181         size_t count = (count_visible * mCountItemInLine) + start;
00182 
00183         size_t index = 0;
00184         for (size_t pos = start; pos<count; ++pos, ++index)
00185         {
00186             // дальше нет айтемов
00187             if (pos >= mItemsInfo.size()) break;
00188 
00189             WidgetPtr item = getItemWidget(index);
00190             if (mAlignVert)
00191             {
00192                 item->setPosition(((int)index % mCountItemInLine) * mSizeItem.width - mContentPosition.left,
00193                     (((int)index / mCountItemInLine) * mSizeItem.height)  - mFirstOffsetIndex);
00194             }
00195             else
00196             {
00197                 item->setPosition((((int)index / mCountItemInLine) * mSizeItem.width)  - mFirstOffsetIndex,
00198                     ((int)index % mCountItemInLine) * mSizeItem.height - mContentPosition.top);
00199             }
00200 
00201             item->setSize(mSizeItem);
00202             item->setVisible(true);
00203 
00204             if (_redraw)
00205             {
00206                 IBDrawItemInfo data(pos, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, true, false);
00207                 requestDrawItem(this, item, data);
00208             }
00209 
00210         }
00211 
00212         // все виджеты еще есть, то их надо бы скрыть
00213         while (index < mVectorItems.size())
00214         {
00215             mVectorItems[index]->setVisible(false);
00216             index ++;
00217         }
00218 
00219     }
00220 
00221     WidgetPtr ItemBox::getItemWidget(size_t _index)
00222     {
00223         // еще нет такого виджета, нуно создать
00224         if (_index == mVectorItems.size())
00225         {
00226 
00227             requestItemSize();
00228 
00229             WidgetPtr item = mWidgetClient->createWidget<Widget>("Default", IntCoord(0, 0, mSizeItem.width, mSizeItem.height), Align::Default);
00230 
00231             // вызываем запрос на создание виджета
00232             requestCreateWidgetItem(this, item);
00233 
00234             item->eventMouseWheel = newDelegate(this, &ItemBox::notifyMouseWheel);
00235             item->eventRootMouseChangeFocus = newDelegate(this, &ItemBox::notifyRootMouseChangeFocus);
00236             item->eventMouseButtonPressed = newDelegate(this, &ItemBox::notifyMouseButtonPressed);
00237             item->eventMouseButtonReleased = newDelegate(this, &ItemBox::notifyMouseButtonReleased);
00238             item->eventMouseButtonDoubleClick = newDelegate(this, &ItemBox::notifyMouseButtonDoubleClick);
00239             item->eventMouseDrag = newDelegate(this, &ItemBox::notifyMouseDrag);
00240             item->_requestGetContainer = newDelegate(this, &ItemBox::_requestGetContainer);
00241             item->eventKeyButtonPressed = newDelegate(this, &ItemBox::notifyKeyButtonPressed);
00242             item->eventKeyButtonReleased = newDelegate(this, &ItemBox::notifyKeyButtonReleased);
00243 
00244             item->_setInternalData((size_t)mVectorItems.size());
00245 
00246             mVectorItems.push_back(item);
00247         }
00248 
00249         // запрашивать только последовательно
00250         MYGUI_ASSERT_RANGE(_index, mVectorItems.size(), "ItemBox::getItemWidget");
00251 
00252         return mVectorItems[_index];
00253     }
00254 
00255     void ItemBox::onMouseWheel(int _rel)
00256     {
00257         notifyMouseWheel(nullptr, _rel);
00258 
00259         Base::onMouseWheel(_rel);
00260     }
00261 
00262     void ItemBox::onKeySetFocus(WidgetPtr _old)
00263     {
00264         mIsFocus = true;
00265         setState("pushed");
00266 
00267         Base::onKeySetFocus(_old);
00268     }
00269 
00270     void ItemBox::onKeyLostFocus(WidgetPtr _new)
00271     {
00272         mIsFocus = false;
00273         setState("normal");
00274 
00275         Base::onKeyLostFocus(_new);
00276     }
00277 
00278     void ItemBox::resetCurrentActiveItem()
00279     {
00280         // сбрасываем старую подсветку
00281         if (mIndexActive != ITEM_NONE)
00282         {
00283             size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
00284             size_t index = mIndexActive;
00285             mIndexActive = ITEM_NONE;
00286 
00287             // если видим, то обновляем
00288             if ((mIndexActive >= start) && (mIndexActive < (start + mVectorItems.size())))
00289             {
00290                 IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
00291 
00292                 requestDrawItem(this, mVectorItems[mIndexActive - start], data);
00293             }
00294         }
00295     }
00296 
00297     void ItemBox::findCurrentActiveItem()
00298     {
00299         MYGUI_DEBUG_ASSERT(mIndexActive == ITEM_NONE, "use : resetCurrentActiveItem() before findCurrentActiveItem()");
00300 
00301         const IntPoint& point = InputManager::getInstance().getMousePosition();
00302 
00303         // сначала проверяем клиентскую зону
00304         const IntRect& rect = mWidgetClient->getAbsoluteRect();
00305         if ((point.left < rect.left) || (point.left > rect.right) || (point.top < rect.top) || (point.top > rect.bottom))
00306         {
00307             return;
00308         }
00309 
00310         for (size_t pos=0; pos<mVectorItems.size(); ++pos)
00311         {
00312             WidgetPtr item = mVectorItems[pos];
00313             const IntRect& abs_rect = item->getAbsoluteRect();
00314             if ((point.left>= abs_rect.left) && (point.left <= abs_rect.right) && (point.top>= abs_rect.top) && (point.top <= abs_rect.bottom))
00315             {
00316 
00317                 size_t index = calcIndexByWidget(item);
00318                 // при переборе индекс может быть больше, так как может создасться сколько угодно
00319                 if (index < mItemsInfo.size())
00320                 {
00321 
00322                     mIndexActive = index;
00323                     IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
00324 
00325                     requestDrawItem(this, item, data);
00326                 }
00327 
00328                 break;
00329             }
00330         }
00331     }
00332 
00333     void ItemBox::_requestGetContainer(WidgetPtr _sender, WidgetPtr& _container, size_t& _index)
00334     {
00335         if (_sender == mWidgetClient)
00336         {
00337             _container = this;
00338             _index = ITEM_NONE;
00339         }
00340         else
00341         {
00342             size_t index = calcIndexByWidget(_sender);
00343             if (index < mItemsInfo.size())
00344             {
00345                 _container = this;
00346                 _index = index;
00347             }
00348         }
00349     }
00350 
00351     void ItemBox::_setContainerItemInfo(size_t _index, bool _set, bool _accept)
00352     {
00353         if (_index == ITEM_NONE) return;
00354         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::_setContainerItemInfo");
00355 
00356         mIndexAccept = (_set && _accept ) ? _index : ITEM_NONE;
00357         mIndexRefuse = (_set && !_accept) ? _index : ITEM_NONE;
00358 
00359         size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
00360         if ((_index >= start) && (_index < (start + mVectorItems.size())))
00361         {
00362 
00363             IBDrawItemInfo data(_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
00364 
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(WidgetPtr _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(WidgetPtr _sender, KeyCode _key, Char _char)
00519     {
00520         eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::KeyPressed, _key, _char));
00521     }
00522 
00523     void ItemBox::notifyKeyButtonReleased(WidgetPtr _sender, KeyCode _key)
00524     {
00525         eventNotifyItem(this, IBNotifyItemData(getIndexByWidget(_sender), IBNotifyItemData::KeyReleased, _key));
00526     }
00527 
00528     size_t ItemBox::getIndexByWidget(WidgetPtr _widget)
00529     {
00530         MYGUI_ASSERT(_widget, "ItemBox::getIndexByWidget : Widget == nullptr");
00531         if (_widget == mWidgetClient) return ITEM_NONE;
00532         MYGUI_ASSERT(_widget->getParent() == mWidgetClient, "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     WidgetPtr 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(WidgetPtr _sender, int _left, int _top)
00643     {
00644         mouseDrag();
00645     }
00646 
00647     void ItemBox::notifyMouseButtonPressed(WidgetPtr _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 == mWidgetClient)
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(WidgetPtr _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(WidgetPtr _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 = mWidgetClient->getWidth() / mSizeItem.width;
00729         }
00730         else
00731         {
00732             // колличество айтемов на одной строке
00733             mCountItemInLine = mWidgetClient->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(VScrollPtr _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(WidgetPtr _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 - mWidgetClient->getHeight()) offset = mContentSize.height - mWidgetClient->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 - mWidgetClient->getWidth()) offset = mContentSize.width - mWidgetClient->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(WidgetPtr _widget)
00851     {
00852         return *_widget->_getInternalData<size_t>() + (mFirstVisibleIndex * mCountItemInLine);
00853     }
00854 
00855 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1