00001 // $Id: ngdrag.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 /* 00099 $Header: /Camelot/kernel/ngdrag.cpp 2 27/06/00 14:54 Justinf $ 00100 Attribute gallery mouse dragging operations 00101 */ 00102 00103 #include "camtypes.h" 00104 00105 #include "ngcore.h" 00106 #include "ngdrag.h" 00107 #include "ngitem.h" 00108 #include "ngsetop.h" 00109 00110 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "sginit.h" 00112 #include "dragmgr.h" 00113 00114 #include "scrvw.h" 00115 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 00117 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "ccdc.h" 00120 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00121 #include "grnddib.h" 00122 #include "grndbmp.h" 00123 #include "wbitmap.h" 00124 00125 //#include "resource.h" 00126 //#include "barsdlgs.h" 00127 //#include "galres.h" 00128 //#include "galstr.h" 00129 00130 //#include "mario.h" 00131 //#include "richard2.h" 00132 //#include "justin3.h" 00133 00134 #ifdef _DEBUG 00135 #undef THIS_FILE 00136 static char BASED_CODE THIS_FILE[] = __FILE__; 00137 #endif 00138 00139 DECLARE_SOURCE("$Revision: 1282 $"); 00140 00141 // Implement the dynamic class bits... 00142 CC_IMPLEMENT_DYNAMIC(SGNameDrag, BitmapDragInformation); 00143 CC_IMPLEMENT_DYNAMIC(SGNameDragTarget, SGListDragTarget); 00144 00145 // This line mustn't go before any CC_IMPLEMENT_... macros 00146 #define new CAM_DEBUG_NEW 00147 00148 00149 /******************************************************************************************** 00150 > SGNameDrag::SGNameDrag() 00151 00152 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00153 Created: 10/7/99 00154 Purpose: Default constructor, required for dynamic creation. 00155 ********************************************************************************************/ 00156 00157 SGNameDrag::SGNameDrag() 00158 : m_pSourceItem(0) 00159 { 00160 // Empty. 00161 } 00162 00163 00164 00165 /******************************************************************************************** 00166 > SGNameDrag::SGNameDrag(SGNameItem* pSourceItem, 00167 SGMouseInfo* pMouseInfo, 00168 SGMiscInfo* pMiscInfo) 00169 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00170 Created: 10/7/99 00171 Inputs: pSourceItem --- the gallery item from which the drag originated 00172 pMouseInfo --- the mouse info which made the item start the drag 00173 pMiscInfo --- the MiscInfo which accompanied the mouse event 00174 Purpose: Constructs a SGNameDrag object. 00175 ********************************************************************************************/ 00176 00177 SGNameDrag::SGNameDrag(SGNameItem* pSourceItem, SGMouseInfo* pMouseInfo, 00178 SGMiscInfo* pMiscInfo) 00179 : BitmapDragInformation( 00180 0, 00181 SG_DefaultNameText, 00182 SG_DefaultSmallIcon * NameGallery::Instance()->GetSelectedItemCount(), 00183 0, 0, pMouseInfo->MenuClick), 00184 m_pSourceItem(pSourceItem), 00185 m_MouseInfo(*pMouseInfo), 00186 m_MiscInfo(*pMiscInfo) 00187 { 00188 // Empty. 00189 } 00190 00191 00192 00193 /******************************************************************************************** 00194 > virtual SGNameDrag::~SGNameDrag() 00195 00196 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00197 Created: 10/7/99 00198 Purpose: Destroys a SGNameDrag object. 00199 ********************************************************************************************/ 00200 00201 SGNameDrag::~SGNameDrag() 00202 { 00203 // Tidy up (why doesn't the base class do this?) 00204 delete TheBitmap; 00205 TheBitmap = 0; 00206 } 00207 00208 00209 00210 /******************************************************************************************** 00211 > virtual void SGNameDrag::OnClick(INT32 nFlags, POINT ptClick) 00212 00213 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00214 Created: 10/7/99 00215 Inputs: nFlags --- which keys are depressed during the drag 00216 ptClick --- the position of the mosue click 00217 Purpose: This is called if a drag was attempted but never started because it was a 00218 click all along. It calls back the SourceItem SGDisplayLine, to get it 00219 to handle the click. 00220 ********************************************************************************************/ 00221 00222 void SGNameDrag::OnClick(INT32 nFlags, POINT ptClick) 00223 { 00224 if (m_pSourceItem != 0) 00225 m_pSourceItem->DragWasReallyAClick(&m_MouseInfo, &m_MiscInfo); 00226 } 00227 00228 00229 00230 /******************************************************************************************** 00231 > void SGNameDrag::GetCursorID(DragTarget* pDragTarget) 00232 00233 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00234 Created: 10/7/99 00235 Inputs: pDragTarget --- the drag target to set the cursor for 00236 Purpose: Set cursor over this target. 00237 ********************************************************************************************/ 00238 00239 UINT32 SGNameDrag::GetCursorID(DragTarget* pDragTarget) 00240 { 00241 // Only allow drops on the document view. 00242 if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget)) 00243 return _R(IDC_CANTDROP); 00244 00245 // If there's an object below the cursor then show the "can drop" cursor, otherwise 00246 // show the "can't drop" cursor. 00247 PageDropInfo pdInfo; 00248 ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo); 00249 return (pdInfo.pObjectHit != 0) ? _R(IDC_CANDROPONPAGE) : _R(IDC_CANTDROP); 00250 } 00251 00252 00253 00254 /******************************************************************************************** 00255 > virtual BOOL SGNameDrag::GetStatusLineText(String_256* pText, 00256 DragTarget* pDragTarget) 00257 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00258 Created: 10/7/99 00259 Inputs: pText --- where to output the status line text 00260 pDragTarget --- the target of the drag (ie. the document view) 00261 Returns: TRUE if the output string is valid. 00262 Purpose: Works out status line text for this target of a Name gallery item drag. 00263 ********************************************************************************************/ 00264 00265 BOOL SGNameDrag::GetStatusLineText(String_256* pText, DragTarget* pDragTarget) 00266 { 00267 // Validate outputs and object state. 00268 ERROR3IF(pText == 0, "SGNameDrag::GetStatusLineText: no output parameter"); 00269 if (TheBitmap == 0 || TheBitmap->ActualBitmap == 0) return FALSE; 00270 00271 // Only provide status-line help for drops on the document view. 00272 if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget)) 00273 return FALSE; 00274 00275 // Get the name and type of the item being dragged. 00276 String_256 strName; 00277 m_pSourceItem->GetNameText(&strName); 00278 String strTypeDesc(((SGNameGroup*) m_pSourceItem->GetParent())->GetTypeID()); 00279 00280 // Describe the object the mouse is over, if any. 00281 PageDropInfo pdInfo; 00282 ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo); 00283 NodeRenderableInk* pObjectHit = pdInfo.pObjectHit; 00284 if (pObjectHit == 0) 00285 pText->MakeMsg(_R(IDST_NAMEOP_CANT_DROP), &strName, &strTypeDesc); 00286 else 00287 { 00288 String_64 strObjectDesc; 00289 strObjectDesc = pObjectHit->Describe(FALSE); 00290 pText->MakeMsg(_R(IDST_NAMEOP_DROP_TO_APPLY), 00291 &strName, &strTypeDesc, &strObjectDesc, &strTypeDesc, &strName); 00292 } 00293 00294 return TRUE; 00295 } 00296 00297 00298 00299 /******************************************************************************************** 00300 > virtual BOOL SGNameDrag::CanDropOnPage() 00301 00302 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00303 Created: 10/7/99 00304 Returns: TRUE if the a name item can be dropped on a page (ie. a document view). 00305 Purpose: Called by the kernel dragging code to test whether a dragged name item 00306 can be dropped on a view onto a document. 00307 ********************************************************************************************/ 00308 00309 BOOL SGNameDrag::CanDropOnPage() 00310 { 00311 return TRUE; 00312 } 00313 00314 00315 00316 /******************************************************************************************** 00317 > virtual BOOL SGNameDrag::OnPageDrop(ViewDragTarget* pDragTarget) 00318 00319 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00320 Created: 10/7/99 00321 Inputs: pDragTarget --- the drag target representing the view onto 00322 a document (the "page"). 00323 Returns: TRUE if successful. 00324 Purpose: Called when a Name gallery item is dropped onto the page. 00325 ********************************************************************************************/ 00326 00327 BOOL SGNameDrag::OnPageDrop(ViewDragTarget* pDragTarget) 00328 { 00329 // Extract the address of the object dropped on and apply the dragged name 00330 // attribute to it. 00331 PageDropInfo pdInfo; 00332 pDragTarget->GetDropInfo(&pdInfo); 00333 if (pdInfo.pObjectHit != 0) 00334 { 00335 OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_APPLY_NAMES_TO_ONE); 00336 ERROR3IF(pDesc == 0, "SGNameDrag::OnPageDrop: no descriptor"); 00337 pDesc->Invoke(&OpParam((INT32) (Node*) pdInfo.pObjectHit, 0)); 00338 } 00339 00340 return TRUE; 00341 } 00342 00343 00344 00345 /******************************************************************************************** 00346 > virtual INT32 SGNameDrag::GetDragTransparency() 00347 00348 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00349 Created: 10/7/99 00350 Returns: A transparency value, in this case, 0% 00351 Purpose: Specifies how transparent a drag should be. 00352 ********************************************************************************************/ 00353 00354 INT32 SGNameDrag::GetDragTransparency() 00355 { 00356 // return 0; 00357 return 100; 00358 } 00359 00360 00361 00362 /******************************************************************************************** 00363 > virtual KernelBitmap* SGNameDrag::GetSolidDragMask() 00364 00365 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00366 Created: 10/7/99 00367 Returns: A pointer to a KernelBitmap to use as a 1bpp mask for the dragged item, 00368 or 0 for failure. 00369 Purpose: Renders an image of the dragged item into monochrome bitmap to use as an 00370 XOR mask for rendering the dragged Name gallery item. 00371 SeeAlso: SGNameDrag::MakeImage 00372 ********************************************************************************************/ 00373 00374 KernelBitmap* SGNameDrag::GetSolidDragMask() 00375 { 00376 // If the mask already exists then return it else else make it by rendering the 00377 // dragged item into a 1 bpp bitmap, and then return it. 00378 return (DragMask != 0) ? DragMask : DragMask = MakeImage(1); 00379 } 00380 00381 00382 00383 /******************************************************************************************** 00384 > virtual BOOL SGNameDrag::OnDrawSolidDrag(CPoint ptOrigin, CDC* pDC) 00385 00386 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00387 Inputs: See BitmapDragInformation::OnDrawSolidDrag 00388 Returns: TRUE if successful. 00389 Purpose: Renders an image of the dragged item into monochrome bitmap to use as an 00390 XOR mask for rendering the dragged Name gallery item. 00391 SeeAlso: SGNameDrag::MakeImage 00392 ********************************************************************************************/ 00393 00394 BOOL SGNameDrag::OnDrawSolidDrag(CPoint ptOrigin, CDC* pDC) 00395 { 00396 // If the dragged item's image doesn't exists then make it by rendering the item into 00397 // a bitmap with the same depth as the screen. 00398 if (TheBitmap == 0) TheBitmap = MakeImage(); 00399 return BitmapDragInformation::OnDrawSolidDrag(ptOrigin, pDC); 00400 } 00401 00402 00403 00404 /******************************************************************************************** 00405 > virtual KernelBitmap* SGNameDrag::MakeImage(UINT32 nDepth = 0) 00406 00407 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00408 Inputs: nDepth --- depth of bitmap to render into (default is screen 00409 depth) 00410 Returns: A pointer to the rendered image of an item in a KernelBitmap of the given 00411 depth, or 0 for failure. 00412 SeeAlso: SGNameDrag::OnDrawSolidDrag; SGNameDrag::GetSolidDragMask 00413 ********************************************************************************************/ 00414 00415 KernelBitmap* SGNameDrag::MakeImage(UINT32 nDepth) 00416 { 00417 // If there's no current View, or no Spread, then fail. 00418 DocView* pView = DocView::GetCurrent(); 00419 if (pView == 0) return 0; 00420 Spread* pSpread = pView->FindEnclosingSpread(OilCoord(0, 0)); 00421 if (pSpread == 0) return 0; 00422 00423 // Create a device context for the display. 00424 CDC sdc; 00425 sdc.CreateDC("DISPLAY", 0, 0, 0); 00426 00427 // Calculate the size of the rendering and set up the rendering matrix etc. 00428 Matrix matConvert; 00429 FIXED16 fxScale = 1; 00430 INT32 nSel = NameGallery::Instance()->GetSelectedItemCount(); 00431 DocRect drClip(0, 0, SG_DefaultNameText, nSel * SG_DefaultSmallIcon); 00432 00433 // Work out the destination bitmap's characteristics. 00434 double dpi = (double) GetDeviceCaps(sdc.m_hDC, LOGPIXELSX); 00435 if (nDepth == 0) 00436 nDepth = GetDeviceCaps(sdc.m_hDC, BITSPIXEL) * GetDeviceCaps(sdc.m_hDC, PLANES); 00437 00438 // Create a render region with the given properties of the display etc. 00439 GRenderBitmap* pRenderer = new GRenderBitmap(drClip, matConvert, fxScale, nDepth, dpi); 00440 ERRORIF(pRenderer == 0, _R(IDE_NOMORE_MEMORY), 0); 00441 pRenderer->AttachDevice(pView, &sdc, pSpread); 00442 pRenderer->StartRender(); 00443 pRenderer->SaveContext(); 00444 00445 // Blank the background. 00446 pRenderer->SetLineWidth(0); 00447 pRenderer->SetLineColour(COLOUR_WHITE); 00448 pRenderer->SetFillColour(COLOUR_WHITE); 00449 pRenderer->DrawRect(&drClip); 00450 00451 // Render the item's name. 00452 DocColour dcText(COLOUR_BLACK), dcBack(COLOUR_WHITE); 00453 pRenderer->SetFixedSystemTextColours(&dcText, &dcBack); 00454 00455 String_256 strName; 00456 m_pSourceItem->GetNameText(&strName); 00457 pRenderer->DrawFixedSystemText(&strName, drClip); 00458 00459 // Create a kernel bitmap from the OIL bitmap and return it. 00460 pRenderer->RestoreContext(); 00461 pRenderer->StopRender(); 00462 OILBitmap* pOilMaskBmp = pRenderer->ExtractBitmap(); 00463 delete pRenderer; 00464 00465 KernelBitmap* pkb = new KernelBitmap(pOilMaskBmp, TRUE); 00466 ERRORIF(pkb == 0, _R(IDE_NOMORE_MEMORY), 0); 00467 return pkb; 00468 } 00469 00470 00471 00472 /******************************************************************************************** 00473 > SGNameItem* SGNameDrag::GetDraggedNameAttr() 00474 00475 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00476 Created: 9/2/95 00477 Returns: A pointer to the NameGallery display item being dragged, 00478 ********************************************************************************************/ 00479 00480 SGNameItem* SGNameDrag::GetDraggedNameAttr() 00481 { 00482 return m_pSourceItem; 00483 } 00484 00485 00486 /******************************************************************************************** 00487 > SGNameDragTarget::SGNameDragTarget(CGadgetID idGadget = 0); 00488 00489 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00490 Created: 10/7/99 00491 Inputs: idGadget --- the gadget within that dialogue which is the target 00492 Purpose: Initialises a drag target for an item from the Name gallery. 00493 ********************************************************************************************/ 00494 00495 SGNameDragTarget::SGNameDragTarget(CGadgetID idGadget) 00496 : SGListDragTarget(NameGallery::Instance(), idGadget) 00497 { 00498 // Empty. 00499 } 00500 00501 00502 00503 /******************************************************************************************** 00504 BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo, 00505 OilCoord* pMousePos, KeyPress* pKeyPress) 00506 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00507 Created: 10/7/99 00508 Inputs: nEvent --- indicates what has happened 00509 pDragInfo --- points to drag information describing this drag. This 00510 should be a BitmapDragInformation or derivation thereof 00511 pMousePos --- points to information on the current mouse position, 00512 in OIL coords 00513 pKeyPress --- NULL, or if for a keypress event, keypress information 00514 Returns: TRUE to claim the event, FALSE to let it through to other targets 00515 Purpose: Event handler for SGNameItem gallery drag events. Overrides the 00516 base class handler to enable it to sort out the node being dragged 00517 for Name drags. 00518 ********************************************************************************************/ 00519 00520 BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo, 00521 OilCoord* pMousePos, KeyPress* pKeyPress) 00522 { 00523 ERROR3IF(!pDragInfo->IS_KIND_OF(SGNameDrag), 00524 "SGNameDragTarget::ProcessEvent: wrong kind of DragInfo"); 00525 00526 SGDisplayNode* pDraggedNode = ((SGNameDrag*) pDragInfo)->GetDraggedNameAttr(); 00527 if (pDraggedNode == 0) return FALSE; 00528 00529 switch (nEvent) 00530 { 00531 case DRAGEVENT_COMPLETED: 00532 // Drag just one item. 00533 HandleDragCompleted((NameGallery*) TargetDialog, pDraggedNode, pMousePos, TRUE); 00534 return TRUE; 00535 00536 case DRAGEVENT_MOUSEMOVED: 00537 case DRAGEVENT_MOUSESTOPPED: 00538 case DRAGEVENT_MOUSEIDLE: 00539 return DetermineCursorShape((NameGallery*) TargetDialog, pDraggedNode, pMousePos); 00540 } 00541 00542 // Not interested in any other event so don't claim it. 00543 return FALSE; 00544 }