sgdrag.cpp

Go to the documentation of this file.
00001 // $Id: sgdrag.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // sgdrag.cpp - Drag Manager classes (information, targets) for supergallery scollbars
00099 //              and generic supergallery item dragging (for rearrangement only)
00100 
00101 
00102 /*
00103 */
00104 
00105 
00106 #include "camtypes.h"
00107 
00108 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "galres.h"
00110 //#include "galstr.h"
00111 //#include "resource.h"
00112 //#include "sgallery.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 #include "sgdrag.h"
00114 //#include "sgtree.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "oilcoord.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 
00117 
00118 DECLARE_SOURCE("$Revision: 1282 $");
00119 
00120 
00121 CC_IMPLEMENT_DYNAMIC(SGScrollDragTarget, KernelDragTarget)
00122 CC_IMPLEMENT_DYNCREATE(SGScrollDragInfo, DragInformation)
00123 
00124 CC_IMPLEMENT_DYNAMIC(SGListDragTarget, KernelDragTarget)
00125 CC_IMPLEMENT_DYNCREATE(SGListDragInfo, DragInformation)
00126 
00127 
00128 
00129 #define new CAM_DEBUG_NEW
00130 
00131 
00132 
00133 const INT32 AUTOREPEATTIME = 150;           // Auto-repeat a maximum of ~7 times per second
00134                                             // (This is the delay, in milliseconds)
00135 
00136 
00137 /********************************************************************************************
00138 
00139 >   SGScrollDragTarget::SGScrollDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL)
00140      
00141     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00142     Created:    27/2/95
00143     Inputs:     TheDialog - The kernel dialog in which the target exists
00144                 TheGadget - The gadget within that dialogue which is the target
00145 
00146     Purpose:    Constructor
00147 
00148 ********************************************************************************************/
00149 
00150 SGScrollDragTarget::SGScrollDragTarget(DialogOp *TheDialog, CGadgetID TheGadget)
00151                     : KernelDragTarget(TheDialog, TheGadget)
00152 {
00153     Timer.Sample();         // Remember the time at which we were created, for autorepeat
00154 
00155     IWantAllEvents = TRUE;  // Ask for all events to be given to us, even if the pointer
00156                             // strays out of our target window area.
00157 }
00158 
00159 
00160 
00161 /********************************************************************************************
00162 
00163     BOOL SGScrollDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
00164                                         OilCoord *pMousePos, KeyPress* pKeyPress)
00165 
00166     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00167     Created:    27/2/95       
00168     Inputs:     Event - Indicates what has happened
00169                 pDragInfo - points to drag information describing this drag. This
00170                 should be an SGScrollDragInfo or something has gone seriously wrong.
00171                 pMousePos - points to information on the current mouse position, in OIL coords
00172                 pKeyPress - NULL, or if for a keypress event, keypress information
00173 
00174     Returns:    TRUE to claim the event, FALSE to let it through to other targets
00175                 This particular handler always returns TRUE
00176 
00177     Purpose:    Event Handler for SuperGallery scrollbar drag events
00178 
00179 ********************************************************************************************/
00180 
00181 BOOL SGScrollDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
00182                                         OilCoord *pMousePos, KeyPress* pKeyPress)
00183 {
00184     // Weed out events that we are not interested in
00185     switch(Event)
00186     {
00187         case DRAGEVENT_ABORT:
00188         case DRAGEVENT_COMPLETED:
00189             // Just claim the event as ours.
00190             // We don't get these events unless the pointer is over us, so we don't do
00191             // anything here - see the deinitialise handler
00192             return(TRUE);
00193 
00194         case DRAGEVENT_INITIALISE:
00195         case DRAGEVENT_DEINITIALISE:
00196         case DRAGEVENT_MOUSEMOVED:
00197         case DRAGEVENT_MOUSESTOPPED:
00198         case DRAGEVENT_MOUSEIDLE:
00199             // We want these events, so break to drop through and process them
00200             break;
00201 
00202         default:
00203             // An unknown/unwanted event type - it could be dangerous to do something on
00204             // an unknown event, so we won't!
00205             return(TRUE);
00206     }
00207 
00208     // Cast the draginfo into the correct type
00209     SGScrollDragInfo *DragInfo = (SGScrollDragInfo *) pDragInfo;
00210 
00211     // FALSE if we aren't dragging, but just handling auto-repeat
00212     BOOL NotAutoRepeat = (DragInfo->GetDragType() == SGDRAG_SAUSAGE);
00213 
00214     SGDisplayRootScroll *Root   = DragInfo->GetDragRootNode();
00215     SGMiscInfo *MiscInfo        = DragInfo->GetDragMiscInfo();
00216     SuperGallery *ParentGallery = Root->GetParentGallery();
00217 
00218     // Convert the OilCoord into a DocCoord, and convert into displaylist coords
00219     DocCoord MousePos(pMousePos->x, pMousePos->y);
00220     ParentGallery->ConvertToVirtualCoords(MiscInfo, &MousePos);
00221 
00222     // And calculate the relevant rectangles...
00223     DocRect UpButton;
00224     DocRect DownButton;
00225     DocRect SausageRect;
00226     DocRect PageUp;
00227     DocRect PageDown;
00228     DocRect ScrollRect;
00229     Root->CalculateScrollRects(MiscInfo, TRUE,
00230                                  &UpButton, &DownButton, &SausageRect,
00231                                  &PageUp, &PageDown, &ScrollRect);
00232 
00233     if (Event == DRAGEVENT_MOUSEMOVED && NotAutoRepeat)
00234     {
00235         // Dragging the scroll sausage
00236 
00237         // Get the offset - the scroll sausage should try to move this point of the
00238         // sausage (measured in millipoints from the top of the sausage) to lie under
00239         // the mouse pointer position if possible.
00240         INT32 AnchorOffset = DragInfo->GetDragAnchorOffset();
00241 
00242         INT32 ScrollWindowTo;
00243         
00244         if (SausageRect.Height() <= SausageRect.Width())
00245         {
00246             // The sausage is a minimum-size square, so now does not proportionally represent
00247             // the displayed area of the window. Thus, we need to use the top position of the
00248             // bar in (barheight - sausageheight) as a fractional scroll between 0 and 
00249             // (ScrollExtent - WindowHeight)
00250             ScrollWindowTo = (INT32) (
00251                                     ( ((double) (ScrollRect.hi.y - (MousePos.y + AnchorOffset))) / 
00252                                         (double) (ScrollRect.Height() - SausageRect.Height()) ) *
00253                                             (double) (Root->GetCachedListExtent() - MiscInfo->WindowHeight)
00254                                     );
00255         }
00256         else
00257         {
00258             // The bar represents the fraction of visible area to extent, so we work out the
00259             // fractional position of the top of the bar, and that gives the position to scroll
00260             // the top of the displayed area to.
00261             ScrollWindowTo = (INT32) (
00262                                     ( ((double) (ScrollRect.hi.y - (MousePos.y + AnchorOffset))) / 
00263                                         (double) ScrollRect.Height() ) *
00264                                             (double) Root->GetCachedListExtent()
00265                                     );
00266         }
00267 
00268         Root->SetScrollOffset(ScrollWindowTo, MiscInfo);
00269         return(TRUE);
00270     }
00271 
00272 
00273     // The drag must therefore be to implement simple AutoRepeat on a button or page-scroll.
00274     // We only bother scrolling if:
00275     //      1) Event is 'initialise' (so it scrolls immediately the button goes down)
00276     //      2) Event is 'deinitialise' (so we must ensure all buttons are popped up)
00277     //      3) Or if it is time for another autorepeat
00278     if (Event != DRAGEVENT_INITIALISE   && 
00279         Event != DRAGEVENT_DEINITIALISE &&
00280         !Timer.Elapsed(AUTOREPEATTIME))
00281     {
00282         // No need to update just now. Return, claiming this event
00283         return(TRUE);
00284     }
00285 
00286     const INT32 ClickScroll = 12000;        // Millipoint distance to scroll for a button click
00287     INT32 ScrollBy = 0;                 // Set this to the amount by which to scroll
00288 
00289     Timer.Sample();                     // Update the autorepeat timer
00290 
00291     switch (DragInfo->GetDragType())
00292     {
00293         case SGDRAG_SCROLLUP:
00294             if (Event == DRAGEVENT_DEINITIALISE)
00295             {
00296                 // Drag completed: Unindent the scroll button
00297                 Root->IndentedButton = IBUTTON_NONE;
00298                 ParentGallery->ForceRedrawOfArea(&UpButton);
00299                 ParentGallery->PaintListNow();
00300             }
00301             else if (UpButton.ContainsCoord(MousePos))
00302             {
00303                 ScrollBy = -ClickScroll;
00304 
00305                 // Indent the scroll button
00306                 Root->IndentedButton = IBUTTON_UP;
00307                 ParentGallery->ForceRedrawOfArea(&UpButton);
00308                 ParentGallery->PaintListNow();
00309             }
00310             break;
00311 
00312 
00313         case SGDRAG_SCROLLDOWN:
00314             if (Event == DRAGEVENT_DEINITIALISE)
00315             {
00316                 // Drag completed: Unindent the scroll button
00317                 Root->IndentedButton = IBUTTON_NONE;
00318                 ParentGallery->ForceRedrawOfArea(&DownButton);
00319                 ParentGallery->PaintListNow();
00320             }
00321             else if (DownButton.ContainsCoord(MousePos))
00322             {
00323                 ScrollBy = ClickScroll;
00324 
00325                 // Indent the scroll button
00326                 Root->IndentedButton = IBUTTON_DOWN;
00327                 ParentGallery->ForceRedrawOfArea(&DownButton);
00328                 ParentGallery->PaintListNow();
00329             }
00330             break;
00331 
00332 
00333         case SGDRAG_PAGEUP:
00334             if (PageUp.IsValid() && PageUp.ContainsCoord(MousePos))
00335             {
00336                 ScrollBy = MiscInfo->WindowHeight - ClickScroll;
00337                 if (ScrollBy < 0)
00338                     ScrollBy = ClickScroll;
00339 
00340                 ScrollBy = -ScrollBy;
00341             }
00342             break;
00343 
00344 
00345         case SGDRAG_PAGEDOWN:
00346             if (PageDown.IsValid() && PageDown.ContainsCoord(MousePos))
00347             {
00348                 ScrollBy = MiscInfo->WindowHeight - ClickScroll;
00349                 if (ScrollBy < 0)
00350                     ScrollBy = ClickScroll;
00351             }
00352             break;
00353 
00354         default:
00355             break;
00356     }
00357 
00358     if (Event != DRAGEVENT_DEINITIALISE && ScrollBy != 0)
00359     {
00360         if (DragInfo->IsAdjustDrag())   // If adjust-drag, reverse scroll direction
00361             ScrollBy = -ScrollBy;
00362 
00363         Root->SetScrollOffset(Root->GetScrollOffset() + ScrollBy, MiscInfo);
00364     }
00365 
00366     // We always claim all events during this drag (it is not a drag to a particular place
00367     // to move an object - really we're using the drag system to "capture" the mouse)
00368     return(TRUE);
00369 }
00370 
00371 
00372 
00373 /********************************************************************************************
00374 
00375 >   void SGScrollDragTarget::GetCursorID()
00376 
00377     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00378     Created:    27/2/95
00379 
00380     Purpose:    Base Method to set cursor over this target
00381 
00382 ********************************************************************************************/
00383 
00384 UINT32 SGScrollDragTarget::GetCursorID()
00385 {
00386     return(0);
00387 }
00388 
00389 
00390 
00391 /********************************************************************************************
00392 
00393 >   virtual BOOL SGScrollDragTarget::GetStatusLineText(String_256 * TheText)
00394 
00395     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00396     Created:    27/2/95
00397 
00398     Returns:    FALSE - we never provide any status line help for scroll-drags
00399 
00400     Purpose:    Provide status line text for this target
00401    
00402 ********************************************************************************************/
00403 
00404 BOOL SGScrollDragTarget::GetStatusLineText(String_256 * TheText)
00405 {
00406     return FALSE;
00407 }
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 /********************************************************************************************
00425 
00426 >   void SGScrollDragInfo::SGScrollDragInfo() 
00427      
00428     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00429     Created:    27/2/95       
00430 
00431     Purpose:    Default constructor. DO NOT CALL THIS CONSTRUCTOR
00432 
00433 ********************************************************************************************/
00434 SGScrollDragInfo::SGScrollDragInfo()
00435 {
00436     ERROR3("Default SGScrollDragInfo constructor called");  
00437 }
00438 
00439 
00440 
00441 /********************************************************************************************
00442 
00443 >   SGScrollDragInfo::SGScrollDragInfo(SGDisplayRootScroll *ParentRootNode,
00444                                         SGDragType TheDragType,
00445                                         SGMiscInfo *MiscInfo,
00446                                         INT32 DragAnchorOffset,
00447                                         BOOL IsAdjust = FALSE)
00448 
00449     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00450     Created:    27/2/95       
00451 
00452     Inputs:     ParentRootNode - The SGDisplayRootScroll for the DisplayTree for which
00453                 the drag is occurring
00454 
00455                 TheDragType - The SGDragType indicating what is being dragged
00456 
00457                 MiscInfo - The normal SGMiscInfo as recieved by display tree event handlers
00458 
00459                 DragAnchorOffset - The offset, in millipoints, from the top of the scroll
00460                 sausage to the point where the drag started (used only when dragging the
00461                 sausage, to "lock" the sausage to the mouse pointer)
00462 
00463                 IsAdjust - TRUE if it is an "adjust" drag [NOTE - Adjust drags are legal
00464                 when dragging scrollbars, and are not turned into clicks like normal drags]             
00465 
00466     Purpose:    Constructor
00467 
00468 ********************************************************************************************/
00469 
00470 SGScrollDragInfo::SGScrollDragInfo(SGDisplayRootScroll *ParentRootNode,
00471                                     SGDragType TheDragType,
00472                                     SGMiscInfo *MiscInfo,
00473                                     INT32 DragAnchorOffset,
00474                                     BOOL IsAdjust)
00475                  : DragInformation(FALSE)
00476 {
00477     DragRootNode = ParentRootNode;
00478     DragType = TheDragType;
00479     DragAnchor = DragAnchorOffset;
00480     DragAdjust = IsAdjust;
00481 
00482     DragMiscInfo = *MiscInfo;       // Copy the MiscInfo structure for ourselves
00483 
00484     // Set up a few things about this drag - it does not do solid drag
00485     DoesSolidDrag = FALSE;
00486     SolidDragOffset.x = SolidDragOffset.y = 0;  // Set up defaults just in case
00487     SolidDragSize.Set(1,1);
00488 }
00489 
00490 
00491 
00492 /********************************************************************************************
00493 
00494 >   virtual UINT32 SGScrollDragInfo::GetCursorID()
00495 
00496     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00497     Created:    27/2/95
00498 
00499     Returns:    a cursor ID to set during this drag
00500 
00501     Purpose:    To provide the resource ID of the cursor to use during this drag.
00502                 For scrollbar drags, the cursor should remain the normal arrow shape.
00503    
00504 ********************************************************************************************/
00505 
00506 UINT32 SGScrollDragInfo::GetCursorID()
00507 {
00508      return(0);
00509 }
00510 
00511 
00512 
00513 /********************************************************************************************
00514 
00515 >   virtual BOOL SGScrollDragInfo::GetStatusLineText(String_256 * TheText)
00516 
00517     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00518     Created:    27/2/95
00519 
00520     Returns:    FALSE - The string has not been filled in
00521     Purpose:    Provide status line text for this drag - While dragging scrollbars no help
00522                 is required/given, so this always returns FALSE
00523    
00524 ********************************************************************************************/
00525 
00526 BOOL SGScrollDragInfo::GetStatusLineText(String_256 * TheText)
00527 {
00528     return(FALSE);
00529 }
00530 
00531 
00532 
00533 /********************************************************************************************
00534 
00535 >   void SGScrollDragInfo::OnClick(INT32 Flags,POINT Point) 
00536      
00537     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00538     Created:    27/2/95       
00539     Inputs:     Flags - Some flags
00540                 Point - the point which was clicked
00541 
00542     Purpose:    This is called if a drag was attempted but never started because it was a 
00543                 click all along
00544 
00545 ********************************************************************************************/
00546 
00547 void SGScrollDragInfo::OnClick(INT32 Flags, POINT Point)
00548 {
00549     // Do nothing. As the thing is scrolled once immediately on SGEVENT_INITIALISE, we
00550     // have already applied the correct click action.
00551 }
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567 /********************************************************************************************
00568 
00569 >   SGListDragTarget::SGListDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL)
00570      
00571     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00572     Created:    14/3/95
00573     Inputs:     TheDialog - The kernel dialog in which the target exists
00574                 TheGadget - The gadget within that dialogue which is the target
00575 
00576     Purpose:    Constructor
00577 
00578 ********************************************************************************************/
00579 
00580 SGListDragTarget::SGListDragTarget(DialogOp *TheDialog, CGadgetID TheGadget)
00581                     : KernelDragTarget(TheDialog, TheGadget)
00582 {
00583     CurrentCursorID = _R(IDC_SGDRAGCURSOR); 
00584 
00585     ERROR3IF(!TheDialog->IsKindOf(CC_RUNTIME_CLASS(SuperGallery)),
00586             "You can only use SGListDragTargets with SuperGallery dialogues!");
00587 }
00588 
00589 
00590 
00591 /********************************************************************************************
00592 
00593 >   BOOL SGListDragTarget::OwnsEntireLine(SGDisplayNode *TheNode)
00594 
00595     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00596     Created:    17/3/95       
00597 
00598     Inputs:     TheNode - the node to check
00599 
00600     Returns:    TRUE if the item fills the entire width of the display list
00601 
00602     Purpose:    Determines if the given display node has siblings to its left/right
00603                 or if it fills an entire 'line' of the display list. This is used to
00604                 determine whether to treat the top/bottom or left/right sides of the
00605                 item as insert-before/after dropzones.
00606 
00607 ********************************************************************************************/
00608 
00609 BOOL SGListDragTarget::OwnsEntireLine(SGDisplayNode *TheNode)
00610 {
00611     DocRect TheRect;
00612     TheNode->GetFormatRect(&TheRect);
00613 
00614     SGDisplayNode *Ptr = TheNode->GetPrevious();
00615     if (Ptr != NULL)
00616     {
00617         DocRect TempRect;
00618         Ptr->GetFormatRect(&TempRect);
00619 
00620         // If overlap in the Y axis, then we are on the same line
00621         if (TempRect.lo.y <= TheRect.hi.y && TempRect.hi.y >= TheRect.lo.y)
00622             return(FALSE);
00623     }
00624 
00625     Ptr = TheNode->GetNext();
00626     if (Ptr != NULL)
00627     {
00628         DocRect TempRect;
00629         Ptr->GetFormatRect(&TempRect);
00630 
00631         // If overlap in the Y axis, then we are on the same line
00632         if (TempRect.lo.y <= TheRect.hi.y && TempRect.hi.y >= TheRect.lo.y)
00633             return(FALSE);
00634     }
00635 
00636     return(TRUE);
00637 }
00638 
00639 
00640 
00641 /********************************************************************************************
00642 
00643 >   SGDragInsertType SGListDragTarget::GetDragInsertType(SuperGallery *ParentGallery,
00644                                                 SGDisplayNode *DraggedNode,
00645                                                 OilCoord *pMousePos,
00646                                                 SGDisplayNode *DestNode)
00647     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00648     Created:    14/3/95       
00649 
00650     Inputs:     ParentGallery - The gallery in which the drag completed
00651 
00652                 DraggedNode - The node being dragged
00653 
00654                 MousePos - The end-drag position, as passed into DragTarget::ProcessEvent
00655 
00656                 DestNode - the DisplayTree node in which the drag completed
00657 
00658     Returns:    An enumerated type indicating whether the node will be added to a group,
00659                 or inserted above or below another node.
00660 
00661     Purpose:    Determines whether we will want to drop an item 'above' or 'below'
00662                 the item under the current pointer position (used to work out which
00663                 pointer shape to use to indicate the action which will be taken when a
00664                 drag ends)
00665 
00666     SeeAlso:    SGListDragTarget::HandleDragCompleted
00667 
00668 ********************************************************************************************/
00669 
00670 SGDragInsertType SGListDragTarget::GetDragInsertType(SuperGallery *ParentGallery,
00671                                                         SGDisplayNode *DraggedNode,
00672                                                         OilCoord *pMousePos,
00673                                                         SGDisplayNode *DestNode)
00674 {
00675     ERROR3IF(DraggedNode == NULL || pMousePos == NULL ||
00676                 ParentGallery == NULL || DestNode == NULL,
00677                 "Illegal NULL params");
00678 
00679     if (DestNode == DraggedNode || DestNode == DraggedNode->GetParent())
00680         return(SGDRAGINSERT_NONE);
00681 
00682     // If dragging a group over an item, then we will insert the group below the item's
00683     // parent group, so we always insert below.
00684     if (DraggedNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup)) &&
00685         DestNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem)))
00686     {
00687         // Dragging a group over an item
00688         SGDisplayNode *DestParent = DestNode->GetParent();
00689 
00690         // It's an item in the group which is being dragged, so no point in dropping here
00691         if (DestParent == DraggedNode)
00692             return(SGDRAGINSERT_NONE);
00693 
00694         // It's an item in the previous group, so we would insert back where we came from
00695         if (DestParent == DraggedNode->GetPrevious())
00696             return(SGDRAGINSERT_NONE);
00697 
00698         // It's a different group, so we will insert after that group
00699         return(SGDRAGINSERT_AFTER);
00700     }
00701 
00702 
00703     // If dragging an item over a group, then we'll ADD to the group
00704     if ((DraggedNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem))) &&
00705         (DestNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup))) )
00706     {
00707         // You can't drop an item into a read-only group (but we still allow moving of items
00708         // within a read-only group)
00709         if (DestNode != DraggedNode->GetParent() && DestNode->Flags.ReadOnly)
00710             return(SGDRAGINSERT_NONE);
00711 
00712         return(SGDRAGINSERT_ADD);
00713     }
00714 
00715 
00716     // If we're dragging an item, check that the destination is legal (not read-only)
00717     if (DraggedNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem)))
00718     {
00719         SGDisplayNode *DestParent = DestNode->GetParent();
00720 
00721         // You can't drop an item into a read-only group (but we still allow moving of items
00722         // within a read-only group)
00723         if (DestParent != NULL && DestParent != DraggedNode->GetParent() && DestParent->Flags.ReadOnly)
00724             return(SGDRAGINSERT_NONE);
00725     }
00726 
00727 
00728     SGMiscInfo MiscInfo;
00729     ParentGallery->FillInMiscInfo(&MiscInfo);
00730 
00731     // Determine where within the display item the drag was dropped
00732     DocCoord ListMouseCoord(pMousePos->x, pMousePos->y);
00733     ParentGallery->ConvertToVirtualCoords(&MiscInfo, &ListMouseCoord);
00734 
00735     DocRect DestRect;
00736     DestNode->GetFormatRect(&DestRect);
00737 
00738     BOOL IsInsertBefore = FALSE;
00739 
00740     if (OwnsEntireLine(DestNode))
00741     {
00742         // This item is full-width, so use top/bottom half as dropzones
00743         if (ListMouseCoord.y > (DestRect.lo.y + DestRect.hi.y) / 2)
00744             IsInsertBefore = TRUE;
00745     }
00746     else
00747     {
00748         // This item is not full width, so use left/right half as dropzones
00749         if (ListMouseCoord.x < (DestRect.lo.x + DestRect.hi.x) / 2)
00750             IsInsertBefore = TRUE;
00751     }
00752 
00753     // Finally, one last check to see if we're still trying to drop the item back
00754     // into the same place.
00755     if (IsInsertBefore)
00756     {
00757         if (DestNode->GetPrevious() == DraggedNode)
00758             return(SGDRAGINSERT_NONE);
00759     }
00760     else
00761     {
00762         if (DestNode->GetNext() == DraggedNode)
00763             return(SGDRAGINSERT_NONE);
00764     }
00765 
00766     return(IsInsertBefore ? SGDRAGINSERT_BEFORE : SGDRAGINSERT_AFTER);
00767 }
00768 
00769 
00770 
00771 /********************************************************************************************
00772 
00773 >   void SGListDragTarget::HandleDragCompleted(SuperGallery *ParentGallery,
00774                                                 SGDisplayNode *DraggedNode,
00775                                                 OilCoord *pMousePos,
00776                                                 BOOL DragThisItemOnly = FALSE)
00777     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00778     Created:    14/3/95       
00779     Inputs:     ParentGallery - The gallery in which the drag completed
00780 
00781                 DraggedNode - The node being dragged
00782 
00783                 MousePos - The end-drag position, as passed into DragTarget::ProcessEvent
00784 
00785                 DragThisItemOnly - if TRUE, indicates that only the 'DragggedNode'
00786                 should be dragged. If FALSE, then all items in the current gallery
00787                 selection, plus DraggedNode, will be treated as if they were dragged.
00788 
00789     Purpose:    Moves/copies gallery items as appropriate when a drag completes
00790 
00791 ********************************************************************************************/
00792 
00793 void SGListDragTarget::HandleDragCompleted(SuperGallery *ParentGallery,
00794                                             SGDisplayNode *DraggedNode,
00795                                             OilCoord *pMousePos,
00796                                             BOOL DragThisItemOnly)
00797 {
00798     TRACEUSER("amb", _T("SGListDragTarget::HandleDragCompleted"));
00799     ERROR3IF(DraggedNode == NULL || pMousePos == NULL || ParentGallery == NULL,
00800                 "Illegal NULL params");
00801 
00802     if (ParentGallery == NULL)
00803         return;
00804 
00805     // Convert the OilCoords into DocCoords
00806     DocCoord MousePos(pMousePos->x, pMousePos->y);
00807     SGDisplayNode *DestNode = ParentGallery->FindNodeUnderPointer(&MousePos);
00808 
00809     if (DestNode == NULL                ||      // No valid target
00810         DestNode == DraggedNode         ||      // Dropped back where we started
00811         (DragThisItemOnly && DestNode == DraggedNode->GetParent())) // Dropped into own parent group
00812     {
00813         return;
00814     }
00815 
00816 
00817     BOOL InsertBefore = FALSE;          // TRUE if should insert-before the DestNode
00818     switch (GetDragInsertType(ParentGallery, DraggedNode, pMousePos, DestNode))
00819     {
00820         case SGDRAGINSERT_NONE:
00821             // The drag has no effect, so we exit now
00822             return;
00823 
00824         case SGDRAGINSERT_ADD:
00825         case SGDRAGINSERT_AFTER:
00826             // We need take no specific action here
00827             break;
00828 
00829         case SGDRAGINSERT_BEFORE:
00830             InsertBefore = TRUE;
00831             break;
00832 
00833         default:
00834             ERROR3("Illegal return value from GetDragInsertType");
00835             return;
00836     }
00837 
00838     // TRUE if dragged a group, FALSE if dragged an item
00839     BOOL GroupBeingDragged = DraggedNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup));
00840 
00841     // Determine if we need to insert multiple nodes, and compile a list of
00842     // all the nodes to affect, if necessary. This list is then used to apply
00843     // the drag-finish to all selected items (done this way, as the movements
00844     // may well affect the selection in nasty ways, so we must cache it before
00845     // we move stuff around)
00846     INT32 ItemCount = 1;
00847     INT32 ItemIndex;
00848     if (!DragThisItemOnly)
00849     {
00850         if (GroupBeingDragged)
00851             ItemCount = ParentGallery->GetSelectedGroupCount();
00852         else
00853             ItemCount = ParentGallery->GetSelectedItemCount(NULL, NULL);
00854 
00855         if (ItemCount < 1)  // Just in case DraggedNode is not selected!
00856             ItemCount = 1;
00857     }
00858 
00859     SGDisplayNode **DraggedArray = NULL;
00860     SGDisplayRoot *DisplayTree = ParentGallery->GetDisplayTree();
00861 
00862     if (ItemCount > 1 && DisplayTree != NULL)
00863     {
00864         DraggedArray = (SGDisplayNode **) CCMalloc(ItemCount * sizeof(SGDisplayNode *));
00865 
00866         if (DraggedArray != NULL)
00867         {
00868             SGDisplayNode *Ptr = NULL;
00869             for (ItemIndex =0; ItemIndex < ItemCount; ItemIndex++)
00870             {
00871                 if (GroupBeingDragged)
00872                     Ptr = DisplayTree->FindNextSelectedGroup(Ptr);
00873                 else
00874                     Ptr = DisplayTree->FindNextSelectedItem(Ptr);
00875                 DraggedArray[ItemIndex] = Ptr;
00876 
00877                 ERROR3IF(Ptr == NULL, "Gallery selection ran out before selection count did");
00878             }
00879         }
00880     }
00881 
00882     if (DraggedArray == NULL)   // Just ensure we're safe
00883         ItemCount = 1;
00884 
00885     // OK, For each item we must move, apply the appropriate action.
00886     // If there is only one item, DraggedArray will be NULL, and ItemCount will be 1, in
00887     // which case, we'll only do the loop once, using DraggedNode as the dropped thing.
00888 
00889     // Determine if the DestNode is a group or an item, and determine the group affected (TargetGroup)
00890     BOOL TargetIsGroup  = DestNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup));
00891     SGDisplayGroup *TargetGroup = (SGDisplayGroup *) ((TargetIsGroup) ? DestNode : DestNode->GetParent());
00892     ERROR3IF(TargetGroup == NULL, "Drag target display group is NULL!?");
00893 
00894     SGDisplayNode *NewItem = NULL;
00895 
00896     for (ItemIndex = 0; ItemIndex < ItemCount; ItemIndex++) 
00897     {
00898         if (DraggedArray != NULL)
00899             DraggedNode = DraggedArray[ItemIndex];
00900 
00901         NewItem = DraggedNode;
00902 
00903         if (DraggedNode->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup)))
00904         {
00905             // Dragged node is a group, so move before/after the target group
00906             if (InsertBefore)
00907                 TargetGroup->MoveBefore(DraggedNode);
00908             else
00909                 TargetGroup->MoveAfter(DraggedNode);
00910         }
00911         else
00912         {
00913             // Dragged node is an item
00914             if (TargetIsGroup)
00915             {
00916                 // Item was dropped on a group title, so copy into that group
00917                 if (TargetGroup != DraggedNode->GetParent())
00918                     NewItem = ParentGallery->CopyDisplayItem((SGDisplayItem *)DraggedNode, TargetGroup);
00919                 // else it's being moved into its own group - do nothing
00920             }
00921             else
00922             {
00923                 // Item was dropped on another item, so use that item as the target position
00924                 if (TargetGroup != DraggedNode->GetParent())
00925                 {
00926                     // But it's in another group, so we must copy the item across
00927                     if (InsertBefore)
00928                     {
00929                         NewItem = ParentGallery->CopyDisplayItem((SGDisplayItem *)DraggedNode, TargetGroup,
00930                                                                     (SGDisplayItem *)DestNode);
00931                     }
00932                     else
00933                     {
00934                         // We want to insert *after* the DestNode, so we make the target node the NEXT node
00935                         // after DestNode (as this routine alwyas does an InsertBefore operation)
00936                         NewItem = ParentGallery->CopyDisplayItem((SGDisplayItem *)DraggedNode, TargetGroup,
00937                                                                     (SGDisplayItem *) (DestNode->GetNext()));
00938                     }
00939                 }
00940                 else
00941                 {
00942                     // We're just moving it within its own group
00943                     if (InsertBefore)
00944                         DestNode->MoveBefore(DraggedNode);
00945                     else
00946                     {
00947                         // We have to be careful with MoveAfter to retain the correct order
00948                         if (ItemIndex == 0 || DraggedArray[ItemIndex-1] == NULL)
00949                             DestNode->MoveAfter(DraggedNode);
00950                         else
00951                             DraggedArray[ItemIndex-1]->MoveAfter(DraggedNode);
00952                     }
00953                 }
00954             }
00955         }
00956 
00957         // Update the selection state for copied items
00958         if (DraggedNode != NewItem)
00959         {
00960             if (DraggedNode != NULL)
00961                 DraggedNode->SetSelected(FALSE);
00962 
00963             if (NewItem != NULL)
00964             {
00965                 // Poke the flags directly to avoid an attempt to redraw, as at this point
00966                 // the item's formatrect will be uninitialised (well, (0,0,0,0))
00967                 NewItem->Flags.Selected = TRUE;
00968             }
00969         }
00970 
00971         // Update the last item in the array to point at the copy rather than the source
00972         if (ItemIndex > 0)
00973             DraggedArray[ItemIndex] = NewItem;
00974     }   // end for
00975 
00976     if (DraggedArray != NULL)                       // Free up our temporary memory allocation
00977         CCFree(DraggedArray);
00978 
00979     ParentGallery->InvalidateCachedFormat();        // Redraw any changed areas of the list
00980     ParentGallery->ReformatAndRedrawIfNecessary();
00981 
00982     ParentGallery->AllItemsCopied(TargetGroup);     // Inform gallery this group has changed
00983 
00984     ParentGallery->SelectionHasChanged();           // And ensure it updates button shading state
00985 }
00986 
00987 
00988 
00989 /********************************************************************************************
00990 
00991 >   BOOL SGListDragTarget::DetermineCursorShape(SuperGallery *ParentGallery,
00992                                                 SGDisplayNode *DraggedNode,
00993                                                 OilCoord *pMousePos)
00994     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00995     Created:    15/3/95
00996 
00997     Inputs:     ParentGallery - The gallery in which the drag completed
00998                 DraggedNode - The node which is being dragged
00999                 pMousePos - The end-drag position, as passed into DragTarget::ProcessEvent
01000 
01001     Returns:    TRUE if we should change the cursor shape (return this value
01002                 from mouse events in ProcessEvent to have the drag manager use
01003                 or not-use our pointer as appropriate)
01004 
01005     Purpose:    Determines what mouse pointer shape should be used during a drag
01006                 while the mouse is over a gallery listbox target area. This sets
01007                 the member variable CurrentCursorID, and if you then return the
01008                 return value of this function from your ProcessEvent handler, this
01009                 will result in the cursor shape beng updated correctly.
01010 
01011     Notes:      This is a subroutine to minimise the amount of work involved in
01012                 deriving classes from SGListDragTarget for recieving drags of 
01013                 specific things (e.g. colours, bitmaps, etc) in gallery listboxes
01014 
01015 ********************************************************************************************/
01016 
01017 BOOL SGListDragTarget::DetermineCursorShape(SuperGallery *ParentGallery,
01018                                             SGDisplayNode *DraggedNode,
01019                                             OilCoord *pMousePos)
01020 {
01021     // By default, we want a simple pointer cursor
01022     CurrentCursorID = _R(IDC_SGDRAGCURSOR);
01023 
01024     if (ParentGallery == NULL)
01025         return(FALSE);
01026 
01027     // Convert the OilCoords into DocCoords
01028     DocCoord MousePos(pMousePos->x, pMousePos->y);  
01029 
01030     // Make the gallery scroll the list if we're dragging near the top/bottom
01031     ParentGallery->AutoScrollForDrag(&MousePos);
01032 
01033     SGDisplayNode *DestNode = ParentGallery->FindNodeUnderPointer(&MousePos);
01034     if (DestNode == NULL)
01035         return(FALSE);      // No valid target area, so return now
01036 
01037     switch (GetDragInsertType(ParentGallery, DraggedNode, pMousePos, DestNode))
01038     {
01039         case SGDRAGINSERT_NONE:
01040             CurrentCursorID = _R(IDC_DRAGGING_COLOUR);      // No-can-drop cursor shape
01041             break;
01042         
01043         case SGDRAGINSERT_ADD:
01044             CurrentCursorID = _R(IDC_SGDRAGCURSOR);         // Can drop here
01045             break;
01046 
01047         case SGDRAGINSERT_BEFORE:
01048             CurrentCursorID = _R(IDC_SGABOVECURSOR);        // Will insert above
01049             break;
01050 
01051         case SGDRAGINSERT_AFTER:
01052             CurrentCursorID = _R(IDC_SGBELOWCURSOR);        // Will insert below
01053             break;
01054     }
01055 
01056     // We claim all mouse movements, so that the manager uses our drag pointer
01057     // while the mouse is over our target area
01058     return(TRUE);
01059 }
01060 
01061 
01062 
01063 /********************************************************************************************
01064 
01065 >   virtual BOOL SGListDragTarget::ProcessEvent(DragEventType Event,
01066                                         DragInformation *pDragInfo,
01067                                         OilCoord *pMousePos, KeyPress* pKeyPress)
01068 
01069     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01070     Created:    14/3/95       
01071     Inputs:     Event - Indicates what has happened
01072                 pDragInfo - points to drag information describing this drag. This
01073                 should be an SGListDragInfo or something has gone seriously wrong.
01074                 pMousePos - points to information on the current mouse position, in OIL coords
01075                 pKeyPress - NULL, or if for a keypress event, keypress information
01076 
01077     Returns:    TRUE to claim the event, FALSE to let it through to other targets
01078 
01079     Purpose:    Event Handler for SuperGallery listitem drag events
01080 
01081 ********************************************************************************************/
01082 
01083 BOOL SGListDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
01084                                     OilCoord *pMousePos, KeyPress* pKeyPress)
01085 {
01086     if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(SGListDragInfo)))
01087         return(FALSE);
01088 
01089     SGListDragInfo *Info = (SGListDragInfo *)pDragInfo;
01090 
01091     switch(Event)
01092     {
01093         case DRAGEVENT_COMPLETED:
01094             HandleDragCompleted((SuperGallery *) TargetDialog,
01095                                 Info->GetDraggedNode(), pMousePos);
01096             return(TRUE);
01097 
01098 
01099         case DRAGEVENT_MOUSESTOPPED:
01100         case DRAGEVENT_MOUSEMOVED:
01101         case DRAGEVENT_MOUSEIDLE:
01102             // Call a subroutine to work out and set our current cursor shape
01103             return(DetermineCursorShape((SuperGallery *) TargetDialog,
01104                                         Info->GetDraggedNode(), pMousePos));
01105         default:
01106             break;
01107     }
01108 
01109     // Otherwise, we aren't interested in the event, so we don't claim it
01110     return(FALSE);
01111 }
01112 
01113 
01114 
01115 /********************************************************************************************
01116 
01117 >   void SGListDragTarget::GetCursorID()
01118 
01119     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01120     Created:    14/3/95
01121 
01122     Purpose:    Base Method to set cursor over this target
01123 
01124 ********************************************************************************************/
01125 
01126 UINT32 SGListDragTarget::GetCursorID()
01127 {
01128     return(CurrentCursorID);
01129 }
01130 
01131 
01132 
01133 /********************************************************************************************
01134 
01135 >   virtual BOOL SGListDragTarget::GetStatusLineText(String_256 * TheText)
01136 
01137     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01138     Created:    14/3/95
01139 
01140     Returns:    FALSE - we never provide any status line help for scroll-drags
01141 
01142     Purpose:    Provide status line text for this target
01143 
01144     Notes:      Bases the text on the current value of the member var CurrentCursorID.
01145                 If this is an unknown value, defaults to _R(IDS_SGDRAG_LISTITEM)
01146    
01147 ********************************************************************************************/
01148 
01149 BOOL SGListDragTarget::GetStatusLineText(String_256 * TheText)
01150 {
01151     ERROR3IF(TheText == NULL, "Illegal NULL param");
01152 
01153     if (CurrentCursorID == _R(IDC_SGABOVECURSOR))
01154     {
01155         TheText->MakeMsg(_R(IDS_SGDRAG_INSABOVE));
01156     }
01157     else if (CurrentCursorID == _R(IDC_SGBELOWCURSOR))
01158     {
01159         TheText->MakeMsg(_R(IDS_SGDRAG_INSBELOW));
01160     }
01161     else
01162     {
01163         TheText->MakeMsg(_R(IDS_SGDRAG_LISTITEM));
01164     }
01165 
01166     return(TRUE);
01167 }
01168 
01169 
01170 
01171 
01172 
01173 
01174 
01175 
01176 
01177 
01178 
01179 
01180 
01181 
01182 
01183 
01184 /********************************************************************************************
01185 
01186 >   void SGListDragInfo::SGListDragInfo() 
01187      
01188     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01189     Created:    14/3/95       
01190 
01191     Purpose:    Default constructor. DO NOT CALL THIS CONSTRUCTOR
01192 
01193 ********************************************************************************************/
01194 SGListDragInfo::SGListDragInfo()
01195 {
01196     ERROR3("Default SGListDragInfo constructor called");    
01197 }
01198 
01199 
01200 
01201 /********************************************************************************************
01202 
01203 >   SGListDragInfo::SGListDragInfo(SuperGallery *ParentGal, SGDisplayNode *DraggedNode,
01204                                     SGMouseInfo *TheMouseInfo, BOOL IsAdjust = FALSE)
01205 
01206     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01207     Created:    14/3/95       
01208 
01209     Inputs:     ParentGal - The gallery from which the drag originated
01210 
01211                 DraggedNode - the SGDisplayNode that is being dragged
01212 
01213                 TheMouseInfo -The MouseInfo which was passed into your HandleEvent
01214                 method for the click which started this drag. (Passed back into the
01215                 SGDisplayNode::DragWasReallyAClick handler if the drag becomes a click)
01216 
01217                 IsAdjust - TRUE if it is an "adjust" drag [NOTE - Adjust drags are legal
01218                 when dragging scrollbars, and are not turned into clicks like normal drags]             
01219 
01220     Purpose:    Constructor
01221 
01222 ********************************************************************************************/
01223 
01224 SGListDragInfo::SGListDragInfo(SuperGallery *ParentGal, SGDisplayNode *DraggedNode,
01225                                 SGMouseInfo *TheMouseInfo, BOOL IsAdjust)
01226                  : DragInformation(IsAdjust)
01227 {
01228     ParentGallery = ParentGal;
01229     DragNode = DraggedNode;
01230     MouseInfo = *TheMouseInfo;  // COPY the MouseInfo structure
01231 
01232     // Set up a few things about this drag - it does not do solid drag
01233     DoesSolidDrag = FALSE;
01234     SolidDragOffset.x = SolidDragOffset.y = 0;  // Set up defaults just in case
01235     SolidDragSize.Set(1,1);
01236 }
01237 
01238 
01239 
01240 /********************************************************************************************
01241 
01242 >   virtual UINT32 SGListDragInfo::GetCursorID()
01243 
01244     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01245     Created:    14/3/95
01246 
01247     Returns:    a cursor ID to set during this drag
01248 
01249     Purpose:    To provide the resource ID of the cursor to use during this drag.
01250                 For scrollbar drags, the cursor should remain the normal arrow shape.
01251    
01252 ********************************************************************************************/
01253 
01254 UINT32 SGListDragInfo::GetCursorID()
01255 {
01256      return(_R(IDC_DRAGGING_COLOUR));       // No-can-drop cursor shape
01257 }
01258 
01259 
01260 
01261 /********************************************************************************************
01262 
01263 >   virtual BOOL SGListDragInfo::GetStatusLineText(String_256 * TheText)
01264 
01265     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01266     Created:    14/3/95
01267 
01268     Returns:    FALSE - The string has not been filled in
01269     Purpose:    Provide status line text for this drag - While dragging scrollbars no help
01270                 is required/given, so this always returns FALSE
01271    
01272 ********************************************************************************************/
01273 
01274 BOOL SGListDragInfo::GetStatusLineText(String_256 * TheText)
01275 {
01276     ERROR3IF(TheText == NULL, "Illegal NULL param");
01277     TheText->MakeMsg(_R(IDS_SGDRAG_LISTITEM));
01278 
01279     return(TRUE);
01280 }
01281 
01282 
01283 
01284 /********************************************************************************************
01285 
01286 >   void SGListDragInfo::OnClick(INT32 Flags,POINT Point) 
01287      
01288     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01289     Created:    14/3/95       
01290     Inputs:     Flags - Some flags
01291                 Point - the point which was clicked
01292 
01293     Purpose:    This is called if a drag was attempted but never started because it was a 
01294                 click all along. It passes the original Click information back to the
01295                 SGDisplayNode which started the drag by calling its DragWasReallyAClick
01296                 method
01297 
01298     SeeAlso:    SGDisplayNode::DragWasReallyAClick
01299 
01300 ********************************************************************************************/
01301 
01302 void SGListDragInfo::OnClick(INT32 Flags, POINT Point)
01303 {
01304     if (DragNode != NULL)
01305     {
01306         SGMiscInfo MiscInfo;
01307         ParentGallery->FillInMiscInfo(&MiscInfo);
01308 
01309         DragNode->DragWasReallyAClick(&MouseInfo, &MiscInfo);
01310     }
01311 }
01312 
01313 

Generated on Sat Nov 10 03:46:52 2007 for Camelot by  doxygen 1.4.4