OpEditFill Class Reference

This operation edits an AttrLinearFill already in the tree. It is normally started when the Tool detects a drag on one of its selected blobs. More...

#include <opgrad.h>

Inheritance diagram for OpEditFill:

OpApplyAttribToSelected OpApplyAttrib SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpEditFill ()
 Dummy Contrustor.
void DoCreate (DocCoord &, Spread *, AttrFillGeometry *)
 

void DoDrag (DocCoord &, Spread *, AttrFillGeometry *, FillControl ControlHit)
 
  • Notes: Phil, 16-09-2005 This code relies on the attributea pplication code using DoHideNode and DoShowNode to record changes to the attributes. By recording the attributes in this way when they are first applied, the undo history contains pointers to them and the dragging code can then modify those attributes in the knowledge that the op history is now pointing at the modified attributes. It should really be changed to use OpApplyAttrInteractive. That would reduce the complexity of the following functions enormously and would be more consistent, smaller and possibly faster. There are too many different ways of "solid dragging" things and they should all: Record current tree state at start of drag Modify tree during drag Produce permanent Undo information at the end, using the same logic as would be used in the simple, parametric or outline drag case

virtual void DragPointerMove (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag)
 Recalculates the GradFill according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.
virtual void DragPointerIdle (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag)
 Recalculates the GradFill according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.
virtual void DragFinished (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL Success, BOOL bSolidDrag)
 If the drag was a success then a copy of the original node in the tree is created and updated GradFill built. The original NodeGradFill is hidden and the new one if inserted into the tree. If any of these things fail then the operation will fail.
virtual BOOL DragKeyPress (KeyPress *pKeyPress, BOOL bSolidDrag)
 Allows the Fill Edit operation to respond to key presses.
virtual void DragModeChanged (BOOL bSolidDrag)
 Find out if any of the key modifiers are being pressed when the mouse is not moving.
void RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag)
 Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.
BOOL GetStatusLineText (String_256 *pText, Spread *pSpread, DocCoord DocPos, ClickModifiers ClickMods)
 Gets the status text during the editing of a fill.
AttrFillGeometryGetGradFill ()

Static Public Member Functions

static BOOL Init ()
 Register this operation into the list of all operations.
static OpState GetState (String_256 *Description, OpDescriptor *)
 Used for greying etc of an operation.

Static Public Attributes

static BOOL InteractiveDragUpdate = TRUE
static BOOL ContinuousEOR = TRUE
static BOOL CreateFill = FALSE
static UINT32 IdleFillDelay = 200

Protected Member Functions

DocRect GetDragBlobRect ()
 This function finds the bounding rect that the parallelogram of the NodeGradFill we are using for EOR renderings parallelogram fits in.
void RedrawFills (ClickModifiers &ClickMods)
 Forces a redraw on the edited fills.
void CheckForCompoundRedraw ()
 Check to see if the redraw needs to invalidate a compound parent. (eg. a blend).
BOOL ApplyNewFill ()
 Applies the newly created fill to the selection.
BOOL ApplyEditedFill ()
 Applies the edited fill, back to the editing objects.
void SelectAllBlobs ()
 Selects all the Start or End fill blobs.
void RenderFinalBlobs (DocRect, Spread *, BOOL bSolidDrag)
 Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.
void RenderSelectionFillBlobs (SelRange *, DocRect, Spread *)
 Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.
void RenderInitSelectionBlobs (SelRange *, DocRect, Spread *)
 Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.
void RenderInitBlobs (DocRect, Spread *, BOOL bSolidDrag)
 Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.
double FindAspectRatio ()
 Find the aspect ratio of the bitmap we are creating.

Protected Attributes

AttrFillGeometryGradFill
AttrFillGeometryFillClone
SpreadStartSpread
FillControl DragControl
BaseDocumentpFillsDoc
DocRect LastDragRect
BOOL InvalidateAll
BOOL InvalidateCompound
NodepCompound
BOOL DragIsIdle
BOOL DoneIdleRedraw
MonotonicTime Time
BOOL ShowDragBlobs
BOOL DontDrawBlobs
BOOL AlwaysFail
BOOL ApplyAtEnd
BOOL ShouldApplyNewFill
BOOL ForceAspectLock
BOOL IsRequired
BOOL CheckForCompound
BOOL CallAllowOp
FlagState TranspState
List AttrGroups
double AspectRatio
DocCoord AnchorPos
DocCoord LastMousePosition

Private Member Functions

 CC_DECLARE_DYNCREATE (OpEditFill)

Detailed Description

This operation edits an AttrLinearFill already in the tree. It is normally started when the Tool detects a drag on one of its selected blobs.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/7/94

Definition at line 215 of file opgrad.h.


Constructor & Destructor Documentation

OpEditFill::OpEditFill  ) 
 

Dummy Contrustor.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94

Definition at line 183 of file opgrad.cpp.

00184 {
00185     // Initialise everything
00186     AlwaysFail          = TRUE;
00187     ApplyAtEnd          = TRUE;
00188     ForceAspectLock     = FALSE;
00189     CreateFill          = FALSE;
00190     IsRequired          = TRUE;
00191     ShouldApplyNewFill  = FALSE;
00192     CheckForCompound    = TRUE;
00193     CallAllowOp         = FALSE;
00194 
00195     InvalidateAll       = TRUE;
00196     InvalidateCompound  = FALSE;
00197 
00198     DragIsIdle          = FALSE;
00199     DoneIdleRedraw      = FALSE;
00200 
00201     ShowDragBlobs       = TRUE;
00202     DontDrawBlobs       = FALSE;
00203 
00204     EditFinished        = FALSE;
00205 
00206     AspectRatio = 1;
00207 }


Member Function Documentation

BOOL OpEditFill::ApplyEditedFill  )  [protected]
 

Applies the edited fill, back to the editing objects.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/5/95
Returns:
TRUE if fill was applied ok.

Definition at line 1447 of file opgrad.cpp.

01448 {
01449     // Put all the fills back like they were so undo will work
01450     ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
01451     while (pAttrPtr != NULL)
01452     {
01453         AttrFillGeometry* pAttr = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
01454 
01455         if (pAttr != GradFill)
01456         {
01457             pAttr->SetStartPoint(FillClone->GetStartPoint());
01458             pAttr->SetEndPoint(FillClone->GetEndPoint());
01459             pAttr->SetEndPoint2(FillClone->GetEndPoint2());
01460             pAttr->SetColourRamp(FillClone->GetColourRamp());
01461         }
01462 
01463         pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
01464     }
01465 
01466     SelRange *Selection = Camelot.FindSelection();
01467 
01468     DocRect Bounds;
01469     if (Selection != NULL && Selection->Count()>0)
01470         Bounds = Selection->GetBoundingRect();
01471     else
01472         Bounds = GetDragBlobRect();
01473 
01474     // Give the attribute a bounding rect
01475     GradFill->SetBoundingRect(Bounds);
01476 
01477     BeginSlowJob(-1, FALSE);
01478     AttributeManager::SendMessages = FALSE;
01479 
01480     // Now replace all the edited attributes with the new one
01481     AttributeManager::ReplaceAttributes(GradFill, &AttrFillGeometry::HitList);
01482     AttrFillGeometry::HitList.DeleteAll();
01483 
01484 //  BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::COLOURATTCHANGED)); 
01485 //  BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED)); 
01486     AttributeManager::SendMessages = TRUE;
01487     EndSlowJob();
01488 
01489     return TRUE;
01490 }

BOOL OpEditFill::ApplyNewFill  )  [protected]
 

Applies the newly created fill to the selection.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/5/95
Returns:
TRUE if fill was applied ok.

Definition at line 1278 of file opgrad.cpp.

01279 {
01280     ShouldApplyNewFill = FALSE;
01281 
01282     SelRange* pSel = GetApplication()->FindSelection();
01283     Range SelRng(*pSel);
01284     // >>Webster
01285     BOOL bShowProgress = TRUE;
01286 #ifndef EXCLUDE_FROM_XARALX 
01287     if (GetKeyState(CAMKEY(LBUTTON)) & 0x80)
01288         bShowProgress = FALSE;
01289 #endif
01290     // << Webster
01291 
01292     if (bShowProgress)
01293         BeginSlowJob(-1, FALSE);
01294 
01295     ObjChangeFlags cFlags;
01296     cFlags.Attribute = TRUE;
01297     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
01298     ObjChange.SetRetainCachedData(TRUE);
01299 
01300     if (!pSel->AllowOp(&ObjChange))
01301     {
01302         if (bShowProgress)
01303             EndSlowJob();
01304         return FALSE;
01305     }
01306 
01307     DoStartSelOp(FALSE,FALSE, TRUE,TRUE);
01308 
01309     // Before we apply the attribute to the selection we must localise all attributes
01310     // with the same type that we are going to apply. If we don't do this then the
01311     // tree will be left in an invalid state. 
01312 
01313     AttrTypeSet AttrTypes; 
01314     AttrTypes.AddToSet((GradFill->GetAttributeType())); 
01315 
01316     // Invalidate before
01317     if (!DoInvalidateRegions(&SelRng, 
01318                              GradFill, 
01319                              TRUE,
01320                              NULL,
01321                              FALSE))  //Mutators have to include bounds
01322     {
01323         if (bShowProgress)
01324             EndSlowJob();
01325         return FALSE;
01326     }
01327     
01328     if (!DoLocaliseForAttrChange(&SelRng, &AttrTypes))
01329     {
01330         if (bShowProgress)
01331             EndSlowJob();
01332         return FALSE;
01333     }
01334 
01335     // Apply the new fill to the selection
01336     //GradFill->SetColourRamp (
01337     
01338     //pAttr->SetColourRamp ((ColourRamp*) GradFill->GetFillRamp ());
01339     ApplyToSelection(GradFill, TRUE);
01340 
01341     // Having applied the attributes, we  must now try and factor out the newly 
01342     // applied attributes
01343     if (!DoFactorOutAfterAttrChange(&SelRng, 
01344                                     &AttrTypes))
01345     {
01346         if (bShowProgress)
01347             EndSlowJob();
01348         return FALSE;
01349     }
01350 
01351     // Invalidate after
01352     if (!DoInvalidateRegions(&SelRng, 
01353                              GradFill, 
01354                              TRUE,
01355                              NULL,
01356                              FALSE))  //Mutators have to include bounds
01357     {
01358         if (bShowProgress)
01359             EndSlowJob();
01360         return FALSE;
01361     }
01362 
01363     AttrTypes.DeleteAll();
01364 
01365     if (Document::GetSelected())
01366         Document::GetSelected()->SetModified(TRUE);
01367 
01368     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01369 ObjChange.SetRetainCachedData(TRUE);    // Tell TextStory not to invalidate everything in OnChildChange
01370     if (!UpdateChangedNodes(&ObjChange))
01371     {
01372         if (bShowProgress)
01373             EndSlowJob();
01374         return FALSE;
01375     }
01376 
01377     // Get the 'actual' fills back, so we can continue to drag them
01378     AttrFillGeometry* pFill = AttrFillGeometry::FindFirstSelectedAttr(GradFill->GetAttributeType());
01379 //  AttrFillGeometry* pFillToEdit = pFill;
01380 
01381     // Build a list of them
01382     while (pFill)
01383     {
01384         BOOL InList = FALSE;
01385 
01386         // We may have already hit this attribute if the selection is
01387         // inside a parent and have common attributes, so we need to
01388         // check and make sure this attribute is NOT in the list
01389         // already.
01390 
01391         if (!AttrFillGeometry::HitList.IsEmpty())
01392         {
01393             ListItem* pItem = AttrFillGeometry::HitList.GetHead();
01394 
01395             while (pItem)
01396             {
01397                 NodeAttributePtrItem* NodePtr = (NodeAttributePtrItem*)pItem;
01398 
01399                 if (NodePtr->NodeAttribPtr == pFill)
01400                 {
01401                     // Ignore this one, we've hit it already
01402                     InList = TRUE;
01403                     break;
01404                 }
01405 
01406                 pItem = AttrFillGeometry::HitList.GetNext(pItem);
01407             }
01408         }
01409 
01410         if (!InList)
01411         {
01412             // Add this to the list of fills to edit
01413             ListItem* pAttr = new NodeAttributePtrItem;
01414             if (pAttr == NULL)
01415             {
01416                 if (bShowProgress)
01417                     EndSlowJob();
01418                 return FALSE;
01419             }
01420 
01421             ERROR3IF(pFill->IsADefaultAttr(), "Default attr in hit list");
01422             ((NodeAttributePtrItem*)pAttr)->NodeAttribPtr = pFill;
01423 
01424             AttrFillGeometry::HitList.AddTail(pAttr);
01425         }
01426 
01427         pFill = AttrFillGeometry::FindNextSelectedAttr(GradFill->GetAttributeType());
01428     }
01429 
01430     if (bShowProgress)
01431         EndSlowJob();
01432 
01433     return TRUE;
01434 }

OpEditFill::CC_DECLARE_DYNCREATE OpEditFill   )  [private]
 

void OpEditFill::CheckForCompoundRedraw  )  [protected]
 

Check to see if the redraw needs to invalidate a compound parent. (eg. a blend).

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/5/95

Definition at line 801 of file opgrad.cpp.

00802 {
00803     CheckForCompound = FALSE;
00804 
00805     pFillsDoc = StartSpread->FindOwnerDoc();
00806 
00807     if (AttrFillGeometry::HitList.GetCount() == GetApplication()->FindSelection()->Count() ||
00808         AttrFillGeometry::HitList.GetCount() > 10)
00809     {
00810         // If we are dragging all selected fills, or if there are
00811         // more than 10 of them, then we'll just invalidate the 
00812         // whole selection, 'cus it's much quicker
00813         InvalidateAll = TRUE;
00814     }
00815     else
00816     {
00817         // We will invalidate just the edited fills
00818         InvalidateAll = FALSE;
00819     }
00820 
00821     InvalidateCompound = FALSE;
00822 
00823     if (AttrFillGeometry::HitList.GetCount() == 1)
00824     {
00825         // If just one Fill is being dragged, then check to see if
00826         // it's a 'Select Inside' of a Compound object.
00827 
00828         // If it is, then we'll need to update the whole compound parent.
00829 
00830         ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
00831         AttrFillGeometry* pGrad = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
00832 
00833         Node* pParent = pGrad->FindParent();
00834         if (pParent == NULL)
00835         {
00836             InvalidateAll = TRUE;
00837             return;
00838         }
00839     
00840         if (pParent->IsCompound())
00841         {
00842             // The parent is compound, so we'll just update that
00843             InvalidateAll = TRUE;
00844             InvalidateCompound = TRUE;
00845             pCompound = pParent;
00846         }
00847 
00848         // Is the parent a blend object, or is there one
00849         // further up the tree ?
00850         while (pParent != NULL && !pParent->IsLayer())
00851         {
00852             if (pParent->IS_KIND_OF(NodeBlend) || pParent->ShouldITransformWithChildren())
00853             {
00854                 // Found a blend, so we'll have to invalidate it
00855                 // each time we want to re-draw
00856                 InvalidateAll = TRUE;
00857                 InvalidateCompound = TRUE;
00858                 pCompound = pParent;
00859 
00860                 // We will call allowop, to invalidate the blend
00861                 CallAllowOp = TRUE;
00862 
00863                 // Don't break out yet, 'cus we need to invalidate
00864                 // the highest blend in the tree
00865             }
00866             
00867             pParent = pParent->FindParent();
00868         }
00869     }
00870 }

void OpEditFill::DoCreate DocCoord Start,
Spread pSpread,
AttrFillGeometry pGrad
 

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
Start - The starting position of the drag [INPUTS] pSpread - The spread that the drag started over pElip - The NodeGradFill that is being edited

Definition at line 222 of file opgrad.cpp.

00223 {
00224     ERROR3IF(pGrad == NULL, "Fill pointer is NULL in OpEditFill::DoCreate()");
00225 
00226     if (pGrad == NULL)
00227     {
00228         // Nothing to create !!
00229         FailAndExecute();
00230         End();
00231         return;
00232     }
00233 
00234     // DMc - do the attribute to change
00235     m_pAttr = (NodeAttribute *)pGrad;
00236 
00237     AlwaysFail = FALSE;
00238     
00239     // DMc - set this to TRUE
00240     ApplyAtEnd = FALSE;
00241     ForceAspectLock = TRUE;
00242     CreateFill = TRUE;
00243 
00244     // Get a description of the attribute being applied so that we can use it to create the 
00245     // undo string. 
00246     UndoAttribStrID = pGrad->GetAttrNameID();
00247     AttrFillGeometry::HitList.DeleteAll();
00248 
00249     SelRange* pSel = GetApplication()->FindSelection(); 
00250     if (pSel && pSel->Count() > 0)
00251     {
00252         // Check it's ok to apply to this object
00253         ObjChangeFlags cFlags;
00254         cFlags.Attribute = TRUE;
00255         ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00256 ObjChange.SetRetainCachedData(TRUE);        // Don't let nodes releasecached data - we will handle that!
00257         if (!pSel->AllowOp(&ObjChange))
00258         {
00259             delete pGrad;
00260             FailAndExecute();
00261             End();
00262             return;
00263         }
00264     }
00265 
00266     AttrFillGeometry* pFillToEdit = pGrad;
00267 
00268     // Now check to make sure someone in the selection will accept this attribute
00269     if (AttributeManager::CanBeAppliedToSelection(pGrad, &AttrGroups))
00270     {
00271         // We're gunna apply to at least one object
00272         IsRequired = TRUE;
00273 
00274         // Flag that we need to apply the fill, either when we try
00275         // and do an interective redraw, or at the end
00276         ShouldApplyNewFill = TRUE;
00277 
00278         // Remove all the existing selection fill blobs
00279         DocRect SelBounds = pSel->GetBlobBoundingRect();
00280         RenderInitSelectionBlobs(pSel, SelBounds, pSpread);
00281     }
00282     else
00283     {
00284         // This attribute is not required by any of the selection,
00285         // but we will continue, without actually applying anything,
00286         // and set the 'current' attribute instead
00287         IsRequired = FALSE;
00288         AttributeManager::pLastNodeAppliedTo = NULL;
00289     }
00290 
00291     // Snap the actual mouse position to the grid if needed
00292     DocView::SnapSelected(pSpread, &Start);
00293 
00294     // Initialise the Control Points
00295     pFillToEdit->SetStartPoint(&Start);
00296     pFillToEdit->SetEndPoint(&Start);
00297     pFillToEdit->SetEndPoint2(&Start);
00298 
00299     // Call the edit code
00300     DoDrag(Start, pSpread, pFillToEdit, FILLCONTROL_ENDPOINT);
00301 }

void OpEditFill::DoDrag DocCoord Start,
Spread pSpread,
AttrFillGeometry pGrad,
FillControl  ControlHit
 

  • Notes: Phil, 16-09-2005 This code relies on the attributea pplication code using DoHideNode and DoShowNode to record changes to the attributes. By recording the attributes in this way when they are first applied, the undo history contains pointers to them and the dragging code can then modify those attributes in the knowledge that the op history is now pointing at the modified attributes. It should really be changed to use OpApplyAttrInteractive. That would reduce the complexity of the following functions enormously and would be more consistent, smaller and possibly faster. There are too many different ways of "solid dragging" things and they should all: Record current tree state at start of drag Modify tree during drag Produce permanent Undo information at the end, using the same logic as would be used in the simple, parametric or outline drag case

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
Start - The starting position of the drag [INPUTS] pSpread - The spread that the drag started over pElip - The NodeGradFill that is being edited

Definition at line 330 of file opgrad.cpp.

00331 {
00332     ERROR3IF(ControlHit > NUMCONTROLPOINTS && 
00333         !ISA_RAMPINDEX(ControlHit), "Invalid control point in OpEditFill::DoDrag()");
00334     ERROR3IF(pGrad == NULL, "Fill pointer is NULL in OpEditFill::DoDrag()");
00335 
00336     if (pGrad == NULL)
00337     {
00338         // Nothing to edit !!
00339         FailAndExecute();
00340         End();
00341         return;
00342     }
00343 
00344     // Various starting positions
00345     StartSpread = pSpread;
00346     DragControl = ControlHit;
00347 
00348     // Keep a copy of the old fill, so we can put it back later if necessary
00349     CCRuntimeClass* ObjectType = pGrad->GetRuntimeClass();
00350     FillClone = (AttrFillGeometry*)ObjectType->CreateObject();
00351     *FillClone = *pGrad;
00352 
00353     // and make another copy to actually edit
00354     ObjectType = pGrad->GetRuntimeClass();
00355     GradFill = (AttrFillGeometry*)ObjectType->CreateObject();
00356     *GradFill = *pGrad;
00357 
00358     pParentOfFill = (NodeRenderableInk*) pGrad->FindParent ();
00359     pTheFill = pGrad;
00360 
00361     if (CreateFill)
00362         delete pGrad;   // Not needed any more
00363 
00364     AspectRatio = FindAspectRatio();
00365 
00366     AnchorPos = Start;
00367     LastMousePosition = Start;
00368 
00369     DontDrawBlobs = FALSE;
00370     DragIsIdle = FALSE;
00371     DoneIdleRedraw = FALSE;
00372 
00373 //  ShowDragBlobs = ContinuousEOR;
00374     ShowDragBlobs = !DocView::SolidDragging;
00375 
00376     if (!IsRequired)            // Always show blobs if we're gunna
00377         ShowDragBlobs = TRUE;   // set the current attribute
00378 
00379     AttrFillGeometry::DraggedFill = NULL;
00380     AttrFillGeometry::EditedFill  = GradFill;
00381 
00382     // And tell the Dragging system that we need drags to happen
00383     StartDrag(DRAGTYPE_AUTOSCROLL, NULL, NULL, TRUE, TRUE);         // We support solid dragging
00384 }

void OpEditFill::DragFinished DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread ,
BOOL  Success,
BOOL  bSolidDrag
[virtual]
 

If the drag was a success then a copy of the original node in the tree is created and updated GradFill built. The original NodeGradFill is hidden and the new one if inserted into the tree. If any of these things fail then the operation will fail.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
PointerPos - The current position of the mouse [INPUTS] ClickMods - Which buttons and modifiers are held down pSpread - The Spread that the mouse is over now. Success - TRUE if the drag was completed sucessfully.

Reimplemented from Operation.

Definition at line 1014 of file opgrad.cpp.

01015 {   
01016     EditFinished = TRUE;
01017     
01018     double APixel;
01019 
01020     // Flag to say if everything has worked
01021     BOOL IsOk = FALSE;
01022 
01023     // First Rub out the old Drag blobs
01024     if (!DontDrawBlobs && AttrFillGeometry::DraggedFill != NULL)
01025     {
01026         if (!(ISA_RAMPINDEX(DragControl)))
01027         {
01028             RenderDragBlobs(GradFill->GetBlobBoundingRect(), StartSpread, bSolidDrag);
01029         }
01030         else
01031         {
01032             if (ISA_RAMPINDEX (DragControl))
01033             {
01034                 GradFill->DisableBoundsRedraw ();
01035             }
01036             RenderDragBlobs(GradFill->GetBlobBoundingRect(), StartSpread, bSolidDrag);
01037             if (ISA_RAMPINDEX (DragControl))
01038             {
01039                 GradFill->EnableBoundsRedraw ();
01040             }
01041         }
01042     }
01043 
01044     DontDrawBlobs = FALSE;
01045     BOOL HaveFailed = FALSE;
01046 
01047     Document* pDoc = Document::GetSelected();
01048 
01049     // check for a fill ramp drag
01050     if (ISA_RAMPINDEX(DragControl))
01051     {
01052         if (Success)
01053         {
01054             if (GradFill->GetColourRamp())
01055             {
01056                 GradFill->GetColourRamp()->SortRamp();
01057             }
01058         }
01059     }
01060 
01061     // End the Drag                             
01062     if (!EndDrag())
01063     {
01064         delete FillClone;
01065         delete GradFill;
01066         goto EndOperation;
01067     }
01068 
01069     if (*GradFill->GetStartPoint() == *GradFill->GetEndPoint())
01070         Success = FALSE;
01071     
01072     APixel = (DocView::GetSelected()->GetScaledPixelWidth()).MakeDouble();
01073 
01074     // If the pointer has moved less than a few pixels, then just do a click
01075     if (PointerPos.Distance(AnchorPos) <= APixel*2)
01076         Success = FALSE;
01077 
01078     // If PointerPos is equal to AnchorPos, then it must have just been a click
01079     if (!Success || (PointerPos == AnchorPos))
01080     {
01081         if (AttrFillGeometry::DraggedFill)
01082         {
01083             // We must have actually dragged a bit,
01084             // so make sure we tidy everying, and then render
01085             // the old fill blobs back on
01086             AttrFillGeometry::DraggedFill = NULL;
01087             AttrFillGeometry::EditedFill = NULL;
01088 
01089             // Failed, so put all the fills back like they were,
01090             // if we have changed them.
01091             if (!(*GradFill == *FillClone))
01092             {
01093                 *GradFill = *FillClone;
01094 
01095                 ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
01096                 while (pAttrPtr != NULL)
01097                 {
01098                     AttrFillGeometry* pAttr = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
01099 ERROR3IF(pAttr->IsADefaultAttr(), "Default attr in hit list");
01100 
01101                     pAttr->SetStartPoint(FillClone->GetStartPoint());
01102                     pAttr->SetEndPoint(FillClone->GetEndPoint());
01103                     pAttr->SetEndPoint2(FillClone->GetEndPoint2());
01104 
01105                     NodeRenderableInk* pParent = (NodeRenderableInk*)pAttr->FindParent();
01106                     ERROR3IF(pParent==NULL, "Can't find parent of edited attribute");
01107                     if (pParent && pAttr->IsEffectAttribute())  // IsValidEffectAttr?
01108                     {
01109 //                      Node* pGrandParent = pParent->FindParent();
01110 //                      if (pGrandParent && pGrandParent->IsBounded())
01111 //                          ((NodeRenderableBounded*)pGrandParent)->ReleaseCached(TRUE, FALSE); // Parents only
01112                         pParent->ReleaseCached(TRUE, FALSE, FALSE, TRUE);   // Parents and derived data only
01113                     }
01114                     else
01115                         pParent->ReleaseCached();
01116 
01117                     pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
01118                 }
01119 
01120                 // Redraw the old fills back
01121                 DocRect SelBounds = GetApplication()->FindSelection()->GetBlobBoundingRect();
01122 
01123                 DocView::GetSelected()->ForceRedraw(StartSpread, SelBounds);
01124             }
01125 
01126         }
01127         else
01128         {
01129             // We didn't drag anything, so it must have just been a click
01130             if (ClickMods.Adjust && ClickMods.Constrain)
01131             {
01132                 // Cntrl/Shift/Click will select all Start or End blobs
01133                 SelectAllBlobs();
01134             }
01135 
01136             // Tell the world that a fill blob has been selected
01137             BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::COLOURATTCHANGED)); 
01138         }
01139 
01140         AttrFillGeometry::LastRenderedMesh = NULL;
01141         AttrFillGeometry::HitList.DeleteAll();
01142 
01143         delete FillClone;
01144         delete GradFill;
01145         goto EndOperation;      // This will fail the op
01146     }
01147 
01148     // We have edited the fill ok, so we'll draw the blobs back on
01149     AttrFillGeometry::DraggedFill = NULL;
01150 
01151     if (IsRequired)
01152         RenderFinalBlobs(GetDragBlobRect(), StartSpread, bSolidDrag);
01153 
01154     if (AlwaysFail)
01155     {
01156         // If we just edited a fill, then we don't want any undo info,
01157         // so we'll fail the op now (and discard the Actions), before we
01158         // apply the edited fill
01159         FailAndExecute();
01160         HaveFailed = TRUE;  // no need to fail at the end
01161     }
01162 
01163     // if the drag was a sucess then make a grad fill
01164     if (Success && (!GetDragBlobRect().IsEmpty()))
01165     {
01166         AttrFillGeometry::EditedFill = NULL;
01167         AttrFillGeometry::DraggedFill = NULL;
01168     
01169         if (ApplyAtEnd)
01170         {
01171             // Update all the edited fills
01172             ApplyEditedFill();
01173 
01174             delete FillClone;
01175             delete GradFill;
01176         }
01177         else
01178         {
01179             if (ShouldApplyNewFill)
01180             {
01181                 ApplyNewFill();
01182             }
01183 
01184             BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::COLOURATTCHANGED)); 
01185             BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED)); 
01186 
01187             SelRange *Selection = Camelot.FindSelection();
01188             DocRect Bounds;
01189             if (Selection != NULL && Selection->Count()>0)
01190                 Bounds = Selection->GetBoundingRect();
01191             else
01192                 Bounds = GetDragBlobRect();
01193 
01194             GradFill->SetBoundingRect(Bounds);
01195 
01196             // Ensure we update all the fills
01197             if (!AttrFillGeometry::HitList.IsEmpty())
01198             {
01199                 ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
01200 
01201                 while (pAttrPtr != NULL)
01202                 {
01203                     AttrFillGeometry* pAttr = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
01204 ERROR3IF(pAttr->IsADefaultAttr(), "Default attr in hit list");
01205 
01206                     // Update the control points on the other fills
01207                     pAttr->SetStartPoint(GradFill->GetStartPoint());
01208                     pAttr->SetEndPoint(GradFill->GetEndPoint());
01209                     pAttr->SetEndPoint2(GradFill->GetEndPoint2());
01210 
01211                     // Give the attribute a bounding rect
01212                     pAttr->SetBoundingRect(Bounds);
01213 
01214                     // We need to ensure that we force a redraw at the end of the drag
01215                     // because redraws during the drag will have been done with QuickRender turned
01216                     // on and so some slow objects may not have rendered themselves
01217                     // fully.
01218                     if (bSolidDrag)
01219                     {
01220                         Node* pParent = pAttr->FindParent();
01221                         if (pParent && pParent->IsBounded())
01222                         {
01223 ((NodeRenderableBounded*)pParent)->ReleaseCached(TRUE, FALSE, !pAttr->IsEffectAttribute(), TRUE);
01224                             DoInvalidateNodeRegion((NodeRenderableBounded*)pParent, FALSE, TRUE, FALSE, FALSE); // Do not recache
01225                             // (SelOperation::DoApply will have called ReleaseCached as needed)
01226                         }
01227                     }
01228 
01229                     pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
01230                 }
01231             }
01232             AttributeManager& AttrMgr = pDoc->GetAttributeMgr();
01233 
01234             if (AttrMgr.WeShouldMakeAttrCurrent(IsRequired,GradFill,&AttrGroups))
01235             {
01236                 AttributeManager::UpdateCurrentAttr(GradFill, TRUE, &AttrGroups);
01237             }
01238 
01239             delete FillClone;
01240             delete GradFill;
01241         }
01242 
01243         IsOk = TRUE;
01244     }
01245 
01246 EndOperation:
01247 
01248     // DMc - should inform all nodes at the end of a drag too
01249     AttrFillGeometry::EditedFill = NULL;
01250     AttrFillGeometry::DraggedFill = NULL;
01251     AttrFillGeometry::HitList.DeleteAll();
01252     CreateFill = FALSE;
01253 
01254     // Don't forget the AttrGroups List
01255     AttrGroups.DeleteAll();
01256 
01257     // If something went wrong, then fail (if we haven't already)
01258     if (!IsOk && !HaveFailed)
01259     {
01260         FailAndExecute();
01261     }
01262 
01263     // always call end
01264     End();
01265 }

BOOL OpEditFill::DragKeyPress KeyPress pKeyPress,
BOOL  bSolidDrag
[virtual]
 

Allows the Fill Edit operation to respond to key presses.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/5/95
Parameters:
pKeyPress - Object describing the nature of the keypress. [INPUTS]

Reimplemented from Operation.

Definition at line 936 of file opgrad.cpp.

00937 {
00938     if (pKeyPress->GetVirtKey() == CAMKEY(TAB) && 
00939         pKeyPress->IsPress() &&
00940         !pKeyPress->IsRepeat())
00941     {
00942         // Toggle the continuous EOR flag
00943         ContinuousEOR = !ContinuousEOR;
00944         ShowDragBlobs = ContinuousEOR;
00945 
00946         String_256 DragText;
00947         ClickModifiers ClickMods;
00948 
00949         // Now update the Status line to show the mode change
00950         GetStatusLineText(&DragText, StartSpread, LastMousePosition, ClickMods);
00951         GetApplication()->UpdateStatusBarText(&DragText);
00952         
00953         return TRUE;
00954     }
00955     return FALSE;
00956 }

void OpEditFill::DragModeChanged BOOL  bSolidDrag  )  [virtual]
 

Find out if any of the key modifiers are being pressed when the mouse is not moving.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/12/2003
Parameters:
pKeyPress - pointer to a keypress object [INPUTS]
Returns:
TRUE if it handled the keypress, FALSE otherwise

Reimplemented from Operation.

Definition at line 974 of file opgrad.cpp.

00975 {
00976 /*  DocView* pDocView = DocView::GetSelected();
00977     BlobManager* pBlobManager = Camelot.GetBlobManager();
00978     ENSURE(pBlobManager, "Can't get BlobManager");
00979 
00980     // Toggle the continuous EOR flag
00981     ContinuousEOR = !bSolidDrag;
00982     ShowDragBlobs = ContinuousEOR;
00983 
00984     String_256 DragText;
00985     ClickModifiers ClickMods;
00986 
00987     // Now update the Status line to show the mode change
00988     GetStatusLineText(&DragText, StartSpread, LastMousePosition, ClickMods);
00989     GetApplication()->UpdateStatusBarText(&DragText);
00990 */
00991 }

void OpEditFill::DragPointerIdle DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Recalculates the GradFill according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
PointerPos - The current position of the mouse [INPUTS] ClickMods - Which buttons and modifiers are held down pSpread - The Spread that the mouse is over now.

Reimplemented from Operation.

Definition at line 888 of file opgrad.cpp.

00889 {   
00890     if (!DragIsIdle)
00891     {
00892         // The Mouse has just become idle, so we'll reset the timer.
00893         DragIsIdle = TRUE;
00894         DoneIdleRedraw = FALSE;
00895         Time.Sample();
00896     }       
00897     else
00898     {
00899         // Has the Mouse been idle for long enough ?
00900         if (Time.Elapsed(IdleFillDelay))
00901         {
00902             if (DontDrawBlobs)
00903             {
00904                 // If we are not redrawing the EOR blobs constantly,
00905                 // then we will stick them back on when the mouse
00906                 // has been idle for a while.
00907                 DontDrawBlobs = FALSE;
00908                 DragIsIdle = FALSE;
00909                 RenderDragBlobs(LastDragRect, StartSpread, bSolidDrag);
00910             }
00911             else
00912             {
00913                 // If we ARE redrawing the blobs, then we'll try and redraw
00914                 // the fills when the mouse has been idle for a while.
00915                 if (InteractiveDragUpdate && !DoneIdleRedraw)
00916                 {
00917                     RedrawFills(ClickMods);
00918                     DoneIdleRedraw = TRUE;
00919                 }
00920             }
00921         }
00922     }
00923 }

void OpEditFill::DragPointerMove DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Recalculates the GradFill according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
PointerPos - The current position of the mouse [INPUTS] ClickMods - Which buttons and modifiers are held down pSpread - The Spread that the mouse is over now.

Reimplemented from Operation.

Definition at line 402 of file opgrad.cpp.

00403 {
00404     if (ISA_RAMPINDEX(DragControl) && !bSolidDrag)
00405     {
00406         GradFill->DisableRampRedraw();
00407     }
00408     
00409     if (EditFinished)
00410         return;
00411 
00412     if (ForceAspectLock)
00413         ClickMods.Adjust = TRUE;
00414 
00415     DragIsIdle = FALSE;
00416     DoneIdleRedraw = FALSE;
00417 
00418     // Snap the actual mouse position to the grid if needed
00419     DocView::SnapSelected(pSpread, &PointerPos);
00420 
00421     if (AttrFillGeometry::DraggedFill == NULL)
00422     {
00423         double APixel = (DocView::GetSelected()->GetScaledPixelWidth()).MakeDouble();
00424 
00425         // If the pointer has moved less than a few pixels, then do nothing
00426         if (PointerPos.Distance(AnchorPos) <= APixel*2)
00427         {
00428             if (!(ISA_RAMPINDEX(DragControl)))
00429             {
00430                 return;
00431             }
00432         }
00433 
00434         // This is the first time the pointer has moved ....
00435         if (!CreateFill)
00436         {
00437             // If we are editing a fill, the check with it's parent
00438             // to make sure it's ok (Mould's will say 'no').
00439 
00440             ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
00441             AttrFillGeometry* pGrad = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
00442 
00443             if (pGrad != NULL)
00444             {
00445                 Node* pParent = pGrad->FindParent();
00446 
00447                 if (pParent != NULL)
00448                 {
00449                     // Check it's ok to edit this fill
00450                     ObjChangeFlags cFlags;
00451                     cFlags.Attribute = TRUE;
00452                     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00453 ObjChange.SetRetainCachedData(TRUE);
00454 
00455                     if (!pParent->AllowOp(&ObjChange))
00456                     {
00457                         // Parent said 'no', so abort the edit
00458     
00459                         EndDrag();
00460                         delete FillClone;
00461                         delete GradFill;
00462 
00463                         FailAndExecute();
00464                         End();
00465                         return;
00466                     }
00467                 }
00468             }
00469         }
00470 
00471         AttrFillGeometry::EditedFill  = GradFill;
00472 
00473         AttrFillGeometry::LastRenderedStartBlob = DocCoord(0,0);
00474         AttrFillGeometry::LastRenderedEndBlob = DocCoord(0,0);
00475         AttrFillGeometry::LastRenderedEnd2Blob = DocCoord(0,0);
00476         AttrFillGeometry::LastRenderedEnd3Blob = DocCoord(0,0);
00477 
00478         // First Rub out the old Fill blobs
00479         RenderInitBlobs(GradFill->GetBlobBoundingRect(), StartSpread, bSolidDrag);
00480 
00481         GradFill->SetBlobState(DragControl, TRUE);
00482 
00483         // And stop any more from being drawn for now
00484         AttrFillGeometry::DraggedFill = GradFill;
00485 
00486         LastDragRect = GradFill->GetBlobBoundingRect();
00487         DontDrawBlobs = !ShowDragBlobs;
00488 
00489         // Now draw in the new 'Drag' blobs
00490         RenderDragBlobs(LastDragRect, StartSpread, bSolidDrag);
00491 
00492         // Update the status line to show we are dragging a fill
00493         String_256 DragText;
00494         GetStatusLineText(&DragText, pSpread, PointerPos, ClickMods);
00495         GetApplication()->UpdateStatusBarText(&DragText);
00496     }
00497 
00498     // If the mouse is in a different position then do something
00499     if (PointerPos != LastMousePosition)
00500     {
00501         // First Rub out the old Drag blobs
00502         RenderDragBlobs(LastDragRect, StartSpread, bSolidDrag);
00503 
00504         // Make sure that the coords are relative to the correct spread
00505         if (pSpread != StartSpread)
00506             PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos);
00507 
00508         // Update the last mouse position and re-calc the bounding rect
00509         GradFill->OnControlDrag(PointerPos, DragControl, ClickMods);
00510 
00511         LastMousePosition = PointerPos;
00512 
00513         // If we are creating a fill, then we'll try and create it with the
00514         // correct aspect ratio
00515         if (ForceAspectLock)
00516             GradFill->SetAspectRatio(AspectRatio);
00517 
00518         LastDragRect = GradFill->GetBlobBoundingRect();
00519         DontDrawBlobs = !ShowDragBlobs;
00520 
00521         // Render 'On' the blobs in the new position
00522         RenderDragBlobs(LastDragRect, StartSpread, bSolidDrag);
00523 
00524         if (DontDrawBlobs)
00525             RedrawFills(ClickMods);     // We're in 'Solid update' mode
00526     }
00527 
00528     if (ISA_RAMPINDEX(DragControl))
00529     {
00530         GradFill->EnableRampRedraw ();
00531     }
00532 }

double OpEditFill::FindAspectRatio  )  [protected]
 

Find the aspect ratio of the bitmap we are creating.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/5/95

Definition at line 544 of file opgrad.cpp.

00545 {
00546     // Are we creating a Bitmap fill ?
00547     if (!GradFill->IsABitmapFill())
00548         return 1;
00549 
00550     SelRange* pSel = GetApplication()->FindSelection();
00551 
00552     NodeAttribute* pCommonAttr;
00553     SelRange::CommonAttribResult Result;
00554     
00555     // Find the common attr in the selection
00556     Result = pSel->FindCommonAttribute(GradFill->GetAttributeType(), &pCommonAttr);
00557 
00558     KernelBitmap* Bmp = NULL;
00559 
00560     if (Result == SelRange::ATTR_COMMON)
00561     {
00562         // There is a common attr, so if it's a Bitmap Fill,
00563         // then use that bitmaps aspect ratio
00564         AttrFillGeometry* pFill = (AttrFillGeometry*)pCommonAttr;
00565 
00566         if (pFill->IsABitmapFill())
00567             Bmp = pFill->GetBitmap();
00568 
00569         GradFill->AttachBitmap(Bmp);
00570     }
00571     else
00572     {
00573         // Otherwise just use the default
00574         Bmp = GradFill->GetBitmap();
00575     }
00576 
00577     if (Bmp == NULL)
00578         return 1;
00579 
00580     BitmapInfo Info;
00581 
00582     if (Bmp->ActualBitmap &&
00583         Bmp->ActualBitmap->GetInfo( &Info ))
00584     {
00585         INT32 BitmapWidth  = Info.RecommendedWidth;
00586         INT32 BitmapHeight = Info.RecommendedHeight;
00587 
00588         // Calculate the aspect ratio of the bitmap
00589         return double(BitmapHeight)/double(BitmapWidth);
00590     }
00591 
00592     // Default to square
00593     return 1;
00594 }

DocRect OpEditFill::GetDragBlobRect  )  [protected]
 

This function finds the bounding rect that the parallelogram of the NodeGradFill we are using for EOR renderings parallelogram fits in.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Returns:
The bounding rect of the NodeGradFill parallelogram

Definition at line 1536 of file opgrad.cpp.

01537 {
01538     return GradFill->GetBlobBoundingRect();
01539 }

AttrFillGeometry* OpEditFill::GetGradFill  )  [inline]
 

Definition at line 244 of file opgrad.h.

00244 { return GradFill; }

OpState OpEditFill::GetState String_256 Description,
OpDescriptor
[static]
 

Used for greying etc of an operation.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
Description - the description of the operation [INPUTS]
Returns:
The State of the operation

Reimplemented from OpApplyAttribToSelected.

Definition at line 1854 of file opgrad.cpp.

01855 {
01856     OpState Blobby;
01857     
01858     return Blobby;
01859 }

BOOL OpEditFill::GetStatusLineText String_256 pText,
Spread pSpread,
DocCoord  DocPos,
ClickModifiers  ClickMods
[virtual]
 

Gets the status text during the editing of a fill.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/1/95
Parameters:
pSpread - pioter to spread mouse is over [INPUTS] DocPos - position of mouse in doc Mods - click modifiers
pText - buffer for StatusLine text [OUTPUTS]
Returns:
FALSE if fails

Reimplemented from Operation.

Definition at line 1780 of file opgrad.cpp.

01782 {
01783     if (GradFill == NULL)
01784     {
01785         *pText="";      // We don't seem to be doing anything at the moment !
01786         return TRUE;
01787     }
01788 
01789     pText->Load(_R(IDS_K_OPGRAD_EDITING));
01790 
01791     String_256 FillName;
01792     if (FillName.Load(GradFill->GetAttrNameID()))
01793     {
01794         // Add the description of the attribute onto the base string
01795         *pText += FillName;
01796 
01797         if (ContinuousEOR)
01798         {
01799             *pText += String_256(_R(IDS_K_OPGRAD_IMMEDIATE));
01800         }
01801         else
01802         {
01803             if (InteractiveDragUpdate)
01804             {
01805                 *pText += String_256(_R(IDS_K_OPGRAD_BACKGROUND));
01806             }
01807             else
01808             {
01809                 *pText += String_256(_R(IDS_K_OPGRAD_NOUPDATE));
01810             }
01811         }
01812 
01813         return TRUE;
01814     }
01815 
01816     return FALSE;
01817 }

BOOL OpEditFill::Init void   )  [static]
 

Register this operation into the list of all operations.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Returns:
TRUE if it works, FALSE if not

Reimplemented from OpApplyAttribToSelected.

Definition at line 1830 of file opgrad.cpp.

01831 {
01832     return (RegisterOpDescriptor(   0, 
01833                                     _R(IDS_EDITFILLOP),
01834                                     CC_RUNTIME_CLASS(OpEditFill), 
01835                                     OPTOKEN_EDITFILL,
01836                                     OpEditFill::GetState,
01837                                     0,  /* help ID */
01838                                     0,
01839                                     0   /* bitmap ID */));
01840 }

void OpEditFill::RedrawFills ClickModifiers ClickMods  )  [protected]
 

Forces a redraw on the edited fills.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/5/95

Definition at line 606 of file opgrad.cpp.

00607 {
00608     if (ClickMods.Alternative1)
00609         return;         // Alt key stops interactive updates
00610 
00611     // Prevent slow renderers from doing their stuff while we try to
00612     // show the results of the feather op interactively.
00613     Operation::SetQuickRender(TRUE);
00614 
00615     if (ShouldApplyNewFill)
00616     {
00617         // If we haven't applied the new fill yet, then we should
00618         // do so now.
00619         ApplyNewFill();
00620     }
00621 
00622     if (CheckForCompound)
00623     {
00624         // If we haven't already done so, we check to see if we need
00625         // to invalidate any compound parents.
00626         CheckForCompoundRedraw();
00627     }
00628 
00629     if (!AttrFillGeometry::HitList.IsEmpty())
00630     {
00631         DocView* pSelView = DocView::GetSelected();
00632 
00633         // Scan the List of Fills
00634         ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
00635 
00636         DocRect SelBounds = GetApplication()->FindSelection()->GetBoundingRect();
00637 
00638         while (pAttrPtr != NULL)
00639         {
00640             AttrFillGeometry* pAttr = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
00641             ERROR3IF(pAttr->IsADefaultAttr(), "Default attr in hit list");
00642 
00643             if (pAttr != GradFill)
00644             {
00645                 if (ISA_RAMPINDEX(DragControl))
00646                 {
00647                     AttrFillGeometry* CurrentFill = AttrFillGeometry::DraggedFill;
00648                     
00649                     AttrFillGeometry::DraggedFill = pAttr;
00650                     DocRect Current = pAttr->GetBlobBoundingRect ();
00651                     SelBounds = SelBounds.Union (Current);
00652 
00653                     AttrFillGeometry::DraggedFill = CurrentFill;
00654                 }
00655                 
00656                 // Update the control points on the other fills
00657                 pAttr->SetStartPoint(GradFill->GetStartPoint());
00658                 pAttr->SetEndPoint(GradFill->GetEndPoint());
00659                 pAttr->SetEndPoint2(GradFill->GetEndPoint2());
00660                 pAttr->SetColourRamp(GradFill->GetColourRamp());
00661                 //pAttr->DisableRampRedraw ();
00662 
00663                 pAttr->RecalcFractal();
00664             }
00665 
00666             if (!InvalidateAll)
00667             {
00668                 // Force the fills parent object to redraw
00669                 NodeRenderableInk* pParent = (NodeRenderableInk*)pAttr->FindParent();
00670                 ERROR3IF(pParent==NULL, "Can't find parent of edited attribute");
00671                 if (pParent && pAttr->IsEffectAttribute())  // IsValidEffectAttr?
00672                 {
00673 //                  Node* pGrandParent = pParent->FindParent();
00674 //                  if (pGrandParent && pGrandParent->IsBounded())
00675 //                      ((NodeRenderableBounded*)pGrandParent)->ReleaseCached(TRUE, FALSE); // Parents only
00676                     pParent->ReleaseCached(TRUE, FALSE, FALSE, TRUE);   // Parents and derived data only
00677                 }
00678                 else
00679                     pParent->ReleaseCached();
00680                 pSelView->ForceRedraw(StartSpread, pParent->GetBoundingRect(), FALSE, pAttr);
00681                 GetApplication ()->ServiceRendering ();
00682             }
00683 
00684             pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
00685         }
00686 
00687         if (InvalidateAll)
00688         {
00689             // Either there were too many objects to invalidate individually,
00690             // or there is a Compound Parent to invalidate
00691             if (InvalidateCompound)
00692             {
00693                 pAttrPtr = AttrFillGeometry::HitList.GetHead();
00694                 AttrFillGeometry* pGrad = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
00695 
00696                 if (CallAllowOp && !pGrad->IsEffectAttribute())
00697                 {
00698                     // For a blend, we need to make sure it re-blends itself,
00699                     // so we need to call AllowOp on it ...
00700 
00701                     ObjChangeFlags cFlags;
00702                     cFlags.Attribute = TRUE;        // Needed to make Blends re-calc themselves
00703 
00704                     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL, this);
00705 
00706                     pGrad->AllowOp(&ObjChange);
00707 
00708                     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL, this);
00709                     UpdateAllChangedNodes(&ObjChange);
00710                 }
00711 
00712                 if (ISA_RAMPINDEX (DragControl))
00713                 {
00714                     GradFill->DisableBoundsRedraw();
00715                 }
00716 
00717                 NodeRenderableInk* pParent = (NodeRenderableInk*)pCompound;
00718                 ERROR3IF(pParent==NULL, "Can't find parent of edited attribute");
00719                 if (pParent && pGrad->IsEffectAttribute())  // IsValidEffectAttr?
00720                 {
00721 //                  Node* pGrandParent = pParent->FindParent();
00722 //                  if (pGrandParent && pGrandParent->IsBounded())
00723 //                      ((NodeRenderableBounded*)pGrandParent)->ReleaseCached(TRUE, FALSE); // Parents only
00724                     pParent->ReleaseCached(TRUE, FALSE, FALSE, TRUE);   // Parents and derived data only
00725                 }
00726                 else
00727                     pParent->ReleaseCached();
00728                 pSelView->ForceRedraw(StartSpread, pParent->GetBoundingRect(), FALSE, pGrad);
00729                 GetApplication ()->ServiceRendering();
00730 
00731                 if (ISA_RAMPINDEX (DragControl))
00732                 {
00733                     GradFill->EnableBoundsRedraw();
00734                 }
00735             }
00736             else
00737             {           
00738                 if (ISA_RAMPINDEX (DragControl))
00739                 {
00740                     GradFill->DisableBoundsRedraw();
00741                 }
00742                 
00743                 // Oh sod it. Just invalidate the whole blinking lot of them,
00744                 // and be done with it.
00745                 //DocRect SelBounds = GetApplication()->FindSelection()->GetBoundingRect();
00746 
00747                 // Scan the List of Fills and ensure that none of them are cached...
00748                 ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
00749                 Node* pBackMost = NULL;
00750                 while (pAttrPtr != NULL)
00751                 {
00752                     AttrFillGeometry* pAttr = (AttrFillGeometry*)((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
00753 
00754                     // Force the fills parent object to redraw
00755                     NodeRenderableInk* pParent = (NodeRenderableInk*)pAttr->FindParent();
00756                     ERROR3IF(pParent==NULL, "Can't find parent of edited attribute");
00757                     if (pParent && pAttr->IsEffectAttribute())  // IsValidEffectAttr?
00758                     {
00759 //                      Node* pGrandParent = pParent->FindParent();
00760 //                      if (pGrandParent && pGrandParent->IsBounded())
00761 //                          ((NodeRenderableBounded*)pGrandParent)->ReleaseCached(TRUE, FALSE); // Parents only
00762                         pParent->ReleaseCached(TRUE, FALSE, FALSE, TRUE);   // Parents and derived data only
00763                     }
00764                     else
00765                         pParent->ReleaseCached();
00766 
00767                     // Work out the backmost attr
00768                     if (pBackMost==NULL || pAttr->IsUnder(pBackMost))
00769                         pBackMost = pAttr;
00770 
00771                     pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
00772                 }
00773 
00774                 pSelView->ForceRedraw(StartSpread, SelBounds, FALSE, pBackMost);
00775 
00776                 GetApplication()->ServiceRendering();
00777 
00778                 if (ISA_RAMPINDEX (DragControl))
00779                 {
00780                     GradFill->EnableBoundsRedraw();
00781                 }
00782             }
00783         }
00784     }
00785 
00786     // Re-enable slow renderers
00787     Operation::SetQuickRender(FALSE);
00788 }

void OpEditFill::RenderDragBlobs DocRect  Rect,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Reimplemented from Operation.

Definition at line 1554 of file opgrad.cpp.

01555 {
01556     if (DontDrawBlobs)
01557         return;
01558 
01559     // If being called from DocView::RenderView, then the spread could be wrong - so
01560     // convert the rectangle if necessary.
01561     if (pSpread != StartSpread)
01562     {
01563         Rect.lo = MakeRelativeToSpread(StartSpread, pSpread, Rect.lo);
01564         Rect.hi = MakeRelativeToSpread(StartSpread, pSpread, Rect.hi);
01565     }
01566 
01567     AttrFillGeometry::EditedFill  = NULL;
01568 
01569     RenderRegion* pRegion = DocView::RenderOnTop(&Rect, StartSpread, UnclippedEOR);
01570     while (pRegion)
01571     {
01572         GradFill->RenderFillBlobs(pRegion);
01573 
01574         // Get the Next render region
01575         pRegion = DocView::GetNextOnTop(&Rect);
01576     }
01577 
01578     AttrFillGeometry::EditedFill  = GradFill;
01579 
01580     // Bodge to stop fill meshes EOR each other out.
01581     AttrFillGeometry::LastRenderedMesh = NULL;
01582 }

void OpEditFill::RenderFinalBlobs DocRect  Rect,
Spread pSpread,
BOOL  bSolidDrag
[protected]
 

Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/6/95
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Definition at line 1680 of file opgrad.cpp.

01681 {
01682     // Render the blobs 'On'
01683     RenderDragBlobs(Rect, pSpread, bSolidDrag);
01684 
01685     // Now EOR off in all the render regions that are still rendering,
01686     // so that the Blob rendering when the region is finished, 
01687     // will put them back
01688     RenderRegionList* pRegionList = GetApplication()->GetRegionList();
01689     
01690     if (!pRegionList->IsEmpty())
01691     {
01692         RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead();  
01693         
01694         while (pRegion)
01695         {
01696             // Check the RenderRegion is for the same spread.
01697             if (pRegion->GetRenderSpread() == pSpread &&
01698                 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper))
01699             {
01700                 // Render the blobs 'clipped' to this Render Region.
01701                 DocRect ClipRect = pRegion->GetRegionRect();
01702         
01703                 if (ClipRect.IsIntersectedWith(Rect))
01704                 {
01705                     ClipRect = ClipRect.Intersection(Rect);
01706                     RenderDragBlobs(ClipRect, pSpread, bSolidDrag);
01707                 }
01708             }
01709 
01710             // Get the Next render region
01711             pRegion = (RenderRegion*)pRegionList->GetNext(pRegion);
01712         }
01713     } 
01714 }

void OpEditFill::RenderInitBlobs DocRect  Rect,
Spread pSpread,
BOOL  bSolidDrag
[protected]
 

Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/6/95
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Definition at line 1729 of file opgrad.cpp.

01730 {
01731     // Now EOR off in all the render regions that are still rendering,
01732     // so that the Blob rendering when the region is finished, 
01733     // will put them back
01734     RenderRegionList* pRegionList = GetApplication()->GetRegionList();
01735     
01736     if (!pRegionList->IsEmpty())
01737     {
01738         RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead();  
01739         
01740         while (pRegion)
01741         {
01742             // Check the RenderRegion is for the same spread.
01743             if (pRegion->GetRenderSpread() == pSpread &&
01744                 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper))
01745             {
01746                 // Render the blobs 'clipped' to this Render Region.
01747                 DocRect ClipRect = pRegion->GetRegionRect();
01748         
01749                 if (ClipRect.IsIntersectedWith(Rect))
01750                 {
01751                     ClipRect = ClipRect.Intersection(Rect);
01752                     RenderDragBlobs(ClipRect, pSpread, bSolidDrag);
01753                 }
01754             }
01755 
01756             // Get the Next render region
01757             pRegion = (RenderRegion*)pRegionList->GetNext(pRegion);
01758         }
01759     }
01760 
01761     // Render the blobs 'On'
01762     RenderDragBlobs(Rect, pSpread, bSolidDrag);
01763 }

void OpEditFill::RenderInitSelectionBlobs SelRange pSel,
DocRect  Rect,
Spread pSpread
[protected]
 

Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/6/95
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Definition at line 1631 of file opgrad.cpp.

01632 {
01633     // EOR on in all the render regions that are still rendering,
01634     // so that the Blob rendering when the region is finished, 
01635     // will put them back
01636     RenderRegionList* pRegionList = GetApplication()->GetRegionList();
01637     
01638     if (!pRegionList->IsEmpty())
01639     {
01640         RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead();  
01641         
01642         while (pRegion)
01643         {
01644             // Check the RenderRegion is for the same spread.
01645             if (pRegion->GetRenderSpread() == pSpread &&
01646                 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper))
01647             {
01648                 // Render the blobs 'clipped' to this Render Region.
01649                 DocRect ClipRect = pRegion->GetRegionRect();
01650         
01651                 if (ClipRect.IsIntersectedWith(Rect))
01652                 {
01653                     ClipRect = ClipRect.Intersection(Rect);
01654                     RenderSelectionFillBlobs(pSel, ClipRect, pSpread);
01655                 }
01656             }
01657 
01658             // Get the Next render region
01659             pRegion = (RenderRegion*)pRegionList->GetNext(pRegion);
01660         }
01661     }
01662 
01663     // Render the blobs 'Off'
01664     RenderSelectionFillBlobs(pSel, Rect, pSpread);
01665 }

void OpEditFill::RenderSelectionFillBlobs SelRange pSel,
DocRect  Rect,
Spread pSpread
[protected]
 

Renders the GradFill as it will look if the drag were to end. If we failed to create the GradFill earlier, it will draw a bounding rect.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/6/95
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Definition at line 1597 of file opgrad.cpp.

01598 {
01599     // Render all the selection fill blobs
01600     RenderRegion* pRegion = DocView::RenderOnTop(&Rect, pSpread, UnclippedEOR);
01601     while (pRegion)
01602     {
01603         Node* pNode = pSel->FindFirst();
01604     
01605         while (pNode)
01606         {
01607             ((NodeRenderable*)pNode)->RenderAppliedFillBlobs(pRegion);
01608             pNode = pSel->FindNext(pNode);
01609         }
01610 
01611         // Get the Next render region
01612         pRegion = DocView::GetNextOnTop(&Rect);
01613     }
01614 
01615     AttrFillGeometry::LastRenderedMesh = NULL;
01616 }

void OpEditFill::SelectAllBlobs  )  [protected]
 

Selects all the Start or End fill blobs.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/5/95

Definition at line 1502 of file opgrad.cpp.

01503 {
01504     // It's a 'Select all Blobs' thingy
01505     AttrFillGeometry::LastRenderedStartBlob = DocCoord(0,0);
01506     AttrFillGeometry::LastRenderedEndBlob = DocCoord(0,0);
01507     AttrFillGeometry::LastRenderedEnd2Blob = DocCoord(0,0);
01508 
01509     // Start again at the beginning
01510     AttrFillGeometry* pSelAttr = AttrFillGeometry::FindFirstSelectedAttr(FillClone->GetAttributeType());
01511     while (pSelAttr != NULL)
01512     {
01513         if (pSelAttr)
01514         {
01515             pSelAttr->SelectBlob(DragControl);
01516             pSelAttr->DeselectAllBut(DragControl);
01517         }
01518 
01519         // Move onto the next.
01520         pSelAttr = AttrFillGeometry::FindNextSelectedAttr(FillClone->GetAttributeType());
01521     }                   
01522 }


Member Data Documentation

BOOL OpEditFill::AlwaysFail [protected]
 

Definition at line 285 of file opgrad.h.

DocCoord OpEditFill::AnchorPos [protected]
 

Definition at line 300 of file opgrad.h.

BOOL OpEditFill::ApplyAtEnd [protected]
 

Definition at line 286 of file opgrad.h.

double OpEditFill::AspectRatio [protected]
 

Definition at line 297 of file opgrad.h.

List OpEditFill::AttrGroups [protected]
 

Definition at line 295 of file opgrad.h.

BOOL OpEditFill::CallAllowOp [protected]
 

Definition at line 291 of file opgrad.h.

BOOL OpEditFill::CheckForCompound [protected]
 

Definition at line 290 of file opgrad.h.

BOOL OpEditFill::ContinuousEOR = TRUE [static]
 

Definition at line 305 of file opgrad.h.

BOOL OpEditFill::CreateFill = FALSE [static]
 

Definition at line 306 of file opgrad.h.

BOOL OpEditFill::DoneIdleRedraw [protected]
 

Definition at line 279 of file opgrad.h.

BOOL OpEditFill::DontDrawBlobs [protected]
 

Definition at line 283 of file opgrad.h.

FillControl OpEditFill::DragControl [protected]
 

Definition at line 270 of file opgrad.h.

BOOL OpEditFill::DragIsIdle [protected]
 

Definition at line 278 of file opgrad.h.

AttrFillGeometry* OpEditFill::FillClone [protected]
 

Definition at line 268 of file opgrad.h.

BOOL OpEditFill::ForceAspectLock [protected]
 

Definition at line 288 of file opgrad.h.

AttrFillGeometry* OpEditFill::GradFill [protected]
 

Definition at line 267 of file opgrad.h.

UINT32 OpEditFill::IdleFillDelay = 200 [static]
 

Definition at line 308 of file opgrad.h.

BOOL OpEditFill::InteractiveDragUpdate = TRUE [static]
 

Definition at line 304 of file opgrad.h.

BOOL OpEditFill::InvalidateAll [protected]
 

Definition at line 274 of file opgrad.h.

BOOL OpEditFill::InvalidateCompound [protected]
 

Definition at line 275 of file opgrad.h.

BOOL OpEditFill::IsRequired [protected]
 

Definition at line 289 of file opgrad.h.

DocRect OpEditFill::LastDragRect [protected]
 

Definition at line 273 of file opgrad.h.

DocCoord OpEditFill::LastMousePosition [protected]
 

Definition at line 301 of file opgrad.h.

Node* OpEditFill::pCompound [protected]
 

Definition at line 276 of file opgrad.h.

BaseDocument* OpEditFill::pFillsDoc [protected]
 

Definition at line 272 of file opgrad.h.

BOOL OpEditFill::ShouldApplyNewFill [protected]
 

Definition at line 287 of file opgrad.h.

BOOL OpEditFill::ShowDragBlobs [protected]
 

Definition at line 282 of file opgrad.h.

Spread* OpEditFill::StartSpread [protected]
 

Definition at line 269 of file opgrad.h.

MonotonicTime OpEditFill::Time [protected]
 

Definition at line 280 of file opgrad.h.

FlagState OpEditFill::TranspState [protected]
 

Definition at line 293 of file opgrad.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:58:06 2007 for Camelot by  doxygen 1.4.4