Ejemplo n.º 1
0
BOOL ColourDragInformation::OnPageDrop(ViewDragTarget* pDragTarget)
{
	PageDropInfo ThePageDropInfo;
	((ViewDragTarget*)pDragTarget)->GetDropInfo(&ThePageDropInfo);

	DocCoord DragPos 			= ThePageDropInfo.DropPos;
	ObjectDragTarget TargetType = ThePageDropInfo.TargetHit;
	NodeRenderableInk* ThisNode = ThePageDropInfo.pObjectHit;

	// DMc 4/10/99
	// test for dragging & dropping onto a bevel/shadow/other compound node which
	// is grouped
	if (ThisNode)
	{
		if (ThisNode->FindParent())
		{
			if (!ThisNode->FindParent()->PromoteHitTestOnChildrenToMe())
			{
				// any compounds with their 'promotehittest' stuff set above me ?
				Node * pNode = ThisNode->FindParent();
				
				while (pNode)
				{
					if (pNode->IsAnObject())
					{
						if (pNode->PromoteHitTestOnChildrenToMe())
						{
							ThisNode = (NodeRenderableInk *)pNode;
						}
					}
					
					pNode = pNode->FindParent();
				}
			}
		}
	}

	NodeAttribute *Attrib = NULL;
	
	// Get a colour to apply to the Selected doc
	IndexedColour *IxColToApply = GetColourForDocument(NULL);

	// And make a DocColour to apply
	DocColour ColourToApply(COLOUR_TRANS);
	if (IxColToApply != NULL)
		ColourToApply.MakeRefToIndexedColour(IxColToApply);


 	if (TargetType == LINE_TARGET) // apply a stroke colour
	{
		// Apply a stroke colour to the object(s) we have been dropped onto
		Attrib = new AttrStrokeColourChange;
		if (Attrib == NULL)
			return FALSE;

		((AttrStrokeColourChange *)Attrib)->SetStartColour(&ColourToApply);
		AttributeManager::ApplyAttribToNode(ThisNode, Attrib);
	}
	else		  
	{
		// Apply a fill colour to the object(s) we have been dropped onto
		// This always used to be the case. If there were no objects then we
		// just set the current fill colour to be the new one.
		// Now, if no objects are the target then apply a page background colour
		// otherwise if control is held down set the current fill colour.
		
		BOOL Constrain = FALSE;

		// get object bounds
		DocRect pSimpleBounds;
		if (ThisNode)
			pSimpleBounds = ThisNode->GetBoundingRect();
		else
		{
			pSimpleBounds.MakeEmpty();
			// See if the control key is pressed
			Constrain = KeyPress::IsConstrainPressed();
		}

		// No node(s) are targetted so see if the constrain key is pressed or not
		if (ThisNode == NULL && Constrain)
		{
			// Use the colour to set the background
			// We should use the document given to us by the page info class
			OpBackgroundParam Param;
			Param.pDocColour = &ColourToApply;
			Param.pDoc = ThePageDropInfo.pDoc;			
			Param.pSpread = ThePageDropInfo.pSpread;
			
			// Obtain a pointer to the op descriptor for the create operation 
			OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BACKGROUND);

			// Invoke the operation, passing in our parameters
			pOpDesc->Invoke(&Param);
		}
		else
		{
			// Apply the colour either to the targetted node(s) or as the current
			// fill colour, if no nodes are targetted.
			Attrib = new AttrColourDrop(DragPos, pSimpleBounds, ColourToApply);
			if (Attrib == NULL)
				return FALSE;

			if (ThisNode)
				((AttrColourDrop*)Attrib)->SetObjectDroppedOn(ThisNode);

			AttributeManager::ApplyAttribToNode(ThisNode, Attrib);
		}
	}

	return TRUE;
}
Ejemplo n.º 2
0
void OpAlign::DoWithParam(OpDescriptor* pOp, OpParam* pAlignParam)
{
	// DMc alterations so that this works with compound nodes	
	SelRange   Selection(*(GetApplication()->FindSelection()));

	RangeControl rg = Selection.GetRangeControlFlags();
	rg.PromoteToParent = TRUE;
	Selection.Range::SetRangeControl(rg);

	DocRect		SelRect   = Selection.GetBoundingRect();
	DocRect		TargetRect;
	TargetRect.MakeEmpty();
	INT32        NumObjs   = Selection.Count();
	AlignParam* pAlign    =(AlignParam*)pAlignParam;

	BOOL moved=FALSE;					// set to TRUE if any object is moved
	BeginSlowJob(-1,FALSE);
	BOOL OK=DoStartTransOp(FALSE);

	// find parent spread of first object in selection
	Node*   pFirstNode=NULL;
	Spread* pSpread   =NULL;
	if (OK)
	{
		pFirstNode=Selection.FindFirst();
		if (pFirstNode!=NULL)
			pSpread=pFirstNode->FindParentSpread();
		OK=(pSpread!=NULL);
		if (!OK)
			ERROR2RAW("OpAlign::DoWithParam() - could not find parent spread");
	}

	// Find the size of the target rectangle
	if (pAlign->target==ToSelection)
		TargetRect=SelRect;
	else
	{
		Page* pPage=pSpread->FindFirstPageInSpread();
		while (pPage)
		{
			DocRect PageRect=pPage->GetPageRect();
			if (pAlign->target==ToSpread || SelRect.IsIntersectedWith(PageRect))
				TargetRect=TargetRect.Union(PageRect);
			pPage=pPage->FindNextPage();
		}
	}

	// allocate all dynamic memory required
	Node**	 pObj=NULL;
	ObjInfo* x   =NULL;
	ObjInfo* y   =NULL;
	INT32*    dx  =NULL;
	INT32*    dy  =NULL;
	if (OK)			ALLOC_WITH_FAIL(pObj,(Node**)  CCMalloc(NumObjs*sizeof(Node*)),  this);
	if (pObj!=NULL)	ALLOC_WITH_FAIL(x,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   x!=NULL) ALLOC_WITH_FAIL(y,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   y!=NULL) ALLOC_WITH_FAIL(dx,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	if (  dx!=NULL) ALLOC_WITH_FAIL(dy,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	OK=(dy!=NULL);

	// if memory claimed OK and target rect not empty proceed with op
	// (ie. do nothing if 'within page(s)' when no object on a page)
	DocRect EmptyRect;
	if (OK && TargetRect!=EmptyRect)
	{
		// create an array of pointers to objects (nodes) to be affected
		Node* pNode=Selection.FindFirst();
		INT32  i=0;
		while (pNode!=NULL)
		{
			if (pNode->IsBounded() && !((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE).IsEmpty())
				pObj[i++]=pNode;
			pNode=Selection.FindNext(pNode);
		}
		NumObjs=i;

		// cache x & y info in separate arrays so they can be sorted separately
		XLONG SumObjWidths =0;
		XLONG SumObjHeights=0;
		for (i=0; i<NumObjs; i++)
		{
			DocRect ObjRect=((NodeRenderableBounded*)pObj[i])->GetBoundingRect();
			x[i].i=i;
			x[i].lo=ObjRect.lo.x;
			x[i].hi=ObjRect.hi.x;
			SumObjWidths+=ObjRect.hi.x-ObjRect.lo.x;
			y[i].i=i;
			y[i].lo=ObjRect.lo.y;
			y[i].hi=ObjRect.hi.y;
			SumObjHeights+=ObjRect.hi.y-ObjRect.lo.y;
		}

		// for each object, calculate the x and y displacements independently
		AlignOneAxis(pAlign->h,NumObjs,SumObjWidths, TargetRect.lo.x,TargetRect.hi.x,x,dx);
		AlignOneAxis(pAlign->v,NumObjs,SumObjHeights,TargetRect.lo.y,TargetRect.hi.y,y,dy);

		// apply the x and y displacements simultaneously to each object
		for (i=0; i<NumObjs; i++)
			if (dx[i]!=0 || dy[i]!=0)
			{
				moved=TRUE;
				Trans2DMatrix* pMatrix=new Trans2DMatrix(dx[i],dy[i]);
				DoTransformNode((NodeRenderableInk*)pObj[i],pMatrix);
			}
	}

	// free up any memory which was allocated
	CCFree(dx);
	CCFree(dy);
	CCFree(x);
	CCFree(y);
	CCFree(pObj);

	if (moved)
	{
		Document::GetSelected()->ForceRedraw(pSpread, TargetRect);
		GetApplication()->UpdateSelection();
	}
	else
		FailAndExecute();
	End();
	EndSlowJob();
}