// $Id: ngdrag.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ /* $Header: /Camelot/kernel/ngdrag.cpp 2 27/06/00 14:54 Justinf $ Attribute gallery mouse dragging operations */ #include "camtypes.h" #include "ngcore.h" #include "ngdrag.h" #include "ngitem.h" #include "ngsetop.h" //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "sginit.h" #include "dragmgr.h" #include "scrvw.h" //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "ccdc.h" //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "grnddib.h" #include "grndbmp.h" #include "wbitmap.h" //#include "resource.h" //#include "barsdlgs.h" //#include "galres.h" //#include "galstr.h" //#include "mario.h" //#include "richard2.h" //#include "justin3.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif DECLARE_SOURCE("$Revision: 1282 $"); // Implement the dynamic class bits... CC_IMPLEMENT_DYNAMIC(SGNameDrag, BitmapDragInformation); CC_IMPLEMENT_DYNAMIC(SGNameDragTarget, SGListDragTarget); // This line mustn't go before any CC_IMPLEMENT_... macros #define new CAM_DEBUG_NEW /******************************************************************************************** > SGNameDrag::SGNameDrag() Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Purpose: Default constructor, required for dynamic creation. ********************************************************************************************/ SGNameDrag::SGNameDrag() : m_pSourceItem(0) { // Empty. } /******************************************************************************************** > SGNameDrag::SGNameDrag(SGNameItem* pSourceItem, SGMouseInfo* pMouseInfo, SGMiscInfo* pMiscInfo) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: pSourceItem --- the gallery item from which the drag originated pMouseInfo --- the mouse info which made the item start the drag pMiscInfo --- the MiscInfo which accompanied the mouse event Purpose: Constructs a SGNameDrag object. ********************************************************************************************/ SGNameDrag::SGNameDrag(SGNameItem* pSourceItem, SGMouseInfo* pMouseInfo, SGMiscInfo* pMiscInfo) : BitmapDragInformation( 0, SG_DefaultNameText, SG_DefaultSmallIcon * NameGallery::Instance()->GetSelectedItemCount(), 0, 0, pMouseInfo->MenuClick), m_pSourceItem(pSourceItem), m_MouseInfo(*pMouseInfo), m_MiscInfo(*pMiscInfo) { // Empty. } /******************************************************************************************** > virtual SGNameDrag::~SGNameDrag() Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Purpose: Destroys a SGNameDrag object. ********************************************************************************************/ SGNameDrag::~SGNameDrag() { // Tidy up (why doesn't the base class do this?) delete TheBitmap; TheBitmap = 0; } /******************************************************************************************** > virtual void SGNameDrag::OnClick(INT32 nFlags, POINT ptClick) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: nFlags --- which keys are depressed during the drag ptClick --- the position of the mosue click Purpose: This is called if a drag was attempted but never started because it was a click all along. It calls back the SourceItem SGDisplayLine, to get it to handle the click. ********************************************************************************************/ void SGNameDrag::OnClick(INT32 nFlags, POINT ptClick) { if (m_pSourceItem != 0) m_pSourceItem->DragWasReallyAClick(&m_MouseInfo, &m_MiscInfo); } /******************************************************************************************** > void SGNameDrag::GetCursorID(DragTarget* pDragTarget) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: pDragTarget --- the drag target to set the cursor for Purpose: Set cursor over this target. ********************************************************************************************/ UINT32 SGNameDrag::GetCursorID(DragTarget* pDragTarget) { // Only allow drops on the document view. if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget)) return _R(IDC_CANTDROP); // If there's an object below the cursor then show the "can drop" cursor, otherwise // show the "can't drop" cursor. PageDropInfo pdInfo; ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo); return (pdInfo.pObjectHit != 0) ? _R(IDC_CANDROPONPAGE) : _R(IDC_CANTDROP); } /******************************************************************************************** > virtual BOOL SGNameDrag::GetStatusLineText(String_256* pText, DragTarget* pDragTarget) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: pText --- where to output the status line text pDragTarget --- the target of the drag (ie. the document view) Returns: TRUE if the output string is valid. Purpose: Works out status line text for this target of a Name gallery item drag. ********************************************************************************************/ BOOL SGNameDrag::GetStatusLineText(String_256* pText, DragTarget* pDragTarget) { // Validate outputs and object state. ERROR3IF(pText == 0, "SGNameDrag::GetStatusLineText: no output parameter"); if (TheBitmap == 0 || TheBitmap->ActualBitmap == 0) return FALSE; // Only provide status-line help for drops on the document view. if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget)) return FALSE; // Get the name and type of the item being dragged. String_256 strName; m_pSourceItem->GetNameText(&strName); String strTypeDesc(((SGNameGroup*) m_pSourceItem->GetParent())->GetTypeID()); // Describe the object the mouse is over, if any. PageDropInfo pdInfo; ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo); NodeRenderableInk* pObjectHit = pdInfo.pObjectHit; if (pObjectHit == 0) pText->MakeMsg(_R(IDST_NAMEOP_CANT_DROP), &strName, &strTypeDesc); else { String_64 strObjectDesc; strObjectDesc = pObjectHit->Describe(FALSE); pText->MakeMsg(_R(IDST_NAMEOP_DROP_TO_APPLY), &strName, &strTypeDesc, &strObjectDesc, &strTypeDesc, &strName); } return TRUE; } /******************************************************************************************** > virtual BOOL SGNameDrag::CanDropOnPage() Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Returns: TRUE if the a name item can be dropped on a page (ie. a document view). Purpose: Called by the kernel dragging code to test whether a dragged name item can be dropped on a view onto a document. ********************************************************************************************/ BOOL SGNameDrag::CanDropOnPage() { return TRUE; } /******************************************************************************************** > virtual BOOL SGNameDrag::OnPageDrop(ViewDragTarget* pDragTarget) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: pDragTarget --- the drag target representing the view onto a document (the "page"). Returns: TRUE if successful. Purpose: Called when a Name gallery item is dropped onto the page. ********************************************************************************************/ BOOL SGNameDrag::OnPageDrop(ViewDragTarget* pDragTarget) { // Extract the address of the object dropped on and apply the dragged name // attribute to it. PageDropInfo pdInfo; pDragTarget->GetDropInfo(&pdInfo); if (pdInfo.pObjectHit != 0) { OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_APPLY_NAMES_TO_ONE); ERROR3IF(pDesc == 0, "SGNameDrag::OnPageDrop: no descriptor"); pDesc->Invoke(&OpParam((INT32) (Node*) pdInfo.pObjectHit, 0)); } return TRUE; } /******************************************************************************************** > virtual INT32 SGNameDrag::GetDragTransparency() Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Returns: A transparency value, in this case, 0% Purpose: Specifies how transparent a drag should be. ********************************************************************************************/ INT32 SGNameDrag::GetDragTransparency() { // return 0; return 100; } /******************************************************************************************** > virtual KernelBitmap* SGNameDrag::GetSolidDragMask() Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Returns: A pointer to a KernelBitmap to use as a 1bpp mask for the dragged item, or 0 for failure. Purpose: Renders an image of the dragged item into monochrome bitmap to use as an XOR mask for rendering the dragged Name gallery item. SeeAlso: SGNameDrag::MakeImage ********************************************************************************************/ KernelBitmap* SGNameDrag::GetSolidDragMask() { // If the mask already exists then return it else else make it by rendering the // dragged item into a 1 bpp bitmap, and then return it. return (DragMask != 0) ? DragMask : DragMask = MakeImage(1); } /******************************************************************************************** > virtual BOOL SGNameDrag::OnDrawSolidDrag(CPoint ptOrigin, CDC* pDC) Author: Justin_Flude (Xara Group Ltd) Inputs: See BitmapDragInformation::OnDrawSolidDrag Returns: TRUE if successful. Purpose: Renders an image of the dragged item into monochrome bitmap to use as an XOR mask for rendering the dragged Name gallery item. SeeAlso: SGNameDrag::MakeImage ********************************************************************************************/ BOOL SGNameDrag::OnDrawSolidDrag(CPoint ptOrigin, CDC* pDC) { // If the dragged item's image doesn't exists then make it by rendering the item into // a bitmap with the same depth as the screen. if (TheBitmap == 0) TheBitmap = MakeImage(); return BitmapDragInformation::OnDrawSolidDrag(ptOrigin, pDC); } /******************************************************************************************** > virtual KernelBitmap* SGNameDrag::MakeImage(UINT32 nDepth = 0) Author: Justin_Flude (Xara Group Ltd) Inputs: nDepth --- depth of bitmap to render into (default is screen depth) Returns: A pointer to the rendered image of an item in a KernelBitmap of the given depth, or 0 for failure. SeeAlso: SGNameDrag::OnDrawSolidDrag; SGNameDrag::GetSolidDragMask ********************************************************************************************/ KernelBitmap* SGNameDrag::MakeImage(UINT32 nDepth) { // If there's no current View, or no Spread, then fail. DocView* pView = DocView::GetCurrent(); if (pView == 0) return 0; Spread* pSpread = pView->FindEnclosingSpread(OilCoord(0, 0)); if (pSpread == 0) return 0; // Create a device context for the display. CDC sdc; sdc.CreateDC("DISPLAY", 0, 0, 0); // Calculate the size of the rendering and set up the rendering matrix etc. Matrix matConvert; FIXED16 fxScale = 1; INT32 nSel = NameGallery::Instance()->GetSelectedItemCount(); DocRect drClip(0, 0, SG_DefaultNameText, nSel * SG_DefaultSmallIcon); // Work out the destination bitmap's characteristics. double dpi = (double) GetDeviceCaps(sdc.m_hDC, LOGPIXELSX); if (nDepth == 0) nDepth = GetDeviceCaps(sdc.m_hDC, BITSPIXEL) * GetDeviceCaps(sdc.m_hDC, PLANES); // Create a render region with the given properties of the display etc. GRenderBitmap* pRenderer = new GRenderBitmap(drClip, matConvert, fxScale, nDepth, dpi); ERRORIF(pRenderer == 0, _R(IDE_NOMORE_MEMORY), 0); pRenderer->AttachDevice(pView, &sdc, pSpread); pRenderer->StartRender(); pRenderer->SaveContext(); // Blank the background. pRenderer->SetLineWidth(0); pRenderer->SetLineColour(COLOUR_WHITE); pRenderer->SetFillColour(COLOUR_WHITE); pRenderer->DrawRect(&drClip); // Render the item's name. DocColour dcText(COLOUR_BLACK), dcBack(COLOUR_WHITE); pRenderer->SetFixedSystemTextColours(&dcText, &dcBack); String_256 strName; m_pSourceItem->GetNameText(&strName); pRenderer->DrawFixedSystemText(&strName, drClip); // Create a kernel bitmap from the OIL bitmap and return it. pRenderer->RestoreContext(); pRenderer->StopRender(); OILBitmap* pOilMaskBmp = pRenderer->ExtractBitmap(); delete pRenderer; KernelBitmap* pkb = new KernelBitmap(pOilMaskBmp, TRUE); ERRORIF(pkb == 0, _R(IDE_NOMORE_MEMORY), 0); return pkb; } /******************************************************************************************** > SGNameItem* SGNameDrag::GetDraggedNameAttr() Author: Justin_Flude (Xara Group Ltd) Created: 9/2/95 Returns: A pointer to the NameGallery display item being dragged, ********************************************************************************************/ SGNameItem* SGNameDrag::GetDraggedNameAttr() { return m_pSourceItem; } /******************************************************************************************** > SGNameDragTarget::SGNameDragTarget(CGadgetID idGadget = 0); Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: idGadget --- the gadget within that dialogue which is the target Purpose: Initialises a drag target for an item from the Name gallery. ********************************************************************************************/ SGNameDragTarget::SGNameDragTarget(CGadgetID idGadget) : SGListDragTarget(NameGallery::Instance(), idGadget) { // Empty. } /******************************************************************************************** BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo, OilCoord* pMousePos, KeyPress* pKeyPress) Author: Justin_Flude (Xara Group Ltd) Created: 10/7/99 Inputs: nEvent --- indicates what has happened pDragInfo --- points to drag information describing this drag. This should be a BitmapDragInformation or derivation thereof pMousePos --- points to information on the current mouse position, in OIL coords pKeyPress --- NULL, or if for a keypress event, keypress information Returns: TRUE to claim the event, FALSE to let it through to other targets Purpose: Event handler for SGNameItem gallery drag events. Overrides the base class handler to enable it to sort out the node being dragged for Name drags. ********************************************************************************************/ BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo, OilCoord* pMousePos, KeyPress* pKeyPress) { ERROR3IF(!pDragInfo->IS_KIND_OF(SGNameDrag), "SGNameDragTarget::ProcessEvent: wrong kind of DragInfo"); SGDisplayNode* pDraggedNode = ((SGNameDrag*) pDragInfo)->GetDraggedNameAttr(); if (pDraggedNode == 0) return FALSE; switch (nEvent) { case DRAGEVENT_COMPLETED: // Drag just one item. HandleDragCompleted((NameGallery*) TargetDialog, pDraggedNode, pMousePos, TRUE); return TRUE; case DRAGEVENT_MOUSEMOVED: case DRAGEVENT_MOUSESTOPPED: case DRAGEVENT_MOUSEIDLE: return DetermineCursorShape((NameGallery*) TargetDialog, pDraggedNode, pMousePos); } // Not interested in any other event so don't claim it. return FALSE; }