OpBarCreation Class Reference

This class makes several copies of the selection, putting them onto particular named layers. Each copy is named button1, button2, etc.. Each layer is created and named Default, Mouse, Clicked or Selected. The copy can be 'mutated' to appear slightly different on each layer. The selection is deleted. More...

#include <opbarcreation.h>

Inheritance diagram for OpBarCreation:

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

Public Member Functions

 OpBarCreation ()
 OpBarCreation constructor.
virtual void Do (OpDescriptor *token)
 Creates a navigation rollover bar in the drawing by copying the selection several times unto named layers, and naming each copy of the selection.
void DoWithParam (OpDescriptor *token, OpParam *pOpParam)
 Creates a navigation rollover bar in the drawing by copying the selection several times unto named layers, and naming each copy of the selection.
LayerAddLayer (String_256 LayerName, INT32 NewLayerNo)
 Create a new named layer.
BOOL ApplyNameAttr (String_256 *pNameAttr, Node *pNode, BOOL UseBarName=TRUE)
 To apply the names Button1, Button2, etc to the different buttons so that the image slicing/rollover stuff works okay. NB. it uses the question part of the wix attribute to store the bar name. This then gets saved out in the wix files but will be destroyed by Merlin if wixxed up.
void ShiftColourValue (DocColour *pdoccol, INT32 PercentColourChange)
 Modifies the colours of objects for the "suggest design" mode Uses HSV colour model. Drops or raises V. When this goes out of bounds it lowers s too.
void FindAttribColours (Node *pAttrNode, INT32 PercentColourChange, INT32 State)
 Modifies the colours of objects for the "suggest design" mode Will also rotate bevels for the SELECTED state.
BOOL CleanSelection (Range *pSel, List *pSelectionList, List *pDeletionList, INT32 LayerNumToCreate)
 Has a look at the selection making it into a node list called selection if it is on a state layer that is not the current state layer it should be excluded from the selection as this must be an accident if the item is in the selection but not in any state layer it needs to be in the selection so it can be copied and added to the deletion list so it can be removed from play.
BOOL CreateOrEditBar (OpParam *pOpParam)
 Creates a navigation rollover bar in the drawing by copying the selection several times unto named layers, and naming each copy of the selection.
BOOL CreateFromDefaultState (OpParam *pOpParam)
 Pretty much just has to copy the contents of this bar from the default layer to the layer prescribed. All bar properties and stetching etc should already have been set up from creating the MouseOff state/layer.
BOOL CreateBackBarFromSelection (OpParam *pOpParam, BOOL Extend=FALSE)
 Creates the back bar from the selection.
BOOL CreateBarAndBackBar (OpParam *pOpParam)
void ShowState (INT32 ShowLayer)
 Makea sure that that just the state is shown, out of the specail states Updates the screen drawing and informs other dlgs/galleries such as the layer gallery.
INT32 GetBarNumber ()

Static Public Member Functions

static BOOL Init ()
 OpBarCreation initialiser method.
static OpState GetState (String_256 *, OpDescriptor *)
 For finding the operations state.

Private Attributes

String_256 m_RolloverName [5]
String_256 m_BarName
DocRect m_BarSelectionRect
DocRect m_FinishedBarRect

Detailed Description

This class makes several copies of the selection, putting them onto particular named layers. Each copy is named button1, button2, etc.. Each layer is created and named Default, Mouse, Clicked or Selected. The copy can be 'mutated' to appear slightly different on each layer. The selection is deleted.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99

Definition at line 126 of file opbarcreation.h.


Constructor & Destructor Documentation

OpBarCreation::OpBarCreation  ) 
 

OpBarCreation constructor.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Returns:
Errors: -
See also:
CarbonCopyOp

Definition at line 183 of file opbarcreation.cpp.

00183                             : CarbonCopyOp()                                
00184 {                              
00185 }


Member Function Documentation

Layer * OpBarCreation::AddLayer String_256  LayerName,
INT32  NewLayerNo
 

Create a new named layer.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Parameters:
Name of the Layer to create [INPUTS]
Pointer to the newly created layer [OUTPUTS]
Returns:
-

Definition at line 1152 of file opbarcreation.cpp.

01153 {
01154     Spread* pSpread = Document::GetSelectedSpread();
01155     if (pSpread == NULL)
01156         return NULL;
01157 
01158     // check to see if we need to add one first 
01159     Layer * pStandardLayer = SliceHelper::FindLayerCalled(LayerName);
01160     if (pStandardLayer)
01161     {
01162         LayerSGallery::MakeActiveLayer(pStandardLayer, FALSE); // dont tell, but we must put this back
01163         return pStandardLayer;
01164     }
01165 
01166     // find out where to add it and create it now
01167     Layer*              pLayer      = NULL;
01168     Node*               pContextNode= pSpread;
01169     AttachNodeDirection AttDir      = FIRSTCHILD;
01170     LayerStatus         NewStatus;
01171     NewStatus.StringLayerID = LayerName;
01172 
01173     // avoid the page - make the layers after the page node
01174     Node * pNode = pSpread->FindFirstChild();
01175     while (pNode)
01176     {
01177         // after the page node
01178         if (IS_A(pNode, Page))
01179         {
01180             pContextNode = pNode;
01181             AttDir = NEXT;
01182         }
01183         // and after any background nodes
01184         else if (pNode->IS_KIND_OF(Layer))
01185         {
01186             if (((Layer *)pNode)->IsBackground())
01187             {
01188                 pContextNode = pNode;
01189                 AttDir = NEXT;
01190             }
01191         }
01192 
01193         pNode = pNode->FindNext();
01194     }
01195 
01196     // order the special layers
01197     BOOL FoundHigherLayer = FALSE;
01198     INT32 LayerToFind = NewLayerNo-1;
01199     while (!FoundHigherLayer && LayerToFind >= DEFAULT)
01200     {
01201         pStandardLayer = SliceHelper::FindLayerCalled(m_RolloverName[LayerToFind]);
01202         if (pStandardLayer)
01203         {
01204             FoundHigherLayer = TRUE; // found the layer to stick it just previous to
01205 
01206             pContextNode = pStandardLayer;
01207             AttDir      = PREV;
01208         }
01209         else
01210         {
01211             LayerToFind--;
01212         }
01213     }
01214 
01215     // create the new layer and stick it in the tree
01216     ALLOC_WITH_FAIL(pLayer, (new Layer()), this);         
01217     if (pLayer == NULL) return NULL;
01218 
01219     // Set the new layer's status  
01220     pLayer->SetLayerStatus(NewStatus); 
01221 
01222     if (DoInsertNewNode(pLayer,pContextNode,AttDir,FALSE))
01223     {
01224         LayerSGallery::MakeActiveLayer(pLayer, FALSE); // dont tell but we must put this back
01225     }
01226 
01227     return pLayer;
01228 }

BOOL OpBarCreation::ApplyNameAttr String_256 pNameAttr,
Node pNode,
BOOL  UseBarName = TRUE
 

To apply the names Button1, Button2, etc to the different buttons so that the image slicing/rollover stuff works okay. NB. it uses the question part of the wix attribute to store the bar name. This then gets saved out in the wix files but will be destroyed by Merlin if wixxed up.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Parameters:
The object name and the node to apply it to [INPUTS]
Returns:
TRUE unless a error occurred

Definition at line 1245 of file opbarcreation.cpp.

01246 {
01247     TemplateAttribute* pAttr = new TemplateAttribute(   String_256(TEXT("ObjectName")),
01248                                                         UseBarName ? m_BarName : "",
01249                                                         *pNameAttr);
01250 
01251     if (!pAttr) return FALSE;
01252 
01253     // add the attrib into the tree
01254     pAttr->AttachNode(pNode, FIRSTCHILD);
01255 
01256     return TRUE;
01257 }

BOOL OpBarCreation::CleanSelection Range pSel,
List pSelectionList,
List pDeletionList,
INT32  LayerNumToCreate
 

Has a look at the selection making it into a node list called selection if it is on a state layer that is not the current state layer it should be excluded from the selection as this must be an accident if the item is in the selection but not in any state layer it needs to be in the selection so it can be copied and added to the deletion list so it can be removed from play.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> K
Date:
30/3/00
Returns:
TRUE if all went well

Definition at line 1853 of file opbarcreation.cpp.

01854 {
01855     Layer * pLayer = NULL;
01856     Node * pCurrent = pSel->FindFirst();
01857     Node * pParent = NULL;
01858     Spread* pSpread = Document::GetSelectedSpread();
01859     BOOL AllOk = TRUE;
01860     String_256 ButtonBeingEdited = "";
01861 
01862     // for each node in the selection
01863     while (pCurrent)
01864     {
01865         // find the layer on which it resides
01866         pParent = pCurrent;
01867         while (!pParent->IsLayer())
01868             pParent = pParent->FindParent();
01869 
01870         pLayer = (Layer *)pParent;
01871 
01872         BOOL ok = FALSE;
01873 
01874         // use nodes from the layer we are going to be adding to
01875         if (LayerNumToCreate >=0 && LayerNumToCreate <=4)
01876         {
01877             if (pLayer->GetLayerID() == m_RolloverName[LayerNumToCreate])
01878                 ok = TRUE;
01879         }
01880 
01881         if (!ok)
01882         {   
01883             ok = TRUE;
01884             // test the newly found layer against the state layers
01885             // if it is not on a state layer it should be in the sel and del lists
01886             for (INT32 i = 0; i < 5; i++)
01887             {
01888                 if (pLayer->GetLayerID() == m_RolloverName[i])
01889                 {
01890                     ok = FALSE;
01891                     AllOk = FALSE;
01892                 }
01893             }
01894 
01895             if (!ok)
01896             {
01897                 // it could be a normal shape drawn on the wrong layer
01898                 // so if it is not tagged with a bar tag make it ok
01899                 ok = TRUE;
01900 
01901                 // of course we need to find the template attribs first
01902 
01903                 Node * pAttr = SliceHelper::FindNextOfClass(pCurrent,pCurrent, CC_RUNTIME_CLASS(TemplateAttribute));
01904 
01905                 while (pAttr)
01906                 {
01907                     if (!SliceHelper::GetBarName((TemplateAttribute *)pAttr).IsEmpty())
01908                     {
01909                         ok = FALSE;
01910                         break;
01911                     }
01912 
01913                     pAttr = SliceHelper::FindNextOfClass(pAttr,pCurrent, CC_RUNTIME_CLASS(TemplateAttribute));
01914                 }
01915             }
01916 
01917             if (ok) // add to the deletion list - its on Layer 1 or whatever
01918             {
01919                 NodeListItem * pItem = new NodeListItem(pCurrent);
01920                 pDeletionList->AddTail(pItem);
01921             }
01922         }
01923         else // drawn on the layer you are going to copy to? 
01924             //  still want to delete your original drawing as it wont have the tags required
01925         {
01926             // only want to copy from a single button
01927             // if it is from a different button do not add it to the selection or
01928             // delete it
01929             // of course we need to find the template attribs first
01930 
01931             Node * pAttr = SliceHelper::FindNextOfClass(pCurrent,pCurrent, CC_RUNTIME_CLASS(TemplateAttribute));
01932             BOOL FromThisBar = TRUE;
01933 
01934             while (pAttr)
01935             {
01936                 if (!SliceHelper::GetBarName((TemplateAttribute *)pAttr).IsEmpty())
01937                 {
01938                     // the source is from another bar
01939                     if (m_BarName.CompareTo(SliceHelper::GetBarName((TemplateAttribute *)pAttr)) != 0)
01940                     {
01941                         FromThisBar = FALSE;
01942                     }
01943 
01944                     String_256 AttrSet = SliceHelper::GetSetNameFromAttrib(pAttr);
01945                     if (ButtonBeingEdited.IsEmpty())
01946                     {
01947                         ButtonBeingEdited = AttrSet;
01948                         break;
01949                     }
01950                     else if (ButtonBeingEdited == AttrSet || AttrSet.IsEmpty())
01951                     {
01952                         break;
01953                     }
01954                     else
01955                         ok = FALSE; // it is of another bar name set
01956                     break;
01957                 }
01958 
01959                 pAttr = SliceHelper::FindNextOfClass(pAttr,pCurrent, CC_RUNTIME_CLASS(TemplateAttribute));
01960             }
01961             
01962             if (ok && FromThisBar) // delete it from here
01963             {
01964                 NodeListItem * pItem = new NodeListItem(pCurrent);
01965                 pDeletionList->AddTail(pItem);
01966             }
01967         }
01968 
01969         if (ok)
01970         { // add to the selection list
01971             NodeListItem * pItem = new NodeListItem(pCurrent);
01972             pSelectionList->AddTail(pItem);
01973         }
01974 
01975         // check the next item on the list
01976         pCurrent = pSel->FindNext(pCurrent);
01977     }
01978 
01979     return AllOk;
01980 }

BOOL OpBarCreation::CreateBackBarFromSelection OpParam pOpParam,
BOOL  Extend = FALSE
 

Creates the back bar from the selection.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> K
Date:
5/4/00
Returns:
TRUE if all went well

Definition at line 1589 of file opbarcreation.cpp.

01590 {
01591     String_256 ActiveLayerStr(_R(IDS_ROLLOVER_DEFAULT));
01592     Spread* pSpread = Document::GetSelectedSpread();
01593     if (pSpread)
01594     {
01595         ActiveLayerStr = pSpread->FindActiveLayer()->GetLayerID();
01596     }
01597 
01598     OpParamBarCreation* pBarParam = (OpParamBarCreation*)pOpParam;
01599 
01600     // get the name of this bar
01601     m_BarName = pBarParam->m_BarName;
01602 
01603     // work out the name of the back bar
01604     String_256 BackBarName = "";
01605     BackBarName.MakeMsg(_R(IDS_BACKBARNAME), SliceHelper::GetBarNumberFromBarName(m_BarName) +1);
01606 
01607     // set up the layer names
01608     m_RolloverName[DEFAULT].Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
01609     m_RolloverName[MOUSE].Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
01610     m_RolloverName[CLICKED].Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
01611     m_RolloverName[SELECTED].Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
01612     m_RolloverName[BACKBAR].Load(_R(IDS_BACK_BAR)); // = "Back Bar";
01613 
01614     List SelectionList;
01615     List DelList;
01616 
01617     // get the selection
01618     Range Sel(*(GetApplication()->FindSelection()));
01619 
01620     // set the range flags so it includes shadow and bevel manager nodes
01621     RangeControl rg = Sel.GetRangeControlFlags();
01622     rg.PromoteToParent = TRUE;
01623     Sel.Range::SetRangeControl(rg);
01624 
01625     // remove any quickshape objects from the selection
01626     if (Extender::ConvertQuickShapesInSelRangeToPaths(this, &Sel))
01627     {
01628         Sel = *(GetApplication()->FindSelection());
01629         rg = Sel.GetRangeControlFlags();
01630         rg.PromoteToParent = TRUE;
01631         Sel.Range::SetRangeControl(rg);
01632     }
01633 
01634     if (Sel.IsEmpty())
01635     {
01636         InformWarning(_R(IDS_WARNING_NO_SEL_BACKBAR));
01637         return FALSE;
01638     }
01639     
01640     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
01641     ObjChangeFlags cFlags;
01642     cFlags.MultiReplaceNode = TRUE;
01643     cFlags.RegenerateNode = TRUE;
01644     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
01645 
01646     // Mark nodes that will allow this to happen, and error if no nodes will let it happen
01647     if (!Sel.AllowOp(&ObjChange))
01648         return FALSE; // op not allowed
01649 
01650     // get the size of the selection
01651     DocRect SelRect; // = Sel.GetBoundingRect();
01652     SelRect.MakeEmpty();
01653 
01654     // modify the selection to the allowed constraints
01655     // use the selection list from now on
01656     CleanSelection (&Sel, &SelectionList, &DelList, BACKBAR);
01657     if (SelectionList.IsEmpty())
01658     {
01659         InformWarning(_R(IDS_WARNING_NO_SEL_BACKBAR));
01660         return FALSE;
01661     }
01662 
01663     // define the SelRect from the selection list
01664     NodeListItem * pNodeListItem = (NodeListItem *)SelectionList.GetHead();
01665     while(pNodeListItem)
01666     {
01667         // localise attribs for this node
01668         DoLocaliseForAttrChange((NodeRenderableInk*) pNodeListItem->pNode, (AttrTypeSet *)NULL, (ObjectSet*) NULL);
01669 
01670         // calc the size of this node as part of the size of the selection
01671         SelRect = SelRect.Union(SliceHelper::BoundingNodeSize(pNodeListItem->pNode));
01672 
01673         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
01674     }
01675 
01676     // create a barBar layer if there isn't one
01677     Layer * pNewLayer = AddLayer(m_RolloverName[BACKBAR], BACKBAR);
01678 
01679     // mark the existing back bar for deletion if not in the selection
01680     SliceHelper::BuildListOfNodesInBar(&DelList, pNewLayer, m_BarName);
01681 
01682     // activate the layer we are about to stuff things on
01683     SliceHelper::ShowLayer(TRUE, pNewLayer, pSpread, this);
01684 
01685     LayerSGallery::MakeActiveLayer(pNewLayer, FALSE); // dont tell as we will put this back
01686 
01687     // add items directly after the layer node as its first child
01688     Node * pTail = pNewLayer;
01689     AttachNodeDirection TailAttachDirection = FIRSTCHILD;
01690 
01691     // copy the selection from where it is to the backbar layer
01692     pNodeListItem = (NodeListItem *)SelectionList.GetHead();
01693     Node * pNode;
01694 
01695     while (pNodeListItem)
01696     {
01697         pNode = pNodeListItem->pNode;
01698         if (pNode)
01699         {
01700             // add this node into the tree on the layer defined in list order
01701             // Make a copy of the current node
01702             Node* pTheCopy;
01703             BOOL ok;
01704             
01705             CALL_WITH_FAIL(pNode->NodeCopy(&pTheCopy), this, ok);
01706 
01707             if (ok && !DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pTail, TailAttachDirection,
01708                                      TRUE,      // Do Invalidate region 
01709                                      FALSE))    // Don't Clear the selections
01710                 {
01711                     ok = FALSE;
01712                 }
01713 
01714             if (ok)
01715             {
01716                 // have all of these new nodes selected
01717                 pTheCopy->SetSelected(TRUE);
01718 
01719                 // delete any wix attribs that are on this node
01720                 TemplateAttribute * pTemplateAttribute = (TemplateAttribute *) SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(TemplateAttribute));
01721                 while (pTemplateAttribute)
01722                 {
01723                     TemplateAttribute * pNextTemplateAttribute = (TemplateAttribute *) SliceHelper::FindNextOfClass(pTemplateAttribute, pTheCopy, CC_RUNTIME_CLASS(TemplateAttribute));
01724                     // found a bar element
01725                     if (SliceHelper::GetBarNumberFromBarName(pTemplateAttribute->GetQuestion()) >= 0)
01726                     {
01727                         // hide this, it is replaced by the ApplyNameAttr call bellow
01728                         // which will use the buttons new name
01729                         DoHideNode(pTemplateAttribute, TRUE);
01730                     }
01731 
01732                     pTemplateAttribute = pNextTemplateAttribute;
01733                 }
01734 
01735                 // if it is not correctly named add the name now
01736                 ApplyNameAttr(&BackBarName, pTheCopy);
01737 
01738                 // if extending extend this backbar item on the fly!
01739                 if (Extend)
01740                 {
01741                     // do the extend
01742                     Extender::Extend((NodeRenderableInk*) (pTheCopy),
01743                         pBarParam->m_ExtendFlags,
01744                         m_BarSelectionRect,
01745                         SelRect,
01746                         m_FinishedBarRect,
01747                         m_BarSelectionRect,
01748                         SelRect,
01749                         NULL, // no restrictions on extending
01750                         TRUE
01751                         );
01752                     
01753                     // wake up blends They appear to need this extra wake up call otherwise they
01754                     // do not redraw to their new extended dimensions
01755                     if (pTheCopy->IsABlend())
01756                         ((NodeBlend*)(pTheCopy))->Reinit(FALSE);
01757                 }
01758 
01759                 // factor out common attribs
01760                 if (pTheCopy->IsCompound() && !pTheCopy->IsABlend())
01761                     DoFactorOutCommonChildAttributes((NodeRenderableInk*) pTheCopy);
01762                 else
01763                     DoFactorOutAfterAttrChange((NodeRenderableInk*) pTheCopy, (AttrTypeSet *)NULL);
01764 
01765                 // attach the next node after this one
01766                 TailAttachDirection = NEXT;
01767                 pTail = pTheCopy;
01768             }
01769         }
01770 
01771         // and for the next item in the list
01772         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
01773     }
01774 
01775 
01776     // add the back bar properties, which means it is extended by every member of the bar
01777     SliceHelper::CreatePropertiesForSet(BackBarName, m_BarName, FALSE, pBarParam->m_ExtendFlags != 0, TRUE, pBarParam->m_ExtendFlags,
01778                 TEXT(""), FALSE, &SelRect, Extend ? &m_BarSelectionRect : NULL, this);
01779 
01780     // clean up the selection list
01781     pNodeListItem = (NodeListItem *)SelectionList.GetHead();
01782     NodeListItem *pNodeListItemToDel = NULL;
01783 
01784     while (pNodeListItem)
01785     {
01786         pNodeListItemToDel = pNodeListItem;
01787         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
01788         SelectionList.RemoveItem((NodeListItem *)pNodeListItemToDel);
01789         delete pNodeListItemToDel;
01790     }
01791 
01792     // delete the existing back bar nodes
01793     pNodeListItem = (NodeListItem *)DelList.GetHead();
01794     pNodeListItemToDel = NULL;
01795 
01796     while(pNodeListItem)
01797     {
01798         pNodeListItemToDel = pNodeListItem;
01799         Node *pParent = pNodeListItem->pNode;
01800 
01801         // if it is the template attrib we are looking at
01802         // we mean the node on which it is attached
01803         if (IS_A(pParent, TemplateAttribute))
01804             pParent = pParent->FindParent();
01805 
01806         if (pParent->FindParent())
01807         {
01808             DoInvalidateNodeRegion((NodeRenderableBounded*) pParent, TRUE, FALSE);
01809             pParent->SetSelected(FALSE);
01810             DoHideNode(pParent, TRUE);
01811         }
01812 
01813         pNodeListItem = (NodeListItem *)DelList.GetNext(pNodeListItem);
01814         DelList.RemoveItem((NodeListItem *)pNodeListItemToDel);
01815         delete pNodeListItemToDel;
01816     }
01817 
01818     // set the active layer to the layer that was active before
01819     // if that is possible
01820     Layer* pActiveLayer = SliceHelper::FindLayerCalled(ActiveLayerStr);
01821     if (pActiveLayer != 0) 
01822     {
01823         LayerSGallery::MakeActiveLayer(pActiveLayer, FALSE); // don't tell as we are putting it back
01824     }
01825 
01826     // inform that there may well be more/less layers about to be visible or not
01827     BROADCAST_TO_ALL(LayerMsg(pActiveLayer, LayerMsg::LayerReason::LAYER_VISIBILITY_CHANGED));
01828 
01829     // the selection will have changed - after all we just deleted it
01830     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
01831     GetApplication()->UpdateSelection();
01832 
01833     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01834     UpdateChangedNodes(&ObjChange, pSpread);
01835     return TRUE;
01836 }

BOOL OpBarCreation::CreateBarAndBackBar OpParam pOpParam  ) 
 

Definition at line 2000 of file opbarcreation.cpp.

02001 {
02002 
02003     // unselect the back object and note it down to make into a back bar
02004     Node * pBackObj = NULL;
02005 
02006     // get the selection
02007     Range Sel(*(GetApplication()->FindSelection()));
02008 
02009     // set the range flags so it includes shadow and bevel manager nodes
02010     RangeControl rg = Sel.GetRangeControlFlags();
02011     rg.PromoteToParent = TRUE;
02012     Sel.Range::SetRangeControl(rg);
02013 
02014     if (Sel.Count() < 2)
02015         return FALSE;
02016     else
02017     {
02018         pBackObj = Sel.FindFirst();
02019         pBackObj->SetSelected(FALSE);
02020     }
02021 
02022 
02023     BOOL ok = CreateOrEditBar(pOpParam);
02024 
02025     if (!ok)
02026     {
02027         InformWarning(_R(IDS_FAILLED_MAKE_BAR));
02028         return FALSE;
02029     }
02030 
02031     // deselect everything
02032     NodeRenderableInk::DeselectAll(TRUE);
02033 
02034     // select everything in the group not the group itself
02035     // dont bother with this now as we deal with true groups extending
02036 /*  if (pBackObj->IsCompound())
02037     {
02038         pBackObj = pBackObj->FindFirstChild();
02039         while (pBackObj)
02040         {
02041             if (!pBackObj->IsNodeHidden() && !pBackObj->IsAnAttribute())
02042                 pBackObj->SetSelected(TRUE);
02043 
02044             pBackObj = pBackObj->FindNext();
02045         }
02046     }
02047     else // else select the node
02048 */      pBackObj->SetSelected(TRUE);
02049 
02050     ok = CreateBackBarFromSelection(pOpParam, TRUE);
02051 
02052     if (!ok)
02053         InformWarning(_R(IDS_FAILLED_MAKE_BACKBAR));
02054 
02055     return ok;
02056 }

BOOL OpBarCreation::CreateFromDefaultState OpParam pOpParam  ) 
 

Pretty much just has to copy the contents of this bar from the default layer to the layer prescribed. All bar properties and stetching etc should already have been set up from creating the MouseOff state/layer.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> K
Date:
25/3/00
Returns:
TRUE if all went well

Definition at line 1417 of file opbarcreation.cpp.

01418 {
01419     // work out which is the active layer so we can set this back when
01420     // we are finished playing around with them all
01421     String_256 ActiveLayerStr(_R(IDS_ROLLOVER_DEFAULT));
01422     Spread* pSpread = Document::GetSelectedSpread();
01423     if (pSpread)
01424     {
01425         ActiveLayerStr = pSpread->FindActiveLayer()->GetLayerID();
01426     }
01427 
01428     OpParamBarCreation* pBarParam = (OpParamBarCreation*)pOpParam;
01429 
01430     // get the name of this bar
01431     m_BarName = pBarParam->m_BarName;
01432 
01433     // set up the layer names
01434     m_RolloverName[DEFAULT].Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
01435     m_RolloverName[MOUSE].Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
01436     m_RolloverName[CLICKED].Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
01437     m_RolloverName[SELECTED].Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
01438     m_RolloverName[BACKBAR].Load(_R(IDS_BACK_BAR)); // = "Back Bar";
01439 
01440     INT32 NewLayerNo = 0;
01441 
01442     if (pBarParam->m_WantMouse)
01443         NewLayerNo = 1;
01444     else if (pBarParam->m_WantClicked)
01445         NewLayerNo = 2;
01446     else if (pBarParam->m_WantSelected)
01447         NewLayerNo = 3;
01448 
01449     // create the new layer
01450     Layer * pNewLayer = AddLayer(m_RolloverName[NewLayerNo], NewLayerNo);
01451     
01452     if (!pNewLayer)
01453         return FALSE;
01454 
01455     // make the new layer visible
01456     SliceHelper::ShowLayer(TRUE, pNewLayer, pSpread, this);
01457 
01458     Layer * pLayer = NULL;
01459 
01460     List BarList;
01461 
01462     pLayer = SliceHelper::FindLayerCalled(m_RolloverName[DEFAULT]);
01463 
01464     if (!pLayer)
01465         return FALSE;
01466 
01467     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
01468     ObjChangeFlags cFlags;
01469     cFlags.RegenerateNode = TRUE;
01470     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
01471 
01472     // list all of this bar that is on the default layer
01473     SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, m_BarName);
01474 
01475     // copy each item referenced by a template attrib marked with this bar ID
01476     NodeListItem * pNodeListItem = (NodeListItem *)BarList.GetHead();
01477     NodeListItem * pDelThisToo = NULL;
01478 
01479     Node * pTail = pNewLayer;
01480     AttachNodeDirection TailAttachDirection = FIRSTCHILD;
01481 
01482     while(pNodeListItem)
01483     {
01484         pDelThisToo = pNodeListItem;
01485         Node *pNode = pNodeListItem->pNode->FindParent();
01486         if (pNode)
01487         {
01488             // add this node into the tree on the layer defined in list order
01489             // Make a copy of the current node
01490             Node* pTheCopy;
01491             BOOL ok = TRUE;
01492             
01493             if (ok)
01494                 CALL_WITH_FAIL(pNode->NodeCopy(&pTheCopy), this, ok);
01495 
01496             if (ok && pBarParam->m_SuggestDesign)
01497             {
01498                 INT32 ColShift = 100;
01499                 if (NewLayerNo == MOUSE)
01500                     ColShift = 40;
01501                 else if (NewLayerNo == SELECTED)
01502                     ColShift = 150;
01503                 else if (NewLayerNo == CLICKED)
01504                     ColShift = 0; // this plays with the hue instead
01505 
01506                 FindAttribColours(pTheCopy, ColShift, NewLayerNo);
01507             }
01508 
01509             if (ok && !DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pTail, TailAttachDirection,
01510                                      TRUE,      // Do Invalidate region 
01511                                      FALSE))    // Don't Clear the selections
01512                 {
01513                     ok = FALSE;
01514                 }
01515 
01516             if (ok)
01517             {
01518                 // if we are making the selected version check that we didn't have a default light angle
01519                 // on the bevel that we would have missed. If we did miss it add in a reverse of the 
01520                 // default light angle
01521                 if (NewLayerNo == SELECTED && pBarParam->m_SuggestDesign)
01522                 {
01523                     // was there a bevel? With out a bev light angle?
01524                     Node * pBev = SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(NodeBevelController), TRUE );
01525                     if (pBev && !SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(AttrBevelLightAngle) ))
01526                     {
01527                         // then give it a bev light angle
01528                         AttrBevelLightAngle* pNewLightAttr = new AttrBevelLightAngle();
01529                         if (pNewLightAttr)
01530                         {
01531                             pNewLightAttr->Value.m_LightAngle = 120; // reverse of the default
01532                             // add the attrib into the tree
01533                             pNewLightAttr->AttachNode(pTheCopy, FIRSTCHILD);
01534 
01535                         }
01536                     }
01537                 }
01538 
01539                 // don't have any of these new nodes selected
01540                 pTheCopy->SetSelected(FALSE);
01541 
01542                 // make it regenerate
01543                 pTheCopy->AllowOp(&ObjChange);
01544 
01545                 // attach the next node after this one
01546                 TailAttachDirection = NEXT;
01547                 pTail = pTheCopy;
01548             }
01549         }
01550 
01551         pNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
01552 
01553         // tidy up the list as we go along
01554         BarList.RemoveItem((NodeListItem *)pDelThisToo);
01555         delete pDelThisToo;
01556     }
01557 
01558     // set the active layer to the layer that was active before
01559     // if that is possible
01560     Layer* pActiveLayer = SliceHelper::FindLayerCalled(ActiveLayerStr);
01561     if (pActiveLayer != 0)
01562         LayerSGallery::MakeActiveLayer(pActiveLayer, FALSE); // dont tell as we are putting this back
01563 
01564     // show just the new layer we have made
01565     ShowState(NewLayerNo);
01566 
01567     // inform that there may well be more/less layers about to be visible or not
01568     BROADCAST_TO_ALL(LayerMsg(pActiveLayer, LayerMsg::LayerReason::LAYER_VISIBILITY_CHANGED));
01569     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
01570 
01571     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01572     UpdateChangedNodes(&ObjChange);
01573 
01574 
01575     // the selection will have changed - after all we just deleted it
01576     GetApplication()->UpdateSelection();
01577     return TRUE;
01578 }

BOOL OpBarCreation::CreateOrEditBar OpParam pOpParam  ) 
 

Creates a navigation rollover bar in the drawing by copying the selection several times unto named layers, and naming each copy of the selection.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99 - re-writen 17/4/00
Parameters:
OpParam - describes the number of buttons, what layers to create, any mutation [INPUTS]
- [OUTPUTS]
Returns:
TRUE on success, FALSE on failure

Errors: -

See also:
OpBarCreation::DoWithParam

Definition at line 352 of file opbarcreation.cpp.

00353 {
00354     String_256 ActiveLayerStr(_R(IDS_ROLLOVER_DEFAULT));
00355     Spread* pSpread = Document::GetSelectedSpread();
00356     if (pSpread)
00357     {
00358         ActiveLayerStr = pSpread->FindActiveLayer()->GetLayerID();
00359     }
00360 
00361     OpParamBarCreation* pBarParam = (OpParamBarCreation*)pOpParam;
00362     if (pBarParam->m_NoOfButtons > MAX_BUTTONS_IN_A_BAR)
00363         return FALSE; // too many buttons requested
00364 
00365     // get the name of this bar
00366     m_BarName = pBarParam->m_BarName;
00367     INT32 BarNo = SliceHelper::GetBarNumberFromBarName(m_BarName);
00368 
00369     // set up the layer names
00370     m_RolloverName[DEFAULT].Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
00371     m_RolloverName[MOUSE].Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
00372     m_RolloverName[CLICKED].Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
00373     m_RolloverName[SELECTED].Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
00374     m_RolloverName[BACKBAR].Load(_R(IDS_BACK_BAR)); // = "Back Bar";
00375 
00376     INT32 NewLayerNo = 0;
00377 
00378     if (pBarParam->m_WantMouse)
00379         NewLayerNo = 1;
00380     else if (pBarParam->m_WantClicked)
00381         NewLayerNo = 2;
00382     else if (pBarParam->m_WantSelected)
00383         NewLayerNo = 3;
00384 
00385     List SelectionList; // list of nodes we are copying to each point
00386     List DelList;       // list of nodes we no longer have any use for
00387     Node * pNode = NULL;
00388 
00389     // get the selection
00390     Range Sel(*(GetApplication()->FindSelection()));
00391 
00392     // set the range flags so it includes shadow and bevel manager nodes
00393     RangeControl rg = Sel.GetRangeControlFlags();
00394     rg.PromoteToParent = TRUE;
00395     Sel.Range::SetRangeControl(rg);
00396 
00397     // remove any quickshape objects from the selection
00398     if (Extender::ConvertQuickShapesInSelRangeToPaths(this, &Sel))
00399     {
00400         Sel = *(GetApplication()->FindSelection());
00401         rg = Sel.GetRangeControlFlags();
00402         rg.PromoteToParent = TRUE;
00403         Sel.Range::SetRangeControl(rg);
00404     }
00405 
00406     if (Sel.IsEmpty())
00407     {
00408         InformWarning(_R(IDS_WARNING_NO_SEL_TEMPLATE));
00409         return FALSE;
00410     }
00411     
00412     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
00413     ObjChangeFlags cFlags;
00414     cFlags.MultiReplaceNode = TRUE;
00415     cFlags.RegenerateNode = TRUE;
00416     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00417 
00418     // Mark nodes that will allow this to happen, and error if no nodes will let it happen
00419     if (!Sel.AllowOp(&ObjChange))
00420         return FALSE; // op not allowed
00421 
00422     // modify the selection to the allowed constraints
00423     // use the selection list from now on
00424     CleanSelection (&Sel, &SelectionList, &DelList, NewLayerNo);
00425 
00426     if (SelectionList.IsEmpty())
00427     {
00428         InformWarning(_R(IDS_WARNING_NO_SEL_TEMPLATE));
00429         return FALSE;
00430     }
00431 
00432     // create the new layer
00433     Layer * pNewLayer = AddLayer(m_RolloverName[NewLayerNo], NewLayerNo);
00434     
00435     if (!pNewLayer)
00436         return FALSE;
00437 
00438     // mark the existing back bar for deletion if not in the selection
00439     SliceHelper::BuildListOfNodesInBar(&DelList, pNewLayer, m_BarName);
00440 
00441     // the deletion list should be of the actual nodes not the attribs as these
00442     // can get removed in the process
00443     NodeListItem * pNodeListItem = (NodeListItem *)DelList.GetHead();
00444 
00445     while(pNodeListItem)
00446     {
00447         Node *pParent = pNodeListItem->pNode;
00448 
00449         // if it is the template attrib we are looking at
00450         // we mean the node on which it is attached
00451         if (IS_A(pParent, TemplateAttribute))
00452         {
00453             pParent = pParent->FindParent();
00454             pNodeListItem->pNode = pParent;
00455         }
00456 
00457         // if it is under a bevel or shadow or something look at the top node of the compound thing
00458         while (!IS_A(pParent->FindParent(), NodeGroup) && !pParent->FindParent()->IsLayer())
00459         {
00460             pParent = pParent->FindParent();
00461             pNodeListItem->pNode = pParent;
00462         }
00463 
00464         pNodeListItem = (NodeListItem *)DelList.GetNext(pNodeListItem);
00465     }
00466 
00467     // get the size of the selection
00468     DocRect SelRect;
00469     SelRect.MakeEmpty();
00470     DocRect FullSelRect;
00471     FullSelRect.MakeEmpty();
00472     
00473     // localise all the attribs in the selection list
00474     pNodeListItem = (NodeListItem *)SelectionList.GetHead();
00475 
00476     while(pNodeListItem)
00477     {
00478         // localise attribs for this node
00479         DoLocaliseForAttrChange((NodeRenderableInk*) pNodeListItem->pNode, (AttrTypeSet *)NULL, (ObjectSet*) NULL);
00480 
00481         // calc the size of this node as part of the size of the selection
00482         SelRect = SelRect.Union(SliceHelper::BoundingNodeSize(pNodeListItem->pNode));
00483         if (IS_A(pNodeListItem->pNode, NodeShadowController) || IS_A(pNodeListItem->pNode, TextStory))
00484             FullSelRect = FullSelRect.Union(SliceHelper::BoundingNodeSize(pNodeListItem->pNode));
00485         else
00486             FullSelRect = FullSelRect.Union(((NodeRenderableBounded*)(pNodeListItem->pNode))->GetBoundingRect());
00487 
00488         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
00489     }
00490 
00491     // find the center of the selection
00492     DocCoord SelCentre = SelRect.Centre();
00493 
00494     // not used by this function but set it up for later
00495     m_BarSelectionRect = SelRect;
00496     m_FinishedBarRect.MakeEmpty();
00497 
00498 
00499     // Matt - 20/12/2000
00500     // We wish you a Merry Christmas, We wish you a Merry Christmas, We wish you a Merry Christmas and a Happy New Year... That'll be 10p guv...
00501     // Find out whereabouts the centre of each button ON THIS LAYER was previously if we have a user positioned bar or LiveStretching is OFF
00502     // This is so that in these cases, when the user chooses 'Set New Design' we know the location and do not reposition/misalign things !!!
00503     BOOL LiveStretching = FALSE;
00504     BOOL IgnoreSettings = FALSE;
00505     INT32 m_ExistingButtonsInBar = 0;
00506     DocCoord oldbuttoncentres[MAX_BUTTONS_IN_A_BAR];
00507     TemplateAttribute ** m_ppFoundButton[MAX_BUTTONS_IN_A_BAR];
00508     for (INT32 temp = 0; temp < MAX_BUTTONS_IN_A_BAR; temp++)
00509     {
00510         m_ppFoundButton[temp] = NULL;
00511     }
00512 
00513     SliceHelper::CountButtonsInBarScan(pNewLayer, (TemplateAttribute **) m_ppFoundButton, &m_ExistingButtonsInBar, m_BarName);
00514 
00515     NodeBarProperty* pNodeBarProperty = (NodeBarProperty*) Document::GetCurrent()->GetSetSentinel()->FindBarProperty();
00516     BarDataType NewBarData = pNodeBarProperty->Bar(BarNo);
00517     if (pNodeBarProperty  && BarNo < pNodeBarProperty->HowMany())
00518     {
00519         LiveStretching = NewBarData.IsLive;
00520     }
00521 
00522     if (!LiveStretching || !NewBarData.RequiresShuffle)
00523     {
00524         // We need to get all nodes that are on this layer, for each of the buttons of this bar (in turn) - then we need to find out their bounding box in order
00525         // to record their centre position - this may take a while...
00526 
00527         for (INT32 i = 0; i < pBarParam->m_NoOfButtons; i++)
00528         {
00529             List * pList = new List;
00530             DocRect ButtonRect;
00531             ButtonRect.MakeEmpty();
00532 
00533             if (!((TemplateAttribute *) m_ppFoundButton[i]))
00534             {
00535                 IgnoreSettings = TRUE;
00536                 i = pBarParam->m_NoOfButtons;
00537             }
00538             else
00539             {
00540                 SliceHelper::BuildListOfNodesInButton(pList, pNewLayer, ((TemplateAttribute *) m_ppFoundButton[i])->GetParam());
00541 
00542                 NodeListItem * pNodeListItem = NULL;
00543                 if (pList)
00544                 {
00545                     pNodeListItem = (NodeListItem *)pList->GetHead();
00546                 }
00547 
00548                 while(pNodeListItem)
00549                 {
00550                     // localise attribs for this node
00551                     DoLocaliseForAttrChange((NodeRenderableInk*) pNodeListItem->pNode, (AttrTypeSet *)NULL, (ObjectSet*) NULL);
00552                     ButtonRect = ButtonRect.Union(SliceHelper::BoundingNodeSize(pNodeListItem->pNode));
00553 
00554                     pNodeListItem = (NodeListItem *)pList->GetNext(pNodeListItem);
00555                 }
00556 
00557                 oldbuttoncentres[i] = ButtonRect.Centre();
00558 
00559                 pList->DeleteAll();
00560                 delete pList;
00561             }
00562         }
00563     }
00564 
00565 
00566 
00567 
00568     // *** Calculate the properties needed to be added to the buttons for stretching *** 
00569 
00570     // set up the target and extender strs by scanning the selection
00571     String_256  Target = ""; // the button name of the selection
00572     String_256  Extender = ""; // the thing in this button that extends it
00573     BOOL        MakeItStretch = TRUE; // nothing stretched before - but I want it to stretch using button text
00574     BOOL        TextStoryInSelection = FALSE;
00575     BYTE        ExtenderFlags = 0; // the way the buttons will extend
00576 
00577     DocRect TargetRect;
00578     DocRect ExtenderRect;
00579     DocRect TextRect;
00580     DocRect NoTextRect;
00581 
00582     // find the Target, extender and if there are any text stories in the selection
00583     pNodeListItem = (NodeListItem *)SelectionList.GetHead();
00584     Node * pTextStory = NULL;
00585 
00586     INT32 RequiredLevel = 0;
00587     while (pNodeListItem && RequiredLevel < 2)
00588     {
00589         Node * pCurrent = pNodeListItem->pNode;
00590 
00591         RequiredLevel = SliceHelper::FindTargetAndExtender(pCurrent, Target, Extender, RequiredLevel, &ExtenderFlags,
00592                                                             &TargetRect, &ExtenderRect);
00593         pTextStory = SliceHelper::FindNextOfClass(pCurrent, pCurrent, CC_RUNTIME_CLASS(TextStory), TRUE);
00594         if (pTextStory)
00595         {
00596             TextStoryInSelection = TRUE;
00597             TextRect = TextRect.Union(SliceHelper::BoundingNodeSize(pCurrent));
00598 
00599             // warn if there are any grouped text stories and fail
00600             while (!pTextStory->IsLayer())
00601             {
00602                 if (IS_A(pTextStory, NodeGroup)) //cant call ->IsAGroup() since shadows say yes!
00603                 {
00604                     InformWarning(