00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "elements/CEGUIDragContainer.h"
00025 #include "CEGUIImageset.h"
00026 #include <math.h>
00027
00028
00029 namespace CEGUI
00030 {
00032
00033 const String DragContainer::WidgetTypeName("DragContainer");
00034
00035 const String DragContainer::EventNamespace("DragContainer");
00036 const String DragContainer::EventDragStarted("DragStarted");
00037 const String DragContainer::EventDragEnded("DragEnded");
00038 const String DragContainer::EventDragPositionChanged("DragPositionChanged");
00039 const String DragContainer::EventDragEnabledChanged("DragEnabledChanged");
00040 const String DragContainer::EventDragAlphaChanged("DragAlphaChanged");
00041 const String DragContainer::EventDragMouseCursorChanged("DragMouseCursorChanged");
00042 const String DragContainer::EventDragThresholdChanged("DragThresholdChanged");
00043 const String DragContainer::EventDragDropTargetChanged("DragDropTargetChanged");
00044
00045 DragContainerProperties::DragAlpha DragContainer::d_dragAlphaProperty;
00046 DragContainerProperties::DragCursorImage DragContainer::d_dragCursorImageProperty;
00047 DragContainerProperties::DraggingEnabled DragContainer::d_dragEnabledProperty;
00048 DragContainerProperties::DragThreshold DragContainer::d_dragThresholdProperty;
00049
00051
00052 DragContainer::DragContainer(const String& type, const String& name) :
00053 Window(type, name),
00054 d_draggingEnabled(true),
00055 d_leftMouseDown(false),
00056 d_dragging(false),
00057 d_dragThreshold(8.0f),
00058 d_dragAlpha(0.5f),
00059 d_dropTarget(0),
00060 d_dragCursorImage((const Image*)DefaultMouseCursor)
00061 {
00062 addDragContainerEvents();
00063 addDragContainerProperties();
00064 }
00065
00066 DragContainer::~DragContainer(void)
00067 {
00068 }
00069
00070 bool DragContainer::isDraggingEnabled(void) const
00071 {
00072 return d_draggingEnabled;
00073 }
00074
00075 void DragContainer::setDraggingEnabled(bool setting)
00076 {
00077 if (d_draggingEnabled != setting)
00078 {
00079 d_draggingEnabled = setting;
00080 WindowEventArgs args(this);
00081 onDragEnabledChanged(args);
00082 }
00083 }
00084
00085 bool DragContainer::isBeingDragged(void) const
00086 {
00087 return d_dragging;
00088 }
00089
00090 float DragContainer::getPixelDragThreshold(void) const
00091 {
00092 return d_dragThreshold;
00093 }
00094
00095 void DragContainer::setPixelDragThreshold(float pixels)
00096 {
00097 if (d_dragThreshold != pixels)
00098 {
00099 d_dragThreshold = pixels;
00100 WindowEventArgs args(this);
00101 onDragThresholdChanged(args);
00102 }
00103 }
00104
00105 float DragContainer::getDragAlpha(void) const
00106 {
00107 return d_dragAlpha;
00108 }
00109
00110 void DragContainer::setDragAlpha(float alpha)
00111 {
00112 if (d_dragAlpha != alpha)
00113 {
00114 d_dragAlpha = alpha;
00115 WindowEventArgs args(this);
00116 onDragAlphaChanged(args);
00117 }
00118 }
00119
00120 const Image* DragContainer::getDragCursorImage(void) const
00121 {
00122 if (d_dragCursorImage == (const Image*)DefaultMouseCursor)
00123 {
00124 return System::getSingleton().getDefaultMouseCursor();
00125 }
00126 else
00127 {
00128 return d_dragCursorImage;
00129 }
00130 }
00131
00132 void DragContainer::setDragCursorImage(const Image* image)
00133 {
00134 if (d_dragCursorImage != image)
00135 {
00136 d_dragCursorImage = image;
00137 WindowEventArgs args(this);
00138 onDragMouseCursorChanged(args);
00139 }
00140 }
00141
00142 void DragContainer::setDragCursorImage(MouseCursorImage image)
00143 {
00144 setDragCursorImage((const Image*)image);
00145 }
00146
00147 void DragContainer::setDragCursorImage(const String& imageset, const String& image)
00148 {
00149 setDragCursorImage(&ImagesetManager::getSingleton().getImageset(imageset)->getImage(image));
00150 }
00151
00152 Window* DragContainer::getCurrentDropTarget(void) const
00153 {
00154 return d_dropTarget;
00155 }
00156
00157 void DragContainer::addDragContainerEvents(void)
00158 {
00159 addEvent(EventDragStarted);
00160 addEvent(EventDragEnded);
00161 addEvent(EventDragPositionChanged);
00162 addEvent(EventDragEnabledChanged);
00163 addEvent(EventDragAlphaChanged);
00164 addEvent(EventDragMouseCursorChanged);
00165 addEvent(EventDragThresholdChanged);
00166 addEvent(EventDragDropTargetChanged);
00167 }
00168
00169 void DragContainer::addDragContainerProperties(void)
00170 {
00171 addProperty(&d_dragEnabledProperty);
00172 addProperty(&d_dragAlphaProperty);
00173 addProperty(&d_dragThresholdProperty);
00174 addProperty(&d_dragCursorImageProperty);
00175 }
00176
00177 bool DragContainer::isDraggingThresholdExceeded(const Point& local_mouse)
00178 {
00179
00180 float deltaX = fabsf(local_mouse.d_x - d_dragPoint.d_x);
00181 float deltaY = fabsf(local_mouse.d_y - d_dragPoint.d_y);
00182
00183
00184 return (deltaX > d_dragThreshold || deltaY > d_dragThreshold) ? true : false;
00185 }
00186
00187 void DragContainer::initialiseDragging(void)
00188 {
00189
00190 if (d_draggingEnabled)
00191 {
00192
00193 d_storedClipState = d_clippedByParent;
00194 setClippedByParent(false);
00195 d_storedAlpha = d_alpha;
00196 setAlpha(d_dragAlpha);
00197 d_startPosition = getPosition(Absolute);
00198
00199 d_dragging = true;
00200
00201
00202 updateActiveMouseCursor();
00203 }
00204 }
00205
00206 void DragContainer::doDragging(const Point& local_mouse)
00207 {
00208 setPosition(Absolute, getPosition(Absolute) + (local_mouse - d_dragPoint));
00209
00210 WindowEventArgs args(this);
00211 onDragPositionChanged(args);
00212 }
00213
00214 void DragContainer::updateActiveMouseCursor(void) const
00215 {
00216 MouseCursor::getSingleton().setImage(d_dragging ? getDragCursorImage() : getMouseCursor());
00217 }
00218
00219 void DragContainer::drawSelf(float z)
00220 {
00221
00222 }
00223
00224 void DragContainer::onMouseButtonDown(MouseEventArgs& e)
00225 {
00226 Window::onMouseButtonDown(e);
00227
00228 if (e.button == LeftButton)
00229 {
00230
00231 if (captureInput())
00232 {
00233
00234 Point localPos = (getMetricsMode() == Relative) ?
00235 relativeToAbsolute(screenToWindow(e.position)) :
00236 screenToWindow(e.position);
00237
00238
00239 d_dragPoint = localPos;
00240 d_leftMouseDown = true;
00241 }
00242
00243 e.handled = true;
00244 }
00245
00246 }
00247
00248 void DragContainer::onMouseButtonUp(MouseEventArgs& e)
00249 {
00250 Window::onMouseButtonUp(e);
00251
00252 if (e.button == LeftButton)
00253 {
00254 if (d_dragging)
00255 {
00256
00257 WindowEventArgs args(this);
00258 onDragEnded(args);
00259 }
00260
00261
00262 releaseInput();
00263 e.handled = true;
00264 }
00265 }
00266
00267 void DragContainer::onMouseMove(MouseEventArgs& e)
00268 {
00269 Window::onMouseMove(e);
00270
00271
00272 Point localMousePos = (getMetricsMode() == Relative) ?
00273 relativeToAbsolute(screenToWindow(e.position)) :
00274 screenToWindow(e.position);
00275
00276
00277 if (d_dragging)
00278 {
00279 doDragging(localMousePos);
00280 }
00281
00282 else
00283 {
00284
00285 if (d_leftMouseDown)
00286 {
00287 if (isDraggingThresholdExceeded(localMousePos))
00288 {
00289
00290 WindowEventArgs args(this);
00291 onDragStarted(args);
00292 }
00293 }
00294 }
00295 }
00296
00297 void DragContainer::onCaptureLost(WindowEventArgs& e)
00298 {
00299 Window::onCaptureLost(e);
00300
00301
00302 if (d_dragging)
00303 {
00304
00305 d_dragging = false;
00306 setPosition(Absolute, d_startPosition);
00307 setClippedByParent(d_storedClipState);
00308 setAlpha(d_storedAlpha);
00309
00310
00311 updateActiveMouseCursor();
00312 }
00313
00314 d_leftMouseDown = false;
00315 d_dropTarget = 0;
00316
00317 e.handled = true;
00318 }
00319
00320 void DragContainer::onAlphaChanged(WindowEventArgs& e)
00321 {
00322
00323 if (d_dragging)
00324 {
00325 d_storedAlpha = d_alpha;
00326 d_alpha = d_dragAlpha;
00327 }
00328
00329 Window::onAlphaChanged(e);
00330 }
00331
00332 void DragContainer::onClippingChanged(WindowEventArgs& e)
00333 {
00334
00335 if (d_dragging)
00336 {
00337 d_storedClipState = d_clippedByParent;
00338 d_clippedByParent = false;
00339 }
00340
00341 Window::onClippingChanged(e);
00342 }
00343
00344 void DragContainer::onDragStarted(WindowEventArgs& e)
00345 {
00346 initialiseDragging();
00347
00348 fireEvent(EventDragStarted, e, EventNamespace);
00349 }
00350
00351 void DragContainer::onDragEnded(WindowEventArgs& e)
00352 {
00353 fireEvent(EventDragEnded, e, EventNamespace);
00354
00355
00356 if (d_dropTarget)
00357 {
00358
00359 d_dropTarget->notifyDragDropItemDropped(this);
00360 }
00361 }
00362
00363 void DragContainer::onDragPositionChanged(WindowEventArgs& e)
00364 {
00365 fireEvent(EventDragPositionChanged, e, EventNamespace);
00366
00367 Window* root;
00368
00369 if (0 != (root = System::getSingleton().getGUISheet()))
00370 {
00371
00372
00373
00374 bool wasEnabled = d_enabled;
00375 d_enabled = false;
00376
00377 Window* eventWindow = root->getChildAtPosition(MouseCursor::getSingleton().getPosition());
00378 d_enabled = wasEnabled;
00379
00380
00381 if (!eventWindow)
00382 {
00383 eventWindow = root;
00384 }
00385
00386
00387 if (eventWindow != d_dropTarget)
00388 {
00389 DragDropEventArgs args(eventWindow);
00390 args.dragDropItem = this;
00391 onDragDropTargetChanged(args);
00392 }
00393 }
00394 }
00395
00396 void DragContainer::onDragEnabledChanged(WindowEventArgs& e)
00397 {
00398 fireEvent(EventDragEnabledChanged, e, EventNamespace);
00399
00400
00401 if (!d_draggingEnabled && d_dragging)
00402 {
00403 releaseInput();
00404 }
00405 }
00406
00407 void DragContainer::onDragAlphaChanged(WindowEventArgs& e)
00408 {
00409 fireEvent(EventDragAlphaChanged, e, EventNamespace);
00410
00411 if (d_dragging)
00412 {
00413 d_alpha = d_storedAlpha;
00414 onAlphaChanged(e);
00415 }
00416 }
00417
00418 void DragContainer::onDragMouseCursorChanged(WindowEventArgs& e)
00419 {
00420 fireEvent(EventDragMouseCursorChanged, e, EventNamespace);
00421
00422 updateActiveMouseCursor();
00423 }
00424
00425 void DragContainer::onDragThresholdChanged(WindowEventArgs& e)
00426 {
00427 fireEvent(EventDragThresholdChanged, e, EventNamespace);
00428 }
00429
00430 void DragContainer::onDragDropTargetChanged(DragDropEventArgs& e)
00431 {
00432 fireEvent(EventDragDropTargetChanged, e, EventNamespace);
00433
00434
00435 if (d_dropTarget)
00436 {
00437 d_dropTarget->notifyDragDropItemLeaves(this);
00438 }
00439
00440
00441 d_dropTarget = e.window;
00442
00443
00444 d_dropTarget->notifyDragDropItemEnters(this);
00445 }
00446
00447 }