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; }
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(); }