#include <opfeathr.h>
Inheritance diagram for OpChangeFeatherSize:
Public Member Functions | |
OpChangeFeatherSize () | |
virtual void | DoWithParam (OpDescriptor *pOp, OpParam *pParam) |
Called to initiate this action. Starts the process of resizing/applying feathers to the selection. | |
virtual BOOL | MayChangeNodeBounds () const |
virtual void | DoSlide (INT32 SlideValue) |
Called by our OpDescriptor's OnSliderChanging() method. Changes all feathers on our list, and causes them to redraw. | |
virtual void | SlideFinished (BOOL SuccessfulFinish=TRUE) |
Called by our OpDescriptor's OnSliderSet() method. Finishes off a feather-size slider drag. Removes any zero-size feathers on our list from the tree, and adds a hide-node action for legitimate feathers, so they hide on undo. Also records an action to invalidate the feathered nodes, for undo. | |
Static Public Member Functions | |
static OpState | GetState (String_256 *Description, OpDescriptor *) |
static BOOL | Init () |
Declares a preference that allows you to clear memory in delete(). | |
static BOOL | DeInit () |
Deallocate anything grabbed in Init or grabbed statically. | |
static void | SetEditContext (INT32 iStackPos=-1, ListRange *pEditRange=NULL) |
Tell the feather UI that it must edit a specific set of feather nodes - not find it's own set from the selection. See also: DoSlide(), SlideFinished(). | |
static ListRange * | GetEditContext () |
Get the current edit context for the feather UI controls See also: DoSlide(), SlideFinished(). | |
static void | ReleaseFeatherCache (NodeRenderableInk *pNode, DocRect &drRegion) |
static BOOL | IsUpdateDisabled () |
Static Private Member Functions | |
static NodeFeatherEffect * | DoReplaceFeatherEffectNode (UndoableOperation *pOp, NodeFeatherEffect *pNode, MILLIPOINT FeatherSize, CProfileBiasGain Profile) |
Private Attributes | |
List | m_NewFeatherAttrs |
Static Private Attributes | |
static INT32 | s_iEditStackPos = -1 |
static ListRange * | s_pEditRange = NULL |
static BOOL | s_DisableUpdates = FALSE |
Definition at line 208 of file opfeathr.h.
|
Definition at line 213 of file opfeathr.h. 00213 : UndoableOperation() {};
|
|
Deallocate anything grabbed in Init or grabbed statically.
Definition at line 768 of file opfeathr.cpp. 00769 { 00770 if (s_pEditRange) 00771 { 00772 delete s_pEditRange; 00773 s_pEditRange = NULL; 00774 } 00775 00776 return TRUE; 00777 }
|
|
Definition at line 1346 of file opfeathr.cpp. 01350 { 01351 ENSURE(pNode, "DoApplyLiveEffect not given a useful node"); 01352 01353 // Read the current state of the node 01354 MILLIPOINT OldFeatherSize = pNode->GetFeatherSize(); 01355 CProfileBiasGain OldFeatherProfile = pNode->GetProfile(); 01356 01357 // Setup the action to undo this Operation 01358 ChangeFeatherEffectAction* pAct = NULL; 01359 if (ChangeFeatherEffectAction::Init(pOp, 01360 pOp->GetUndoActionList(), 01361 pNode, 01362 OldFeatherSize, 01363 OldFeatherProfile, 01364 &pAct ) != AC_OK ) 01365 { 01366 pOp->FailAndExecute(); 01367 pOp->End(); 01368 return NULL; 01369 } 01370 01371 // Now we know the action was allocated OK, change the data structure... 01372 pNode->SetFeatherSize(FeatherSize); 01373 pNode->SetProfile(Profile); 01374 01375 return pNode; 01376 }
|
|
Called by our OpDescriptor's OnSliderChanging() method. Changes all feathers on our list, and causes them to redraw.
See also: SlideFinished(), DoWithParam(). Definition at line 1082 of file opfeathr.cpp. 01083 { 01085 // What we do: 01086 // 1. Change the feather sizes for all feathers in our list with a valid parent. 01087 // 2. Cause a redraw of the invalid region, so the user gets immediate feedback. 01088 // 01089 01090 // after each slide change, we'll need to invalidate the feathered region 01091 // so that the feathers re-render themselves correctly. 01092 DocRect drInvalidRegion(0, 0, 0, 0); 01093 01094 NodeListItem* pListItem = NULL; 01095 NodeListItem* pNextListItem = (NodeListItem*)m_NewFeatherAttrs.GetHead(); 01096 01097 AttrFeather* pFthrAttr = NULL; 01098 Node* pFeatheredNode = NULL; 01099 01100 // Prevent slow renderers from doing their stuff while we try to 01101 // show the results of the feather op interactively. 01102 Operation::SetQuickRender(TRUE, this); 01103 01104 while (pNextListItem != NULL) 01105 { 01106 pListItem = pNextListItem; 01107 pNextListItem = (NodeListItem*)m_NewFeatherAttrs.GetNext(pListItem); 01108 Node* pNode = pListItem->pNode; 01109 #ifdef FEATHER_EFFECT 01110 if (pNode->IsEffect() && ((NodeEffect*)pNode)->IsFeatherEffect()) 01111 { 01112 NodeFeatherEffect* pEffect = (NodeFeatherEffect*)pNode; 01113 pEffect->SetFeatherSize(SlideValue); 01114 01115 drInvalidRegion = drInvalidRegion.Union(pEffect->GetBoundingRect()); 01116 drInvalidRegion = drInvalidRegion.Union(pEffect->GetEffectStackBounds()); // There might be effects above us which will re-render after this change 01117 pEffect->ReleaseCached(TRUE, FALSE, TRUE, FALSE); // Parents and Self 01118 } 01119 else 01120 #endif 01121 { 01122 pFthrAttr = (AttrFeather*)pNode; 01123 pFeatheredNode = pFthrAttr->FindParent(); 01124 01125 if (pFeatheredNode != NULL && pFeatheredNode->IsAnObject()) 01126 { 01127 pFthrAttr->Value.SetFeatherSize(SlideValue); 01128 pFeatheredNode = pFthrAttr->FindParent(); 01129 drInvalidRegion = drInvalidRegion.Union( 01130 ((NodeRenderableInk*)pFeatheredNode)->GetBoundingRect() 01131 ); 01132 drInvalidRegion = drInvalidRegion.Union(((NodeRenderableInk*)pFeatheredNode)->GetEffectStackBounds()); // There might be effects above us which will re-render after this change 01133 ((NodeRenderableInk*)pFeatheredNode)->ReleaseCached(TRUE, FALSE, TRUE, FALSE); // Parents only 01134 } 01135 } 01136 } 01137 01138 // force a redraw of all the feathered nodes. 01139 if (!drInvalidRegion.IsEmpty()) 01140 { 01141 Document* pDoc = Document::GetSelected(); 01142 if (pDoc != NULL) 01143 { 01144 Spread* pSpread = pDoc->GetSelectedSpread(); 01145 if (pSpread != NULL) 01146 { 01147 pDoc->ForceRedraw(pSpread, drInvalidRegion); 01148 GetApplication()->ServiceRendering(); 01149 } 01150 } 01151 } 01152 01153 // Re-enable slow renderers 01154 Operation::SetQuickRender(FALSE, this); 01155 }
|
|
Called to initiate this action. Starts the process of resizing/applying feathers to the selection.
See also: DoSlide(), SlideFinished(). Reimplemented from Operation. Definition at line 880 of file opfeathr.cpp. 00881 { 00883 // What we do: 00884 // For all AllowOp()'d nodes in the selection: 00885 // 1. Undoably hide any existing feather attribute. 00886 // 2. Apply a new feather attribute with default settings or same as the old attr, 00887 // 3. adding it to a list of feather attrs to update. 00888 // 00889 BOOL bAddNewFeathers = TRUE; 00890 MILLIPOINT size = 0; 00891 ListRange* pLevelRange = NULL; 00892 ListRange* pLocalRange = NULL; 00893 BOOL bGotSelRange = FALSE; 00894 if (pParam && IS_A(pParam, OpChangeFeatherSizeParam)) 00895 { 00896 OpChangeFeatherSizeParam* pCFSParam = (OpChangeFeatherSizeParam*)pParam; 00897 bAddNewFeathers = pCFSParam->bAddNewFeathers; 00898 size = pCFSParam->size; 00899 pLevelRange = pCFSParam->pLevelRange; 00900 } 00901 00902 ObjChangeFlags cFlags; 00903 cFlags.Attribute = TRUE; 00904 00905 SelRange* pSelRange = GetApplication()->FindSelection(); 00906 pSelRange->MakePartialSelectionWhole(FALSE, TRUE); 00907 00908 // Since the selection may change during this Op we must get a permanent copy of 00909 // the PostProcessor stack 00910 // INT32 iStackPos = STACKPOS_TOP; 00911 // EffectsStack* pStack = pSelRange->GetEffectsStack(TRUE, TRUE); 00912 // ListRange* pLevelRange = pStack->GetLevelRange(&iStackPos); 00913 00914 // Since the selection may change during this Op we must get a permanent copy of 00915 // the level range we are working on 00916 if (pLevelRange==NULL) 00917 { 00918 SelRange* pSelRange = GetApplication()->FindSelection(); 00919 pLevelRange = pSelRange->GetTopClassRange(CC_RUNTIME_CLASS(NodeFeatherEffect), FALSE, TRUE); 00920 pLocalRange = new ListRange(pLevelRange); 00921 pLevelRange = pLocalRange; 00922 bGotSelRange = TRUE; 00923 } 00924 00925 DoInvalidateNodesRegions(*pLevelRange, TRUE, FALSE, FALSE, FALSE); 00926 00927 Node* pSelNode = NULL; 00928 for ( pSelNode = pLevelRange->FindFirst(); 00929 pSelNode != NULL; 00930 pSelNode = pLevelRange->FindNext(pSelNode) ) 00931 { 00932 if (!pSelNode->IsAnObject()) 00933 continue; 00934 00935 // What a mess! The following logic allows feather effects to 00936 // be applied to effects, EXCEPT when those effects are shadows 00937 NodeRenderableInk* pInkNode = (NodeRenderableInk*)pSelNode; 00938 AttrFeather* pFthr = (AttrFeather*)pInkNode->FindFirstChild(CC_RUNTIME_CLASS(AttrFeather)); 00939 ListRange* pStack = NULL; 00940 Node* pTopEffectNode = NULL; 00941 if (bAddNewFeathers && pFthr==NULL && !pInkNode->IsKindOf(CC_RUNTIME_CLASS(NodeFeatherEffect))) 00942 { 00943 pStack = EffectsStack::GetEffectsStackFromNode(pInkNode); 00944 if (pStack) 00945 { 00946 pTopEffectNode = pStack->FindLast(); 00947 while (pTopEffectNode && pTopEffectNode->IsAShadowController()) 00948 { 00949 pTopEffectNode = pStack->FindPrev(pTopEffectNode); 00950 } 00951 delete pStack; 00952 } 00953 } 00954 if (bAddNewFeathers && pFthr==NULL && pTopEffectNode!=NULL && pTopEffectNode->IsAnObject()) 00955 pInkNode = (NodeRenderableInk*)pTopEffectNode; 00956 00957 #ifdef FEATHER_EFFECT 00958 // For each node in the top level range 00959 // If the node is a postprocessor we must apply a feather effect 00960 // Otherwise we can apply a legacy style feather effect 00961 NodeCompound* pCompound = NULL; 00962 if (pInkNode->IsCompoundClass()) 00963 pCompound = (NodeCompound*)pInkNode; 00964 if (pInkNode->IsEffect() || 00965 (pCompound && (pCompound->HasEffectAttrs() || pCompound->ContainsEffects())) 00966 ) 00967 { 00968 // ---------------------------------------------------- 00969 // Feather Effect 00970 // 00971 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, pInkNode, this, OBJCHANGE_CALLEDBYOP); 00972 if (pInkNode->AllowOp(&ObjChange)) 00973 { 00974 Node* pEffect = NULL; 00975 if (pInkNode->IsEffect() && ((NodeEffect*)pInkNode)->IsFeatherEffect()) 00976 { 00977 // Existing Feather Effect 00978 NodeFeatherEffect* pFeatherNode = (NodeFeatherEffect*)pInkNode; 00979 pEffect = OpChangeFeatherSize::DoReplaceFeatherEffectNode( this, 00980 pFeatherNode, 00981 pFeatherNode->GetFeatherSize(), 00982 pFeatherNode->GetProfile()); 00983 } 00984 else if (bAddNewFeathers) 00985 { 00986 PORTNOTE("effect", "Removed LiveEffect usage") 00987 #ifndef EXCLUDE_FROM_XARALX 00988 // New Feather Effect 00989 pEffect = OpLiveEffect::DoApplyFeatherEffectNode(this, 00990 pInkNode, 00991 POSTPRO_ID_FEATHER, 00992 POSTPRO_DISPLAYNAME_FEATHER, 00993 10 * 750, 00994 CProfileBiasGain()); 00995 #endif 00996 } 00997 00998 if (pEffect==NULL && bAddNewFeathers) 00999 { 01000 FailAndExecute(); 01001 return; 01002 } 01003 01004 if (pEffect) 01005 m_NewFeatherAttrs.AddHead(new NodeListItem(pEffect)); 01006 } 01007 } 01008 else 01009 #endif 01010 { 01011 // ---------------------------------------------------- 01012 // Feather Legacy Attribute 01013 // 01014 // ensure that this is a featherable node 01015 // (which currently can only be derivatives of NodeRenderableInk). 01016 ObjChangeParam ObjChange( OBJCHANGE_STARTING, cFlags, pInkNode, this, 01017 OBJCHANGE_CALLEDBYOP ); 01018 if (pInkNode->AllowOp(&ObjChange)) 01019 { 01020 // undoably hide any existing feather attr. 01021 FeatherAttrValue* pOldFeatherVal = NULL; 01022 if (pFthr != NULL) 01023 { 01024 pOldFeatherVal = &pFthr->Value; 01025 DoHideNode(pFthr, FALSE); 01026 } 01027 01028 // non-undoably attach a new feather attr to the selected node. 01029 if (pFthr || bAddNewFeathers) 01030 { 01031 AttrFeather* pNewFthr = new AttrFeather(); 01032 pNewFthr->AttachNode(pInkNode, FIRSTCHILD); 01033 if (pNewFthr != NULL) 01034 { 01035 if (pOldFeatherVal != NULL) 01036 pNewFthr->Value.SimpleCopy(pOldFeatherVal); 01037 else 01038 pNewFthr->Value.SetFeatherSize(0); 01039 01040 m_NewFeatherAttrs.AddHead(new NodeListItem(pNewFthr)); 01041 } 01042 } 01043 } 01044 } 01045 } 01046 01047 // If we didn't use a supplied edit context 01048 // Then this would be a good time to clear any existing edit context that existed 01049 if (bGotSelRange) 01050 { 01051 SetEditContext(); 01052 if (pLocalRange) 01053 { 01054 delete pLocalRange; 01055 pLocalRange = NULL; 01056 } 01057 } 01058 }
|
|
Get the current edit context for the feather UI controls See also: DoSlide(), SlideFinished().
Definition at line 846 of file opfeathr.cpp. 00847 { 00848 if (s_iEditStackPos==STACKPOS_INVALID || s_pEditRange==NULL) 00849 return NULL; 00850 00851 if (s_pEditRange->MatchesSelectionEffectLevel(s_iEditStackPos)) 00852 return s_pEditRange; 00853 00854 return NULL; 00855 }
|
|
Definition at line 782 of file opfeathr.cpp. 00783 { 00784 // Always enabled. 00785 // Wherever a feather attr can't be applied we can apply a feather effect... 00786 00787 OpState OpSt; 00788 00789 OpSt.Greyed = FALSE; 00790 00791 return OpSt; 00792 }
|
|
Declares a preference that allows you to clear memory in delete().
Reimplemented from SimpleCCObject. Definition at line 736 of file opfeathr.cpp. 00737 { 00738 OpDescriptor* OpDesc = new ChangeFeatherSizeSliderOpDesc(0, 00739 _R(IDS_FEATHERSIZEOP), 00740 CC_RUNTIME_CLASS(OpChangeFeatherSize), 00741 OPTOKEN_FEATHERSIZE, 00742 OpChangeFeatherSize::GetState, // NB Operations GetState 00743 0, 00744 _R(IDBBL_FEATHERSIZEOP), 00745 SYSTEMBAR_FEATHER, 00746 _R(IDC_FEATHERSIZE_CUSTOMEDIT), 00747 TRUE, 00748 FALSE, 00749 FALSE, 00750 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE ) ); 00751 00752 ERROR2IF(!OpDesc, FALSE, _R(IDE_NOMORE_MEMORY)); 00753 00754 return TRUE; 00755 }
|
|
Definition at line 231 of file opfeathr.h. 00231 {return s_DisableUpdates;}
|
|
Reimplemented from UndoableOperation. Definition at line 224 of file opfeathr.h. 00224 { return FALSE; }
|
|
Definition at line 1303 of file opfeathr.cpp. 01304 { 01305 ERROR3IF(pNode==NULL, "ReleaseFeatherCache passed NULL node ptr"); 01306 01307 // T'would be better if ReleaseCached returned a rectangle that needs to 01308 // be invalidated to recover all the cached data... 01309 if (pNode->IsEffect()) 01310 pNode->ReleaseCached(TRUE, FALSE, FALSE, FALSE); 01311 else 01312 pNode->ReleaseCached(TRUE, FALSE, TRUE, TRUE); 01313 01314 NodeRenderableInk* pBoundsNode = pNode; 01315 ListRange* pStack = EffectsStack::GetEffectsStackFromNode(pNode); 01316 if (pStack) 01317 { 01318 pBoundsNode = (NodeEffect*)pStack->FindLast(); 01319 delete pStack; 01320 } 01321 01322 drRegion = drRegion.Union(pBoundsNode->GetBoundingRect()); 01323 }
|
|
Tell the feather UI that it must edit a specific set of feather nodes - not find it's own set from the selection. See also: DoSlide(), SlideFinished().
Definition at line 810 of file opfeathr.cpp. 00811 { 00812 if (s_pEditRange && s_pEditRange != pEditRange) 00813 { 00814 delete s_pEditRange; 00815 s_pEditRange = NULL; 00816 } 00817 00818 s_iEditStackPos = iStackPos; 00819 if (pEditRange) 00820 s_pEditRange = new ListRange(pEditRange); 00821 else 00822 s_pEditRange = NULL; 00823 00824 s_DisableUpdates = TRUE; // Disable updates to the slider triggered from this as we haven't set the new 00825 // feather attribute so we risk setting it back and causing jumpiness 00826 BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 00827 s_DisableUpdates = FALSE; 00828 }
|
|
Called by our OpDescriptor's OnSliderSet() method. Finishes off a feather-size slider drag. Removes any zero-size feathers on our list from the tree, and adds a hide-node action for legitimate feathers, so they hide on undo. Also records an action to invalidate the feathered nodes, for undo.
Notes: There is not time at the mo' (is there ever?), but it may be an idea to build these methods into a rudimentery slider or similar framework, like the drag framework, which would make implementing slider UI a lot easier, and remove lots of bodges. See also: DoSlide(), DoWithParam(). Definition at line 1187 of file opfeathr.cpp. 01188 { 01190 // What we do: 01191 // 1. Check the size of all feathers in our list. 01192 // zero size => remove and delete it from the tree. 01193 // ok size => record a hide-node action so it will be hidden on undo. 01194 // 01195 // 2. Undoably invalidate the region covered by all validly feathered nodes. 01196 // 01197 01198 // we need to undoably invalidate a region of the document. 01199 DocRect drInvalidRegion(0, 0, 0, 0); 01200 01201 NodeListItem* pListItem = (NodeListItem*)m_NewFeatherAttrs.GetHead(); 01202 AttrFeather* pFthrAttr = NULL; 01203 while (pListItem != NULL) 01204 { 01205 Node* pNode = pListItem->pNode; 01206 PORTNOTE("effect", "Removed LiveEffect usage") 01207 #ifndef EXCLUDE_FROM_XARALX 01208 #ifdef FEATHER_EFFECT 01209 if (pNode->IsEffect() && ((NodeEffect*)pNode)->IsFeatherEffect()) 01210 { 01211 NodeFeatherEffect* pEffect = (NodeFeatherEffect*)pNode; 01212 if (pEffect->GetFeatherSize()==0) 01213 OpLiveEffect::DoDeletePostProcessor(this, pEffect); 01214 01215 ReleaseFeatherCache(pEffect, drInvalidRegion); 01216 } 01217 else 01218 #endif 01219 #endif 01220 { 01221 pFthrAttr = (AttrFeather*)pNode; 01222 Node* pFeatheredNode = pFthrAttr->FindParent(); 01223 01224 // remove all zero-size feathers from the selection. 01225 if (pFthrAttr->Value.GetFeatherSize() == 0) 01226 { 01227 pFthrAttr->UnlinkNodeFromTree(); 01228 delete pFthrAttr; 01229 } 01230 else 01231 { 01232 // all remaining feathers should have a hide-node-action given to them, 01233 // so that when the user hits 'undo', they are hidden. 01234 HideNodeAction* pUndoHideNodeAction = NULL; 01235 ActionCode ac = HideNodeAction::Init(this, 01236 &UndoActions, 01237 pFthrAttr, 01238 FALSE, // don't include subtree size 01239 (Action**)&pUndoHideNodeAction, 01240 FALSE); // don't tell subtree when undone 01241 if (ac == AC_FAIL) 01242 { 01243 pFthrAttr->UnlinkNodeFromTree(); 01244 delete pFthrAttr; 01245 } 01246 } 01247 01248 if (pFeatheredNode != NULL && pFeatheredNode->IsAnObject()) 01249 { 01250 ReleaseFeatherCache((NodeRenderableInk*)pFeatheredNode, drInvalidRegion); 01251 } 01252 } 01253 01254 pListItem = (NodeListItem*)m_NewFeatherAttrs.GetNext(pListItem); 01255 } 01256 01257 // invalidate the feathered region. 01258 // Note that this is needed to allow nodes which were rendering themselves in a fast mode 01259 // during slider dragging (see Get/SetQuickRender) are now able to render themselves 01260 // fully now that the drag is over 01261 if (!drInvalidRegion.IsEmpty()) 01262 { 01263 Document* pDoc = Document::GetSelected(); 01264 if (pDoc != NULL) 01265 { 01266 Spread* pSpread = pDoc->GetSelectedSpread(); 01267 if (pSpread != NULL) 01268 DoInvalidateRegion(pSpread, drInvalidRegion); 01269 } 01270 } 01271 01272 // update any changed nodes. 01273 ObjChangeFlags ocf; 01274 ocf.Attribute = TRUE; 01275 ObjChangeParam ocp(OBJCHANGE_FINISHED, ocf, NULL, this, OBJCHANGE_CALLEDBYOP); 01276 UpdateChangedNodes(&ocp); 01277 01278 m_NewFeatherAttrs.DeleteAll(); 01279 01280 BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 01281 01282 if (!SuccessfulFinish) 01283 FailAndExecute(); 01284 01285 End(); 01286 }
|
|
Definition at line 242 of file opfeathr.h. |
|
Definition at line 246 of file opfeathr.h. |
|
Definition at line 244 of file opfeathr.h. |
|
Definition at line 245 of file opfeathr.h. |