sgldrag.cpp

Go to the documentation of this file.
00001 // $Id: sgldrag.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 // sgldrag.cpp - Line gallery item dragging
00099 
00100 #include "camtypes.h"
00101 
00102 #include "sgldrag.h"
00103 #include "dragmgr.h"
00104 #include "dragbmp.h"
00105 //#include "viewrc.h"
00106 //#include "resource.h"
00107 #include "camview.h"
00108 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 #include "grndbmp.h"
00112 #include "nodepath.h"
00113 #include "lineattr.h"
00114 #include "sgline.h"
00115 #include "osrndrgn.h"
00116 
00117 //#include "richard2.h" // string resources
00118 
00119 // Implement the dynamic class bits...
00120 CC_IMPLEMENT_DYNCREATE(GalleryLineDragInfo, BitmapDragInformation)
00121 CC_IMPLEMENT_DYNAMIC(SGLineDragTarget, SGListDragTarget);
00122 
00123 // This line mustn't go before any CC_IMPLEMENT_... macros
00124 #define new CAM_DEBUG_NEW
00125 
00126 // This determines where, if at all, the text description of a dragged line gallery item
00127 // will be displayed.
00128 const LineAttrItem::TextPosition c_eLineAttrDragTextPos = LineAttrItem::NO_LABEL;
00129 
00130 
00131 /********************************************************************************************
00132 
00133 >   SGLineDragTarget::SGLineDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL)
00134      
00135     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00136     Created:    10/4/95
00137     Inputs:     TheDialog - The kernel dialog in which the target exists
00138                 TheGadget - The gadget within that dialogue which is the target
00139 
00140     Purpose:    Constructor
00141 
00142 ********************************************************************************************/
00143 
00144 SGLineDragTarget::SGLineDragTarget(DialogOp *TheDialog, CGadgetID TheGadget)
00145                     : SGListDragTarget(TheDialog, TheGadget)
00146 {
00147     ERROR3IF(!TheDialog->IsKindOf(CC_RUNTIME_CLASS(LineGallery)),
00148             "You can only use SGLineDragTargets with LineGallery dialogues!");
00149 }
00150 
00151 
00152 
00153 /********************************************************************************************
00154 
00155     BOOL SGLineDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
00156                                             OilCoord *pMousePos, KeyPress* pKeyPress)
00157 
00158     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00159     Created:    10/4/95
00160     Inputs:     Event - Indicates what has happened
00161                 pDragInfo - points to drag information describing this drag. This
00162                 should be a BitmapDragInformation or derivation thereof
00163                 pMousePos - points to information on the current mouse position, in OIL coords
00164                 pKeyPress - NULL, or if for a keypress event, keypress information
00165 
00166     Returns:    TRUE to claim the event, FALSE to let it through to other targets
00167 
00168     Purpose:    Event Handler for SuperGallery listitem drag events. Overrides the
00169                 base class handler to enable it to sort out the node being dragged
00170                 for Line drags.
00171 
00172 ********************************************************************************************/
00173 
00174 BOOL SGLineDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
00175                                         OilCoord *pMousePos, KeyPress* pKeyPress)
00176 {
00177     if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(GalleryLineDragInfo)))
00178         return(FALSE);
00179 
00180     SGDisplayNode *DraggedNode = NULL;
00181     BOOL IsSimpleBitmapDrag = TRUE;
00182 
00183     if (IS_A(pDragInfo, GalleryLineDragInfo))
00184     {
00185         DraggedNode = ((GalleryLineDragInfo *)pDragInfo)->GetDraggedLineAttr();
00186     }
00187 
00188     if (DraggedNode != NULL)
00189     {
00190         switch(Event)
00191         {
00192             case DRAGEVENT_COMPLETED:
00193                 HandleDragCompleted((SuperGallery *) TargetDialog,
00194                                     DraggedNode, pMousePos, IsSimpleBitmapDrag);
00195                 return(TRUE);
00196 
00197 
00198             case DRAGEVENT_MOUSESTOPPED:
00199             case DRAGEVENT_MOUSEMOVED:
00200             case DRAGEVENT_MOUSEIDLE:
00201                 // Call a subroutine to work out and set our current cursor shape
00202                 return(DetermineCursorShape((SuperGallery *) TargetDialog,
00203                                             DraggedNode, pMousePos));
00204             default:
00205                 break;
00206         }
00207     }
00208 
00209     // Otherwise, we aren't interested in the event, so we don't claim it
00210     return(FALSE);
00211 }
00212 
00213 /********************************************************************************************
00214 
00215 >   void GalleryLineDragInfo::GalleryLineDragInfo() 
00216      
00217     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00218     Created:    10/4/95       
00219 
00220     Purpose:    Default constructor - do not call this constructor
00221 
00222 ********************************************************************************************/
00223 
00224 GalleryLineDragInfo::GalleryLineDragInfo()
00225 {
00226     ERROR3("Default GalleryLineDragInfo constructor called");   
00227 }
00228 
00229 
00230 
00231 /********************************************************************************************
00232 
00233 >   GalleryLineDragInfo::GalleryLineDragInfo(LineAttrItem *pSourceItem,
00234                                             SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo,
00235                                             BOOL IsAdjust = FALSE)
00236      
00237     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00238     Created:    10/4/95       
00239 
00240     Inputs:     pSourceItem - The gallery item from which the drag originated
00241                 pMouseInfo  - The mouse info which made the item start the drag
00242                 pMiscInfo   - The MiscInfo which accompanied the mouse event
00243                 IsAdjust    - TRUE if this is an adjust (line-Bitmap) drag
00244 
00245     Purpose:    Constructor
00246 
00247 ********************************************************************************************/
00248 
00249 GalleryLineDragInfo::GalleryLineDragInfo(LineAttrItem *pSourceItem,
00250                                             SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo,
00251                                             BOOL IsAdjust)
00252                       : BitmapDragInformation(NULL, 100,50,0,0,
00253                                                 IsAdjust)
00254 {
00255     SourceItem  = pSourceItem;  // Copy the source item pointer
00256 
00257     pAttr       = SourceItem->CreateNewAttribute(IsAdjust);
00258 
00259     MouseInfo   = *pMouseInfo;  // Duplicate the structures (they may cease to exist
00260     MiscInfo    = *pMiscInfo;   // soon after the drag is started)
00261 }
00262 
00263 /********************************************************************************************
00264 
00265 >   GalleryLineDragInfo::~GalleryLineDragInfo()
00266  
00267     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00268     Created:    10/4/95       
00269 
00270     Purpose:    Destructor. Deletes the dragged bitmap.
00271 
00272 ********************************************************************************************/
00273 
00274 GalleryLineDragInfo::~GalleryLineDragInfo()
00275 {
00276     if (TheBitmap != NULL)
00277     {
00278         delete TheBitmap;
00279         TheBitmap = NULL;
00280     }
00281 
00282     if (pAttr != NULL)
00283         delete pAttr;
00284 }
00285 
00286 /********************************************************************************************
00287 
00288 >   void GalleryLineDragInfo::OnClick(INT32 Flags,POINT Point) 
00289      
00290     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00291     Created:    10/4/95       
00292     Inputs:     -
00293     Outputs:    -
00294     Returns:    -
00295     Purpose:    This is called if a drag was attempted but never started because it was a 
00296                 click all along. It calls back the SourceItem SGDisplayLine, to get it
00297                 to handle the click.
00298     Errors:     -
00299     SeeAlso:    -
00300 
00301 ********************************************************************************************/
00302 
00303 void GalleryLineDragInfo::OnClick(INT32 Flags ,POINT Point)
00304 {
00305     if (SourceItem != NULL)
00306         SourceItem->DragWasReallyAClick(&MouseInfo, &MiscInfo);
00307 }
00308 
00309 /********************************************************************************************
00310 
00311 >   void GalleryLineDragInfo::GetCursorID(DragTarget* pDragTarget)
00312 
00313     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00314     Created:    10/4/95
00315     Purpose:    Set cursor over this target
00316 
00317 
00318 ********************************************************************************************/
00319 
00320 UINT32 GalleryLineDragInfo::GetCursorID(DragTarget* pDragTarget)
00321 {
00322     if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget))
00323     {
00324         PageDropInfo PageDropInfo;
00325         ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo);
00326 
00327         NodeRenderableInk* pObjectHit   = PageDropInfo.pObjectHit;
00328         ObjectDragTarget TargetHit      = PageDropInfo.TargetHit;
00329 
00330         if (IS_A(pAttr, AttrStartArrow) || IS_A(pAttr, AttrEndArrow))
00331         {
00332             if (pObjectHit && pObjectHit->IS_KIND_OF(NodePath))
00333             {
00334                 Path* pPath = &((NodePath*)pObjectHit)->InkPath;
00335                 BOOL IsStart;
00336                 if (DropStartOrEndArrow(pPath, PageDropInfo.DropPos, &IsStart))
00337                 {
00338                     TargetHit = IsStart ? STARTCOL_TARGET : ENDCOL_TARGET;
00339                 }
00340             }
00341         }
00342 
00343         ClickModifiers ClickMods = ClickModifiers::GetClickModifiers();
00344         BOOL IsInside = ClickMods.Constrain;
00345 
00346         if (!IsInside && pObjectHit && pObjectHit->IsCompound())
00347         {
00348             TargetHit = MANY_TARGET;
00349         }
00350 
00351         switch (TargetHit)
00352         {
00353             case FILL_TARGET:
00354                 return IsInside ? _R(IDC_DROPINSIDEONLINE) : _R(IDC_CANDROPONLINE);
00355             case LINE_TARGET:
00356                 return IsInside ? _R(IDC_DROPINSIDEONLINE) : _R(IDC_CANDROPONLINE);
00357             case STARTCOL_TARGET:
00358                 return IsInside ? _R(IDC_DROPINSIDEONFILLSTART) : _R(IDC_CANDROPONFILLSTART);
00359             case ENDCOL_TARGET:
00360                 return IsInside ? _R(IDC_DROPINSIDEONFILLEND) : _R(IDC_CANDROPONFILLEND);
00361             case MANY_TARGET:
00362                 return IsInside ? _R(IDC_DROPINSIDEONLINE) : _R(IDC_CANDROPONLINE);
00363 
00364             case NO_TARGET:
00365                 return _R(IDC_CANDROPONPAGE);
00366             default:
00367                 break;
00368         };
00369 
00370         return _R(IDC_CANDROPONPAGE);
00371     }
00372 
00373     return _R(IDC_CANTDROP);
00374 }
00375 
00376 /********************************************************************************************
00377 
00378 >   virtual BOOL GalleryLineDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget)
00379 
00380     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00381     Created:    10/4/95
00382     Returns:    Whether String is valid
00383     Purpose:    provide status line text for this target
00384    
00385 ********************************************************************************************/
00386 
00387 BOOL GalleryLineDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget)
00388 {
00389     ERROR2IF(TheText==NULL,FALSE,"NULL string in GetStatusLineText()");
00390 
00391     if (TheBitmap == NULL || TheBitmap->ActualBitmap == NULL)
00392         return FALSE;
00393 
00394     String_256 DragString(_R(IDS_SGLDRAG_DRAG_LINE_ATTR)); // "Dragging line attribute"
00395     DragString += String_8(_R(IDS_SGDFONTS_STAT_COLON_SEP)); //" : ";
00396 
00397     if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget))
00398     {
00399         PageDropInfo PageDropInfo;
00400         ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo);
00401 
00402         NodeRenderableInk* pObjectHit   = PageDropInfo.pObjectHit;
00403         ObjectDragTarget TargetHit      = PageDropInfo.TargetHit;
00404 
00405         String_256 ObjectDesc = _R(IDS_SGLDRAG_THIS_OBJECT); // " this object";
00406 
00407         if (pObjectHit)
00408         {
00409             ObjectDesc = pObjectHit->Describe(FALSE);
00410         }
00411 
00412         ClickModifiers ClickMods = ClickModifiers::GetClickModifiers();
00413         BOOL IsInside = ClickMods.Constrain;
00414 
00415         if (!IsInside && pObjectHit && pObjectHit->IsCompound())
00416         {
00417             TargetHit = MANY_TARGET;
00418         }
00419 
00420         switch (TargetHit)
00421         {
00422             case FILL_TARGET:
00423             case LINE_TARGET:
00424             case STARTCOL_TARGET:
00425             case ENDCOL_TARGET:
00426                 DragString += String_64(_R(IDS_SGLDRAG_DROP_TO_APPLY)); // "Drop to apply this attribute to this ";
00427                 DragString += ObjectDesc;
00428                 if (IsInside)
00429                     DragString += String_64(_R(IDS_SGLDRAG_SPACE_ALONE)); // " alone";
00430                 break;
00431 
00432             case MANY_TARGET:
00433                 DragString += String_64(_R(IDS_SGLDRAG_DROP_TO_APPLY)); // "Drop to apply this attribute to this ";
00434                 DragString += ObjectDesc;
00435                 DragString += String_64(_R(IDS_SGLDRAG_CONTROL_DROP_INSIDE)); // "; Press 'Control' to drop 'Inside'";
00436                 break;
00437 
00438             case NO_TARGET:
00439                 DragString += String_64(_R(IDS_SGLDRAG_DROP_CURRENT_ATTRIBUTE)); // "Drop to set the Current Attribute";
00440                 break;
00441             default:
00442                 break;
00443         };
00444 
00445         *TheText = DragString;
00446         return TRUE;
00447     }
00448     
00449     return FALSE;
00450 }
00451 
00452 /********************************************************************************************
00453 
00454 >   BOOL GalleryBitmapDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
00455  
00456     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00457     Created:    10/4/95       
00458     Inputs:     -
00459     Outputs:    -
00460     Returns:    -
00461     Purpose:    Called when a Line Attr is dropped onto the page.
00462     Errors:     -
00463     SeeAlso:    -
00464 
00465 ********************************************************************************************/
00466 
00467 BOOL GalleryLineDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
00468 {
00469     PageDropInfo PageDropInfo;
00470     ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo);
00471     NodeRenderableInk* pObjectHit = PageDropInfo.pObjectHit;
00472 
00473     NodeAttribute* Attrib = SourceItem->CreateNewAttribute(IsAnAdjustDrag());
00474 
00475     if (Attrib == NULL)
00476         return FALSE;
00477 
00478     if (pObjectHit && (IS_A(Attrib, AttrStartArrow) || IS_A(Attrib, AttrEndArrow)))
00479     {
00480         if (!pObjectHit->IS_KIND_OF(NodePath))
00481         {
00482             delete Attrib;
00483             return FALSE;
00484         }
00485 
00486         Path* pPath = &((NodePath*)pObjectHit)->InkPath;
00487         BOOL IsStart;
00488 
00489         if (!DropStartOrEndArrow(pPath, PageDropInfo.DropPos, &IsStart))
00490         {
00491             delete Attrib;
00492             return FALSE;
00493         }
00494 
00495         Attrib = MakeStartOrEndArrow(Attrib, IsStart);
00496     }
00497 
00498     if (pObjectHit) 
00499     {
00500         // Hit a Line Object, so apply attribute to it
00501         AttributeManager::ApplyAttribToNode(pObjectHit, Attrib);
00502     }
00503     else
00504     {
00505         // Didn't hit anything, so just set the current attribute
00506         AttributeManager::AttributeSelected(Attrib);
00507     }
00508 
00509     return TRUE;
00510 }
00511 
00512 
00513 /********************************************************************************************
00514 
00515 >   INT32 GalleryLineDragInfo::GetDragTransparency()
00516  
00517     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00518     Created:    10/4/95       
00519     Returns:    -
00520     Purpose:    Specifies how transparent a drag should be.
00521                 A value of 0, will cause a normal solid blit.
00522                 Any other value (between 0 and 100), will cause a masked blit.
00523     SeeAlso:    -
00524 
00525 ********************************************************************************************/
00526 
00527 INT32 GalleryLineDragInfo::GetDragTransparency()
00528 {
00529 //  if (IS_A(pAttr, AttrStartArrow) || IS_A(pAttr, AttrEndArrow))
00530 //      return 50;
00531 
00532     return 50;
00533 }
00534 
00535 /********************************************************************************************
00536 
00537 >   KernelBitmap* GalleryLineDragInfo::GetSolidDragMask()
00538 
00539     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00540     Created:    10/4/95       
00541     Returns:    -
00542     Purpose:    Makes a 1bpp KernelBitmap mask for the solid drag.
00543     SeeAlso:    -
00544 
00545 ********************************************************************************************/
00546 
00547 KernelBitmap* GalleryLineDragInfo::GetSolidDragMask()
00548 {
00549     // Note we abuse this call (like our base class abuses this call) to create the bitmap
00550     // itself. We don't use DragMask itself anymore (i.e. it stays NULL)
00551     if (!DragMask && !TheBitmap)
00552     {
00553         DocView *View = DocView::GetCurrent();
00554         if (View == NULL)
00555         {
00556             return NULL;
00557         }
00558         
00559         Spread *pSpread = View->FindEnclosingSpread(OilCoord(0,0));
00560         if (pSpread == NULL)
00561         {
00562             return NULL;
00563         }
00564 
00565         // Find the size of the rendered item.
00566         DocRect ClipRegion(0,0, 750*100, 750*50);
00567 //      ClipRegion.lo.x = ClipRegion.lo.y = 0;
00568 //      SourceItem->GetSize(c_eLineAttrDragTextPos, &ClipRegion.hi.x, &ClipRegion.hi.y);
00569         Matrix ConvertMatrix;
00570         FIXED16 ViewScale = 1;
00571 
00572         wxScreenDC DisplayDC;
00573         double dpi = (double) OSRenderRegion::GetFixedDCPPI(DisplayDC).GetWidth();
00574 
00575         GRenderBitmap* pMaskRegion  = new GRenderBitmap(ClipRegion, ConvertMatrix, ViewScale, 
00576                                                         32, dpi);
00577 
00578         pMaskRegion->SetDoCompression(TRUE); // misnamed call to indicate we want transparency
00579         pMaskRegion->AttachDevice(View, &DisplayDC, pSpread);
00580 
00581         // Make a Mask Bitmap
00582         pMaskRegion->StartRender();
00583         SourceItem->Render(pMaskRegion, ClipRegion, c_eLineAttrDragTextPos);
00584         pMaskRegion->StopRender();
00585 
00586         OILBitmap* pOilMaskBmp = pMaskRegion->ExtractBitmap();
00587         TheBitmap = new KernelBitmap(pOilMaskBmp, TRUE);    
00588 
00589         delete pMaskRegion;
00590     }
00591 
00592     return BitmapDragInformation::GetSolidDragMask();
00593 }
00594 
00595 /********************************************************************************************
00596 
00597 >   BOOL GalleryLineDragInfo::DropStartOrEndArrow(Path* pPathHit, DocCoord DropPos,
00598                                               BOOL* IsStart)
00599 
00600     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00601     Created:    10/4/95       
00602     Returns:    -
00603     Purpose:    Checks to see whether the arrow was dropped nearer to the start or end of
00604                 a path.
00605     SeeAlso:    -
00606 
00607 ********************************************************************************************/
00608 
00609 BOOL GalleryLineDragInfo::DropStartOrEndArrow(Path* pPathHit, DocCoord DropPos,
00610                                               BOOL* IsStart)
00611 {
00612     double NearestDist = -1;
00613     BOOL GotNearest = FALSE;
00614     BOOL NearestIsStart = FALSE;
00615 
00616     DocCoord* Coords = pPathHit->GetCoordArray();
00617     PathVerb* Verbs  = pPathHit->GetVerbArray();
00618     INT32 NumCoords   = pPathHit->GetNumCoords();
00619 
00620     DocCoord ArrowCentre;
00621     DocCoord ArrowDirection;
00622 
00623     INT32 PathIndex = 0;
00624 
00625     // Find the first position of an ArrowHead
00626     BOOL GotPos = ArrowRec::GetFirstArrowPos(TRUE,
00627                                              Coords, Verbs, NumCoords, 
00628                                              &PathIndex, &ArrowCentre, &ArrowDirection);
00629     while (GotPos)
00630     {
00631         double Dist = ArrowCentre.Distance(DropPos);
00632 
00633         if (NearestDist == -1 || Dist < NearestDist)
00634         {
00635             NearestDist = Dist;
00636             GotNearest = TRUE;
00637             NearestIsStart = TRUE;
00638         }
00639 
00640         // Find the next Arrow position (if there are any more subpaths)
00641         GotPos = ArrowRec::GetNextArrowPos(TRUE,
00642                                            Coords, Verbs, NumCoords, 
00643                                            &PathIndex, &ArrowCentre, &ArrowDirection);
00644     }
00645 
00646     // Now test all the end positions
00647     PathIndex = 0;
00648 
00649     // Find the first position of an ArrowHead
00650     GotPos = ArrowRec::GetFirstArrowPos(FALSE,
00651                                          Coords, Verbs, NumCoords, 
00652                                          &PathIndex, &ArrowCentre, &ArrowDirection);
00653     while (GotPos)
00654     {
00655         double Dist = ArrowCentre.Distance(DropPos);
00656 
00657         if (NearestDist == -1 || Dist < NearestDist)
00658         {
00659             NearestDist = Dist;
00660             GotNearest = TRUE;
00661             NearestIsStart = FALSE;
00662         }
00663 
00664         // Find the next Arrow position (if there are any more subpaths)
00665         GotPos = ArrowRec::GetNextArrowPos(FALSE,
00666                                            Coords, Verbs, NumCoords, 
00667                                            &PathIndex, &ArrowCentre, &ArrowDirection);
00668     }
00669 
00670     if (GotNearest)
00671         *IsStart = NearestIsStart;
00672 
00673     return GotNearest;
00674 }
00675 
00676 /********************************************************************************************
00677 
00678 >   NodeAttribute* GalleryLineDragInfo::MakeStartOrEndArrow(NodeAttribute* pArrowAttr, BOOL Start)
00679 
00680     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00681     Created:    10/4/95       
00682     Returns:    -
00683     Purpose:    Makes a Start or End arrow depending on where the arrow was dropped.
00684     SeeAlso:    -
00685 
00686 ********************************************************************************************/
00687 
00688 NodeAttribute* GalleryLineDragInfo::MakeStartOrEndArrow(NodeAttribute* pArrowAttr, BOOL Start)
00689 {
00690     ArrowRec Arrow;
00691     NodeAttribute* NewAttr;
00692 
00693     if (IS_A(pArrowAttr, AttrStartArrow))
00694     {
00695         Arrow = ((AttrStartArrow*)pArrowAttr)->Value.StartArrow;
00696     }
00697     else
00698     {
00699         Arrow = ((AttrEndArrow*)pArrowAttr)->Value.EndArrow;
00700     }
00701 
00702     if (Start)
00703     {
00704         NewAttr = new AttrStartArrow(); 
00705         ((AttrStartArrow*)NewAttr)->Value.StartArrow = Arrow;
00706     }
00707     else
00708     {
00709         NewAttr = new AttrEndArrow();   
00710         ((AttrEndArrow*)NewAttr)->Value.EndArrow = Arrow;
00711     }
00712 
00713     delete pArrowAttr;
00714     return NewAttr;
00715 }

Generated on Sat Nov 10 03:48:55 2007 for Camelot by  doxygen 1.4.4