EffectsStack Class Reference

#include <effects_stack.h>

Inheritance diagram for EffectsStack:

List CCObject SimpleCCObject List of all members.

Public Member Functions

 EffectsStack ()
 Constructor.
 ~EffectsStack ()
 Destructor.
BOOL FindBestProcessor (String_256 *pstrEffectID, INT32 *piStackPos)
 Find the most appropriate effect in this effect stack mathcing the given name and stack position.
BOOL GetLevelInfo (String_256 *pstrEffectID, INT32 *piStackPos)
 Find the most appropriate effect in this effect stack mathcing the given name and stack position.
BOOL LockableNonEmpty ()
 Determine whether stack is empty or has destructive effects in it.
void Clear ()
ListRangeGetLevelRange (INT32 *piStackPos, BOOL bEscapeOldControllers=TRUE)
ListRangeGetBaseLevelRange ()
 Get a range of nodes forming a surface above the selection and BELOW any live effects applied to the selection! (Used by legacy effects like Bevel, Contour).
PPStackLevelGetLevel (INT32 iStackPos)
ListRangeFindLevelContaining (NodeEffect *pNode, INT32 *piStackPos)
 Find a given node in the post processor stack.
BOOL NodeInTopLevel (NodeEffect *pNode)
 Find a given node in the post processor stack.
INT32 FindSelectionPos ()
 Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.
BOOL BuildEffectMenu (ContextMenu *pMenu)
 Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.
void AttrsHaveChanged ()
 Tell any stored ranges that any cahced attr data trhey have is now out of date.

Static Public Member Functions

static ListRangeGetEffectsStackFromNode (Node *pNode, BOOL bNodeMaybeMidStack=FALSE, BOOL bEscapeDerived=TRUE, BOOL bIncludeLocked=FALSE)
 Get a list of LE nodes that are common to all selected nodes Only returns a list of ALL the selected nodes have identical stacks above them... Does nothing about setting current stack pos or current effect name.
static EffectsStackGetEffectsStackFromSelection (Range *pRange=NULL, BOOL bEscapeDerived=TRUE, BOOL bIncludeLocked=FALSE)
 Get a list of LE nodes that are common to all selected nodes Only returns a list of ALL the selected nodes have identical stacks above them...
static BOOL NodesSharePPStack (Node *pNode, Node *pLastNode, BOOL bNodeMaybeMidStack=FALSE, BOOL bIncludeLocked=FALSE)
 Find out whether two sibling nodes in the tree share the same stack (So that we can avoid adding the same node stack to the combined stack more than once).
static NodeFindStackBaseFrom (Node *pNode, BOOL bIncludeLocked)
 From the specified node, find the base of the local stack containing that node.
static NodeEscapeOldControllers (Node *pUserNode)
 Find the node which PostProcessors should be wrapped around, taking old style Controller nodes into account.
static ListRangeGetNewLevelRange (Range *pRange=NULL, BOOL bEscapeOldControllers=TRUE)
 Get a range of nodes forming a surface above the selection and above any live effects applied to the selection.
static ListRangeGetTopClassRange (CCRuntimeClass *pClass, BOOL bClassOnly=TRUE, BOOL bIgnorePassThroughEffects=FALSE, Node **ppMasterNode=NULL, INT32 *piStackPos=NULL, Range *pRange=NULL, BOOL bEscapeOldControllers=TRUE)
 Get a range of nodes forming a surface above the selection and within any live effects applied to the selection consisting of all effect nodes of type "class" applied to the selection.

Public Attributes

BOOL bConsistent

Protected Member Functions

BOOL Initialise (ListRange *pRange)
BOOL Intersect (ListRange *pRange)
 Find whether the LE nodes in the presented range match those already in this LE stack. Remove any mismatches from the PPStack, add new nodes to the stack level lists.
PPStackLevelFindMatch (PPStackLevel *pFirstItem, ListRange *pRange, NodeEffect *pPP)
 Find whether the LE nodes in the presented range match those already in this LE stack. Remove any mismatches from the PPStack, add new nodes to the stack level lists.

Private Attributes

ListRangem_pNewLevelRange

Detailed Description

Definition at line 167 of file effects_stack.h.


Constructor & Destructor Documentation

EffectsStack::EffectsStack  ) 
 

Constructor.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/11/2004
Returns:
Errors: See also:

Definition at line 134 of file effects_stack.cpp.

00135 {
00136     bConsistent = FALSE;
00137     m_pNewLevelRange = NULL;
00138 }

EffectsStack::~EffectsStack  ) 
 

Destructor.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/11/2004
Returns:
Errors: See also:

Definition at line 153 of file effects_stack.cpp.

00154 {
00155     // We own m_pNewLevelRange so we must delete it...
00156     if (m_pNewLevelRange)
00157     {
00158         delete m_pNewLevelRange;
00159         m_pNewLevelRange = NULL;
00160     }
00161 
00162     Clear();
00163 }


Member Function Documentation

void EffectsStack::AttrsHaveChanged  ) 
 

Tell any stored ranges that any cahced attr data trhey have is now out of date.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
01/10/2005
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 893 of file effects_stack.cpp.

00894 {
00895     if (m_pNewLevelRange)
00896     {
00897         m_pNewLevelRange->AttrsHaveChanged();
00898     }
00899 }

BOOL EffectsStack::BuildEffectMenu ContextMenu pMenu  ) 
 

Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/06/2005
Parameters:
pMenu - Pointer to ContextMenu we should add items to [INPUTS]
- [OUTPUTS]
Returns:
TRUE if everything is OK FALSE if something went wrong enough to require caller to stop building menus

Errors: See also:

Definition at line 1330 of file effects_stack.cpp.

01331 {
01332 PORTNOTE("menu", "BuildEffectMenu can't do anything until we have XPEHost::GetEffectDetails or equivalent");
01333 #ifndef EXCLUDE_FROM_XARALX
01334     PPStackLevel* pItem = (PPStackLevel*)GetHead();
01335 //  PPStackLevel* pNextItem = NULL;
01336     INT32 pos = 0;
01337 
01338     pMenu->BuildCommand(OPTOKEN_EDITEFFECTS);
01339     MenuItem* pRootItem = pMenu->GetLastItem();
01340 
01341     while (pItem!=NULL)
01342     {
01343 //      pNextItem = (PPStackLevel*)GetNext(pItem);
01344 
01345         String_64 strDisplayName;
01346         BOOL bDestructive = FALSE;
01347         XPEHost::GetEffectDetails(pItem->strPostProID, &strDisplayName, &bDestructive);
01348         OpLiveEffectParam* pParam = new OpLiveEffectParam();
01349         if (pParam==NULL)
01350             return FALSE;
01351 
01352         pParam->strOpUnique = pItem->strPostProID;
01353         pParam->bIsDestructive = bDestructive;
01354         pParam->StackPosition = pos;
01355         pParam->pPPStack = this;
01356 
01357         if (pItem->strPostProID==String_256(POSTPRO_ID_SHADOW))
01358             pMenu->BuildCommand(OPTOKEN_EDIT_LEGACYEFFECT, FALSE, pRootItem, strDisplayName, pParam);
01359 
01360         else if (pItem->strPostProID==String_256(POSTPRO_ID_FEATHER))
01361             pMenu->BuildCommand(OPTOKEN_EDIT_LEGACYEFFECT, FALSE, pRootItem, strDisplayName, pParam);
01362 
01363         else
01364             pMenu->BuildCommand(OPTOKEN_EDIT_LIVEEFFECT, FALSE, pRootItem, strDisplayName, pParam);
01365 
01366         pItem = (PPStackLevel*)GetNext(pItem);
01367         pos++;
01368     }
01369 
01370 #endif
01371     return TRUE;
01372 }

void EffectsStack::Clear  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 515 of file effects_stack.cpp.

00516 {
00517     // No match so clear out the Stack and return
00518     while (GetCount()!=0)
00519     {
00520         PPStackLevel* pItem = (PPStackLevel*)RemoveTail();
00521         delete pItem;
00522     }
00523 }

Node * EffectsStack::EscapeOldControllers Node pUserNode  )  [static]
 

Find the node which PostProcessors should be wrapped around, taking old style Controller nodes into account.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/11/2004
Parameters:
pNode - pointer to node in tree which may have a LiveEffect stack above it [INPUTS]
- [OUTPUTS]
Returns:
Node* - pointer to node above presented node which is an old style non-postprocessor controller node

Definition at line 762 of file effects_stack.cpp.

00763 {
00764     Node* pTestNode = pUserNode->FindParent();
00765     while (pTestNode && pTestNode->IsController() && !pTestNode->IsEffect())
00766     {
00767         pUserNode = pTestNode;
00768         pTestNode = pTestNode->FindParent();
00769     }
00770 
00771     return pUserNode;
00772 }

BOOL EffectsStack::FindBestProcessor String_256 pstrEffectID,
INT32 *  piStackPos
 

Find the most appropriate effect in this effect stack mathcing the given name and stack position.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE if an effect was found FALSE otherwise

Errors: See also:

Definition at line 421 of file effects_stack.cpp.

00422 {
00423     INT32 pos = *piStackPos;
00424     PPStackLevel* pLevel = NULL;
00425 
00426     // Search up from the last known stack position for an effect of the same name
00427     do
00428     {
00429         pLevel = (PPStackLevel*)FindItem(pos);
00430 
00431         if (pLevel && pLevel->strPostProID==*pstrEffectID)
00432         {
00433             *piStackPos = pos;
00434             return TRUE;
00435         }
00436 
00437         pos++;
00438     }
00439     while (pLevel);
00440 
00441     // Search down from the last known stack position for an effect of the same name
00442     pos = *piStackPos-1;
00443     do
00444     {
00445         pLevel = (PPStackLevel*)FindItem(pos);
00446 
00447         if (pLevel && pLevel->strPostProID==*pstrEffectID)
00448         {
00449             *piStackPos = pos;
00450             return TRUE;
00451         }
00452 
00453         pos--;
00454     }
00455     while (pLevel);
00456 
00457     return FALSE;
00458 }

ListRange * EffectsStack::FindLevelContaining NodeEffect pNode,
INT32 *  piStackPos
 

Find a given node in the post processor stack.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/2004
Parameters:
pNode - Pointer to node to search for [INPUTS]
- [OUTPUTS]
Returns:
A pointer to a list range owned by the PostProcessor stack describing the layer of consistent nodes in the stack of which Node was a member NULL if couldn't find node in stack

Errors: See also:

Definition at line 1168 of file effects_stack.cpp.

01169 {
01170     *piStackPos = STACKPOS_TOP;
01171     if (IsEmpty())
01172         return NULL;
01173 
01174     PPStackLevel* pItem = (PPStackLevel*)GetHead();
01175     *piStackPos = 0;
01176     while (pItem!=NULL)
01177     {
01178         Node* pTestNode = pItem->listSelNodes.FindFirst();
01179         while (pTestNode)
01180         {
01181             if (pNode==pTestNode)
01182                 return &pItem->listSelNodes;
01183 
01184             pTestNode = pItem->listSelNodes.FindNext(pTestNode);
01185         }
01186 
01187         (*piStackPos)++;
01188         pItem = (PPStackLevel*)GetNext(pItem);
01189     }
01190 
01191     *piStackPos = STACKPOS_TOP;
01192     return NULL;
01193 }

PPStackLevel * EffectsStack::FindMatch PPStackLevel pFirstItem,
ListRange pRange,
NodeEffect pPP
[protected]
 

Find whether the LE nodes in the presented range match those already in this LE stack. Remove any mismatches from the PPStack, add new nodes to the stack level lists.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
pRange - A stack of LiveEffects above a node in the selection [INPUTS]
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 544 of file effects_stack.cpp.

00545 {
00546     PPStackLevel* pItem = pFirstItem;
00547     PPStackLevel* pLastMatchItem = NULL;
00548     BOOL bMatch = TRUE;
00549 //  HRESULT hr;
00550 
00551     do
00552     {
00553         bMatch = pPP->CompareState(pItem->pPPNode);         // Polymorphic compare for PostProcessors
00554         if (bMatch)
00555             pLastMatchItem = pItem;
00556 // Possible future change to detect inconsistent levels. But this would require changes elsewhere
00557 //      bMatch = (pPP->GetRuntimeClass() == pItem->pPPNode->GetRuntimeClass());
00558 //      if (pItem->bConsistent)
00559 //      {
00560 //          pItem->bConsistent = pPP->CompareState(pItem->pPPNode);
00561 //      }
00562 
00563         pPP = (NodeEffect*)pRange->FindNext(pPP);
00564         pItem = (PPStackLevel*)GetNext(pItem);
00565     }
00566     while (bMatch && pItem!=NULL && pPP);
00567 
00568     return pLastMatchItem;
00569 }

INT32 EffectsStack::FindSelectionPos  ) 
 

Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/11/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The stack position of the selection or -1

Errors: See also:

Definition at line 1249 of file effects_stack.cpp.

01250 {
01251     INT32 Pos = -1;
01252 
01253     Range* pRange = GetApplication()->FindSelection();
01254     ENSURE(pRange, "!");
01255     ENSURE(pRange->GetRangeControlFlags().PromoteToParent==FALSE, "GetEffectsStackFromSel given a bad range");
01256 
01257     PPStackLevel* pFoundLevel = NULL;
01258     Node* pNode = pRange->FindFirst();
01259     while (pNode)
01260     {
01261         Node* pStackNode = pNode->GetParentController();
01262         if (pStackNode==NULL)
01263             return -1;
01264 
01265         if (pFoundLevel==NULL)
01266         {
01267             PPStackLevel* pItem = (PPStackLevel*)GetHead();
01268             Pos = 0;
01269             while (pItem!=NULL && pFoundLevel==NULL)
01270             {
01271                 Node* pTestNode = pItem->listSelNodes.FindFirst();
01272                 while (pTestNode && pTestNode!=pStackNode)
01273                 {
01274                     pTestNode = pItem->listSelNodes.FindNext(pTestNode);
01275                 }
01276 
01277                 if (pTestNode==pStackNode)
01278                 {
01279                     pFoundLevel = pItem;
01280                     break;
01281                 }
01282 
01283                 Pos++;
01284                 pItem = (PPStackLevel*)GetNext(pItem);
01285             }
01286 
01287             if (pFoundLevel==NULL)
01288                 return -1;
01289         }
01290         else
01291         {
01292             // Just look in the level we have already identified...
01293             Node* pTestNode = pFoundLevel->listSelNodes.FindFirst();
01294             while (pTestNode && pTestNode!=pStackNode)
01295             {
01296                 pTestNode = pFoundLevel->listSelNodes.FindNext(pTestNode);
01297             }
01298 
01299             if (pTestNode!=pStackNode)
01300             {
01301                 return -1;
01302             }
01303         }
01304 
01305         pNode = pRange->FindNext(pNode);
01306     }
01307 
01308     return Pos;
01309 }

Node * EffectsStack::FindStackBaseFrom Node pNode,
BOOL  bIncludeLocked
[static]
 

From the specified node, find the base of the local stack containing that node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/11/2004
Parameters:
pNode - pointer to node in tree which may have a LiveEffect stack above it [INPUTS] and below it!
- [OUTPUTS]
Returns:
Pointer to node at the base of the stack containing the input node

Definition at line 719 of file effects_stack.cpp.

00720 {
00721     Node* pStackNode = pNode;
00722 
00723     if (!pStackNode->IsEffect())
00724     {
00725         if (pStackNode->GetParentController())
00726             pStackNode = pStackNode->GetParentController();
00727     }
00728 
00729     while (pStackNode && pStackNode->IsEffect())
00730     {
00731         // Stop immediately if we find a destructive post pro - the user cannot be
00732         // allowed to see or manipulate anything underneath one of those...
00733         if (!bIncludeLocked && ((NodeEffect*)pStackNode)->IsLockedEffect())
00734             break;
00735 
00736         if (!((NodeEffect*)pStackNode)->CanBeUnlocked())
00737             break;
00738 
00739         pStackNode = ((NodeEffect*)pStackNode)->GetInkNodeFromController();
00740     }
00741 
00742     return pStackNode;
00743 }

ListRange * EffectsStack::GetBaseLevelRange  ) 
 

Get a range of nodes forming a surface above the selection and BELOW any live effects applied to the selection! (Used by legacy effects like Bevel, Contour).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
03/12/2004
Parameters:
- [INPUTS]
[OUTPUTS] 
Returns:
A pointer to a list range owned by you!

Errors: See also:

Definition at line 1119 of file effects_stack.cpp.

01120 {
01121     // Loop through selection ensuring that all nodes are LiveEffects
01122     // and that they all share the same edit list
01123     Range* pRange = GetApplication()->FindSelection();
01124     ENSURE(pRange, "No selection in GetNewLevelRange!");
01125 
01126     // We want to apply the LiveEffect to the entire selection, underneath any PostProcessors
01127     //
01128     // Loop through the current selection and search the parents of each selected node
01129     ListRange* pLERange = new ListRange();
01130     Node* pNode = pRange->FindFirst();
01131 //  INT32 pos = 0;
01132     while (pNode!=NULL)
01133     {
01134         Node* pEscNode = pNode;
01135 
01136         // Only traverse the effect stack if the selected node is 'in' the effect stack
01137         // (it could be offset, e.g. NodeShadow)
01138         if (!pNode->NeedsParent(pNode->FindParent()))
01139             pEscNode = EscapeOldControllers(pNode);
01140 
01141         pLERange->AddNode(pEscNode);
01142 
01143         pNode = pRange->FindNext(pNode);
01144     }
01145 
01146     return pLERange;
01147 }

ListRange * EffectsStack::GetEffectsStackFromNode Node pNode,
BOOL  bNodeMaybeMidStack = FALSE,
BOOL  bEscapeDerived = TRUE,
BOOL  bIncludeLocked = FALSE
[static]
 

Get a list of LE nodes that are common to all selected nodes Only returns a list of ALL the selected nodes have identical stacks above them... Does nothing about setting current stack pos or current effect name.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
pNode - pointer to node in tree which may have a LiveEffect stack above it [INPUTS]
- [OUTPUTS]
Returns:
pPPStack - NULL if <None>
  • Empty if <Many>
  • Populated if consistent stack (caller becomes owner of this list!)
See also:
LiveEffectsTool::GetLEListFromSelAndStack

Definition at line 593 of file effects_stack.cpp.

00594 {
00595     // First, test whether node CAN be in a PPStack or stands aside from it
00596     // (E.g. shadows)
00597     //
00598     if (!bEscapeDerived && pNode->NeedsParent(pNode->FindParent()))
00599         return NULL;
00600 
00601     ListRange* pStack = new ListRange();
00602     Node* pUpNode = pNode;
00603 
00604     // If the node could be in the middle of a stack then we need to find the base
00605     // of the stack before we start our scan
00606     // (E.g. the node could be a selected Shadow node somewhere high above the
00607     //  object it applies to)
00608     if (bNodeMaybeMidStack)
00609     {
00610         pUpNode = FindStackBaseFrom(pUpNode, bIncludeLocked);
00611     }
00612 
00613     // Special case handling for old legacy effects until they become true
00614     // PostProcessors...
00615     // Search for Contour, Bevel, ClipView controllers above selected node
00616     // and if found, make them the base for PostProcessor scanning
00617     pUpNode = EscapeOldControllers(pUpNode);
00618 
00619     // Now go up the post processor stack, adding every one we find to the list
00620     do
00621     {
00622         if (pUpNode->IsEffect())
00623             pStack->AddNode(pUpNode);
00624 
00625         pUpNode = pUpNode->FindParent();
00626     }
00627     while (pUpNode && pUpNode->IsEffect());
00628 
00629     // Best to get rid of the list here if it's empty (don't trust caller)
00630     if (pStack->IsEmpty())
00631     {
00632         delete pStack;
00633         pStack = NULL;
00634     }
00635 
00636     return pStack;
00637 }

EffectsStack * EffectsStack::GetEffectsStackFromSelection Range pRange = NULL,
BOOL  bEscapeDerived = TRUE,
BOOL  bIncludeLocked = FALSE
[static]
 

Get a list of LE nodes that are common to all selected nodes Only returns a list of ALL the selected nodes have identical stacks above them...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/10/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
pStack - pointer to ListRange representing stack applied consistently to selection

Definition at line 182 of file effects_stack.cpp.

00183 {
00184     // Loop through selection ensuring that all nodes are LiveEffects
00185     // and that they all share the same edit list
00186     if (pRange==NULL)
00187         pRange = GetApplication()->FindSelection();
00188     ENSURE(pRange, "!");
00189     ENSURE(pRange->GetRangeControlFlags().PromoteToParent==FALSE, "GetEffectsStackFromSel given a bad range");
00190 
00191     EffectsStack* pPPStack = new EffectsStack();        // New stack is marked as being "inconsistent"
00192     BOOL bStartNewStack = TRUE;
00193     ListRange* pLocalStack = NULL;
00194     BOOL bLiveEffectsAreApplied = FALSE;
00195 
00196     // Ensure that pEditedLE has a useful value...
00197     // Loop through the current selection and search the parents of each selected node for LiveEffects...
00198     Node* pNode = pRange->FindFirst();
00199     Node* pLastNode = NULL;
00200     while (pNode!=NULL)
00201     {
00202         if (pNode->IsAnObject())
00203         {
00204             // Don't try to add the same stack to the system more than once
00205             // (For instance NodeShadows and their originals are siblings and can both be selected
00206             //  below a NodeShadowController)
00207             if (!NodesSharePPStack(pNode, pLastNode, TRUE, bIncludeLocked))
00208             {
00209                 // Get the local stack
00210                 pLocalStack = GetEffectsStackFromNode(pNode, TRUE, bEscapeDerived, bIncludeLocked);     // If this node is in the middle of a stack, find the whole stack
00211 
00212                 if (pLocalStack)
00213                 {
00214                     bLiveEffectsAreApplied = TRUE;
00215 
00216                     if (bStartNewStack)
00217                     {
00218                         if (pPPStack->IsEmpty())
00219                         {
00220                             pPPStack->Initialise(pLocalStack);
00221                         }
00222                         else
00223                         {
00224                             BOOL bOK = pPPStack->Intersect(pLocalStack);
00225                             if (!bOK)
00226                             {
00227                                 delete pLocalStack;
00228                                 pPPStack->Clear();                      // Just to make sure!
00229                                 return pPPStack;
00230                             }
00231                         }
00232                     }
00233 
00234                     delete pLocalStack;
00235                 }
00236                 else
00237                 {
00238                     // A node in the selection doesn't have any LiveEffects applied but we can't stop
00239                     // because we have to keep scanning to see whether ANY nodes have LiveEffects
00240                     // Clear the effect stack out because this node has none.
00241                     pPPStack->Clear();
00242                     bStartNewStack = FALSE;
00243 
00244                     // Could test for lengthy scanning here and if it takes too long return <UNKNOWN>
00245                     // if (taking too long) code = SELTYPE_UNKNOWN;
00246                 }
00247             }
00248             pLastNode = pNode;
00249         }
00250 
00251         pNode = pRange->FindNext(pNode);
00252     }
00253 
00254     if (pPPStack->IsEmpty() && bLiveEffectsAreApplied)
00255         pPPStack->bConsistent = FALSE;
00256     else
00257         pPPStack->bConsistent = TRUE;
00258 
00259     return pPPStack;
00260 }

PPStackLevel* EffectsStack::GetLevel INT32  iStackPos  )  [inline]
 

Definition at line 196 of file effects_stack.h.

00196 {return (PPStackLevel*)FindItem(iStackPos);}

BOOL EffectsStack::GetLevelInfo String_256 pstrEffectID,
INT32 *  piStackPos
 

Find the most appropriate effect in this effect stack mathcing the given name and stack position.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/11/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE if an effect was found FALSE otherwise

Errors: See also:

Definition at line 479 of file effects_stack.cpp.

00480 {
00481     PPStackLevel* pLevel = NULL;
00482 
00483     if (*piStackPos>=STACKPOS_TOP)
00484         pLevel = (PPStackLevel*)GetTail();
00485     else
00486         pLevel = (PPStackLevel*)FindItem(*piStackPos);
00487 
00488     if (pLevel)
00489     {
00490         *piStackPos = (INT32) this->FindPosition(pLevel);
00491         *pstrEffectID = pLevel->strPostProID;
00492         return TRUE;
00493     }
00494 
00495     return FALSE;
00496 }

ListRange * EffectsStack::GetLevelRange INT32 *  piStackPos,
BOOL  bEscapeOldControllers = TRUE
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/09/2004
Parameters:
iStackPos - position in LiveEffect stack to find nodes [INPUTS] 0 means first stack pos above selection
[OUTPUTS] 
Returns:
A pointer to a list range owned by the EffectsStack - i.e. you don't have to delete it when you're finished.

Errors: See also:

Definition at line 832 of file effects_stack.cpp.

00833 {
00834     ENSURE(*piStackPos>=0, "Invalid stack pos in GetLevelRange!");
00835 
00836     // If the stack is inconsistent then we need to make a range of nodes that arch
00837     // over the selection and any stacked PostProcessors that might be on them
00838     // In this case we expect our caller to not have specified a valid stack position
00839     if (!bConsistent || IsEmpty() || *piStackPos>=STACKPOS_TOP)
00840     {
00841         ENSURE(*piStackPos>=STACKPOS_TOP, "Incorrect attempt to insert into an inconsistent PostPro stack");
00842 
00843         // By definition, if someone had previously requested a new level range
00844         // during the lifetime of this effects stack then the same range must
00845         // still apply (otherwise the EffectsStack would have been destroyed).
00846         // So just return the range we already found...
00847         if (m_pNewLevelRange)
00848         {
00849             return m_pNewLevelRange;
00850 //          delete m_pNewLevelRange;
00851 //          m_pNewLevelRange = NULL;
00852         }
00853 
00854         m_pNewLevelRange = GetNewLevelRange(NULL, bEscapeOldControllers);           // We own this listrange, so we can delete it later
00855 
00856         // Return new stack pos; correct number for consistent stack, INVALID for inconsistent stack
00857         if (bConsistent)
00858             *piStackPos = ((INT32)GetCount())-1;
00859         else
00860             *piStackPos = STACKPOS_INVALID;
00861 
00862         return m_pNewLevelRange;
00863     }
00864 
00865     // This is the typical case: Adding/Inserting to a consistent stack
00866     if (*piStackPos>=(INT32)GetCount())
00867         *piStackPos = ((INT32)GetCount())-1;
00868 
00869     PPStackLevel* pLevel = (PPStackLevel*)FindItem(*piStackPos);
00870     ENSURE(pLevel, "Argh something's got out of line!");
00871     ListRange* pLERange = &pLevel->listSelNodes;
00872 
00873     return pLERange;                                        // The EffectsStack owns this listrange
00874 }

ListRange * EffectsStack::GetNewLevelRange Range pRange = NULL,
BOOL  bEscapeOldControllers = TRUE
[static]
 

Get a range of nodes forming a surface above the selection and above any live effects applied to the selection.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/10/2004
Parameters:
- [INPUTS]
[OUTPUTS] 
Returns:
A pointer to a list range owned by you!

Errors: See also:

Definition at line 919 of file effects_stack.cpp.

00920 {
00921     // Loop through selection ensuring that all nodes are LiveEffects
00922     // and that they all share the same edit list
00923     if (pRange==NULL)
00924         pRange = GetApplication()->FindSelection();
00925     ENSURE(pRange, "No selection in GetNewLevelRange!");
00926 
00927     // We want to apply the LiveEffect to the entire selection, however inconsistent it is
00928     //
00929     // Loop through the current selection and search the parents of each selected node for LiveEffects...
00930     ListRange* pLERange = new ListRange();
00931     Node* pNode = pRange->FindFirst();
00932     INT32 pos = 0;
00933     while (pNode!=NULL)
00934     {
00935         NodeEffect* pFirstEditedLE = NULL;
00936         Node* pBaseNode = pNode;
00937 
00938         // Only traverse the effect stack if the selected node is 'in' the effect stack
00939         // (it could be offset, e.g. NodeShadow)
00940         if (!pNode->NeedsParent(pNode->FindParent()))
00941         {
00942             if (bEscapeOldControllers)
00943                 pBaseNode = EscapeOldControllers(pNode);
00944 
00945             Node* pUpNode = pBaseNode;
00946 
00947             pos = 0;
00948             do
00949             {
00950                 pUpNode = pUpNode->FindParent();
00951 
00952                 if (pUpNode && pUpNode->IsEffect())
00953                     pFirstEditedLE = (NodeEffect*)pUpNode;
00954 
00955                 pos++;
00956             }
00957             while (pUpNode && pUpNode->IsEffect());
00958         }
00959 
00960         if (pFirstEditedLE)
00961         {
00962             pLERange->AddNode(pFirstEditedLE);
00963         }
00964         else
00965         {
00966             pLERange->AddNode(pBaseNode);
00967         }
00968 
00969         pNode = pRange->FindNext(pNode);
00970     }
00971 
00972     return pLERange;
00973 }

ListRange * EffectsStack::GetTopClassRange CCRuntimeClass pClass,
BOOL  bClassOnly = TRUE,
BOOL  bIgnorePassThroughEffects = FALSE,
Node **  ppMasterNode = NULL,
INT32 *  piStackPos = NULL,
Range pRange = NULL,
BOOL  bEscapeOldControllers = TRUE
[static]
 

Get a range of nodes forming a surface above the selection and within any live effects applied to the selection consisting of all effect nodes of type "class" applied to the selection.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/05/2005
Parameters:
pClass - pointer to class of node to find in effects stack [INPUTS] bClassOnly - Only allow nodes of the specified class to be added to the list pRange - pointer to range of nodes to scan bEscapeConts- TRUE if old controller nodes should be escaped
pMasterNode - pointer to one example of this class of node in the returned range [OUTPUTS] piStackPos - pointer to stack pos INT32
Returns:
A pointer to a list range owned by you!

Errors:

Definition at line 1004 of file effects_stack.cpp.

01012 {
01013     // Loop through selection ensuring that all nodes are LiveEffects
01014     // and that they all share the same edit list
01015     if (pRange==NULL)
01016         pRange = GetApplication()->FindSelection();
01017     ENSURE(pRange, "No selection in GetClassRange!");
01018 
01019     if (ppMasterNode)
01020         *ppMasterNode = NULL;
01021 
01022     // We want to apply the LiveEffect to the entire selection, however inconsistent it is
01023     //
01024     // Loop through the current selection and search the parents of each selected node for LiveEffects...
01025     ListRange* pLERange = new ListRange();
01026     Node* pNode = pRange->FindFirst();
01027     INT32 pos = 0;
01028     while (pNode!=NULL)
01029     {
01030         NodeEffect* pFirstEditedLE = NULL;
01031         NodeEffect* pFirstEditedEffectClass = NULL;
01032         Node* pBaseNode = pNode;
01033 
01034         // Only traverse the effect stack if the selected node is 'in' the effect stack
01035         // (it could be offset/derived, e.g. NodeShadow)
01036 // In this context we know that we always want to go up effects stacks whether the selected node
01037 // is mainstream or derived...
01038 //      if (!pNode->NeedsParent(pNode->FindParent()))
01039 //      {
01040             if (bEscapeOldControllers)
01041                 pBaseNode = EscapeOldControllers(pNode);
01042 
01043             Node* pUpNode = pBaseNode;
01044 
01045             pos = 0;
01046             do
01047             {
01048                 pUpNode = pUpNode->FindParent();
01049 
01050                 if (pUpNode && pUpNode->IsEffect())
01051 //                  if (!(bIgnorePassThroughEffects && ((NodeEffect*)pUpNode)->IsPassThroughEffect()))
01052 //  The meaning of the bIgnorePassThroughEffects has changed to mean "ignore all effects"
01053                     if (!bIgnorePassThroughEffects)
01054                         pFirstEditedLE = (NodeEffect*)pUpNode;
01055 
01056                 if (pUpNode && pUpNode->IsEffect() && pUpNode->GetRuntimeClass() == pClass)
01057                 {
01058                     pFirstEditedEffectClass = (NodeEffect*)pUpNode;
01059 //                  iClassPos = pos;
01060                 }
01061 
01062                 pos++;
01063             }
01064             while (pUpNode && pUpNode->IsEffect());
01065 //      }
01066 
01067         // Decide what effect node should be added to the listrange for this node in the input range
01068         // Add a node of the specified class if we found one
01069         if (pFirstEditedEffectClass)
01070         {
01071             pLERange->AddNode(pFirstEditedEffectClass);
01072 
01073             if (ppMasterNode && *ppMasterNode==NULL)
01074                 *ppMasterNode = pFirstEditedEffectClass;
01075         }
01076         // Add the last effect if effects were found
01077         else if (!bClassOnly)
01078         {
01079             if (pFirstEditedLE)
01080             {
01081                 pLERange->AddNode(pFirstEditedLE);
01082             }
01083             // Add the input node itself if no effects were found
01084             else
01085             {
01086                 pLERange->AddNode(pBaseNode);
01087             }
01088         }
01089 
01090         pNode = pRange->FindNext(pNode);
01091     }
01092 
01093     // Temp hack
01094     if (piStackPos)
01095         *piStackPos = STACKPOS_INVALID;
01096 
01097     return pLERange;
01098 }

BOOL EffectsStack::Initialise ListRange pRange  )  [protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 279 of file effects_stack.cpp.

00280 {
00281     ENSURE(pRange, "EffectsStack::Initialise must be given a range");
00282 
00283     Node* pNode = pRange->FindFirst();
00284     while (pNode)
00285     {
00286         ENSURE(pNode->IsEffect(), "PostProcessor list contains non-PostProcessor in EffectsStack::Initialise");
00287         NodeEffect* pLE = (NodeEffect*)pNode;
00288 
00289         PPStackLevel* pNewItem = new PPStackLevel();
00290 
00291         pNewItem->pPPNode = pLE;
00292 
00293         pNewItem->listSelNodes.AddNode(pLE);
00294         pNewItem->strPostProID = pLE->GetPostProcessorID();
00295 
00296         AddTail(pNewItem);
00297 
00298         pNode = pRange->FindNext(pNode);
00299     }
00300 
00301     return TRUE;
00302 }

BOOL EffectsStack::Intersect ListRange pRange  )  [protected]
 

Find whether the LE nodes in the presented range match those already in this LE stack. Remove any mismatches from the PPStack, add new nodes to the stack level lists.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
pRange - A stack of LiveEffects above a node in the selection [INPUTS]
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 323 of file effects_stack.cpp.

00324 {
00325     ENSURE(pRange, "EffectsStack::Intersect must be given a range");
00326 
00327     Node* pNode = pRange->FindFirst();
00328     while (pNode)
00329     {
00330         ENSURE(pNode->IsEffect(), "PostProcessor list contains non-PostProcessor in EffectsStack::Intersect");
00331         NodeEffect* pLE = (NodeEffect*)pNode;
00332 
00333         PPStackLevel* pLastMatchItem = NULL;
00334         PPStackLevel* pFirstMatchItem = (PPStackLevel*)GetHead();
00335         NodeEffect* pStackSample;
00336         while (pFirstMatchItem!=NULL && pLastMatchItem==NULL)
00337         {
00338             pStackSample = pFirstMatchItem->pPPNode;
00339 
00340             pLastMatchItem = FindMatch(pFirstMatchItem, pRange, pLE);
00341             if (pLastMatchItem)
00342                 break;                                              // Stop as soon as we find a match!
00343 
00344             pFirstMatchItem = (PPStackLevel*)GetNext(pFirstMatchItem);
00345         }
00346 
00347         if (pLastMatchItem)
00348         {
00349             // ------------------------------------------------------------
00350             // We have a match so remove the stack levels that didn't match
00351             PPStackLevel* pItem = (PPStackLevel*)GetHead();
00352             while (pItem != pFirstMatchItem)
00353             {
00354                 PPStackLevel* pNextItem = (PPStackLevel*)GetNext(pItem);
00355 
00356                 RemoveItem(pItem);
00357 
00358                 pItem = pNextItem;
00359             }
00360 
00361             // ------------------------------------------------------------
00362             // Add the nodes that do match to the ListRanges in the levels
00363             do
00364             {
00365                 pItem->listSelNodes.AddNode(pLE);
00366 
00367                 pLE = (NodeEffect*)pRange->FindNext(pLE);
00368                 pItem = (PPStackLevel*)GetNext(pItem);
00369             }
00370             while (pItem!=NULL && pItem!=pLastMatchItem && pLE!=NULL);
00371 
00372             if (pItem!=NULL && pItem==pLastMatchItem && pLE!=NULL)
00373             {
00374                 pItem->listSelNodes.AddNode(pLE);
00375             }
00376 
00377             // ------------------------------------------------------------
00378             // Remove further levels that didn't match
00379             if (pItem)
00380             {
00381                 pItem = (PPStackLevel*)GetNext(pItem);
00382                 while (pItem != NULL)
00383                 {
00384                     PPStackLevel* pNextItem = (PPStackLevel*)GetNext(pItem);
00385 
00386                     RemoveItem(pItem);
00387 
00388                     pItem = pNextItem;
00389                 }
00390             }
00391 
00392             return TRUE;
00393         }
00394 
00395         pNode = pRange->FindNext(pNode);
00396     }
00397 
00398     Clear();
00399     return FALSE;
00400 }

BOOL EffectsStack::LockableNonEmpty  ) 
 

Determine whether stack is empty or has destructive effects in it.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/10/2004
Parameters:
pNode - pointer to node in tree which may have a LiveEffect stack above it [INPUTS]
- [OUTPUTS]
Returns:
TRUE if stack has some lockable effects layers FALSE if no levels or any level contains an unlockable effect
See also:
LiveEffectsTool::GetLEListFromSelAndStack

Definition at line 792 of file effects_stack.cpp.

00793 {
00794     if (IsEmpty())
00795         return FALSE;
00796 
00797     PPStackLevel* pItem = (PPStackLevel*)GetHead();
00798     NodeEffect* pLENode;
00799     while (pItem!=NULL)
00800     {
00801         pLENode = pItem->pPPNode;
00802         ENSURE(pLENode, "PPStackLevel node pointer is NULL in LockableNonEmpty");
00803 
00804         if (!pLENode->CanBeUnlocked())
00805             return FALSE;
00806 
00807         pItem = (PPStackLevel*)GetNext(pItem);
00808     }
00809 
00810     return TRUE;
00811 }

BOOL EffectsStack::NodeInTopLevel NodeEffect pNode  ) 
 

Find a given node in the post processor stack.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/11/2004
Parameters:
pNode - Pointer to node to search for [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the node is in the top level of the stack FALSE otherwise

Errors: See also:

Definition at line 1213 of file effects_stack.cpp.

01214 {
01215     if (IsEmpty())
01216         return TRUE;
01217 
01218     PPStackLevel* pItem = (PPStackLevel*)GetTail();
01219     Node* pTestNode = pItem->listSelNodes.FindFirst();
01220     while (pTestNode)
01221     {
01222         if (pNode==pTestNode)
01223             return TRUE;
01224 
01225         pTestNode = pItem->listSelNodes.FindNext(pTestNode);
01226     }
01227 
01228     return FALSE;
01229 }

BOOL EffectsStack::NodesSharePPStack Node pNode,
Node pLastNode,
BOOL  bNodeMaybeMidStack = FALSE,
BOOL  bIncludeLocked = FALSE
[static]
 

Find out whether two sibling nodes in the tree share the same stack (So that we can avoid adding the same node stack to the combined stack more than once).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/11/2004
Parameters:
pNode - pointer to node in tree which may have a LiveEffect stack above it [INPUTS] pLastNode - pointer to another node whicyh may have a LiveEffect stack
- [OUTPUTS]
Returns:
TRUE if both nodes have the same stack above them FALSE if the nodes have different stacks
See also:
LiveEffectsTool::GetLEListFromSelAndStack

Definition at line 660 of file effects_stack.cpp.

00661 {
00662     if (pNode==NULL || pLastNode==NULL)
00663         return FALSE;
00664 
00665     if (bNodeMaybeMidStack)
00666     {
00667         // Find the true stack base for both these
00668         pNode = FindStackBaseFrom(pNode, bIncludeLocked);
00669         pLastNode = FindStackBaseFrom(pLastNode, bIncludeLocked);
00670     }
00671 
00672     // Special case handling for old legacy effects until they become true
00673     // PostProcessors...
00674     // Search for Contour, Bevel, ClipView controllers above selected node
00675     // and if found, make them the base for PostProcessor scanning
00676     pNode = EscapeOldControllers(pNode);
00677     pLastNode = EscapeOldControllers(pLastNode);
00678 
00679     if (!bIncludeLocked)
00680     {
00681         if (pNode->IsEffect() && ((NodeEffect*)pNode)->IsLockedEffect())
00682             return FALSE;
00683 
00684         if (pLastNode->IsEffect() && ((NodeEffect*)pLastNode)->IsLockedEffect())
00685             return FALSE;
00686     }
00687 
00688     if (pNode->IsEffect() && !((NodeEffect*)pNode)->CanBeUnlocked())
00689         return FALSE;
00690 
00691     if (pLastNode->IsEffect() && !((NodeEffect*)pLastNode)->CanBeUnlocked())
00692         return FALSE;
00693 
00694     Node* pParent = pNode->FindParent();
00695     if (pParent==NULL)
00696         return FALSE;
00697 
00698     return (pParent == pLastNode->FindParent() && pParent->IsEffect());
00699 }


Member Data Documentation

BOOL EffectsStack::bConsistent
 

Definition at line 210 of file effects_stack.h.

ListRange* EffectsStack::m_pNewLevelRange [private]
 

Definition at line 213 of file effects_stack.h.


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