MyGUI 3.0.1

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