MyGUI 3.0.1
|
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, Widget* _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 // сбрасываем инфу для дропа 00100 mDropResult = false; 00101 mOldDrop = nullptr; 00102 mDropInfo.reset(); 00103 mReseiverContainer = nullptr; 00104 00105 // сбрасываем, чтобы обновился дропный виджет 00106 mCurrentSender = nullptr; 00107 mStartDrop = false; 00108 00109 } 00110 // если нажата другая клавиша и был дроп то сбрасываем 00111 else 00112 { 00113 endDrop(true); 00114 } 00115 } 00116 00117 void DDContainer::mouseButtonReleased(MouseButton _id) 00118 { 00119 if (MouseButton::Left == _id) 00120 { 00121 endDrop(false); 00122 } 00123 } 00124 00125 void DDContainer::mouseDrag() 00126 { 00127 // нужно ли обновить данные 00128 bool update = false; 00129 00130 // первый раз дропаем елемент 00131 if (!mStartDrop && mDropSenderIndex != ITEM_NONE) 00132 { 00133 mStartDrop = true; 00134 mNeedDrop = false; 00135 update = true; 00136 // запрос на нужность дропа по индексу 00137 mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE); 00138 mReseiverContainer = nullptr; 00139 00140 eventStartDrag(this, mDropInfo, mNeedDrop); 00141 00142 if (mNeedDrop) 00143 { 00144 eventChangeDDState(this, DDItemState::Start); 00145 setEnableToolTip(false); 00146 } 00147 else 00148 { 00149 // сбрасываем фокус мыши (не обязательно) 00150 InputManager::getInstance().resetMouseCaptureWidget(); 00151 } 00152 } 00153 00154 // дроп не нужен 00155 if (!mNeedDrop) 00156 { 00157 return; 00158 } 00159 00160 // делаем запрос, над кем наша мыша 00161 const IntPoint& point = InputManager::getInstance().getMousePosition(); 00162 Widget* item = LayerManager::getInstance().getWidgetFromPoint(point.left, point.top); 00163 00164 updateDropItems(); 00165 00166 // если равно, значит уже спрашивали 00167 if (mOldDrop == item) return; 00168 mOldDrop = item; 00169 00170 // сбрасываем старую подсветку 00171 if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false); 00172 00173 mDropResult = false; 00174 mReseiverContainer = nullptr; 00175 Widget* receiver = nullptr; 00176 size_t receiver_index = ITEM_NONE; 00177 // есть виджет под нами 00178 if (item) 00179 { 00180 // делаем запрос на индекс по произвольному виджету 00181 item->_getContainer(receiver, receiver_index); 00182 // работаем только с контейнерами 00183 if (receiver && receiver->isType<DDContainer>()) 00184 { 00185 // подписываемся на информацию о валидности дропа 00186 mReseiverContainer = static_cast<DDContainer*>(receiver); 00187 mReseiverContainer->_eventInvalideContainer = newDelegate(this, &DDContainer::notifyInvalideDrop); 00188 00189 // делаем запрос на возможность дропа 00190 mDropInfo.set(this, mDropSenderIndex, mReseiverContainer, receiver_index); 00191 00192 eventRequestDrop(this, mDropInfo, mDropResult); 00193 00194 // устанавливаем новую подсветку 00195 mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, true, mDropResult); 00196 } 00197 else 00198 { 00199 mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE); 00200 } 00201 } 00202 // нет виджета под нами 00203 else 00204 { 00205 mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE); 00206 } 00207 00208 DDItemState state; 00209 00210 DDWidgetState data(mDropSenderIndex); 00211 data.update = update; 00212 00213 if (receiver == nullptr) 00214 { 00215 data.accept = false; 00216 data.refuse = false; 00217 state = DDItemState::Miss; 00218 } 00219 else if (mDropResult) 00220 { 00221 data.accept = true; 00222 data.refuse = false; 00223 state = DDItemState::Accept; 00224 } 00225 else 00226 { 00227 data.accept = false; 00228 data.refuse = true; 00229 state = DDItemState::Refuse; 00230 } 00231 00232 updateDropItemsState(data); 00233 00234 eventChangeDDState(this, state); 00235 } 00236 00237 void DDContainer::endDrop(bool _reset) 00238 { 00239 if (mStartDrop) 00240 { 00241 removeDropItems(); 00242 00243 // сбрасываем старую подсветку 00244 if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false); 00245 00246 if (_reset) mDropResult = false; 00247 eventDropResult(this, mDropInfo, mDropResult); 00248 eventChangeDDState(this, DDItemState::End); 00249 setEnableToolTip(true); 00250 00251 // сбрасываем инфу для дропа 00252 mStartDrop = false; 00253 mDropResult = false; 00254 mNeedDrop = false; 00255 mOldDrop = nullptr; 00256 mDropInfo.reset(); 00257 mReseiverContainer = nullptr; 00258 mDropSenderIndex = ITEM_NONE; 00259 } 00260 } 00261 00262 void DDContainer::removeDropItems() 00263 { 00264 mDropItem = nullptr; 00265 } 00266 00267 void DDContainer::updateDropItems() 00268 { 00269 00270 if (mDropItem == nullptr) 00271 { 00272 requestDragWidgetInfo(this, mDropItem, mDropDimension); 00273 } 00274 00275 const IntPoint& point = InputManager::getInstance().getMousePositionByLayer(); 00276 00277 if (mDropItem) 00278 { 00279 mDropItem->setCoord(point.left - mClickInWidget.left + mDropDimension.left, point.top - mClickInWidget.top + mDropDimension.top, mDropDimension.width, mDropDimension.height); 00280 mDropItem->setVisible(true); 00281 } 00282 } 00283 00284 void DDContainer::updateDropItemsState(const DDWidgetState& _state) 00285 { 00286 eventUpdateDropState(this, mDropItem, _state); 00287 } 00288 00289 void DDContainer::notifyInvalideDrop(DDContainer* _sender) 00290 { 00291 mouseDrag(); 00292 } 00293 00294 void DDContainer::_getContainer(Widget*& _container, size_t& _index) 00295 { 00296 _container = this; 00297 _index = ITEM_NONE; 00298 } 00299 00300 void DDContainer::setProperty(const std::string& _key, const std::string& _value) 00301 { 00302 if (_key == "DDContainer_NeedDragDrop") setNeedDragDrop(utility::parseValue<bool>(_value)); 00303 else 00304 { 00305 Base::setProperty(_key, _value); 00306 return; 00307 } 00308 eventChangeProperty(this, _key, _value); 00309 } 00310 00311 } // namespace MyGUI