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

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

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1