MyGUI
3.2.0
|
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