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(_R(IDS_WARNING_GROUPED_TEXT));
00605                     SelectionList.DeleteAll();
00606                     DelList.DeleteAll();
00607                     return FALSE;
00608                 }
00609                 pTextStory = pTextStory->FindParent();
00610             }
00611 
00612         }
00613         else
00614             NoTextRect = NoTextRect.Union(SliceHelper::BoundingNodeSize(pCurrent));
00615 
00616 
00617         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
00618     }
00619 
00620     // for this level we copy the stretch data across rather than "make it stretch"
00621     // or if there is no text story then it we can't use the "make it stretch"
00622     if (RequiredLevel > 1 || !TextStoryInSelection || NoTextRect.IsEmpty())
00623         MakeItStretch = FALSE;
00624 
00625 //  if (MakeItStretch)
00626 //  {
00627 //      NoTextRect = NoTextRect.Union(TextRect); // since the text trigger is also part of the target!
00628 //  }
00629 
00630 
00631     // *** calculate the translation to build up the bar into the correct location ***
00632 
00633     // data class to store temp data needed to build up this bar
00634     class ButtonDataType
00635     {
00636     public:
00637         DocCoord Translation;
00638         String_256  Name;
00639         BOOL HaveCreatedProperty;
00640         TextStory * pOriginalStory;
00641         String_256 Storytext;
00642         DocRect OriginalTextStoryDims;
00643         DocRect NewTextStoryDims;
00644     } ButtonData[MAX_BUTTONS_IN_A_BAR];
00645 
00646     INT32 ButtonsInitialised = 0;
00647 
00648     // ask the name gallery what buttons do we already have defined
00649     // get their names and work out the translations to line up a new state
00650     NameGallery * pNameGallery = NameGallery::Instance();
00651 
00652     if (pNameGallery)
00653     {
00654         pNameGallery->FastUpdateNamedSetSizes(); // make sure we are using the most up-to-date data
00655         
00656         SGUsedNames* pNames = pNameGallery->GetUsedNames();
00657         SGNameItem* pNameGalleryItem = pNames ? (SGNameItem*) pNames->GetChild() : NULL;
00658     
00659             
00660         while (pNameGalleryItem)
00661         {
00662             if (pNameGalleryItem->m_BarNumber == BarNo && !pNameGalleryItem->IsEmpty() && !pNameGalleryItem->IsABackBar())
00663             {
00664                 // set the name
00665                 pNameGalleryItem->GetNameText(&(ButtonData[ButtonsInitialised].Name));
00666                 ButtonData[ButtonsInitialised].HaveCreatedProperty = FALSE;
00667     
00668                 // Matt 19/12/2000
00669                 // If the LiveStretching check box is turned on, then we should reposition the buttons relative to the centre of their set bounds.
00670                 // If not, then we should position them central to where their set bounds on THIS layer are...
00671                 // This is so that you can change some colours (etc) on one state, click 'SetNewDesign' and be sure that your button isn't
00672                 // about to realign itself centrally to its set (when this may not have been appropriate)
00673                 BOOL LiveStretching = FALSE;
00674                 NodeBarProperty* pNodeBarProperty = (NodeBarProperty*) Document::GetCurrent()->GetSetSentinel()->FindBarProperty();
00675                 BarDataType NewBarData = pNodeBarProperty->Bar(BarNo);
00676                 if (pNodeBarProperty  && BarNo < pNodeBarProperty->HowMany())
00677                 {
00678                     LiveStretching = NewBarData.IsLive;
00679                 }
00680     
00681                 // If LiveStretching is not enabled or the bar does not require shuffling (ie user positioned)
00682                 if ((!LiveStretching || !NewBarData.RequiresShuffle) && !IgnoreSettings)
00683                 {
00684                     // Unfortunately, I now want to know where the old version of this button was... I need to know this so that I can position the new buttons with
00685                     // their new designs in the same place as the original ones so as to minimise on-screen fun... Also, we should use this in the case of User Positioned
00686                     // buttons so that we don't turn them into Vertical Bars everytime the user clicks 'Set New Design' - not very user positioned!
00687                     ButtonData[ButtonsInitialised].Translation.x = oldbuttoncentres[ButtonsInitialised].x - SelCentre.x;
00688                     ButtonData[ButtonsInitialised].Translation.y = oldbuttoncentres[ButtonsInitialised].y - SelCentre.y;
00689                 }
00690                 else
00691                 {
00692                     // position to new button state on top of the other button states
00693                     ButtonData[ButtonsInitialised].Translation.x = pNameGalleryItem->GetSetBounds().Centre().x - SelCentre.x;
00694                     ButtonData[ButtonsInitialised].Translation.y = pNameGalleryItem->GetSetBounds().Centre().y - SelCentre.y;
00695                 }
00696     
00697                 ButtonsInitialised++;
00698     
00699             }
00700             pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
00701         }
00702     }
00703 
00704     // init buttons that haven't been seen yet working out their new names and their locations
00705     INT32 listbuttonno = 0;
00706     for (;ButtonsInitialised < pBarParam->m_NoOfButtons; ButtonsInitialised++)
00707     {
00708         // get the next free button name and put it into listbuttonno
00709         SliceHelper::GetNextFreeButtonName(listbuttonno, &(ButtonData[ButtonsInitialised].Name));
00710         ButtonData[ButtonsInitialised].HaveCreatedProperty = FALSE;
00711 
00712         if (ButtonsInitialised == 0)
00713         {
00714             ButtonData[ButtonsInitialised].Translation.x = 0;
00715             ButtonData[ButtonsInitialised].Translation.y = 0;
00716 
00717         }
00718         else
00719         {
00720             if (pBarParam->m_IsVertical)
00721             {
00722                 ButtonData[ButtonsInitialised].Translation.x = ButtonData[ButtonsInitialised-1].Translation.x;
00723 
00724                 ButtonData[ButtonsInitialised].Translation.y = ButtonData[ButtonsInitialised-1].Translation.y
00725                     - pBarParam->m_Spacing - SelRect.Height();
00726 
00727                 // place the new button on the same subpixel level as the first button?
00728                 if (pBarParam->m_Spacing == 0 || pBarParam->m_Spacing >= 3750)
00729                     ButtonData[ButtonsInitialised].Translation.y = (ButtonData[ButtonsInitialised].Translation.y /750)*750;
00730             }
00731             else
00732             {
00733                 ButtonData[ButtonsInitialised].Translation.x = ButtonData[ButtonsInitialised-1].Translation.x
00734                     + pBarParam->m_Spacing + SelRect.Width();
00735 
00736                 ButtonData[ButtonsInitialised].Translation.y = ButtonData[ButtonsInitialised-1].Translation.y;
00737 
00738                 // place the new button on the same subpixel level as the first button?
00739                 if (pBarParam->m_Spacing == 0 || pBarParam->m_Spacing >= 3750)
00740                     ButtonData[ButtonsInitialised].Translation.x = (ButtonData[ButtonsInitialised].Translation.x /750)*750;
00741             }
00742         }
00743     }
00744 
00745     // find a ptr to the original text stories in this bar
00746     for (ButtonsInitialised = 0; ButtonsInitialised < pBarParam->m_NoOfButtons; ButtonsInitialised++)
00747     {
00748         ButtonData[ButtonsInitialised].pOriginalStory = SliceHelper::FindNextTextStoryToSync( NULL,
00749                                                 pNewLayer,
00750                                                 NULL,
00751                                                 ButtonData[ButtonsInitialised].Name,
00752                                                 "",
00753                                                 TRUE);
00754 
00755         if (ButtonData[ButtonsInitialised].pOriginalStory)
00756             ButtonData[ButtonsInitialised].Storytext = ButtonData[ButtonsInitialised].pOriginalStory->GetStoryAsString();
00757 
00758 
00759         ButtonData[ButtonsInitialised].OriginalTextStoryDims.MakeEmpty();
00760         ButtonData[ButtonsInitialised].NewTextStoryDims.MakeEmpty();
00761     }
00762 
00763     // activate the layer we are about to stuff things on
00764     SliceHelper::ShowLayer(TRUE, pNewLayer, pSpread, this);
00765     LayerSGallery::MakeActiveLayer(pNewLayer, FALSE); // dont tell as this will be restored
00766 
00767     // add items directly after the layer node as its first child
00768     Node * pTail = pNewLayer;
00769     AttachNodeDirection TailAttachDirection = FIRSTCHILD;
00770 
00771     pNodeListItem = NULL;
00772     Trans2DMatrix Transformer;
00773 
00774 
00775     // for each button we want to produce
00776     INT32 but;
00777     for (but = 0; but < pBarParam->m_NoOfButtons; but++)
00778     {
00779         // copy the selection from where it is to the new layer
00780         pNodeListItem = (NodeListItem *)SelectionList.GetHead();
00781 
00782         // set the transformer to position the button
00783         Transformer.SetTransform(   ButtonData[but].Translation.x,
00784                                     ButtonData[but].Translation.y);
00785 
00786         while (pNodeListItem)
00787         {
00788             pNode = pNodeListItem->pNode;
00789             if (pNode)
00790             {
00791                 // add this node into the tree on the layer defined in list order
00792                 // Make a copy of the current node
00793                 Node* pTheCopy;
00794                 BOOL ok;
00795                 
00796                 CALL_WITH_FAIL(pNode->NodeCopy(&pTheCopy), this, ok);
00797 
00798                 if (ok && !DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pTail, TailAttachDirection,
00799                                          TRUE,      // Do Invalidate region 
00800                                          FALSE))    // Don't Clear the selections
00801                     {
00802                         ok = FALSE;
00803                     }
00804 
00805                 if (ok)
00806                 {
00807                     // don't have any of these new nodes selected
00808                     pTheCopy->SetSelected(but == 0);
00809 
00810                     // move it to the new location
00811                     ((NodeRenderableBounded *)pTheCopy)->Transform(Transformer);
00812                     pTheCopy->AllowOp(&ObjChange);
00813                     DoInvalidateNodeRegion((NodeRenderableBounded*) pTheCopy, TRUE, FALSE);
00814 
00815                     // not used by this function but recorded by the object
00816                     m_FinishedBarRect = m_FinishedBarRect.Union(SliceHelper::BoundingNodeSize(pTheCopy));
00817 
00818                     // sync the text as it goes in
00819                     if (ButtonData[but].pOriginalStory && !ButtonData[but].Storytext.IsEmpty())
00820                     {
00821                         TextStory * pStory = (TextStory *) SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(TextStory), TRUE);
00822                         while (pStory)
00823                         {
00824                             // work out how to reposition this newly sync'ed text
00825                             Node * pNodeSetSentinel = Document::GetSelected()->GetSetSentinel();
00826                             NodeBarProperty * pNodeBarProperty = (NodeBarProperty*) ((NodeSetSentinel *)pNodeSetSentinel)->FindBarProperty();
00827                             INT32 alignment = pNodeBarProperty->Bar(BarNo).SameSize;
00828 
00829                             // where is the defining position of the text story before the change?
00830                             DocRect OldRect = SliceHelper::BoundingNodeSize(pStory);
00831                             BOOL changed = SliceHelper::SyncTextStories(pStory, ButtonData[but].pOriginalStory, this);
00832                             if (changed)
00833                             {
00834                                 DocRect NewRect = SliceHelper::BoundingNodeSize(pStory);
00835                                 // make the new and old texts be centred in the same place
00836                                 INT32 tx = OldRect.Centre().x - NewRect.Centre().x;
00837                                 INT32 ty = OldRect.Centre().y - NewRect.Centre().y;
00838 
00839                                 if (alignment == 1)
00840                                     tx = OldRect.lox - NewRect.lox;
00841                                 else
00842                                 if (alignment == 2)
00843                                     tx = OldRect.hix - NewRect.hix;
00844                                 
00845                                 Trans2DMatrix TextTransformer(tx, ty);
00846                                 pStory->Transform(TextTransformer);
00847 
00848                                 if (alignment == 3) // only store the data if they are different sizes
00849                                 {
00850                                     NewRect.Translate(tx,ty);
00851                                     ButtonData[but].NewTextStoryDims = ButtonData[but].NewTextStoryDims.Union(NewRect);
00852                                     ButtonData[but].OriginalTextStoryDims = ButtonData[but].OriginalTextStoryDims.Union(OldRect);
00853                                 }
00854                             }
00855                             // translate the altered text story to have the same defining position
00856                             pStory = (TextStory *) SliceHelper::FindNextOfClass(pStory, pTheCopy, CC_RUNTIME_CLASS(TextStory));
00857                         }
00858                     }
00859 
00860                     // Look at the wix attribs it has been given
00861                     if (!Target.IsEmpty()) // only if we know the target name
00862                     {
00863                         TemplateAttribute * pTemplateAttribute = (TemplateAttribute *) SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(TemplateAttribute));
00864                         while (pTemplateAttribute)
00865                         {
00866                             TemplateAttribute * pNextTemplateAttribute = (TemplateAttribute *) SliceHelper::FindNextOfClass(pTemplateAttribute, pTheCopy, CC_RUNTIME_CLASS(TemplateAttribute));
00867                             // found a target
00868                             if (Target.CompareTo(pTemplateAttribute->GetParam()) == 0)
00869                             {
00870                                 // hide this, it is replaced by the ApplyNameAttr call bellow
00871                                 // which will use the buttons new name
00872                                 //NodeListItem * pItem = new NodeListItem(pTemplateAttribute);
00873                                 //DelList.AddTail(pItem);
00874                                 DoHideNode(pTemplateAttribute, TRUE);
00875                             }
00876                             else if (!Extender.IsEmpty() && Extender.CompareTo(pTemplateAttribute->GetParam()) == 0)
00877                             {
00878                                 // found a node that matches the extender object in the selection
00879                                 // replace this with a new button name that matches the buttons
00880                                 // new name but has the word extender stuffed after it.
00881                                 // We also need to add to the node sentinel the fact that
00882                                 // NewExtenderName stretches ButtonName in the same way that
00883                                 // Extender stretched Target
00884                                 String_32   ExtenderPostfix;
00885                                 ExtenderPostfix.Load(_R(IDS_EXTENDER_POSTFIX));
00886                                 String_256  NewExtenderName = ButtonData[but].Name;
00887                                 NewExtenderName += ExtenderPostfix;
00888                                 // apply the extender name, but not the bar name to it
00889                                 ApplyNameAttr(&NewExtenderName, pTheCopy, FALSE);
00890 
00891                                 //NodeListItem * pItem = new NodeListItem(pTemplateAttribute);
00892                                 //DelList.AddTail(pItem);
00893                                 DoHideNode(pTemplateAttribute, TRUE);
00894 
00895                                 if (!ButtonData[but].HaveCreatedProperty)
00896                                 {
00897                                     TRACE( _T("redef from existing data\n"));
00898 
00899                                     DocRect TempTarget(TargetRect);
00900                                     TempTarget.Translate(   ButtonData[but].Translation.x,
00901                                                             ButtonData[but].Translation.y);
00902                                     DocRect TempExtender(ExtenderRect);
00903                                     TempExtender.Translate( ButtonData[but].Translation.x,
00904                                                             ButtonData[but].Translation.y);
00905 
00906                                     // create the properties for the button/Target that this extender extends
00907                                     SliceHelper::CreatePropertiesForSet(ButtonData[but].Name, m_BarName, TRUE, ExtenderFlags != 0, FALSE, ExtenderFlags,
00908                                                                         NewExtenderName, FALSE, &TempTarget, &TempExtender,
00909                                                                         this);
00910 
00911                                     // create default properties for the extender
00912                                     SliceHelper::CreatePropertiesForSet(NewExtenderName, TEXT(""),  FALSE, FALSE, FALSE, 0,
00913                                                                         TEXT(""), FALSE, NULL, NULL, this);
00914 
00915                                     ButtonData[but].HaveCreatedProperty = TRUE;
00916                                 }
00917                             }
00918                             pTemplateAttribute = pNextTemplateAttribute;
00919                         }
00920                     }
00921 
00922                     // make it stretch if it didn't before
00923                     if (MakeItStretch)
00924                     {
00925                         if (IS_A(pTheCopy,TextStory) || SliceHelper::FindNextOfClass(pTheCopy, pTheCopy, CC_RUNTIME_CLASS(TextStory)))
00926                         {
00927                             // found a node that matches the extender object in the selection
00928                             // replace this with a new button name that matches the buttons
00929                             // new name but has the word extender stuffed after it.
00930                             // We also need to add to the node sentinel the fact that
00931                             // NewExtenderName stretches ButtonName in the same way that
00932                             // Extender stretched Target
00933                             String_32   ExtenderPostfix;
00934                             ExtenderPostfix.Load(_R(IDS_EXTENDER_POSTFIX));
00935                             String_256  NewExtenderName = ButtonData[but].Name;
00936                             NewExtenderName += ExtenderPostfix;
00937                             // apply the extender name, but not the bar name to it
00938                             ApplyNameAttr(&NewExtenderName, pTheCopy, FALSE);
00939 
00940                             if (!ButtonData[but].HaveCreatedProperty)
00941                             {
00942                                 DocRect TempTarget(NoTextRect);
00943                                 TempTarget.Translate(   ButtonData[but].Translation.x,
00944                                                         ButtonData[but].Translation.y);
00945                                 DocRect TempExtender(TextRect);
00946                                 TempExtender.Translate( ButtonData[but].Translation.x,
00947                                                         ButtonData[but].Translation.y);
00948 
00949                                 // create the properties for the button/Target that this extender extends
00950                                 SliceHelper::CreatePropertiesForSet(ButtonData[but].Name, m_BarName, TRUE, pBarParam->m_ExtendFlags != 0, FALSE,
00951                                                                     pBarParam->m_ExtendFlags, NewExtenderName, FALSE,
00952                                                                     &TempTarget, &TempExtender, this);
00953 
00954                                 // create default properties for the extender
00955                                 SliceHelper::CreatePropertiesForSet(NewExtenderName, m_BarName, FALSE, FALSE, FALSE, 0,
00956                                                                     TEXT(""), FALSE, NULL, NULL, this);
00957 
00958                                 ButtonData[but].HaveCreatedProperty = TRUE;
00959                             }
00960                         }
00961                     }
00962 
00963                     // give it the button's name
00964                     ApplyNameAttr(&ButtonData[but].Name, pTheCopy);
00965 
00966                     // no extender?
00967                     // then we should add the default properties to the button
00968                     // in the node sentry too
00969                     if (Extender.IsEmpty() && !ButtonData[but].HaveCreatedProperty && !MakeItStretch)
00970                     {
00971                         SliceHelper::CreatePropertiesForSet(ButtonData[but].Name, m_BarName, TRUE, FALSE, FALSE,
00972                                                             0, TEXT(""), FALSE, NULL, NULL, this);
00973                         ButtonData[but].HaveCreatedProperty = TRUE;
00974                     }
00975 
00976                     // factor out common attribs
00977                     if (pTheCopy->IsCompound() && !pTheCopy->IsABlend())
00978                         DoFactorOutCommonChildAttributes((NodeRenderableInk*) pTheCopy);
00979                     else
00980                         DoFactorOutAfterAttrChange((NodeRenderableInk*) pTheCopy, (AttrTypeSet *)NULL);
00981 
00982                     // attach the next node after this one
00983                     TailAttachDirection = NEXT;
00984                     pTail = pTheCopy;
00985                 }
00986             }
00987 
00988             // and for the next item in the list
00989             pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
00990         }
00991     }
00992 
00993     // clean up the selection list
00994     pNodeListItem = (NodeListItem *)SelectionList.GetHead();
00995     NodeListItem *pNodeListItemToDel = NULL;
00996 
00997     while (pNodeListItem)
00998     {
00999         pNodeListItemToDel = pNodeListItem;
01000         pNodeListItem = (NodeListItem *)SelectionList.GetNext(pNodeListItem);
01001         SelectionList.RemoveItem((NodeListItem *)pNodeListItemToDel);
01002         delete pNodeListItemToDel;
01003     }
01004 
01005     // delete the existing back bar nodes
01006     pNodeListItem = (NodeListItem *)DelList.GetHead();
01007 
01008     while(pNodeListItem)
01009     {
01010         Node *pParent = pNodeListItem->pNode;
01011 
01012         BOOL HideIt = TRUE;
01013         NodeListItem * pPreviousNodeListItem = (NodeListItem *)DelList.GetHead();
01014 
01015         //TRACEUSER( "SimonK", _T("considering %s %d\n"), (LPCTSTR) pParent->GetRuntimeClass()->m_lpszClassName, pParent);
01016 
01017         // test for deleting this item twice - a double delete will crash!!!
01018         while (pPreviousNodeListItem && pPreviousNodeListItem != pNodeListItem && HideIt)
01019         {
01020             //TRACEUSER( "SimonK", _T("testing %s %d\n"), (LPCTSTR) pPreviousNodeListItem->pNode->GetRuntimeClass()->m_lpszClassName, pPreviousNodeListItem->pNode);
01021             if (pParent == pPreviousNodeListItem->pNode)
01022             {
01023                 HideIt = FALSE; // since it has already been hidden by us
01024                 //TRACEUSER( "SimonK", _T("MATCHED\n"));
01025             }
01026 
01027             pPreviousNodeListItem = (NodeListItem *)DelList.GetNext(pPreviousNodeListItem);
01028         }
01029 
01030         // hide the node if we haven't already done so
01031         if (HideIt)
01032         {
01033             DoInvalidateNodeRegion((NodeRenderableBounded*) pParent, TRUE, FALSE);
01034             pParent->SetSelected(FALSE);
01035             DoHideNode(pParent, TRUE);
01036         }
01037 
01038         pNodeListItem = (NodeListItem *)DelList.GetNext(pNodeListItem);
01039     }
01040 
01041 
01042     pNodeListItem = (NodeListItem *)DelList.GetHead();
01043     pNodeListItemToDel = NULL;
01044 
01045     while(pNodeListItem)
01046     {
01047         pNodeListItemToDel = pNodeListItem;
01048         pNodeListItem = (NodeListItem *)DelList.GetNext(pNodeListItem);
01049         DelList.RemoveItem((NodeListItem *)pNodeListItemToDel);
01050         delete pNodeListItemToDel;
01051     }
01052 
01053     // sort out any buttons just created that need to be extended due to the text
01054     // having been swapped. This usually happens if during the "redefine state" op
01055     // added 25/8/00 by sjk
01056 
01057     for (but = 0; but < pBarParam->m_NoOfButtons; but++)
01058     {
01059         NodeSetSentinel * pNodeSetSentinel = Document::GetSelected()->GetSetSentinel();
01060         if (ButtonData[but].OriginalTextStoryDims != ButtonData[but].NewTextStoryDims)
01061         {
01062             NodeSetProperty * pProp = pNodeSetSentinel->FindPropertyNode(ButtonData[but].Name);
01063             NamedStretchProp* pStretchProp = pProp ? (NamedStretchProp*) pProp->GetProperty(NamedStretchProp::nIndex) : NULL;
01064 
01065             if (pStretchProp)
01066             {
01067                 // found an altered text story
01068                 DocRect ButtonRect = TargetRect;
01069                 if (ButtonRect.IsEmpty() || !ButtonRect.IsValid())
01070                     ButtonRect = SelRect;
01071 
01072                 ButtonRect.Translate(   ButtonData[but].Translation.x,
01073                                         ButtonData[but].Translation.y);
01074 
01075                 Node * pNode = SliceHelper::FindNextNameNode(pNewLayer, pNewLayer);
01076 
01077                 while (pNode)
01078                 {
01079                     Node * pParent = pNode->FindParent();
01080                     if (!IS_A(pParent, TextStory) && ButtonData[but].Name.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
01081                         // do the extend
01082                         Extender::Extend((NodeRenderableInk*) (pParent),
01083                             pBarParam->m_ExtendFlags,
01084                             pStretchProp->GetRefUnionTriggerBounds(),
01085                             pStretchProp->GetRefTargetBounds(),
01086                             ButtonData[but].NewTextStoryDims,
01087                             ButtonData[but].OriginalTextStoryDims,
01088                             ButtonRect,
01089                             NULL, // no restrictions on extending
01090                             TRUE
01091                             );
01092 
01093                     pNode = SliceHelper::FindNextNameNode(pNode, pNewLayer);
01094                 }
01095             }
01096         }
01097     }
01098 
01099     // set the active layer to the layer that was active before
01100     // if that is possible
01101     Layer* pActiveLayer = SliceHelper::FindLayerCalled(ActiveLayerStr);
01102     if (pActiveLayer != 0)
01103         LayerSGallery::MakeActiveLayer(pActiveLayer, FALSE); // dont tell as we are putting it back
01104 
01105     // inform that there may well be more/less layers about to be visible or not
01106     BROADCAST_TO_ALL(LayerMsg(pActiveLayer, LayerMsg::LayerReason::LAYER_VISIBILITY_CHANGED));
01107 
01108     // the selection will have changed - after all we just deleted it
01109     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
01110     GetApplication()->UpdateSelection();
01111 
01112     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01113     UpdateChangedNodes(&ObjChange);
01114 
01115     return TRUE;
01116 }

void OpBarCreation::Do OpDescriptor token  )  [virtual]
 

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
Parameters:
OpDescriptor (unused) [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
OpBarCreation::DoWithParam, CarbonCopyOp::Do

Reimplemented from Operation.

Definition at line 1133 of file opbarcreation.cpp.

01134 {   
01135     OpParamBarCreation BarParam;
01136     DoWithParam(token, &BarParam);
01137 }

void OpBarCreation::DoWithParam OpDescriptor token,
OpParam pOpParam
[virtual]
 

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
Parameters:
OpParam - describes the number of buttons, what layers to create, any mutation [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
OpBarCreation::DoWithParam, CarbonCopyOp::DoProcessing

Reimplemented from Operation.

Definition at line 262 of file opbarcreation.cpp.

00263 {
00264     // start the op
00265     if (pOpParam != NULL && DoStartSelOp(FALSE,TRUE))
00266     {
00267         // do the biz
00268         // create or edit the bar depending on the params
00269         BOOL ok = TRUE;
00270         
00271         // touch the bar in question
00272         NameGallery * pNameGallery = NameGallery::Instance();
00273         if (pNameGallery)
00274         {
00275             pNameGallery->m_TouchedBar = SliceHelper::GetBarNumberFromBarName(((OpParamBarCreation*)pOpParam)->m_BarName);
00276         }
00277 
00278         if (((OpParamBarCreation*)pOpParam)->m_DelExistingState)
00279         {
00280             INT32 NewLayerNo = 0;
00281 
00282             if (((OpParamBarCreation*)pOpParam)->m_WantMouse)
00283                 NewLayerNo = 1;
00284             else if (((OpParamBarCreation*)pOpParam)->m_WantClicked)
00285                 NewLayerNo = 2;
00286             else if (((OpParamBarCreation*)pOpParam)->m_WantSelected)
00287                 NewLayerNo = 3;
00288 
00289             // delete elements in this state before we create it
00290             OpDelBar::DelBar(((OpParamBarCreation*)pOpParam)->m_BarName, NewLayerNo, this);
00291         }
00292 
00293         if (((OpParamBarCreation*)pOpParam)->m_WantBackBar)
00294         {
00295             // want to build the bar and the backbar at once!!!
00296             if (((OpParamBarCreation*)pOpParam)->m_WantDefault)
00297                 ok = CreateBarAndBackBar(pOpParam); // generates its own warnings if required
00298             else
00299             {
00300                 ok = CreateBackBarFromSelection(pOpParam);
00301                 if (ok)
00302                     InformMessage(_R(IDS_BACKBAR_CREATED_OK));
00303                 else
00304                     InformWarning(_R(IDS_FAILLED_MAKE_BACKBAR));
00305             }
00306         }
00307         else
00308         {
00309             if (((OpParamBarCreation*)pOpParam)->m_FromSelection)
00310                 ok = CreateOrEditBar(pOpParam);
00311             else
00312                 ok = CreateFromDefaultState(pOpParam);
00313 
00314             if (!ok)
00315                 InformWarning(_R(IDS_FAILLED_MAKE_BAR));
00316         }
00317 
00318         if (!ok)
00319             FailAndExecute();
00320 
00321         // end the op
00322         End();
00323 
00324         // update the bars
00325         DialogBarOp::SetSystemStateChanged();
00326         DialogBarOp::UpdateStateOfAllBars(); 
00327     }
00328     else
00329     {
00330         // give up and go home
00331         FailAndExecute();
00332         End();
00333     }
00334 }

void OpBarCreation::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.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Parameters:
The Node to test and manipulate (it will test all its children too and their [INPUTS] children recursively - so use with care). PercentColourChange - is a relative amount to change the colours by (100 does nothing) State = (DEFAULT = 0, MOUSE = 1, CLICKED = 2, SELECTED = 3) used to gadge the state of the button being modified.
Returns:
-

Definition at line 1276 of file opbarcreation.cpp.

01277 {
01278     if (pAttrNode->IsAnAttribute())
01279     {
01280         // change the colour of the attribute
01281         if (PercentColourChange != 100 && pAttrNode->IsKindOf(CC_RUNTIME_CLASS(AttrFlatColourFill)))
01282         {
01283             DocColour* pdoccol = ((AttrFlatColourFill *)pAttrNode)->GetStartColour();
01284             ShiftColourValue(pdoccol, PercentColourChange);
01285         }
01286         // this else clause *must* come before that which tests for AttrFillGeometry!
01287         else if (PercentColourChange != 100 && pAttrNode->IsKindOf(CC_RUNTIME_CLASS(AttrFillGeometry)))
01288         {
01289             ColRampItem* pColItem;
01290             ColourRamp* pColRamp = ((AttrFillGeometry*)pAttrNode)->GetColourRamp();
01291             if (pColRamp != NULL)
01292             {
01293                 pColItem = pColRamp->GetFirstCol();
01294                 while (pColItem != NULL)
01295                 {
01296                     ShiftColourValue(pColItem->GetColourAddr(), PercentColourChange);
01297                     pColItem = pColRamp->GetNextCol(pColItem);
01298                 }
01299             }
01300 
01301             DocColour* pdoccol = ((AttrFillGeometry *)pAttrNode)->GetStartColour();
01302             ShiftColourValue(pdoccol, PercentColourChange);
01303             pdoccol = ((AttrFillGeometry *)pAttrNode)->GetEndColour();
01304             ShiftColourValue(pdoccol, PercentColourChange);
01305             pdoccol = ((AttrFillGeometry *)pAttrNode)->GetEndColour2();
01306             ShiftColourValue(pdoccol, PercentColourChange);
01307             pdoccol = ((AttrFillGeometry *)pAttrNode)->GetEndColour3();
01308             ShiftColourValue(pdoccol, PercentColourChange);
01309         }
01310         // rotate the bevel light angle for selected states
01311         else if (State == SELECTED && pAttrNode->IsKindOf(CC_RUNTIME_CLASS(AttrBevelLightAngle)))
01312         {
01313             // assumes the parent of the bevel attrib is the bevel controller
01314             INT32 angle = 135;
01315             Node * pParent = pAttrNode->FindParent();
01316             if (pParent->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController)))
01317             {
01318                 angle = (INT32)((NodeBevelController *)pAttrNode->FindParent())->m_LightAngle + 180;
01319                 if (angle > 360) angle -= 360;
01320             }
01321             ((AttrBevelLightAngle *)pAttrNode)->SetValue(angle);
01322         }
01323     }
01324     else // find anything else interesting?
01325     {
01326         Node * pChildNode = pAttrNode->FindFirstChild();
01327 
01328         while (pChildNode)
01329         {
01330             // recursive call
01331             FindAttribColours(pChildNode, PercentColourChange, State);
01332             pChildNode = pChildNode->FindNext();
01333         }
01334     }
01335 }

INT32 OpBarCreation::GetBarNumber  )  [inline]
 

Definition at line 153 of file opbarcreation.h.

OpState OpBarCreation::GetState String_256 UIDescription,
OpDescriptor Bob
[static]
 

For finding the operations state.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com> based on Jason
Date:
27/8/99
Returns:
The state of the OpBarCreation

Reimplemented from CarbonCopyOp.

Definition at line 234 of file opbarcreation.cpp.

00235 {
00236     OpState OpSt;
00237 
00238     // if we don't allow it
00239     OpSt.Greyed = TRUE;
00240     Spread* pSpread = Document::GetSelectedSpread();
00241     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
00242         OpSt.Greyed = FALSE;
00243 
00244     return(OpSt);   
00245 }

BOOL OpBarCreation::Init void   )  [static]
 

OpBarCreation initialiser method.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Returns:
TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated

Errors: ERROR will be called if there was insufficient memory to allocate the operation.

See also:
-

Reimplemented from SimpleCCObject.

Definition at line 203 of file opbarcreation.cpp.

00204 {
00205     return  (RegisterOpDescriptor(0,
00206                                 _R(IDS_BARCREATIONOP),
00207                                 CC_RUNTIME_CLASS(OpBarCreation),
00208                                 OPTOKEN_BARCREATIONOP,
00209                                 OpBarCreation::GetState,
00210                                 0,                  // help ID 
00211                                 _R(IDBBL_BARCREATIONOP),// bubble help
00212                                 0,                  // resource ID
00213                                 0, //_R(IDC_BC_CREATE),     // control ID
00214                                 SYSTEMBAR_ILLEGAL,  // Bar ID
00215                                 TRUE,               // Receive messages
00216                                 FALSE,
00217                                 FALSE,
00218                                 0,
00219                                 (GREY_WHEN_NO_CURRENT_DOC) ));
00220 }

void OpBarCreation::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.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/8/99
Parameters:
ptr to the doc colour - changing this changes the colour [INPUTS] PercentColourChange - amount of colour to change
Returns:
-

Definition at line 1352 of file opbarcreation.cpp.

01353 {
01354     if (!pdoccol || pdoccol->IsTransparent())
01355         return;
01356 
01357     INT32 h,s,v;
01358 
01359     pdoccol->GetHSVValue(&h, &s, &v);
01360 
01361 
01362     // usual lighter and darker code
01363     if (PercentColourChange != 0)
01364     {
01365         v -= PercentColourChange - 100;
01366         if (v < 0)
01367         {
01368             s -= v*2;
01369             if (s > 255) s = 255;
01370             v = 0;
01371         }
01372         else
01373         if (v > 255)
01374         {
01375             s -= (v-255)*2;
01376             if (s < 0) s = 0;
01377             v = 255;
01378         }
01379     }
01380     else // spin the hue!!!
01381     {
01382         h += 35; // arbitry amount that you can see the difference with
01383         if (h > 255)
01384             h -= 255;
01385     }
01386     pdoccol->SetHSVValue(h, s, v);
01387 
01388 }

void OpBarCreation::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.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/6/00
Returns:
-

Definition at line 1995 of file opbarcreation.cpp.

01996 {
01997     OpShowState::ShowState(ShowLayer, this);
01998 }


Member Data Documentation

String_256 OpBarCreation::m_BarName [private]
 

Definition at line 159 of file opbarcreation.h.

DocRect OpBarCreation::m_BarSelectionRect [private]
 

Definition at line 161 of file opbarcreation.h.

DocRect OpBarCreation::m_FinishedBarRect [private]
 

Definition at line 162 of file opbarcreation.h.

String_256 OpBarCreation::m_RolloverName[5] [private]
 

Definition at line 158 of file opbarcreation.h.


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