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

MyGUI_DDContainer.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_DDContainer.h"
00025 #include "MyGUI_InputManager.h"
00026 #include "MyGUI_LayerManager.h"
00027 
00028 namespace MyGUI
00029 {
00030 
00031     DDContainer::DDContainer() :
00032         mDropResult(false),
00033         mNeedDrop(false),
00034         mStartDrop(false),
00035         mOldDrop(nullptr),
00036         mCurrentSender(nullptr),
00037         mDropSenderIndex(ITEM_NONE),
00038         mDropItem(nullptr),
00039         mNeedDragDrop(false),
00040         mReseiverContainer(nullptr)
00041     {
00042     }
00043 
00044     void DDContainer::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, WidgetPtr _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00045     {
00046         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00047 
00048         initialiseWidgetSkin(_info);
00049     }
00050 
00051     DDContainer::~DDContainer()
00052     {
00053         shutdownWidgetSkin();
00054     }
00055 
00056     void DDContainer::baseChangeWidgetSkin(ResourceSkin* _info)
00057     {
00058         shutdownWidgetSkin();
00059         Base::baseChangeWidgetSkin(_info);
00060         initialiseWidgetSkin(_info);
00061     }
00062 
00063     void DDContainer::initialiseWidgetSkin(ResourceSkin* _info)
00064     {
00065     }
00066 
00067     void DDContainer::shutdownWidgetSkin()
00068     {
00069     }
00070 
00071     void DDContainer::onMouseButtonPressed(int _left, int _top, MouseButton _id)
00072     {
00073         // смещение внутри виджета, куда кликнули мышкой
00074         mClickInWidget = InputManager::getInstance().getLastLeftPressed() - getAbsolutePosition();
00075 
00076         mouseButtonPressed(_id);
00077 
00078         Base::onMouseButtonPressed(_left, _top, _id);
00079     }
00080 
00081     void DDContainer::onMouseButtonReleased(int _left, int _top, MouseButton _id)
00082     {
00083         mouseButtonReleased(_id);
00084 
00085         Base::onMouseButtonReleased(_left, _top, _id);
00086     }
00087 
00088     void DDContainer::onMouseDrag(int _left, int _top)
00089     {
00090         mouseDrag();
00091 
00092         Base::onMouseDrag(_left, _top);
00093     }
00094 
00095     void DDContainer::mouseButtonPressed(MouseButton _id)
00096     {
00097         if (MouseButton::Left == _id) {
00098             // сбрасываем инфу для дропа
00099             mDropResult = false;
00100             mOldDrop = nullptr;
00101             mDropInfo.reset();
00102             mReseiverContainer = nullptr;
00103 
00104             // сбрасываем, чтобы обновился дропный виджет
00105             mCurrentSender = nullptr;
00106             mStartDrop = false;
00107 
00108         }
00109         // если нажата другая клавиша и был дроп то сбрасываем
00110         else {
00111             endDrop(true);
00112         }
00113     }
00114 
00115     void DDContainer::mouseButtonReleased(MouseButton _id)
00116     {
00117         if (MouseButton::Left == _id) {
00118             endDrop(false);
00119         }
00120     }
00121 
00122     void DDContainer::mouseDrag()
00123     {
00124         // нужно ли обновить данные
00125         bool update = false;
00126 
00127         // первый раз дропаем елемент
00128         if (false == mStartDrop) {
00129             mStartDrop = true;
00130             mNeedDrop = false;
00131             update = true;
00132             // запрос на нужность дропа по индексу
00133             mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00134             mReseiverContainer = nullptr;
00135 
00136             eventStartDrag(this, mDropInfo, mNeedDrop);
00137 
00138             if (mNeedDrop) {
00139                 eventChangeDDState(this, DDItemState::Start);
00140                 setEnableToolTip(false);
00141             }
00142             else {
00143                 // сбрасываем фокус мыши (не обязательно)
00144                 InputManager::getInstance().resetMouseCaptureWidget();
00145             }
00146         }
00147 
00148         // дроп не нужен
00149         if (false == mNeedDrop) {
00150             return;
00151         }
00152 
00153         // делаем запрос, над кем наша мыша
00154         const IntPoint& point = InputManager::getInstance().getMousePosition();
00155         WidgetPtr item = LayerManager::getInstance().getWidgetFromPoint(point.left, point.top);
00156 
00157         updateDropItems();
00158 
00159         // если равно, значит уже спрашивали
00160         if (mOldDrop == item) return;
00161         mOldDrop = item;
00162 
00163         // сбрасываем старую подсветку
00164         if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
00165 
00166         mDropResult = false;
00167         mReseiverContainer = nullptr;
00168         WidgetPtr receiver = nullptr;
00169         size_t receiver_index = ITEM_NONE;
00170         // есть виджет под нами
00171         if (item) {
00172             // делаем запрос на индекс по произвольному виджету
00173             item->_getContainer(receiver, receiver_index);
00174             // работаем только с контейнерами
00175             if (receiver && receiver->isType<DDContainer>()) {
00176                 // подписываемся на информацию о валидности дропа
00177                 mReseiverContainer = static_cast<DDContainerPtr>(receiver);
00178                 mReseiverContainer->_eventInvalideContainer = newDelegate(this, &DDContainer::notifyInvalideDrop);
00179 
00180                 // делаем запрос на возможность дропа
00181                 mDropInfo.set(this, mDropSenderIndex, mReseiverContainer, receiver_index);
00182 
00183                 eventRequestDrop(this, mDropInfo, mDropResult);
00184 
00185                 // устанавливаем новую подсветку
00186                 mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, true, mDropResult);
00187             }
00188             else {
00189                 mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00190             }
00191         }
00192         // нет виджета под нами
00193         else {
00194             mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00195         }
00196 
00197         DDItemState state;
00198 
00199         DDWidgetState data(mDropSenderIndex);
00200         data.update = update;
00201 
00202         if (receiver == nullptr) {
00203             data.accept = false;
00204             data.refuse = false;
00205             state = DDItemState::Miss;
00206         }
00207         else if (mDropResult) {
00208             data.accept = true;
00209             data.refuse = false;
00210             state = DDItemState::Accept;
00211         }
00212         else {
00213             data.accept = false;
00214             data.refuse = true;
00215             state = DDItemState::Refuse;
00216         }
00217 
00218         updateDropItemsState(data);
00219 
00220         eventChangeDDState(this, state);
00221     }
00222 
00223     void DDContainer::endDrop(bool _reset)
00224     {
00225         if (mStartDrop) {
00226             removeDropItems();
00227 
00228             // сбрасываем старую подсветку
00229             if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
00230 
00231             if (_reset) mDropResult = false;
00232             eventDropResult(this, mDropInfo, mDropResult);
00233             eventChangeDDState(this, DDItemState::End);
00234             setEnableToolTip(true);
00235 
00236             // сбрасываем инфу для дропа
00237             mStartDrop = false;
00238             mDropResult = false;
00239             mOldDrop = nullptr;
00240             mDropInfo.reset();
00241             mReseiverContainer = nullptr;
00242             mDropSenderIndex = ITEM_NONE;
00243         }
00244     }
00245 
00246     void DDContainer::removeDropItems()
00247     {
00248         mDropItem = nullptr;
00249     }
00250 
00251     void DDContainer::updateDropItems()
00252     {
00253 
00254         if (mDropItem == nullptr) {
00255             requestDragWidgetInfo(this, mDropItem, mDropDimension);
00256         }
00257 
00258         const IntPoint& point = InputManager::getInstance().getMousePosition();
00259 
00260         if (mDropItem)
00261         {
00262             mDropItem->setCoord(point.left - mClickInWidget.left + mDropDimension.left, point.top - mClickInWidget.top + mDropDimension.top, mDropDimension.width, mDropDimension.height);
00263             mDropItem->setVisible(true);
00264         }
00265     }
00266 
00267     void DDContainer::updateDropItemsState(const DDWidgetState& _state)
00268     {
00269         eventUpdateDropState(this, mDropItem, _state);
00270     }
00271 
00272     void DDContainer::notifyInvalideDrop(DDContainerPtr _sender)
00273     {
00274         mouseDrag();
00275     }
00276 
00277     void DDContainer::_getContainer(WidgetPtr& _container, size_t& _index)
00278     {
00279         _container = this;
00280         _index = ITEM_NONE;
00281     }
00282 
00283     void DDContainer::setProperty(const std::string& _key, const std::string& _value)
00284     {
00285         if (_key == "DDContainer_NeedDragDrop") setNeedDragDrop(utility::parseValue<bool>(_value));
00286         else Base::setProperty(_key, _value);
00287     }
00288 
00289 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1