Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CEGUIDragContainer.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIDragContainer.cpp
00003         created:        14/2/2005
00004         author:         Paul D Turner
00005 *************************************************************************/
00006 /*************************************************************************
00007     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00008     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Lesser General Public
00012     License as published by the Free Software Foundation; either
00013     version 2.1 of the License, or (at your option) any later version.
00014 
00015     This library 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 GNU
00018     Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public
00021     License along with this library; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 *************************************************************************/
00024 #include "elements/CEGUIDragContainer.h"
00025 #include "CEGUIImageset.h"
00026 #include <math.h>
00027 
00028 // Start of CEGUI namespace section
00029 namespace CEGUI
00030 {
00032     // Window type string
00033     const String DragContainer::WidgetTypeName("DragContainer");
00034     // Event Strings
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     // Properties
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         // calculate amount mouse has moved.
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         // see if mouse has moved far enough to start dragging operation
00184         return (deltaX > d_dragThreshold || deltaY > d_dragThreshold) ? true : false;
00185     }
00186 
00187     void DragContainer::initialiseDragging(void)
00188     {
00189         // only proceed if dragging is actually enabled
00190         if (d_draggingEnabled)
00191         {
00192             // initialise drag moving state
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             // Now drag mode is set, change cursor as required
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         // No rendering for this window
00222     }
00223 
00224     void DragContainer::onMouseButtonDown(MouseEventArgs& e)
00225     {
00226         Window::onMouseButtonDown(e);
00227 
00228         if (e.button == LeftButton)
00229         {
00230             // ensure all inputs come to us for now
00231             if (captureInput())
00232             {
00233                 // get position of mouse as co-ordinates local to this window.
00234                 Point localPos = (getMetricsMode() == Relative) ? 
00235                     relativeToAbsolute(screenToWindow(e.position)) :
00236                     screenToWindow(e.position);
00237 
00238                 // store drag point for possible sizing or moving operation.
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                 // fire off event
00257                 WindowEventArgs args(this);
00258                 onDragEnded(args);
00259             }
00260 
00261             // release our capture on the input data
00262             releaseInput();
00263             e.handled = true;
00264         }
00265     }
00266 
00267     void DragContainer::onMouseMove(MouseEventArgs& e)
00268     {
00269         Window::onMouseMove(e);
00270 
00271         // get position of mouse as co-ordinates local to this window.
00272         Point localMousePos = (getMetricsMode() == Relative) ? 
00273             relativeToAbsolute(screenToWindow(e.position)) :
00274             screenToWindow(e.position);
00275 
00276         // handle dragging
00277         if (d_dragging)
00278         {
00279             doDragging(localMousePos);
00280        }
00281         // not dragging
00282         else
00283         {
00284             // if mouse button is down (but we're not yet being dragged)
00285             if (d_leftMouseDown)
00286             {
00287                 if (isDraggingThresholdExceeded(localMousePos))
00288                 {
00289                     // Trigger the event
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         // reset state
00302         if (d_dragging)
00303         {
00304             // restore windows 'normal' state.
00305             d_dragging = false;
00306             setPosition(Absolute, d_startPosition);
00307             setClippedByParent(d_storedClipState);
00308             setAlpha(d_storedAlpha);
00309 
00310             // restore normal mouse cursor
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         // store new value and re-set dragging alpha as required.
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         // store new value and re-set clipping for drag as required.
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         // did we drop over a window?
00356         if (d_dropTarget)
00357         {
00358             // Notify that item was dropped in the target window
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             // this hack with the 'enabled' state is so that getChildAtPosition
00372             // returns something useful instead of a pointer back to 'this'.
00373             // This hack is only acceptable because I am CrazyEddie!
00374             bool wasEnabled = d_enabled;
00375             d_enabled = false;
00376             // find out which child of root window has the mouse in it
00377             Window* eventWindow = root->getChildAtPosition(MouseCursor::getSingleton().getPosition());
00378             d_enabled = wasEnabled;
00379 
00380             // use root itself if no child was hit
00381             if (!eventWindow)
00382             {
00383                 eventWindow = root;
00384             }
00385 
00386             // if the window with the mouse is different to current drop target
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         // abort current drag operation if dragging gets disabled part way through
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         // Notify old target that drop item has left
00435         if (d_dropTarget)
00436         {
00437             d_dropTarget->notifyDragDropItemLeaves(this);
00438         }
00439 
00440         // update to new target
00441         d_dropTarget = e.window;
00442 
00443         // Notify new target window that someone has dragged a DragContainer over it
00444         d_dropTarget->notifyDragDropItemEnters(this);
00445     }
00446 
00447 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:30 2005 for Crazy Eddies GUI System by  doxygen 1.4.3