MyGUI  3.2.0
MyGUI_DDContainer.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_DDContainer.h"
00024 #include "MyGUI_InputManager.h"
00025 #include "MyGUI_LayerManager.h"
00026 
00027 namespace MyGUI
00028 {
00029 
00030     DDContainer::DDContainer() :
00031         mDropResult(false),
00032         mNeedDrop(false),
00033         mStartDrop(false),
00034         mOldDrop(nullptr),
00035         mCurrentSender(nullptr),
00036         mDropSenderIndex(ITEM_NONE),
00037         mDropItem(nullptr),
00038         mNeedDragDrop(false),
00039         mReseiverContainer(nullptr)
00040     {
00041     }
00042 
00043     void DDContainer::onMouseButtonPressed(int _left, int _top, MouseButton _id)
00044     {
00045         // смещение внутри виджета, куда кликнули мышкой
00046         mClickInWidget = InputManager::getInstance().getLastPressedPosition(MouseButton::Left) - getAbsolutePosition();
00047 
00048         mouseButtonPressed(_id);
00049 
00050         Base::onMouseButtonPressed(_left, _top, _id);
00051     }
00052 
00053     void DDContainer::onMouseButtonReleased(int _left, int _top, MouseButton _id)
00054     {
00055         mouseButtonReleased(_id);
00056 
00057         Base::onMouseButtonReleased(_left, _top, _id);
00058     }
00059 
00060     void DDContainer::onMouseDrag(int _left, int _top, MouseButton _id)
00061     {
00062         mouseDrag(_id);
00063 
00064         Base::onMouseDrag(_left, _top, _id);
00065     }
00066 
00067     void DDContainer::mouseButtonPressed(MouseButton _id)
00068     {
00069         if (MouseButton::Left == _id)
00070         {
00071             // сбрасываем инфу для дропа
00072             mDropResult = false;
00073             mOldDrop = nullptr;
00074             mDropInfo.reset();
00075             mReseiverContainer = nullptr;
00076 
00077             // сбрасываем, чтобы обновился дропный виджет
00078             mCurrentSender = nullptr;
00079             mStartDrop = false;
00080 
00081         }
00082         // если нажата другая клавиша и был дроп то сбрасываем
00083         else
00084         {
00085             endDrop(true);
00086         }
00087     }
00088 
00089     void DDContainer::mouseButtonReleased(MouseButton _id)
00090     {
00091         if (MouseButton::Left == _id)
00092         {
00093             endDrop(false);
00094         }
00095     }
00096 
00097     void DDContainer::mouseDrag(MouseButton _id)
00098     {
00099         if (MouseButton::Left != _id)
00100             return;
00101 
00102         // нужно ли обновить данные
00103         bool update = false;
00104 
00105         // первый раз дропаем елемент
00106         if (!mStartDrop && mDropSenderIndex != ITEM_NONE)
00107         {
00108             mStartDrop = true;
00109             mNeedDrop = false;
00110             update = true;
00111             // запрос на нужность дропа по индексу
00112             mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00113             mReseiverContainer = nullptr;
00114 
00115             eventStartDrag(this, mDropInfo, mNeedDrop);
00116 
00117             if (mNeedDrop)
00118             {
00119                 eventChangeDDState(this, DDItemState::Start);
00120             }
00121             else
00122             {
00123                 // сбрасываем фокус мыши (не обязательно)
00124                 InputManager::getInstance().resetMouseCaptureWidget();
00125             }
00126         }
00127 
00128         // дроп не нужен
00129         if (!mNeedDrop)
00130         {
00131             return;
00132         }
00133 
00134         // делаем запрос, над кем наша мыша
00135         const IntPoint& point = InputManager::getInstance().getMousePosition();
00136         Widget* item = LayerManager::getInstance().getWidgetFromPoint(point.left, point.top);
00137 
00138         updateDropItems();
00139 
00140         // если равно, значит уже спрашивали
00141         if (mOldDrop == item) return;
00142         mOldDrop = item;
00143 
00144         // сбрасываем старую подсветку
00145         if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
00146 
00147         mDropResult = false;
00148         mReseiverContainer = nullptr;
00149         Widget* receiver = nullptr;
00150         size_t receiver_index = ITEM_NONE;
00151         // есть виджет под нами
00152         if (item)
00153         {
00154             // делаем запрос на индекс по произвольному виджету
00155             receiver = item->_getContainer();
00156             // работаем только с контейнерами
00157             if (receiver && receiver->isType<DDContainer>())
00158             {
00159                 receiver_index = receiver->_getItemIndex(item);
00160 
00161                 // подписываемся на информацию о валидности дропа
00162                 mReseiverContainer = static_cast<DDContainer*>(receiver);
00163                 mReseiverContainer->_eventInvalideContainer.clear();
00164                 mReseiverContainer->_eventInvalideContainer += newDelegate(this, &DDContainer::notifyInvalideDrop);
00165 
00166                 // делаем запрос на возможность дропа
00167                 mDropInfo.set(this, mDropSenderIndex, mReseiverContainer, receiver_index);
00168 
00169                 eventRequestDrop(this, mDropInfo, mDropResult);
00170 
00171                 // устанавливаем новую подсветку
00172                 mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, true, mDropResult);
00173             }
00174             else
00175             {
00176                 mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00177             }
00178         }
00179         // нет виджета под нами
00180         else
00181         {
00182             mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
00183         }
00184 
00185         DDItemState state;
00186 
00187         DDWidgetState data(mDropSenderIndex);
00188         data.update = update;
00189 
00190         if (receiver == nullptr)
00191         {
00192             data.accept = false;
00193             data.refuse = false;
00194             state = DDItemState::Miss;
00195         }
00196         else if (mDropResult)
00197         {
00198             data.accept = true;
00199             data.refuse = false;
00200             state = DDItemState::Accept;
00201         }
00202         else
00203         {
00204             data.accept = false;
00205             data.refuse = true;
00206             state = DDItemState::Refuse;
00207         }
00208 
00209         updateDropItemsState(data);
00210 
00211         eventChangeDDState(this, state);
00212     }
00213 
00214     void DDContainer::endDrop(bool _reset)
00215     {
00216         if (mStartDrop)
00217         {
00218             removeDropItems();
00219 
00220             // сбрасываем старую подсветку
00221             if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
00222 
00223             if (_reset) mDropResult = false;
00224             eventDropResult(this, mDropInfo, mDropResult);
00225             eventChangeDDState(this, DDItemState::End);
00226 
00227             // сбрасываем инфу для дропа
00228             mStartDrop = false;
00229             mDropResult = false;
00230             mNeedDrop = false;
00231             mOldDrop = nullptr;
00232             mDropInfo.reset();
00233             mReseiverContainer = nullptr;
00234             mDropSenderIndex = ITEM_NONE;
00235         }
00236     }
00237 
00238     void DDContainer::removeDropItems()
00239     {
00240         mDropItem = nullptr;
00241     }
00242 
00243     void DDContainer::updateDropItems()
00244     {
00245 
00246         if (mDropItem == nullptr)
00247         {
00248             requestDragWidgetInfo(this, mDropItem, mDropDimension);
00249         }
00250 
00251         const IntPoint& point = InputManager::getInstance().getMousePositionByLayer();
00252 
00253         if (mDropItem)
00254         {
00255             mDropItem->setCoord(point.left - mClickInWidget.left + mDropDimension.left, point.top - mClickInWidget.top + mDropDimension.top, mDropDimension.width, mDropDimension.height);
00256             mDropItem->setVisible(true);
00257         }
00258     }
00259 
00260     void DDContainer::updateDropItemsState(const DDWidgetState& _state)
00261     {
00262         eventUpdateDropState(this, mDropItem, _state);
00263     }
00264 
00265     void DDContainer::notifyInvalideDrop(DDContainer* _sender)
00266     {
00267         mouseDrag(MouseButton::Left);
00268     }
00269 
00270     void DDContainer::setPropertyOverride(const std::string& _key, const std::string& _value)
00271     {
00272         if (_key == "NeedDragDrop")
00273             setNeedDragDrop(utility::parseValue<bool>(_value));
00274         else
00275         {
00276             Base::setPropertyOverride(_key, _value);
00277             return;
00278         }
00279         eventChangeProperty(this, _key, _value);
00280     }
00281 
00282     void DDContainer::setNeedDragDrop(bool _value)
00283     {
00284         mNeedDragDrop = _value;
00285     }
00286 
00287     bool DDContainer::getNeedDragDrop() const
00288     {
00289         return mNeedDragDrop;
00290     }
00291 
00292     void DDContainer::_setContainerItemInfo(size_t _index, bool _set, bool _accept)
00293     {
00294     }
00295 
00296     void DDContainer::resetDrag()
00297     {
00298         _resetContainer(false);
00299     }
00300 
00301 } // namespace MyGUI