DragManagerOp Class Reference

An instantiation of this class (created by a call to its static StartDrag method) is used to describe a current global drag. When the drag completes, this object will self destruct. While alive, this object controls the drag, passing relevant events on to registered drag targets, etc. See the documentation for a fuller description of the global drag system. More...

#include <dragmgr.h>

Inheritance diagram for DragManagerOp:

Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

virtual BOOL OnIdleEvent (void)
 To process idle events. If the mouse hasn't moved, then we'll allow low priority handlers a look-in. This means that (e.g.) when dragging background- redrawing galleries, we get instant response while dragging, and the background redraw will only occur while the mouse is held still.

Static Public Member Functions

static void StartDrag (DragInformation *Descriptor, CWindowID DragWindow)
 Starts a global-drag off This will create a new DragManagerOp object, set up the drag, and broadcast a DragMsg DRAGSTARTED, as a result of which, DragTargets should be created by interested parties (these will register with the Drag Manager, and then be called to handle events during the drag).
static void EndDrag (INT32 Flags)
 Input : Flags : mouse button state( 1=leftclick/-1= rightclick ).
static void AbortDrag (void)
 To forcibly abort the current drag. If there is no current drag, then nothing happens (so it can be called just to ensure that no drag is left current on exit for example).
static DragManagerOpGetCurrentManager (void)
 To find the current drag manager.
static BOOL GetStatusText (String_256 *StatusText)
 put status text in a buffer
static CaptureHandlerGetDragCaptureHandler ()
 return the capture handler
static DragInformationGetCurrentDragInfo ()
 return Current drag information
static wxPoint GetDragMousePos ()
 return a CPoint for the Last Mouse Position
static BOOL IsDragActive ()
static void SetDragActive (BOOL State)
static void RedrawStarting (void)
 Tell the drag manager that an external redraw has started. This allows it to remove its solid drag stuff so that the screen display is not screwed up. You should also call RedrawFinished when you finish redrawing.
static void RedrawStarting (CWindowID TheWindow, CGadgetID TheGadget, DocRect *TheArea=NULL)
 Tell the drag manager that an external redraw has started, within a specific window and gadget.
static void RedrawFinished (void)
 Tell the drag manager that an external redraw has finished.

Protected Member Functions

 DragManagerOp ()
 DragManagerOp constructor - DO NOT CALL THE DEFAULT CONSTRUCTOR!
 DragManagerOp (DragInformation *Descriptor)
 DragManagerOp constructor.
 ~DragManagerOp ()
 DragManagerOp destructor.
void RegisterTarget (DragTarget *NewTarget, BOOL HighPriority=FALSE)
 To register a Drag Target with the current Drag Manager This method is automatically called by DragTargets when they are constructed, and is only available to frined classes.
void DeregisterTarget (DragTarget *OldTarget)
 To register a Drag Target with the current Drag Manager This method is automatically called by DragTargets when they are constructed, and is only available to frined classes.

Static Protected Member Functions

static void SetCursor ()
 Set the cursor !
static void SetStatusLineText ()
 Write Status line help.

Private Member Functions

BOOL ProcessEvent (DragEventType Event)
 To process global drag events This method calls each DragTarget event processor in turn (until one claims the event), with the event. The 3 'Current' member variables are passed in to the event processor, so ensure they are set up appropriately before calling this method.
void CleanUpAfterDrag (void)
 Generic clean-up method. Deletes all registered DragTargets, and any other information (DragInformation, last keypress info, etc) which is still lying about in the DragManagerOp. Also deregisters our idle event handlers etc. Used by destructor, and also by all forms of Drag completion to free our memory claims, etc.

Private Attributes

UINT32 CurrentID
CursorCurrentCursor
List Targets
KeyPressCurrentKeypress
wxPoint InitialMousePos
wxPoint CurrentMousePos
wxPoint LastMousePos
DragEventType LastEvent

Static Private Attributes

static DragManagerOpCurrentManager = NULL
static DragInformationCurrentDragInfo = NULL
static DragTargetCurrentDragTarget = NULL
static UINT32 StatusLineStringID = 0
static CaptureHandlerTheCaptureHandler = NULL
static BOOL DragPending = FALSE
static BOOL DragEnded = FALSE
static MonotonicTime DragStartTimer
static UINT32 DragMinDist = DEFAULT_DRAGDIST
static UINT32 DragDelay = DEFAULT_DRAGDELAY
static wxRect DragStartRect
static wxRect StillClickRect
static BOOL DragActive = FALSE
static BOOL RedrawInProgress = FALSE

Friends

class DragTarget
class KernelDragTarget
class OilDragTarget
class CaptureHandler
class DragInformation

Detailed Description

An instantiation of this class (created by a call to its static StartDrag method) is used to describe a current global drag. When the drag completes, this object will self destruct. While alive, this object controls the drag, passing relevant events on to registered drag targets, etc. See the documentation for a fuller description of the global drag system.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/1/95
See also:
DragManagerOp::StartDrag; DragTarget; DragInformation
Documentation: Docs.doc

Definition at line 186 of file dragmgr.h.


Constructor & Destructor Documentation

DragManagerOp::DragManagerOp  )  [protected]
 

DragManagerOp constructor - DO NOT CALL THE DEFAULT CONSTRUCTOR!

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 927 of file dragmgr.cpp.

00928 {
00929     ERROR3("DragManagerOp::DragManagerOp - Illegal (default) constructor called!\n");
00930 
00931     ERROR3IF(CurrentManager != NULL, "Attempt to start a drag while already dragging!");
00932     CurrentManager = this;
00933 
00934     CurrentID = 0;
00935     CurrentCursor = NULL;
00936 }

DragManagerOp::DragManagerOp DragInformation Descriptor  )  [protected]
 

DragManagerOp constructor.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Parameters:
Descriptor - Describes the current drag. May not be NULL. [INPUTS]

Definition at line 953 of file dragmgr.cpp.

00954 {
00955     ERROR3IF(Descriptor == NULL, "DragManagerOp must be given a valid DragInformation ptr");
00956     ERROR3IF(CurrentManager != NULL, "Attempt to start a drag while already dragging!");
00957 
00958     AbortDrag();
00959     CurrentManager  = this;
00960     CurrentDragInfo = Descriptor;
00961 
00962     CurrentKeypress = NULL;
00963     
00964     DragEnded = FALSE;
00965 
00966     CurrentID = 0;
00967     CurrentCursor = NULL;
00968 
00969     // get system drag start values. We override the default values suggested by the
00970     // OLE2 docs, because their values are stupid. (2 pixels? Bleedin' heck! I wish MY
00971     // mouse was that steady!). However, we red the values from Win.INI like good boys, so
00972     // the user can override them if they so desire.
00973 //  DragMinDist = GetProfileInt("windows", "DragMinDist", DEFAULT_DRAGDIST);
00974 //  DragDelay = GetProfileInt("windows", "DragDelay", DEFAULT_DRAGDELAY);
00975 
00976     DragMinDist = DEFAULT_DRAGDIST;
00977     DragDelay = DEFAULT_DRAGDELAY;
00978 
00979     DragStartRect = wxRect();
00980 }

DragManagerOp::~DragManagerOp  )  [protected]
 

DragManagerOp destructor.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 995 of file dragmgr.cpp.

00996 {
00997     // Ensure all memory allocations are deleted
00998     CleanUpAfterDrag();
00999 
01000     // We are no longer the current drag manager
01001     CurrentManager = NULL;
01002 
01003     DragActive = FALSE;
01004 
01005     StatusLineStringID = 0; 
01006 
01007     if (CurrentCursor)
01008         delete CurrentCursor;
01009 }


Member Function Documentation

void DragManagerOp::AbortDrag void   )  [static]
 

To forcibly abort the current drag. If there is no current drag, then nothing happens (so it can be called just to ensure that no drag is left current on exit for example).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 1248 of file dragmgr.cpp.

01249 {
01250     if (CurrentManager != NULL)
01251     {
01252         CurrentManager->LastMousePos = CurrentManager->CurrentMousePos;
01253         CurrentManager->CurrentMousePos = wxGetMousePosition();
01254 
01255         if (TheCaptureHandler != NULL)
01256             TheCaptureHandler->CleanUpSolidDrag();
01257 
01258         CurrentManager->ProcessEvent(DRAGEVENT_ABORT);
01259 
01260         // Let all drag targets know that the drag is well and truly dead
01261         CurrentManager->ProcessEvent(DRAGEVENT_DEINITIALISE);
01262 
01263         CurrentManager->End();
01264     }
01265 
01266     SetDragActive(FALSE);   
01267 }

void DragManagerOp::CleanUpAfterDrag void   )  [private]
 

Generic clean-up method. Deletes all registered DragTargets, and any other information (DragInformation, last keypress info, etc) which is still lying about in the DragManagerOp. Also deregisters our idle event handlers etc. Used by destructor, and also by all forms of Drag completion to free our memory claims, etc.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Scope: private

Definition at line 1747 of file dragmgr.cpp.

01748 {
01749     TRACEUSER("Gerry", _T("DragManagerOp::CleanUpAfterDrag"));
01750 
01751     GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
01752 
01753     if (TheCaptureHandler != NULL)
01754     {
01755         TRACEUSER("Gerry", _T("Deleting TheCaptureHandler"));
01756         // Simply delete the CaptureHandler and it will detach itself
01757         delete TheCaptureHandler;
01758         TheCaptureHandler = NULL;
01759     }
01760 
01761     if (CurrentDragInfo != NULL)
01762     {
01763         delete CurrentDragInfo;
01764         CurrentDragInfo = NULL;
01765     }
01766 
01767     if (CurrentKeypress != NULL)
01768     {
01769         delete CurrentKeypress;
01770         CurrentKeypress = NULL;
01771     }
01772 
01773     // Delete all entries from the list. We do it this way to ensure that we don't try
01774     // to destruct the same target multiple times if it registered multiple times
01775     while (!Targets.IsEmpty())
01776         DeregisterTarget((DragTarget *) Targets.GetHead());
01777 }

void DragManagerOp::DeregisterTarget DragTarget OldTarget  )  [protected]
 

To register a Drag Target with the current Drag Manager This method is automatically called by DragTargets when they are constructed, and is only available to frined classes.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Parameters:
OldTarget - points at the DragTarget object to remove [INPUTS]
Notes: Copes with a drag target being registered several times.

Scope: protected (for friend class DragTarget only)

Definition at line 1708 of file dragmgr.cpp.

01709 {
01710     DragTarget *Ptr = (DragTarget *) Targets.GetHead();
01711     DragTarget *Next;
01712 
01713     while (Ptr != NULL)
01714     {
01715         Next = (DragTarget *) Targets.GetNext(Ptr);
01716 
01717         if (Ptr == OldTarget)
01718         {
01719             Targets.RemoveItem(Ptr);
01720             delete Ptr;
01721         }
01722 
01723         Ptr = Next;
01724     }
01725 }

void DragManagerOp::EndDrag INT32  Flags  )  [static]
 

Input : Flags : mouse button state( 1=leftclick/-1= rightclick ).

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 1190 of file dragmgr.cpp.

01191 {
01192     if(!CurrentManager)
01193         return;
01194 
01195     // clean up
01196     if (TheCaptureHandler != NULL)
01197     {
01198         TheCaptureHandler->CleanUpSolidDrag();
01199     }
01200 
01201     if(DragPending)      // not a drag - user intended a click
01202     {
01203         // call the click handler in the drag
01204         wxPoint StartMouse;
01205         StartMouse.x = CurrentManager->InitialMousePos.x;
01206         StartMouse.y = CurrentManager->InitialMousePos.y;
01207         CurrentManager->CurrentDragInfo->OnClick(Flags,StartMouse);
01208     }
01209     else                // this is a genuine end of drag
01210     {
01211         // Update the mouse position, so we give the event to the correct target
01212         CurrentManager->LastMousePos = CurrentManager->CurrentMousePos;
01213         CurrentManager->CurrentMousePos = wxGetMousePosition();
01214 
01215         // Process the drag completion event
01216         DragEventType Event = DRAGEVENT_COMPLETED;
01217         CurrentManager->ProcessEvent(Event);
01218 
01219         // make sure we don't get any idles after the drag has finished
01220         DragEnded = TRUE;
01221     }
01222 
01223     // Let all drag targets know that the drag is well and truly dead
01224     if (CurrentManager)
01225         CurrentManager->ProcessEvent(DRAGEVENT_DEINITIALISE);
01226 
01227     SetDragActive(FALSE);
01228 
01229     // end this op
01230     if (CurrentManager)
01231         CurrentManager->End();
01232 }

DragInformation * DragManagerOp::GetCurrentDragInfo  )  [static]
 

return Current drag information

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 1064 of file dragmgr.cpp.

01065 {
01066     if( CurrentManager == NULL )
01067         return NULL;
01068     
01069     return CurrentDragInfo;
01070 
01071 }

DragManagerOp * DragManagerOp::GetCurrentManager void   )  [static]
 

To find the current drag manager.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Returns:
NULL (if no current drag), or a pointer to the current DragManagerOp

Definition at line 1284 of file dragmgr.cpp.

01285 {
01286     return(CurrentManager);
01287 }

CaptureHandler * DragManagerOp::GetDragCaptureHandler  )  [static]
 

return the capture handler

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 1045 of file dragmgr.cpp.

01046 {
01047     if( CurrentManager == NULL )
01048         return NULL;
01049     
01050     return TheCaptureHandler;
01051 }

wxPoint DragManagerOp::GetDragMousePos  )  [static]
 

return a CPoint for the Last Mouse Position

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95

Definition at line 1024 of file dragmgr.cpp.

01025 {
01026     wxPoint MPos(0,0);
01027     
01028     if( CurrentManager != NULL )
01029         MPos = CurrentManager->CurrentMousePos;
01030     return MPos;
01031 }

BOOL DragManagerOp::GetStatusText String_256 StatusText  )  [static]
 

put status text in a buffer

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/11/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the buffer is valid FALSE otherwise

Errors: -

See also:
-

Definition at line 1870 of file dragmgr.cpp.

01871 {
01872     ERROR2IF(StatusText==NULL,FALSE,"DragManagerOp::GetStatusLineText() - StatusText==NULL!");
01873 
01874     String_256 Text;
01875     if(CurrentDragTarget)
01876     {
01877         if(CurrentDragInfo->GetStatusLineText(&Text))
01878             * StatusText = Text;
01879         else
01880             return FALSE;
01881     }
01882     else
01883     {
01884         if(CurrentDragTarget->GetStatusLineText(&Text))
01885            * StatusText = Text;
01886         else
01887             return FALSE;
01888     }
01889         
01890     return TRUE; 
01891 
01892 }

static BOOL DragManagerOp::IsDragActive  )  [inline, static]
 

Definition at line 224 of file dragmgr.h.

00224 {return DragActive;}

BOOL DragManagerOp::OnIdleEvent void   )  [virtual]
 

To process idle events. If the mouse hasn't moved, then we'll allow low priority handlers a look-in. This means that (e.g.) when dragging background- redrawing galleries, we get instant response while dragging, and the background redraw will only occur while the mouse is held still.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> & Chris
Date:
9/1/95
Returns:
TRUE if it does not want low-priority idle handlers to be called this time FALSE if it's OK to call low-priority idles (i.e. if I'm not busy this turn)

Reimplemented from Operation.

Definition at line 1551 of file dragmgr.cpp.

01552 {
01553     LastMousePos = CurrentMousePos;
01554     CurrentMousePos = wxGetMousePosition();
01555 
01556     if(DragEnded)
01557         return(FALSE);  // Done nothing, so let low-priority handlers have a go
01558 
01559     BOOL JustStartedDrag = FALSE;
01560 
01561     // We have received a start drag message but we are not sure whether this is the real 
01562     // thing yet.
01563     if (DragPending)
01564     {
01565         // We start a drag if DragDelay milliseconds have elapsed
01566         // or the pointer has left DragStartRect
01567         if (!DragStartTimer.Elapsed(DragDelay) &&
01568             StillClickRect.Inside(CurrentMousePos))
01569         {
01570             // The drag is still pending
01571             return(FALSE);  // Done nothing, so let low-priority handlers have a go
01572         }
01573 
01574         DragPending = FALSE;
01575         JustStartedDrag = TRUE; // Flag that we have "just turned on" the drag
01576 
01577         TheCaptureHandler->SetUpSolidDrag(CurrentMousePos);
01578     }
01579 
01580     // Determine what event type to send around...
01581     DragEventType Event = DRAGEVENT_MOUSEIDLE;
01582     if (LastMousePos == CurrentMousePos)
01583     {
01584         if (LastEvent == DRAGEVENT_MOUSESTOPPED || LastEvent == DRAGEVENT_MOUSEIDLE)
01585         {
01586             // The mouse has not moved for a while, so send another idle
01587             Event = DRAGEVENT_MOUSEIDLE;
01588         }
01589         else
01590         {
01591             // The mouse has only just stopped moving, so send a mouse-stopped
01592             Event = DRAGEVENT_MOUSESTOPPED;
01593         }
01594     }
01595     else
01596     {
01597         // The mouse has moved since we last checked, so send a mouse-moved
01598         Event = DRAGEVENT_MOUSEMOVED;
01599     }
01600 
01601     // If the mouse moved, then we will not allow low-priority idle processors to have a go
01602     // this time around, for maximum mouse-move interactiveness.
01603     BOOL ClaimTheIdle = (Event == DRAGEVENT_MOUSEMOVED);
01604 
01605 // **** !!!! ToDo: This could be considered bodgy and nasty, mostly because it is.
01606 
01607 // ToDo: Somehow detect if the drag has ended? A bodge I know, but we wanna compile
01608 // this and see if it works!
01609 
01610 if (KeyPress::IsEscapePressed())    // If escape (or equivalent) pressed, abort the drag
01611 {
01612     AbortDrag();
01613     return(FALSE);  // Let low-priority handlers have a go
01614 }
01615 
01616 // **** 
01617 
01618     ProcessEvent(Event);    // Pass the event around all registered DragTargets
01619 
01620 #if FALSE
01621 /* On the first update, the mouse may not have moved, so we need to pop up the
01622    solid drag stuff. Unfortunately, this doesn't work quite right and I don't
01623    have time to deal with it right now.
01624 
01625     if (!DragEnded && JustStartedDrag)
01626     {
01627         // The mouse may not have moved, but we have just 'turned on' the drag - we'd
01628         // better ensure that the solid drag stuff is drawn onto screen for the fist time
01629 
01630         if (TheCaptureWindow != NULL)
01631         {
01632             CPoint PointInCaptureWnd(CurrentMousePos);
01633 
01634             // Convert the current mouse coordinate into capture window client coords,
01635             // and call it to update the solid drag
01636             TheCaptureWindow->ScreenToClient(&PointInCaptureWnd);
01637             TheCaptureWindow->DrawSolidDrag(PointInCaptureWnd);
01638         }
01639     }
01640 */
01641 #endif
01642 
01643     return(ClaimTheIdle);   // Return, allowing or not-allowing low-priority handlers to have a go
01644                             // depending on whether the mouse moved or not.
01645 }

BOOL DragManagerOp::ProcessEvent DragEventType  Event  )  [private]
 

To process global drag events This method calls each DragTarget event processor in turn (until one claims the event), with the event. The 3 'Current' member variables are passed in to the event processor, so ensure they are set up appropriately before calling this method.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Parameters:
Event - Indicates what type of Drag Event is occurring [INPUTS]
Returns:
TRUE if a DragTarget claimed the event
Notes: DragTargets can safely de-register themselves during processing of the events (i.e. the list traversal code won't get upset)

When calling a kernel target which includes both a dialogue ID and a gadget, the coordinates passed into the event handler are millipoint offsets from the bottom left corner of the gadget, just as with normal kernel-rendered gadgets. Note that the event will not be passed to the gadget unless the mouse pointer is over the gadget window. If no gadget is specified, then the mouse coordinates will always be (0,0) at present.

The INITIALISE and DEINITIALISE events are broadcast to all active targets, while all other events are broadcast only to general (no target window) targets, and the target (if any) over which the mouse pointer lies.

See also:
keyword DragEventType

DragTarget::ProcessEvent

Definition at line 1327 of file dragmgr.cpp.

01328 {
01329     BOOL BroadcastToAll = FALSE;        // Determine if the event goes to everybody or
01330                                     // only to target under the pointer
01331     if (Event == DRAGEVENT_INITIALISE || Event == DRAGEVENT_DEINITIALISE)
01332         BroadcastToAll = TRUE;
01333 
01334     if(CurrentManager == NULL || (DragEnded && Event != DRAGEVENT_DEINITIALISE))
01335         return FALSE;
01336 
01337     LastEvent = Event;          // Remember the type of the last event we processed
01338     
01339     DragTarget *Ptr  = (DragTarget *) Targets.GetHead();
01340     DragTarget *Next;
01341 
01342     OilCoord KernelMousePos(0,0);
01343     wxPoint   WinoilMousePos(CurrentMousePos);
01344     CurrentDragTarget = NULL;
01345     BOOL OverTarget = FALSE;
01346 
01347 //  TRACEUSER("Gerry", _T("ProcessEvent = (%d, %d)"), WinoilMousePos.x, WinoilMousePos.y);
01348 
01349     while (Ptr != NULL)
01350     {
01351         // Copy the mouse position, as each iteration of the loop corrupts it
01352         WinoilMousePos = CurrentMousePos;
01353 
01354         // Allow things like targets de-registering during processing
01355         Next = (DragTarget *) Targets.GetNext(Ptr);
01356         BOOL GoAhead = TRUE;
01357         
01358         if (Ptr->IsAKernelObject())
01359         {
01360             KernelMousePos = OilCoord(0,0);
01361 
01362             DialogOp  *pDialogOp;
01363             CGadgetID GadgetID;
01364             Ptr->GetTargetAreaInfo(&pDialogOp, &GadgetID);
01365 
01366             if (pDialogOp != NULL)
01367             {
01368                 wxWindow* TargetWindow = (wxWindow*)pDialogOp->WindowID;    // use whole window if no gadget specified
01369 
01370                 if (GadgetID != 0)
01371                     TargetWindow = TargetWindow->FindWindow((INT32)GadgetID);
01372 
01373                 // We want to do the following. But it doesn't work because GetRect() is relative to the
01374                 // parent window when TargetWindow is not a TLW. What we need is (consistently) screen
01375                 // coordinates
01376 
01377 //              TRACEUSER("Gerry", _T("KernelTargetWindow = %s"), TargetWindow->GetClassInfo()->GetClassName());
01378                 wxRect TargetRect = TargetWindow->GetRect();
01379 //              TRACEUSER("Gerry", _T("TargetRect = (%d, %d) [%d, %d]"), TargetRect.x, TargetRect.y, TargetRect.width, TargetRect.height);
01380                 if (TargetWindow->GetParent() && !TargetWindow->IsTopLevel())
01381                 {
01382                     TargetWindow->GetParent()->ClientToScreen(&TargetRect.x, &TargetRect.y);
01383 //                  TRACEUSER("Gerry", _T("TargetRect = (%d, %d) [%d, %d]"), TargetRect.x, TargetRect.y, TargetRect.width, TargetRect.height);
01384                 }
01385 
01386 //              TRACEUSER("Gerry", _T("Point is %sinside"), TargetRect.Inside(WinoilMousePos) ? _T("") : _T("not "));
01387 
01388                 if (BroadcastToAll || Ptr->WantsAllEvents() ||
01389                     TargetRect.Inside(WinoilMousePos))
01390                 {
01391                     // Determine if the pointer is over the target window, or any of its children
01392                     wxWindow* WindowUnderPoint = wxChildWindowFromPoint(WinoilMousePos, false, -1);
01393                     BOOL AreOverTargetWnd = (WindowUnderPoint == TargetWindow);
01394                     
01395                     if (!AreOverTargetWnd)
01396                     {
01397                         // We're not immediately over the background of the window, but may be over
01398                         // a child-window of our window! The subtlety here is that wxChildWindowFromPoint may have
01399                         // failed because another window is on top (in the way). So we also check the child window
01400                         // of the target window which is under the mousepointer is also the window which is
01401                         // under the mouse pointner
01402                         wxWindow* ChildWindowUnderPoint = ::wxChildWindowFromPoint(TargetWindow, WinoilMousePos, false, -1);
01403                         AreOverTargetWnd = (ChildWindowUnderPoint != NULL &&
01404                                                 ChildWindowUnderPoint == WindowUnderPoint);
01405                     }
01406 
01407                     if (BroadcastToAll || Ptr->WantsAllEvents() || AreOverTargetWnd)
01408                     {
01409                         wxScreenDC dc;
01410                         wxSize ppi = OSRenderRegion::GetFixedDCPPI(dc);
01411 
01412                         KernelMousePos.x = ((WinoilMousePos.x - TargetRect.GetLeft()) * 72000) / ppi.GetWidth();
01413 // CHECKRECT: This may need to be the exclusive bottom coord
01414                         KernelMousePos.y = ((TargetRect.GetBottom() - WinoilMousePos.y) * 72000) / ppi.GetHeight();
01415                     }
01416                     else
01417                         GoAhead = FALSE;
01418                 }
01419                 else
01420                     GoAhead = FALSE;
01421             }
01422 
01423 //          TRACEUSER("Gerry", _T("%s"), GoAhead ? _T("Process") : _T("Skipping"));
01424 
01425             if (GoAhead &&
01426                 Ptr->ProcessEvent(Event, CurrentDragInfo, &KernelMousePos, CurrentKeypress))
01427             {
01428                 CurrentDragTarget = Ptr;
01429                 OverTarget = TRUE;  // This Target claimed the event, so return TRUE
01430 
01431                 if (!BroadcastToAll)
01432                     break;
01433             }
01434         }
01435         else
01436         {
01437             wxWindow* TargetWindow;
01438             wxRect TargetRect;
01439             Ptr->GetTargetAreaInfo(&TargetWindow, &TargetRect);
01440 #if FALSE
01441             if (TargetWindow)
01442             {
01443                 TRACEUSER("Gerry", _T("OilTargetWindow = %s"), TargetWindow->GetClassInfo()->GetClassName());
01444                 TRACEUSER("Gerry", _T("TargetRect = (%d, %d) [%d, %d]"), TargetRect.x, TargetRect.y, TargetRect.width, TargetRect.height);
01445             }
01446             else
01447             {
01448                 TRACEUSER("Gerry", _T("OilTargetWindow = <NONE>"));
01449             }
01450 #endif
01451             wxPoint ClientPoint;                    // This will be screen coords, or will end up as 
01452             ClientPoint.x = WinoilMousePos.x;   // client coords if we have a window... 
01453             ClientPoint.y = WinoilMousePos.y;
01454 
01455             if (TargetWindow != NULL)
01456             {
01457                 // Get the mouse position in client coords
01458                 ClientPoint = TargetWindow->ScreenToClient(ClientPoint);
01459 
01460                 // Don't bother giving the event to targets which don't contain the pointer
01461                 if (BroadcastToAll || Ptr->WantsAllEvents() ||
01462                     TargetRect.Inside(ClientPoint))
01463                 {
01464                     // Don't give the event to oil targets unless the pointer is over the
01465                     // window (ie dont pass on events to overlapped windows) unless we want
01466                     // to broadcast to all, or this target really wants to know!
01467 
01468                     wxWindow* WindowUnderPoint = ::wxChildWindowFromPoint(WinoilMousePos, false, -1);
01469 //                  TRACEUSER("Gerry", _T("WindowUnderPoint = 0x%08x (%s)"), WindowUnderPoint, WindowUnderPoint ? WindowUnderPoint->GetClassInfo()->GetClassName() : _T("null"));
01470                     if (WindowUnderPoint)
01471                     {
01472 //                      TRACEUSER("Gerry", _T("Title = %s"), WindowUnderPoint->GetTitle().c_str());
01473                     }
01474 
01475                     BOOL AreOverTargetWnd = (WindowUnderPoint == TargetWindow);
01476 //                  TRACEUSER("Gerry", _T("Point is %sover target window"), AreOverTargetWnd ? _T("") : _T("not "));
01477 
01478                     if (!AreOverTargetWnd)
01479                     {
01480                         // We're not immediately over the background of the window, but may be over
01481                         // a child-window of our window! The subtlety here is that wxChildWindowFromPoint may have
01482                         // failed because another window is on top (in the way). So we also check the child window
01483                         // of the target window which is under the mousepointer is also the window which is
01484                         // under the mouse pointner
01485                         wxWindow* ChildWindowUnderPoint = ::wxChildWindowFromPoint(TargetWindow, WinoilMousePos, false, -1);
01486 //                      TRACEUSER("Gerry", _T("ChildFromPoint = 0x%08x (%s)"), ChildWindowUnderPoint, ChildWindowUnderPoint ? ChildWindowUnderPoint->GetClassInfo()->GetClassName() : _T("null"));
01487                         AreOverTargetWnd = (ChildWindowUnderPoint != NULL &&
01488                                                 ChildWindowUnderPoint == WindowUnderPoint);
01489 
01490 //                      TRACEUSER("Gerry", _T("Point is %sover child of target window"), AreOverTargetWnd ? _T("") : _T("not "));
01491                     }
01492 
01493                     if (!BroadcastToAll && !Ptr->WantsAllEvents() && !AreOverTargetWnd)
01494                     {
01495                         GoAhead = FALSE;
01496                     }
01497                 }
01498                 else
01499                     GoAhead = FALSE;
01500             }
01501 
01502 //          TRACEUSER("Gerry", _T("%s"), GoAhead ? _T("Process") : _T("Skipping"));
01503 
01504             // we are in a target area, or this is a broadcast-to-all, so send the event
01505             if (GoAhead)
01506             {
01507                 wxPoint PointInWindow(ClientPoint); // "Cast" to wxPoint
01508 
01509                 if (Ptr->ProcessEvent(Event, CurrentDragInfo, &PointInWindow, CurrentKeypress))
01510                 {
01511                     CurrentDragTarget = Ptr;
01512                     OverTarget = TRUE;  // This Target claimed the event, so return TRUE
01513 
01514                     if (!BroadcastToAll)
01515                         break;
01516                 }
01517             }
01518         }
01519 
01520         Ptr = Next;
01521     }
01522 
01523     if (!DragPending && Event != DRAGEVENT_COMPLETED)
01524     { 
01525         SetStatusLineText();
01526         SetCursor();
01527     }   
01528 
01529     return OverTarget;  // Return status to indicate wheteher or not the event was claimed
01530 }

void DragManagerOp::RedrawFinished void   )  [static]
 

Tell the drag manager that an external redraw has finished.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/3/95
Returns:
-

Definition at line 2028 of file dragmgr.cpp.

void DragManagerOp::RedrawStarting CWindowID  TheWindow,
CGadgetID  TheGadget,
DocRect TheArea = NULL
[static]
 

Tell the drag manager that an external redraw has started, within a specific window and gadget.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/5/95
Parameters:
TheWindow - The CWindowID of your DialogOp [INPUTS] TheGadget - The Gadget ID of the gadget being redrawn TheArea - A kernel-rendered dialogue rectangle (MILLIPOINTS) which is being redrawn. If NULL, the entire gadget is assumed. NOTE that this is clipped within the gadget bounds, so may be outside the 'visible area' of the gadget
Returns:
-
This allows it to remove its solid drag stuff so that the screen display is not screwed up. You should also call RedrawFinished when you finish redrawing

This call specifies a particular gadget that is redrawing - if this doesn't overlap the solid drag area, then nothing will be done - this will reduce flicker if you're background redrawing while a drag is going on.

See also:
DragManagerOp::RedrawFinished()

Definition at line 1961 of file dragmgr.cpp.

01962 {
01963     if (RedrawInProgress)
01964         return;
01965 
01966     if (DragManagerOp::CurrentManager &&
01967         DragManagerOp::CurrentManager->CurrentDragInfo &&
01968         DragManagerOp::CurrentManager->CurrentDragInfo->DoesSolidDrag)
01969     {
01970         wxWindow* pWindow = (wxWindow*)TheWindow;
01971         wxWindow* pGadget = pWindow->FindWindow((INT32)TheGadget);
01972         if (pGadget != NULL)
01973         {
01974             wxRect AreaClientRect;
01975             wxRect ClientRect;
01976             if (TheArea != NULL)
01977             {
01978                 ReDrawInfoType DlgInfo;
01979                 DialogManager::GetKernelRenderedGadgetInfo(TheWindow, TheGadget, &DlgInfo);
01980 
01981                 INT32 PixelSize = 72000 / DlgInfo.Dpi;      // Size of a pixel in MILLIPOINTS
01982                 AreaClientRect.x        = TheArea->lo.x / PixelSize;
01983                 AreaClientRect.y        = TheArea->hi.x / PixelSize;
01984                 AreaClientRect.width    = TheArea->Width() / PixelSize;
01985                 AreaClientRect.height   = TheArea->Height() / PixelSize;
01986             }
01987             else
01988                 AreaClientRect = pGadget->GetClientRect();
01989 
01990             ClientRect = pGadget->GetClientRect();
01991 
01992             wxRect ScreenRect(ClientRect);
01993 
01994             // Get the intersection of the rects (clip the redrawing area within the window)
01995             if (!ScreenRect.Intersect(AreaClientRect).IsEmpty())
01996             {
01997                 // Convert the client coordinates to screen coords, and tell the drag capture window
01998                 // to get it's solid drag stuff out of the way
01999                 pGadget->ClientToScreen(&ScreenRect.x, &ScreenRect.y);
02000 
02001                 RedrawInProgress = DragManagerOp::CurrentManager->TheCaptureHandler->
02002                                                     CleanUpSolidDragInScreenArea(ScreenRect);
02003             }
02004             else
02005                 RedrawInProgress = FALSE;
02006         }
02007         else
02008         {
02009             // We failed to get the window area, so we'll have to clean up just in case
02010             DragManagerOp::CurrentManager->TheCaptureHandler->CleanUpSolidDrag();
02011             RedrawInProgress = TRUE;
02012         }
02013     }   
02014 }

void DragManagerOp::RedrawStarting void   )  [static]
 

Tell the drag manager that an external redraw has started. This allows it to remove its solid drag stuff so that the screen display is not screwed up. You should also call RedrawFinished when you finish redrawing.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/3/95
Returns:
-
Notes: If you are redrawing in a particular window & gadget, see the other variant of this method, which will reduce solid-drag flicker.

See also:
DragManagerOp::RedrawFinished()

Definition at line 1914 of file dragmgr.cpp.

01915 {
01916     if (RedrawInProgress)
01917         return;
01918 
01919     RedrawInProgress = TRUE;
01920 
01921     if (DragManagerOp::CurrentManager &&
01922         DragManagerOp::CurrentManager->CurrentDragInfo &&
01923         DragManagerOp::CurrentManager->CurrentDragInfo->DoesSolidDrag)
01924     {
01925         DragManagerOp::CurrentManager->TheCaptureHandler->CleanUpSolidDrag();
01926     }
01927 }

void DragManagerOp::RegisterTarget DragTarget NewTarget,
BOOL  HighPriority = FALSE
[protected]
 

To register a Drag Target with the current Drag Manager This method is automatically called by DragTargets when they are constructed, and is only available to frined classes.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Parameters:
NewTarget - points at the DragTarget object to add. NOTE that from this [INPUTS] time on, the manager owns the target, and it will delete it when the drag completes. However, the caller may delete the target at any time, in which case it will automatically deregister itself before it dies.
HighPriority - TRUE to place the target on the front of the target list, FALSE to place it on the end. (Targets are called in list order to handle events, so one on the front of the list has higher priority...)

Notes: A drag target object can be registered several times, in which case it will be placed on the list several times. Not that this should happen...

Scope: protected (for friend class DragTarget only)

Definition at line 1676 of file dragmgr.cpp.

01677 {
01678     ERROR3IF(NewTarget == NULL,
01679                 "DragManagerOp::RegisterTarget - NULL Target parameter is illegal");
01680 
01681     if (HighPriority)
01682         Targets.AddHead(NewTarget);
01683     else
01684         Targets.AddTail(NewTarget);
01685 }

void DragManagerOp::SetCursor  )  [static, protected]
 

Set the cursor !

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/1/95
Returns:
-

Definition at line 1792 of file dragmgr.cpp.

01793 {
01794     UINT32 CursorID;
01795 
01796     // are we over a target ??
01797     if(CurrentDragTarget== NULL)
01798       CursorID = CurrentDragInfo->GetCursorID();    // nope
01799     else
01800       CursorID = CurrentDragTarget->GetCursorID();  // yep
01801     
01802     // the target does not want to change the cursor
01803     if(CursorID == 0)
01804         return;
01805     
01806     if(CurrentManager->CurrentID != CursorID)                       // nothing to change
01807     {
01808         if(CurrentManager->CurrentCursor)                           // delete the old
01809         {
01810             delete CurrentManager->CurrentCursor;
01811             CurrentManager->CurrentCursor = NULL;
01812         }
01813         if(CurrentManager->CurrentCursor==NULL)
01814         {
01815             CurrentManager->CurrentCursor = new Cursor(CursorID);   // create the new
01816             if (CurrentManager->CurrentCursor)
01817                 CurrentManager->CurrentCursor->SetActive();         // make the active cursor
01818         }
01819         
01820         CurrentManager->CurrentID = CursorID;
01821     }
01822 }

static void DragManagerOp::SetDragActive BOOL  State  )  [inline, static]
 

Definition at line 226 of file dragmgr.h.

00226 {DragActive = State;}

void DragManagerOp::SetStatusLineText  )  [static, protected]
 

Write Status line help.

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/1/95
Returns:
-

Definition at line 1836 of file dragmgr.cpp.

01837 {
01838     String_256 StatusText;
01839     if(CurrentDragTarget==NULL) //we are not over a target
01840     {   // get the drag status text
01841         if(CurrentDragInfo)
01842             if(CurrentDragInfo->GetStatusLineText(&StatusText))
01843                 GetApplication()->UpdateStatusBarText(&StatusText,FALSE); 
01844     }
01845     else
01846     {   // get the target status text
01847         if(CurrentDragTarget->GetStatusLineText(&StatusText))
01848             GetApplication()->UpdateStatusBarText(&StatusText,FALSE); 
01849     }
01850             
01851 
01852 }

void DragManagerOp::StartDrag DragInformation Descriptor,
CWindowID  DragWindow
[static]
 

Starts a global-drag off This will create a new DragManagerOp object, set up the drag, and broadcast a DragMsg DRAGSTARTED, as a result of which, DragTargets should be created by interested parties (these will register with the Drag Manager, and then be called to handle events during the drag).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/1/95
Parameters:
Descriptor - A DragInformation object describing the current drag. [INPUTS] NOTE WELL that this is given to the DragManager, who is then responsible for deleting it when the drag completes. DO NOT DELETE IT! DragWindow - The window that is starting the drag. NOTE: For correct operation under wxGTK this must be the window that received the button down event that started this drag

Definition at line 1097 of file dragmgr.cpp.

01098 {
01099     if (Descriptor == NULL)
01100     {
01101         // Handle a NULL pointer by just not starting up the drag
01102         TRACE( _T("NULL Descriptor given to DragManagerOp::StartDrag()\n"));
01103         return;
01104     }
01105 
01106     ERROR3IF(Descriptor == NULL, "DragManagerOp must be given a valid DragInformation ptr");
01107 
01108     DragManagerOp* pNewManager = new DragManagerOp(Descriptor);
01109 
01110     if (Descriptor->IsAdjustDrag)       // Adjust drags just immediately become clicks
01111     {
01112         DragPending = TRUE;             // Make sure it turns into a click properly (see EndDrag)
01113         if (pNewManager != NULL)
01114         {
01115             pNewManager->CurrentMousePos = wxGetMousePosition();
01116             pNewManager->InitialMousePos = pNewManager->LastMousePos = pNewManager->CurrentMousePos;
01117 
01118             EndDrag(-1);
01119         }
01120         return;
01121     }
01122 
01123     if (pNewManager != NULL)
01124     {
01125         // Attach the CaptureHandler to the correct window
01126         wxWindow* pWindow = (wxWindow*)DragWindow;
01127         if (pWindow == NULL)
01128             pWindow = GetMainFrame();
01129 
01130         TheCaptureHandler = new CaptureHandler(pWindow);
01131         if (TheCaptureHandler != NULL)
01132         {
01133             DragPending = TRUE;
01134             
01135             // Remember where the mouse is at the start of the drag
01136             pNewManager->CurrentMousePos = wxGetMousePosition();
01137             pNewManager->InitialMousePos = pNewManager->LastMousePos = pNewManager->CurrentMousePos;
01138 
01139             // Request that all interested parties attach DragTargets now
01140             BROADCAST_TO_ALL(DragMessage(DragMessage::DRAGSTARTED, pNewManager, Descriptor));
01141 
01142             // views don't receive messages so we'll have to do this the hard way..
01143             // App->Document->View... 
01144             GetApplication()->CreateDragTargets(Descriptor);
01145 
01146             // Send an Initialise event to all registered targets
01147 
01148             // Forget this - drags with no targets are perfectly legal - see colour picker
01149 #if 0
01150 #ifdef _DEBUG
01151             if (pNewManager->Targets.IsEmpty())
01152                 TRACE( _T("DragManagerOp::StartDrag - No drag targets specified for this drag!"));
01153 #endif
01154 #endif
01155             pNewManager->ProcessEvent(DRAGEVENT_INITIALISE);        
01156 
01157             // Start the mouse capture
01158             TheCaptureHandler->StartCapture();
01159 
01160             // Register for idle events
01161             GetApplication()->RegisterIdleProcessor(IDLEPRIORITY_HIGH, pNewManager);
01162 
01163             // get drag start time
01164             DragStartTimer.Sample();
01165 
01166             // we will use this rect to test whether we have started a drag
01167             StillClickRect = wxRect( pNewManager->InitialMousePos.x - DragMinDist,
01168                                     pNewManager->InitialMousePos.y - DragMinDist,
01169                                     DragMinDist * 2,
01170                                     DragMinDist * 2);
01171             SetDragActive(TRUE);
01172         }
01173     }
01174     GetMainFrame()->SetFocus();
01175 }


Friends And Related Function Documentation

friend class CaptureHandler [friend]
 

Definition at line 191 of file dragmgr.h.

friend class DragInformation [friend]
 

Definition at line 192 of file dragmgr.h.

friend class DragTarget [friend]
 

Definition at line 188 of file dragmgr.h.

friend class KernelDragTarget [friend]
 

Definition at line 189 of file dragmgr.h.

friend class OilDragTarget [friend]
 

Definition at line 190 of file dragmgr.h.


Member Data Documentation

Cursor* DragManagerOp::CurrentCursor [private]
 

Definition at line 270 of file dragmgr.h.

DragInformation * DragManagerOp::CurrentDragInfo = NULL [static, private]
 

Definition at line 263 of file dragmgr.h.

DragTarget * DragManagerOp::CurrentDragTarget = NULL [static, private]
 

Definition at line 265 of file dragmgr.h.

UINT32 DragManagerOp::CurrentID [private]
 

Definition at line 269 of file dragmgr.h.

KeyPress* DragManagerOp::CurrentKeypress [private]
 

Definition at line 274 of file dragmgr.h.

DragManagerOp * DragManagerOp::CurrentManager = NULL [static, private]
 

Definition at line 261 of file dragmgr.h.

wxPoint DragManagerOp::CurrentMousePos [private]
 

Definition at line 277 of file dragmgr.h.

BOOL DragManagerOp::DragActive = FALSE [static, private]
 

Definition at line 299 of file dragmgr.h.

UINT32 DragManagerOp::DragDelay = DEFAULT_DRAGDELAY [static, private]
 

Definition at line 292 of file dragmgr.h.

BOOL DragManagerOp::DragEnded = FALSE [static, private]
 

Definition at line 286 of file dragmgr.h.

UINT32 DragManagerOp::DragMinDist = DEFAULT_DRAGDIST [static, private]
 

Definition at line 290 of file dragmgr.h.

BOOL DragManagerOp::DragPending = FALSE [static, private]
 

Definition at line 284 of file dragmgr.h.

wxRect DragManagerOp::DragStartRect [static, private]
 

Definition at line 294 of file dragmgr.h.

MonotonicTime DragManagerOp::DragStartTimer [static, private]
 

Definition at line 288 of file dragmgr.h.

wxPoint DragManagerOp::InitialMousePos [private]
 

Definition at line 276 of file dragmgr.h.

DragEventType DragManagerOp::LastEvent [private]
 

Definition at line 280 of file dragmgr.h.

wxPoint DragManagerOp::LastMousePos [private]
 

Definition at line 278 of file dragmgr.h.

BOOL DragManagerOp::RedrawInProgress = FALSE [static, private]
 

Definition at line 301 of file dragmgr.h.

UINT32 DragManagerOp::StatusLineStringID = 0 [static, private]
 

Definition at line 267 of file dragmgr.h.

wxRect DragManagerOp::StillClickRect [static, private]
 

Definition at line 296 of file dragmgr.h.

List DragManagerOp::Targets [private]
 

Definition at line 272 of file dragmgr.h.

CaptureHandler * DragManagerOp::TheCaptureHandler = NULL [static, private]
 

Definition at line 282 of file dragmgr.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:53:53 2007 for Camelot by  doxygen 1.4.4