#include <effects_stack.h>
Inheritance diagram for EffectsStack:
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 () |
ListRange * | GetLevelRange (INT32 *piStackPos, BOOL bEscapeOldControllers=TRUE) |
ListRange * | 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). | |
PPStackLevel * | GetLevel (INT32 iStackPos) |
ListRange * | FindLevelContaining (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 ListRange * | GetEffectsStackFromNode (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 EffectsStack * | GetEffectsStackFromSelection (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 Node * | FindStackBaseFrom (Node *pNode, BOOL bIncludeLocked) |
From the specified node, find the base of the local stack containing that node. | |
static Node * | EscapeOldControllers (Node *pUserNode) |
Find the node which PostProcessors should be wrapped around, taking old style Controller nodes into account. | |
static ListRange * | GetNewLevelRange (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 ListRange * | GetTopClassRange (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. | |
PPStackLevel * | FindMatch (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 | |
ListRange * | m_pNewLevelRange |
Definition at line 167 of file effects_stack.h.
|
Constructor.
Definition at line 134 of file effects_stack.cpp. 00135 { 00136 bConsistent = FALSE; 00137 m_pNewLevelRange = NULL; 00138 }
|
|
Destructor.
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 }
|
|
Tell any stored ranges that any cahced attr data trhey have is now out of date.
Definition at line 893 of file effects_stack.cpp. 00894 { 00895 if (m_pNewLevelRange) 00896 { 00897 m_pNewLevelRange->AttrsHaveChanged(); 00898 } 00899 }
|
|
Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.
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 }
|
|
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 }
|
|
Find the node which PostProcessors should be wrapped around, taking old style Controller nodes into account.
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 }
|
|
Find the most appropriate effect in this effect stack mathcing the given name and stack position.
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 }
|
|
Find a given node in the post processor stack.
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 }
|
|
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.
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 }
|
|
Find whether the selection has a consistent level INT32 he stack other than the usual base level, -1.
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 }
|
|
From the specified node, find the base of the local stack containing that 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 }
|
|
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).
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 }
|
|
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.
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 }
|
|
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...
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 }
|
|
Definition at line 196 of file effects_stack.h. 00196 {return (PPStackLevel*)FindItem(iStackPos);}
|
|
Find the most appropriate effect in this effect stack mathcing the given name and stack position.
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 }
|
|
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 }
|
|
Get a range of nodes forming a surface above the selection and above any live effects applied to the selection.
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 }
|
|
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.
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 }
|
|
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 }
|
|
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.
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 }
|
|
Determine whether stack is empty or has destructive effects in it.
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 }
|
|
Find a given node in the post processor stack.
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 }
|
|
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).
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 }
|
|
Definition at line 210 of file effects_stack.h. |
|
Definition at line 213 of file effects_stack.h. |