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