freeinfo.cpp

Go to the documentation of this file.
00001 // $Id: freeinfo.cpp 1771 2007-06-17 20:14:43Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // FreeHand Tool Info bar operations
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 #include "freehand.h"
00105 #include "freeinfo.h"
00106 #include "dlgmgr.h"
00107 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "resource.h"
00109 //#include "barsdlgs.h"
00110 //#include "rikdlg.h"
00111 //#include "rik.h"
00112 //#include "justin2.h"
00113 #include "pen.h"
00114 //#include "freehres.h"
00115 #include "opbevel.h"   // for the list of selected node
00116 //#include "simon.h"
00117 #include "opdrbrsh.h"
00118 #include "brshcomp.h"   // for the brush spacing 
00119 #include "brushmsg.h"
00120 #include "brushdlg.h"   // for the brush edit dialog(s)
00121 //#include "brdlgres.h"
00122 #include "brshdata.h"
00123 #include "sgstroke.h"
00124 #include "strkattr.h"
00125 #include "valfunc.h"
00126 #include "ndoptmz.h"
00127 #include "ppstroke.h"
00128 #include "brpress.h"
00129 #include "valfunc.h"
00130 //#include "will.h" // for the 'many' string
00131 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00132 //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00133 #include "colmsg.h"
00134 #include "brshattr.h"
00135 
00136 DECLARE_SOURCE( "$Revision: 1771 $" );
00137 
00138 // Declare stuff for the memory tracking
00139 CC_IMPLEMENT_DYNCREATE( FreeHandInfoBarOp, InformationBarOp )
00140 #define new CAM_DEBUG_NEW
00141 
00142 PORTNOTE("other", "Disabled Brush editing")
00143 #ifndef EXCLUDE_FROM_XARALX
00144 CBrushGadget FreeHandInfoBarOp::BrushGadget;
00145 #endif
00146 
00147 // enumerate the valuefunctions that we are using in the stroke combo
00148 
00149 // Just found out that if you don't enumerate these in the order in which you place them into
00150 // the combo, then everything screws up big style! Matt 16/10/2000...
00151 enum {
00152         CONSTANT,
00153         SS_Fallout,
00154         SS_Iron,
00155         ELLIPSE,
00156         SS_SlimBlip,
00157         BLIP,
00158         SS_Cigar,
00159         SS_Cigar2,
00160         SS_Cigar3,
00161         SS_Convex,
00162         RAMPS2,
00163         RAMPS, 
00164         SS_Concave,
00165         RAMPL2,
00166         RAMPL,
00167         TEARDROPCURVEDEND,
00168         TEARDROP,
00169         SS_Comet,
00170         SS_Petal,
00171         SS_Reed,
00172         SS_Meteor,
00173         SS_Torpedo,
00174         SS_Missile,
00175         SS_Goldfish,
00176         SS_Yacht,
00177         SS_Barb,
00178         SS_OceanLiner,
00179         PROPELLER,
00180         DOUBLERAMPS,
00181         BEVELENDS,
00182         SAWTOOTH,
00183         INTESTINE,
00184         DECAY
00185 };
00186 
00187 // used to indicate that our brush control needs to display the 'many' string
00188 const BrushHandle BrushHandle_Many = BrushHandle_NoBrush - 1;
00189 
00190 /********************************************************************************************
00191 
00192 >   FreeHandInfoBarOp::FreeHandInfoBarOp()
00193 
00194     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00195     Created:    30/8/94
00196     Purpose:    Sets the info bars vars to NULL defaults
00197 
00198 ********************************************************************************************/
00199 
00200 FreeHandInfoBarOp::FreeHandInfoBarOp()
00201 {
00202     DlgResID = _R(IDD_FREEHANDTOOL);
00203 
00204     // Don't know about the tool and can not retro fit to start with
00205     pTool = NULL;
00206     CanRetroFit = FALSE;
00207 
00208     // The Controls hasve not been created yet
00209     ControlsExist = FALSE;
00210 
00211     m_pBrushList = NULL;
00212 
00213     m_DisplayBrush = BrushHandle_NoBrush;
00214 
00215 /*  m_pStrokeList = NULL;
00216 
00217     m_DisplayStroke = StrokeHandle_NoStroke;
00218     */
00219 
00220     m_SelectedStroke = CONSTANT; // we want to start by displaying the constant stroke
00221 }
00222 
00223 
00224 /********************************************************************************************
00225 
00226 >   FreeHandInfoBarOp::~FreeHandInfoBarOp()
00227 
00228     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00229     Created:    18/5/2000
00230     Purpose:    destructor
00231 
00232 ********************************************************************************************/
00233 
00234 FreeHandInfoBarOp::~FreeHandInfoBarOp()
00235 {
00236     if (m_pBrushList != NULL)
00237     {
00238         m_pBrushList->clear();
00239         delete m_pBrushList;
00240         m_pBrushList = NULL;
00241     }
00242 
00243     /*
00244     if (m_pStrokeList != NULL)
00245     {
00246         m_pStrokeList->RemoveAll();
00247         delete m_pStrokeList;
00248         m_pStrokeList = NULL;
00249     }
00250     */
00251 }
00252 
00253 
00254 /********************************************************************************************
00255 
00256 >   MsgResult FreeHandInfoBarOp::Message(Msg* Message) 
00257 
00258     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00259     Created:    12/5/94
00260     Inputs:     Message - A dialog message 
00261     Returns:    The result of the message
00262     Purpose:    Takes a look at the message and if it is for me it responds to it.
00263                 Here the scroll bar for the freehand tool is Created and closed. It
00264                 also responds to changes in the sliders position and tells the freehand
00265                 tool to set its smoothing factor to something appropriate.
00266 
00267 ********************************************************************************************/
00268 
00269 MsgResult FreeHandInfoBarOp::Message(Msg* Message) 
00270 {
00271     if (IS_OUR_DIALOG_MSG(Message))
00272     {
00273         DialogMsg* Msg = (DialogMsg*)Message;
00274 
00275         // Check if the message is a CANCEL
00276         if (Msg->DlgMsg == DIM_CANCEL)
00277         {
00278             // Mark the controls as no longer existing
00279             ControlsExist = FALSE;
00280             
00281             // Close the dialog 
00282             Close();
00283         }
00284 
00285         else if (Msg->DlgMsg == DIM_CREATE)
00286         {
00287 #if 0
00288 // NB - not #ifndef
00289 #ifdef EXCLUDE_FROM_XARALX
00290             EnableGadget(_R(IDC_CREATEBRUSH), FALSE);
00291             EnableGadget(_R(IDC_EDITBRUSH), FALSE);
00292 #endif
00293 #endif
00294             HandleCreate();
00295         }
00296         else
00297         {
00298             if (FALSE) {}
00299 // WEBSTER - markn 25/4/97
00300 // No pen presure stuff required in Webster
00301 // Taken out by vector stroking code Neville 2/10/97
00302 #ifdef VECTOR_STROKING
00303             else if (Msg->GadgetID == _R(IDC_FREEHANDPRESSURE))
00304             {
00305                 if (Msg->DlgMsg == DIM_LFT_BN_CLICKED)
00306                 {
00307                     OpDescriptor *pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_TOGGLEPRESSURE);
00308                     if (pOpDesc != NULL)
00309                     {
00310                         pOpDesc->Invoke();
00311                         UpdateState();
00312                     }
00313                 }
00314             }
00315 #endif // VECTOR_STROKING
00316             else if (Msg->GadgetID == _R(IDC_FREEHANDSLIDER))
00317             {
00318                 switch (Msg->DlgMsg)
00319                 {
00320                     case DIM_SLIDER_POS_CHANGING:
00321                     {
00322                         HandleSliderPosChanging();
00323                         break;
00324                     }
00325 
00326                     case DIM_SLIDER_POS_SET:
00327                     {
00328                         // Tell the tool that things are all finished with
00329                         pTool->RetroFitFinished();
00330                             break;
00331                     }
00332                     default:
00333                         break;
00334                 }
00335             }
00336             else if (Msg->GadgetID == _R(IDC_CREATEBRUSH))
00337             {
00338                 pTool->CreateBrush();
00339                 UpdateState();
00340             }
00341             else if (Msg->GadgetID == _R(IDC_EDITBRUSH))
00342             {
00343                 switch (Msg->DlgMsg)
00344                 {
00345                     case DIM_LFT_BN_CLICKED:
00346                     {
00347                         LaunchBrushEditDialog();
00348                         break;
00349                     }
00350                     default:
00351                         break;
00352                 }
00353             }
00354             else if (Msg->GadgetID == _R(IDC_BRUSHTYPE))
00355             {
00356                 switch (Msg->DlgMsg)
00357                 {
00358                     case DIM_SELECTION_CHANGED:
00359                     {
00360                         HandleBrushSelectChange();
00361                         UpdateState();
00362                         break;
00363                     }
00364                     default:
00365                         break;
00366                 }
00367             }
00368             else if (Msg->GadgetID == _R(IDC_STROKETYPE))
00369             {
00370                 switch (Msg->DlgMsg)
00371                 {
00372                     case DIM_SELECTION_CHANGED:
00373                     {
00374                         HandleStrokeSelectChange();
00375                         //UpdateState();
00376                         break;
00377                     }
00378                     default:
00379                         break;
00380                 }
00381             }
00382         }
00383     }
00384     else
00385     {
00386         // Handle non dialog messages in here
00387         if (ControlsExist && Message->IsKindOf(CC_RUNTIME_CLASS(SelChangingMsg)))
00388         {
00389             // Yep, we had better go an see if the retro path field is still valid
00390             if (pTool!=NULL)
00391             {
00392                 // Find out if we can still do the retro fitting stuff
00393                 CanRetroFit = pTool->IsRetroPathStillValid();
00394 
00395                 // set the string in the info bar
00396                 SetRetroString();
00397             }
00398         }
00399 
00400         // the following is required because the brushes do NOT exist until the document has
00401         // been created!  We need to init brushes in three cases:
00402 
00403         // 1) THIS infobar is made active by the user - brushes inited via DIM_CREATE
00404         // 2) THIS infobar was the last used infobar when camelot quit - which means it will
00405         //    be the first one created; occuring BEFORE the document has been created!
00406         // 3) Someone has edited the brush definition fron the line gallery, thereby changing the
00407         //    appearance of the brushes.
00408         // we overcome this problem by detecting the documents BORNANDSTABLE and message
00409         
00410         if (ControlsExist) 
00411         {
00412             if (IsVisible ())       // BUT only if the infobar is visible!
00413             {
00414                 if (Message->IsKindOf(CC_RUNTIME_CLASS(DocChangingMsg)))
00415                 {
00416                     Document* pDoc = Document::GetCurrent();
00417                     BOOL EnableCombos = pDoc != NULL;
00418                     if (!EnableCombos)
00419                     {
00420                         EnableGadget(_R(IDC_BRUSHTYPE), EnableCombos);
00421                         EnableGadget(_R(IDC_STROKETYPE), EnableCombos);
00422                         EnableGadget(_R(IDC_FREEHANDSLIDER), EnableCombos);
00423                     }
00424                     DocChangingMsg* pDocMsg = (DocChangingMsg*)Message;
00425                     if (pDocMsg->State == DocChangingMsg::BORNANDSTABLE)
00426                     {
00427                         EnableGadget(_R(IDC_BRUSHTYPE), TRUE);
00428                         EnableGadget(_R(IDC_STROKETYPE), TRUE);
00429                         EnableGadget(_R(IDC_FREEHANDSLIDER), TRUE);
00430                         if (m_pBrushList == NULL || m_pBrushList->size() == 0)
00431                             InitBrushList();
00432                         else
00433                             ReInitBrushList();
00434 
00435                         SetBrushListToControl ();
00436 
00437                     }
00438                 
00439                 }
00440                 else if (Message->IsKindOf(CC_RUNTIME_CLASS(BrushDefMsg)))
00441                 {
00442                     SetBrushListToControl();  // we've updated a brush definition so refresh
00443                     SetHeadOfListSelected();  // the display
00444 
00445                 }
00446             }
00447         }
00448 
00449         // if it is a brush selection message then pass the new handle on to the tool
00450         if (Message->IsKindOf(CC_RUNTIME_CLASS(BrushMsg)))
00451          
00452         // only pass it on if a) our tool is the current tool and b)we have a current document
00453         {
00454             BrushHandle SelHandle = ((BrushMsg*)Message)->m_BrushSelected;
00455                 
00456             if (pTool != NULL)
00457             {
00458                 pTool->SetBrushUpdateState(UPDATE_ONIDLE);
00459                 pTool->BrushSelected(SelHandle, FALSE);
00460             }
00461             
00462             // tell the list it has a new head
00463             if (SelHandle != BrushHandle_NoBrush)
00464                 SetHeadOfList(SelHandle);
00465 
00466             m_DisplayBrush = SelHandle;
00467                     
00468             // display the new list
00469             if (ControlsExist)
00470             {
00471                 SetBrushListToControl();
00472                 SetHeadOfListSelected();
00473             }
00474         }
00475 
00476         // if it is a stroke message then update our combo
00477         if (Message->IsKindOf(CC_RUNTIME_CLASS(StrokeMsg)) && ControlsExist && IsVisible())
00478             SetStrokeComboFromSelection();
00479 
00480         // likewise if it is a screen change message
00481         if (Message->IsKindOf(CC_RUNTIME_CLASS(ScreenChangeMsg)) || Message->IsKindOf(CC_RUNTIME_CLASS(CurrentAttrChangedMsg))
00482             || Message->IsKindOf(CC_RUNTIME_CLASS(BrushDefMsg)))
00483         {
00484             if (pTool != NULL && HasWindow() 
00485                 && (Document::GetCurrent() != NULL))
00486             {
00487                 pTool->ScreenChanged(TRUE); //((ScreenChangeMsg*)Message)->m_bClear);
00488                 UpdateState();
00489             }
00490         }
00491 
00492 
00493         if (Message->IsKindOf(CC_RUNTIME_CLASS(DocViewMsg)))
00494         {
00495             DocViewMsg* pDVM = (DocViewMsg*)Message;
00496             if (pDVM->State == DocViewMsg::SELCHANGED)
00497                 pTool->ScreenChanged(TRUE);
00498         }
00499     
00500         // if it is a new brush then we need to update our list
00501         if (Message->IsKindOf(CC_RUNTIME_CLASS(NewBrushMsg)))
00502         {
00503             AddBrush();
00504             if (pTool)
00505             {
00506                 UINT32 BrushNum = BrushComponent::GetNumberOfBrushes() - 1;
00507                 pTool->BrushSelected(BrushNum, FALSE);
00508             }
00509         }
00510     }
00511 
00512     // do we have a selection change message? 
00513     if (MESSAGE_IS_A(Message, SelChangingMsg))
00514     {
00515         Document* pDoc  = Document::GetCurrent();
00516         if (pDoc != NULL)
00517         {
00518             if (ControlsExist && IsVisible())
00519             {
00520                 // we may have just undone a brush edit, if the brush edit dialog is open then we
00521                 // want to make sure it has the uptodate data.
00522                 BrushData Data = GetBrushDataFromSelection();
00523                 if (Data.m_BrushHandle != BrushHandle_NoBrush)
00524                 {
00525 PORTNOTE("other", "Disabled Brush editing")
00526 #ifndef EXCLUDE_FROM_XARALX
00527                     if (BrushGadget.IsDialogOpen())
00528                         BrushGadget.ReInitialiseDialog(&Data);
00529 #endif  
00530                 }
00531                 // also make sure our combo reflects the selection
00532                 SetBrushComboFromSelection();
00533                 SetStrokeComboFromSelection();
00534             }
00535         }
00536         // ask the tool to refresh its cache, as blobs will have changed
00537         if (pTool != NULL && HasWindow()) 
00538             pTool->ScreenChanged(TRUE); 
00539     }
00540 
00541     if (MESSAGE_IS_A(Message, ColourChangingMsg))
00542     {
00543         ColourChangingMsg *TheMsg = (ColourChangingMsg *) Message;
00544 
00545         // handle the selected View's Colour Context is changing
00546         // e.g. if the show printer colours (plate) has changed
00547         if(TheMsg->State == ColourChangingMsg::SELVIEWCONTEXTCHANGE)
00548         {
00549             // ask the tool to refresh its cache
00550             // (so that the cache does not have the old colour in it
00551             //  and the drawing will be agains the correct (current)
00552             //  background!)
00553             if (pTool != NULL && HasWindow()) 
00554                 pTool->ScreenChanged(TRUE);
00555         }
00556     }
00557 
00558     // Pass message on
00559     return (InformationBarOp::Message(Message)); 
00560 }    
00561 
00562 
00563 
00564 /********************************************************************************************
00565 
00566 >   void FreeHandInfoBarOp::AddBrush ()
00567 
00568     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00569     Created:    23/3/2000
00570     Inputs:     -
00571     Returns:    -
00572     Purpose:    Tells the infobar that a new brush has been added to the brush component.  This
00573                 function finds the last created brush and selects it as the head of the list of
00574                 brushes to be displayed in the brush combo
00575 
00576 ********************************************************************************************/
00577 
00578 void FreeHandInfoBarOp::AddBrush ()
00579 {
00580         UINT32 BrushNum = BrushComponent::GetNumberOfBrushes() - 1;
00581         
00582         // Simply add this to the head of the list
00583         if (m_pBrushList == NULL)
00584         {
00585             ERROR3("Brush list is null in FreeHandInfoBarOp::AddBrush");
00586         }
00587         SetHeadOfList((BrushHandle)BrushNum);
00588         m_DisplayBrush = 2;
00589         // display the new list
00590         if (ControlsExist)
00591         {
00592             SetBrushListToControl();
00593             SetHeadOfListSelected();
00594         }
00595         
00596 }
00597 
00598 
00599 /********************************************************************************************
00600 
00601 >   void FreeHandInfoBarOp::AddBrush(BrushHandle Handle)
00602 
00603     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    23/3/2000
00605     Inputs:     Handle of the brush to add
00606     Returns:    -
00607     Purpose:    Overridden version of above function.  In this version we specify the handle of
00608                 the brush to add, plus we do not select the new brush
00609 
00610 ********************************************************************************************/
00611 
00612 void FreeHandInfoBarOp::AddBrush(BrushHandle Handle)
00613 {
00614     // Simply add this to the head of the list
00615     if (m_pBrushList == NULL)
00616     {
00617         // we might get here on start-up before the list is generated so just leave
00618         return;
00619     }
00620     m_pBrushList->push_back(Handle);
00621 
00622     if (ControlsExist)
00623     {
00624         SetBrushListToControl();
00625         SetDisplayBrush();
00626     }
00627 }
00628 
00629 /********************************************************************************************
00630 
00631 >   void FreeHandInfoBarOp::RemoveBrush(BrushHandle Handle)
00632 
00633     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00634     Created:    23/3/2000
00635     Inputs:     Handle - identifier of the brush to remove
00636     Returns:    -
00637     Purpose:    to remove the specified brush from the brush list
00638 
00639 ********************************************************************************************/
00640 
00641 void FreeHandInfoBarOp::RemoveBrush(BrushHandle Handle)
00642 {
00643     // first remove it from the list
00644     if (m_pBrushList != NULL)
00645     {
00646         m_pBrushList->remove(Handle);
00647     }
00648 
00649     // now we want to display the no-brush
00650     m_DisplayBrush = BrushHandle_NoBrush;
00651     
00652     if (ControlsExist)
00653     {
00654         SetBrushListToControl();
00655         SetDisplayBrush();
00656     }
00657 
00658     // tell the tool
00659     if (pTool != NULL)
00660     {
00661         pTool->SetBrushUpdateState(UPDATE_NOW);
00662         pTool->BrushSelected(BrushHandle_NoBrush, FALSE);
00663     }
00664 }
00665 
00666 /********************************************************************************************
00667 
00668 >   void FreeHandInfoBarOp::HandleCreate()
00669 
00670     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00671     Created:    23/3/2000
00672     Inputs:     -
00673     Returns:    -
00674     Purpose:    Called when a DIM_CREATE message is received
00675 
00676 ********************************************************************************************/
00677 void FreeHandInfoBarOp::HandleCreate()
00678 {
00679     if (WindowID!=NULL)
00680     {
00681         // Set the state of the pressure button according to the Op's state.
00682         // Why buttons on infobars can't dynamically auto-connect to their ops is beyond me
00683         UpdateState();
00684 
00685         // Set the range of the control
00686         SetGadgetRange(_R(IDC_FREEHANDSLIDER), 0, 100, 5);
00687         SetGadgetBitmaps(_R(IDC_FREEHANDSLIDER), _R(IDB_SLIDERBASE), _R(IDB_SLIDERSLIDER));
00688 
00689         // and its position
00690         INT32 Smoothness = 50;
00691         if (pTool!=NULL)
00692             Smoothness = pTool->GetSmoothness();
00693         SetLongGadgetValue(_R(IDC_FREEHANDSLIDER), Smoothness);
00694     
00695         // Set the percentage string
00696         TCHAR Str[32];
00697         String_32 jcf(_R(IDS_PERCENT_FORMAT));
00698         camSnprintf(Str, 32, jcf, (INT32) Smoothness);
00699         String_32 PercentStr(Str);
00700         SetStringGadgetValue(_R(IDC_FREEHANDPERCENT), PercentStr);
00701     
00702         // Set the Retro field (Will be empty initially)
00703         if (pTool!=NULL)
00704             CanRetroFit = pTool->IsRetroPathStillValid();
00705         SetRetroString();
00706         
00707         // only initialise the brush list once otherwise we upset the order
00708         if (m_pBrushList == NULL || m_pBrushList->size() == 0)
00709             InitBrushList();
00710 
00711         // Create the brush type combobox.
00712         m_bgddBrushType.Init(WindowID, _R(IDC_BRUSHTYPE));
00713         m_bgddBrushType.SetColumns(3);
00714         m_bgddBrushType.SetItemSize(wxSize(75, 40));
00715 
00716         // Create the stroke type combobox.
00717         m_bgddStrokes.Init(WindowID, _R(IDC_STROKETYPE));
00718         m_bgddStrokes.SetColumns(3);
00719         m_bgddStrokes.SetItemSize(wxSize(50, 50));
00720 
00721         // create our brush list objects and put them in the control
00722         SetBrushListToControl();
00723 
00724         // make sure the combo shows the right thing
00725         SetBrushComboFromSelection();
00726 //#ifdef BUILDNEWBRUSHES
00727         // set up the brush gadget
00728 PORTNOTE("other", "Disabled BrushGadget")
00729 #ifndef EXCLUDE_FROM_XARALX
00730         BrushGadget.LinkControlButton (this, _R(IDC_EDITBRUSH), _R(IDBBL_BRUSHEDIT), _R(IDS_BRUSHEDITDLG));
00731         BrushGadget.DisableTimeStamping ();
00732 #endif
00733 //#endif    
00734     
00735     }
00736     // Mark the controls as existing
00737     ControlsExist = TRUE;
00738 }
00739 
00740 /********************************************************************************************
00741 
00742 >   void FreeHandInfoBarOp::HandleBrushSelectChange()
00743 
00744     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00745     Created:    23/3/2000
00746     Inputs:     -
00747     Returns:    -
00748     Purpose:    Called when a DIM_SELECTION message is received from _R(IDC_BRUSHTYPE).  
00749 
00750     Notes:      10/10/2000 We have been through a few variants of this, but the current version
00751                 is that when we select a brush from the drop down it is selected to draw with
00752                 as well as being used to apply to the selection.
00753 ********************************************************************************************/
00754 
00755 void FreeHandInfoBarOp::HandleBrushSelectChange()
00756 {
00757 //#ifdef BUILDNEWBRUSHES
00758     
00759     // if we don't have a document then forget it, though its not erroneous
00760     Document* pDoc = Document::GetCurrent();
00761     if (!pDoc)
00762         return;
00763 
00764     // Someone selected a new brush
00765     INT32 iIndex = m_bgddBrushType.GetSelected();
00766 
00767     BrushHandle SelHandle;
00768     
00769     // the zeroth index is always reserved for the 'no-brush' 
00770 //  if (iIndex == 0)
00771 //      SelHandle = BrushHandle_NoBrush;
00772 //  else
00773         SelHandle = GetBrushHandleFromControlIndex(iIndex);
00774     //TRACEUSER( "Diccon", _T("Brush Combo: Handle = %d, Index = %d\n"), SelHandle, Index); 
00775 
00776     // tell the tool our selection has changed
00777     if (pTool != NULL)
00778     {
00779         pTool->SetBrushUpdateState(UPDATE_ONIDLE);
00780         pTool->BrushSelected(SelHandle);
00781     }
00782             
00783     if (SelHandle != BrushHandle_NoBrush)
00784     {
00785         SetHeadOfList(SelHandle);
00786         SetBrushListToControl();
00787         m_DisplayBrush = SelHandle;
00788     //  TRACEUSER( "Diccon", _T("Brush Combo: Handle = %d, Index = %d\n"), SelHandle, Index);SetBrushListToControl();   
00789         SetHeadOfListSelected();
00790     }
00791     else
00792     {
00793         m_DisplayBrush = SelHandle;
00794     //  SetDisplayBrush();
00795     }
00796         
00797     
00798 
00799 //#endif
00800 }
00801 
00802 /********************************************************************************************
00803 
00804 >   void FreeHandInfoBarOp::HandleStrokeSelectChange()
00805 
00806     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00807     Created:    23/3/2000
00808     Inputs:     -
00809     Returns:    -
00810     Purpose:    Called when a DIM_SELECTION message is received from _R(IDC_STROKETYPE).  
00811 
00812 ********************************************************************************************/
00813 
00814 void FreeHandInfoBarOp::HandleStrokeSelectChange()
00815 {
00816     // if we don't have a document then forget it, though its not erroneous
00817     Document* pDoc = Document::GetCurrent();
00818     if (!pDoc)
00819         return;
00820 
00821     // Someone selected a new brush
00822     INT32 Index = m_bgddStrokes.GetSelected();
00823 
00824 
00825     // what we are going to do is apply a stroke attribute and a variable width attribute at the 
00826     // same time via the attribute manager. This will require making a list
00827 
00828     List AttribsList;
00829     
00830     // create new list items
00831     NodeAttributePtrItem* pStrokeItem = new NodeAttributePtrItem;
00832     if (pStrokeItem == NULL)
00833     {
00834         ERROR3("Unable to create new stroke item in FreeHandInfoBarOp::HandleStrokeSelectChange");
00835         return;
00836     }
00837     
00838 
00839     NodeAttributePtrItem* pVarWidthItem = new NodeAttributePtrItem;
00840     if (pVarWidthItem == NULL)
00841     {
00842         ERROR3("Unable to create new variable width item in FreeHandInfoBarOp::HandleStrokeSelectChange");
00843         delete pStrokeItem;
00844         return;
00845     }
00846 
00847     NodeAttribute* pVarWidth = NULL;    
00848     NodeAttribute* pStrokeType = NULL;
00849 
00850     // now make a pathprocessor and a stroke attribute, note that if we apply a CONSTANT stroke we don't need to
00851     PathProcessorStroke* PPS = NULL;
00852     if (Index != CONSTANT)
00853     {
00854         PPS = new PathProcessorStroke;
00855         if (PPS == NULL)
00856         {
00857             ERROR3("Unable to create new path processor in FreeHandInfoBarOp::HandleStrokeSelectChange");
00858             delete pStrokeItem;
00859             delete pVarWidthItem;
00860             return;
00861         }
00862     }
00863 
00864     StrokeTypeAttrValue NewStroke(PPS);
00865     pStrokeType = NewStroke.MakeNode();
00866     
00867     if (pStrokeType == NULL)
00868     {
00869         ERROR3("Unable to create new stroke attribute in FreeHandInfoBarOp::HandleStrokeSelectChange");
00870         delete pStrokeItem;
00871         delete pVarWidthItem;
00872         delete PPS;
00873         return;
00874     }
00875 
00876     pStrokeItem->NodeAttribPtr = pStrokeType;
00877     
00878 
00879     switch (Index)
00880     {
00881         case CONSTANT:
00882         {
00883             // Create a default variable width value (should get optimised out when applied to the doc)
00884             VariableWidthAttrValue VarWidth; // creates a CONSTANT variable width
00885             
00886             pVarWidth = VarWidth.MakeNode();
00887 
00888             if (pVarWidth)
00889             {
00890                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00891             }
00892             else
00893             {
00894                 delete pVarWidthItem;
00895                 return;
00896             }
00897         }
00898         break;
00899         
00900         case RAMPL:
00901         {
00902             // create our attrval with a valuefunction
00903             VariableWidthAttrValue VarWidth(new ValueFunctionRampL);
00904 
00905             pVarWidth = VarWidth.MakeNode();
00906 
00907             if (pVarWidth)
00908             {
00909                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00910             }
00911             else
00912             {
00913                 delete pStrokeItem;
00914                 delete pVarWidthItem;
00915                 delete pStrokeType;
00916                 return;
00917             }
00918         }
00919         break;
00920 
00921         case RAMPL2:
00922         {
00923             // create our attrval with a valuefunction
00924             VariableWidthAttrValue VarWidth(new ValueFunctionRampL2);
00925 
00926             pVarWidth = VarWidth.MakeNode();
00927 
00928             if (pVarWidth)
00929             {
00930                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00931             }
00932             else
00933             {
00934                 delete pStrokeItem;
00935                 delete pVarWidthItem;
00936                 delete pStrokeType;
00937                 return;
00938             }
00939         }
00940         break;
00941 
00942         case RAMPS:
00943         {
00944             // create our attrval with a valuefunction
00945             VariableWidthAttrValue VarWidth(new ValueFunctionRampS);
00946 
00947             pVarWidth = VarWidth.MakeNode();
00948 
00949             if (pVarWidth)
00950             {
00951                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00952             }
00953             else
00954             {
00955                 delete pStrokeItem;
00956                 delete pVarWidthItem;
00957                 delete pStrokeType;
00958                 return;
00959             }
00960         }
00961         break;
00962 
00963         case RAMPS2:
00964         {
00965             // create our attrval with a valuefunction
00966             VariableWidthAttrValue VarWidth(new ValueFunctionRampS2);
00967 
00968             pVarWidth = VarWidth.MakeNode();
00969 
00970             if (pVarWidth)
00971             {
00972                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00973             }
00974             else
00975             {
00976                 delete pStrokeItem;
00977                 delete pVarWidthItem;
00978                 delete pStrokeType;
00979                 return;
00980             }
00981         }
00982         break;
00983 
00984         case BLIP:
00985         {
00986             // create our attrval with a valuefunction
00987             VariableWidthAttrValue VarWidth(new ValueFunctionBlip);
00988 
00989             pVarWidth = VarWidth.MakeNode();
00990 
00991             if (pVarWidth)
00992             {
00993                 pVarWidthItem->NodeAttribPtr = pVarWidth;
00994             }
00995             else
00996             {
00997                 delete pStrokeItem;
00998                 delete pVarWidthItem;
00999                 delete pStrokeType;
01000                 return;
01001             }
01002         }
01003         break;
01004 
01005         case ELLIPSE:
01006         {
01007             // create our attrval with a valuefunction
01008             VariableWidthAttrValue VarWidth(new ValueFunctionEllipse);
01009 
01010             pVarWidth = VarWidth.MakeNode();
01011 
01012             if (pVarWidth)
01013             {
01014                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01015             }
01016             else
01017             {
01018                 delete pStrokeItem;
01019                 delete pVarWidthItem;
01020                 delete pStrokeType;
01021                 return;
01022             }
01023 
01024         }
01025         break;
01026 
01027         case TEARDROP:
01028         {
01029             // create our attrval with a valuefunction
01030             VariableWidthAttrValue VarWidth(new ValueFunctionTeardrop);
01031 
01032             pVarWidth = VarWidth.MakeNode();
01033 
01034             if (pVarWidth)
01035             {
01036                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01037             }
01038             else
01039             {
01040                 delete pStrokeItem;
01041                 delete pVarWidthItem;
01042                 delete pStrokeType;
01043                 return;
01044             }
01045         }
01046         break;
01047 
01048         case TEARDROPCURVEDEND:
01049         {
01050             // create our attrval with a valuefunction
01051             VariableWidthAttrValue VarWidth(new ValueFunctionTeardropCurvedEnd);
01052 
01053             pVarWidth = VarWidth.MakeNode();
01054 
01055             if (pVarWidth)
01056             {
01057                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01058             }
01059             else
01060             {
01061                 delete pStrokeItem;
01062                 delete pVarWidthItem;
01063                 delete pStrokeType;
01064                 return;
01065             }
01066         }
01067         break;
01068 
01069         case DOUBLERAMPS:
01070         {
01071             // create our attrval with a valuefunction
01072             VariableWidthAttrValue VarWidth(new ValueFunctionDoubleRampS);
01073 
01074             pVarWidth = VarWidth.MakeNode();
01075 
01076             if (pVarWidth)
01077             {
01078                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01079             }
01080             else
01081             {
01082                 delete pStrokeItem;
01083                 delete pVarWidthItem;
01084                 delete pStrokeType;
01085                 return;
01086             }
01087         }
01088         break;
01089 
01090         case SAWTOOTH:
01091         {
01092             // create our attrval with a valuefunction
01093             VariableWidthAttrValue VarWidth(new ValueFunctionSawTooth);
01094 
01095             pVarWidth = VarWidth.MakeNode();
01096 
01097             if (pVarWidth)
01098             {
01099                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01100             }
01101             else
01102             {
01103                 delete pStrokeItem;
01104                 delete pVarWidthItem;
01105                 delete pStrokeType;
01106                 return;
01107             }
01108         }
01109         break;
01110 
01111         case PROPELLER:
01112         {
01113             // create our attrval with a valuefunction
01114             VariableWidthAttrValue VarWidth(new ValueFunctionPropeller);
01115 
01116             pVarWidth = VarWidth.MakeNode();
01117 
01118             if (pVarWidth)
01119             {
01120                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01121             }
01122             else
01123             {
01124                 delete pStrokeItem;
01125                 delete pVarWidthItem;
01126                 delete pStrokeType;
01127                 return;
01128             }
01129         }
01130         break;
01131 
01132         case INTESTINE:
01133         {
01134             // create our attrval with a valuefunction
01135             VariableWidthAttrValue VarWidth(new ValueFunctionIntestine);
01136 
01137             pVarWidth = VarWidth.MakeNode();
01138 
01139             if (pVarWidth)
01140             {
01141                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01142             }
01143             else
01144             {
01145                 delete pStrokeItem;
01146                 delete pVarWidthItem;
01147                 delete pStrokeType;
01148                 return;
01149             }
01150         }
01151         break;
01152 
01153         case DECAY:
01154         {
01155             // create our attrval with a valuefunction
01156             VariableWidthAttrValue VarWidth(new ValueFunctionDecay);
01157 
01158             pVarWidth = VarWidth.MakeNode();
01159 
01160             if (pVarWidth)
01161             {
01162                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01163             }
01164             else
01165             {
01166                 delete pStrokeItem;
01167                 delete pVarWidthItem;
01168                 delete pStrokeType;
01169                 return;
01170             }
01171         }
01172         break;
01173 
01174         case BEVELENDS:
01175         {
01176             // create our attrval with a valuefunction
01177             VariableWidthAttrValue VarWidth(new ValueFunctionBevelEnds);
01178 
01179             pVarWidth = VarWidth.MakeNode();
01180 
01181             if (pVarWidth)
01182             {
01183                 pVarWidthItem->NodeAttribPtr = pVarWidth;
01184             }
01185             else
01186             {
01187                 delete pStrokeItem;
01188                 delete pVarWidthItem;
01189                 delete pStrokeType;
01190                 return;
01191             }
01192         }
01193         break;
01194 
01195         case SS_Yacht:
01196         {
01197             // create our attrval with a valuefunction
01198             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Yacht);
01199 
01200             pVarWidth = VarWidth.MakeNode();
01201 
01202             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01203             else
01204             {
01205                 delete pStrokeItem;
01206                 delete pVarWidthItem;
01207                 delete pStrokeType;
01208                 return;
01209             }
01210         }
01211         break;
01212 
01213         case SS_Iron:
01214         {
01215             // create our attrval with a valuefunction
01216             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Iron);
01217 
01218             pVarWidth = VarWidth.MakeNode();
01219 
01220             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01221             else
01222             {
01223                 delete pStrokeItem;
01224                 delete pVarWidthItem;
01225                 delete pStrokeType;
01226                 return;
01227             }
01228         }
01229         break;
01230 
01231         case SS_Reed:
01232         {
01233             // create our attrval with a valuefunction
01234             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Reed);
01235 
01236             pVarWidth = VarWidth.MakeNode();
01237 
01238             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01239             else
01240             {
01241                 delete pStrokeItem;
01242                 delete pVarWidthItem;
01243                 delete pStrokeType;
01244                 return;
01245             }
01246         }
01247         break;
01248 
01249         case SS_Meteor:
01250         {
01251             // create our attrval with a valuefunction
01252             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Meteor);
01253 
01254             pVarWidth = VarWidth.MakeNode();
01255 
01256             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01257             else
01258             {
01259                 delete pStrokeItem;
01260                 delete pVarWidthItem;
01261                 delete pStrokeType;
01262                 return;
01263             }
01264         }
01265         break;
01266 
01267         case SS_Petal:
01268         {
01269             // create our attrval with a valuefunction
01270             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Petal);
01271 
01272             pVarWidth = VarWidth.MakeNode();
01273 
01274             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01275             else
01276             {
01277                 delete pStrokeItem;
01278                 delete pVarWidthItem;
01279                 delete pStrokeType;
01280                 return;
01281             }
01282         }
01283         break;
01284 
01285         case SS_Comet:
01286         {
01287             // create our attrval with a valuefunction
01288             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Comet);
01289 
01290             pVarWidth = VarWidth.MakeNode();
01291 
01292             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01293             else
01294             {
01295                 delete pStrokeItem;
01296                 delete pVarWidthItem;
01297                 delete pStrokeType;
01298                 return;
01299             }
01300         }
01301         break;
01302 
01303         case SS_Fallout:
01304         {
01305             // create our attrval with a valuefunction
01306             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Fallout);
01307 
01308             pVarWidth = VarWidth.MakeNode();
01309 
01310             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01311             else
01312             {
01313                 delete pStrokeItem;
01314                 delete pVarWidthItem;
01315                 delete pStrokeType;
01316                 return;
01317             }
01318         }
01319         break;
01320 
01321         case SS_Torpedo:
01322         {
01323             // create our attrval with a valuefunction
01324             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Torpedo);
01325 
01326             pVarWidth = VarWidth.MakeNode();
01327 
01328             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01329             else
01330             {
01331                 delete pStrokeItem;
01332                 delete pVarWidthItem;
01333                 delete pStrokeType;
01334                 return;
01335             }
01336         }
01337         break;
01338 
01339         case SS_Missile:
01340         {
01341             // create our attrval with a valuefunction
01342             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Missile);
01343 
01344             pVarWidth = VarWidth.MakeNode();
01345 
01346             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01347             else
01348             {
01349                 delete pStrokeItem;
01350                 delete pVarWidthItem;
01351                 delete pStrokeType;
01352                 return;
01353             }
01354         }
01355         break;
01356 
01357         case SS_Convex:
01358         {
01359             // create our attrval with a valuefunction
01360             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Convex);
01361 
01362             pVarWidth = VarWidth.MakeNode();
01363 
01364             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01365             else
01366             {
01367                 delete pStrokeItem;
01368                 delete pVarWidthItem;
01369                 delete pStrokeType;
01370                 return;
01371             }
01372         }
01373         break;
01374 
01375         case SS_Concave:
01376         {
01377             // create our attrval with a valuefunction
01378             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Concave);
01379 
01380             pVarWidth = VarWidth.MakeNode();
01381 
01382             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01383             else
01384             {
01385                 delete pStrokeItem;
01386                 delete pVarWidthItem;
01387                 delete pStrokeType;
01388                 return;
01389             }
01390         }
01391         break;
01392 
01393         case SS_SlimBlip:
01394         {
01395             // create our attrval with a valuefunction
01396             VariableWidthAttrValue VarWidth(new ValueFunctionSS_SlimBlip);
01397 
01398             pVarWidth = VarWidth.MakeNode();
01399 
01400             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01401             else
01402             {
01403                 delete pStrokeItem;
01404                 delete pVarWidthItem;
01405                 delete pStrokeType;
01406                 return;
01407             }
01408         }
01409         break;
01410 
01411         case SS_Cigar:
01412         {
01413             // create our attrval with a valuefunction
01414             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Cigar);
01415 
01416             pVarWidth = VarWidth.MakeNode();
01417 
01418             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01419             else
01420             {
01421                 delete pStrokeItem;
01422                 delete pVarWidthItem;
01423                 delete pStrokeType;
01424                 return;
01425             }
01426         }
01427         break;
01428         case SS_Cigar2:
01429         {
01430             // create our attrval with a valuefunction
01431             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Cigar2);
01432 
01433             pVarWidth = VarWidth.MakeNode();
01434 
01435             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01436             else
01437             {
01438                 delete pStrokeItem;
01439                 delete pVarWidthItem;
01440                 delete pStrokeType;
01441                 return;
01442             }
01443         }
01444         break;
01445 
01446         case SS_Cigar3:
01447         {
01448             // create our attrval with a valuefunction
01449             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Cigar3);
01450 
01451             pVarWidth = VarWidth.MakeNode();
01452 
01453             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01454             else
01455             {
01456                 delete pStrokeItem;
01457                 delete pVarWidthItem;
01458                 delete pStrokeType;
01459                 return;
01460             }
01461         }
01462         break;
01463 
01464         case SS_OceanLiner:
01465         {
01466             // create our attrval with a valuefunction
01467             VariableWidthAttrValue VarWidth(new ValueFunctionSS_OceanLiner);
01468 
01469             pVarWidth = VarWidth.MakeNode();
01470 
01471             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01472             else
01473             {
01474                 delete pStrokeItem;
01475                 delete pVarWidthItem;
01476                 delete pStrokeType;
01477                 return;
01478             }
01479         }
01480         break;
01481 
01482         case SS_Goldfish:
01483         {
01484             // create our attrval with a valuefunction
01485             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Goldfish);
01486 
01487             pVarWidth = VarWidth.MakeNode();
01488 
01489             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01490             else
01491             {
01492                 delete pStrokeItem;
01493                 delete pVarWidthItem;
01494                 delete pStrokeType;
01495                 return;
01496             }
01497         }
01498         break;
01499 
01500         case SS_Barb:
01501         {
01502             // create our attrval with a valuefunction
01503             VariableWidthAttrValue VarWidth(new ValueFunctionSS_Barb);
01504 
01505             pVarWidth = VarWidth.MakeNode();
01506 
01507             if (pVarWidth)  { pVarWidthItem->NodeAttribPtr = pVarWidth; }
01508             else
01509             {
01510                 delete pStrokeItem;
01511                 delete pVarWidthItem;
01512                 delete pStrokeType;
01513                 return;
01514             }
01515         }
01516         break;
01517 
01518         default:
01519         {
01520             ERROR3("Unrecognised stroke type in HandleStrokeSelectChange");
01521             delete pStrokeItem;
01522             delete pVarWidthItem;
01523             delete pStrokeType;
01524             m_SelectedStroke = CONSTANT;
01525             return;
01526         }
01527     }
01528 
01529     
01530     // now if the selection is empty then we want to update our selected stroke member
01531     SelRange* pSel = GetApplication()->FindSelection();
01532     if (pSel)
01533     {
01534         // recall that the indexes in the control are 1 greater than our enum constants
01535         if (pSel->IsEmpty())
01536             m_SelectedStroke = Index;
01537 
01538         // update the selection bounds
01539         pSel->UpdateParentBoundsOfSelection();
01540     }
01541 
01542 
01543     // OK so now we should have two ListItems to add to the list, or only one if
01544     // its a CONSTANT stroke
01545 
01546     if (pStrokeItem != NULL)
01547         AttribsList.AddTail(pStrokeItem);
01548 
01549     if (pVarWidthItem != NULL)
01550         AttribsList.AddTail(pVarWidthItem);
01551 
01552     // apply those attributes!
01553     AttributeManager::AttributesSelected(AttribsList, _R(IDS_STROKEAPPLY_UNDO));
01554 
01555 
01556     // We don't need the list of attrs anymore
01557     NodeAttributePtrItem* pAttrItem = (NodeAttributePtrItem*)AttribsList.GetHead();
01558     while (pAttrItem)
01559     {
01560         delete (pAttrItem->NodeAttribPtr);
01561         pAttrItem->NodeAttribPtr = NULL;
01562         pAttrItem = (NodeAttributePtrItem*)AttribsList.GetNext(pAttrItem);
01563     }
01564     AttribsList.DeleteAll(); // tidyup  
01565 
01566 }
01567 
01568 
01569 /********************************************************************************************
01570 
01571 >   void FreeHandInfoBarOp::HandleBrushSelectChange()
01572 
01573     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01574     Created:    23/3/2000
01575     Inputs:     -
01576     Returns:    -
01577     Purpose:    Called when a SLIDER_POS_CHANGING message is received 
01578 
01579 ********************************************************************************************/
01580 
01581 void FreeHandInfoBarOp::HandleSliderPosChanging()
01582 {
01583     // Find the current scrollers position
01584     TCHAR Str[32];
01585     BOOL Valid;
01586     INT32 Result = GetLongGadgetValue(_R(IDC_FREEHANDSLIDER), 0, 100, 0, &Valid);
01587 
01588     // Build the Percentage string and set it
01589     String_32 jcf(_R(IDS_PERCENT_FORMAT));
01590     camSnprintf(Str, 32, jcf, (INT32) Result);
01591     String_8 PercentStr(Str);
01592     SetStringGadgetValue(_R(IDC_FREEHANDPERCENT), PercentStr);
01593 
01594     // Tell the freehand tool about the new smoothness
01595     if (Valid)
01596     {
01597         // Set the smoothness and re-fit the path if possible
01598         pTool->SetSmoothness(Result);
01599         pTool->RetroFitChanging();
01600     }
01601 
01602 }
01603 
01604 
01605 /********************************************************************************************
01606 
01607 >   void FreeHandInfoBarOp::LaunchBrushEditDialog()
01608     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01609     Created:    23/3/2000
01610     Inputs:     -
01611     Returns:    -
01612     Purpose:    launches the brush edit dialog based upon data from the selection
01613 
01614 ********************************************************************************************/
01615 
01616 void FreeHandInfoBarOp::LaunchBrushEditDialog()
01617 {
01618 
01619     // launch the dialog
01620     OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BRUSHEDIT_DLG);
01621     if (pDesc != NULL)
01622     {
01623         pDesc->Invoke();
01624     }
01625     
01626 }
01627 
01628 /********************************************************************************************
01629 
01630 >   void FreeHandInfoBarOp::GetBrushDataFromSelection(BOOL* pSelectionEmpty = NULL)
01631 
01632     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01633     Created:    23/3/2000
01634     Inputs:     -
01635     Outputs:    pSelectionEmpty - flag is set if the selection is empty
01636     Returns:    brush data object representing a selected brush, you can tell if there are no
01637                 real brushes selected by looking at the m_BrushHandle member of the returned data
01638     Purpose:    if there is one and only one brush in the selection the this function returns
01639                 a brush data object representing its current state.  If there is any other number
01640                 then a data item is still returned but it will not be valid
01641 
01642 ********************************************************************************************/
01643 
01644 BrushData FreeHandInfoBarOp::GetBrushDataFromSelection(BOOL* pSelEmpty)
01645 {
01646     // find all the brushes in the current selection
01647     List NodeList;
01648     BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(AttrBrushType));
01649     BrushData Data; // initialises to default values
01650     INT32 NumItems = NodeList.GetCount();
01651     
01652     // we can only retrieve a valid data item if there is a single item selected,
01653     // if there is any other number then we must return
01654     switch (NumItems)
01655     {
01656         case 0:
01657             if (pSelEmpty != NULL)
01658                 *pSelEmpty = TRUE;
01659             NodeList.DeleteAll();
01660             return Data;
01661         case 1:
01662             if (pSelEmpty != NULL)
01663                 *pSelEmpty = FALSE;
01664             break;
01665         default:
01666             if (pSelEmpty != NULL)
01667                 *pSelEmpty = FALSE;
01668             NodeList.DeleteAll();
01669             return Data;
01670     }
01671 
01672     // we've got an item, so find its applied brush attribute
01673     NodeListItem * pItem = (NodeListItem *)NodeList.GetHead();
01674 
01675     if (pItem)
01676     {
01677         Node* pBrush = pItem->pNode;
01678         if (pBrush)
01679         {
01680             AttrBrushType* pAttrBrush = (AttrBrushType*)pBrush;
01681             if (pAttrBrush->GetBrushHandle() != BrushHandle_NoBrush)
01682             {
01683                 Data = pAttrBrush->GetBrushData();
01684                 
01685             }
01686         }
01687     }
01688     NodeList.DeleteAll();
01689     return Data;
01690 }
01691 
01692 
01693 /********************************************************************************************
01694 
01695 >   void FreeHandInfoBarOp::GetBrushHandleFromSelection(BOOL* pSelEmpty = NULL)
01696 
01697     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01698     Created:    23/3/2000
01699     Inputs:     -
01700     Outputs:    pSelectionEmpty - flag is set if the selection is empty
01701     Returns:    handle of the brush in the selection.  Note that if there are many different
01702                 brushes selected then BrushHandle_NoBrush will be returned
01703     Purpose:    To find out if there are any brushed objects in the selection
01704 
01705 ********************************************************************************************/
01706 
01707 BrushHandle FreeHandInfoBarOp::GetBrushHandleFromSelection(BOOL* pSelEmpty)
01708 {
01709     // find all the brushes in the current selection
01710     List NodeList;
01711     BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(AttrBrushType), TRUE);
01712     BrushData Data; // initialises to default values
01713     INT32 NumItems = NodeList.GetCount();
01714 
01715     BrushHandle SelHandle = BrushHandle_NoBrush;
01716 
01717     if (NumItems != 0)
01718     {
01719         if (pSelEmpty !=NULL)
01720             *pSelEmpty = FALSE;
01721         // we've got an item, so find its applied brush attribute
01722         NodeListItem * pItem = (NodeListItem *)NodeList.GetHead();
01723 //      BrushHandle LastHandle = BrushHandle_NoBrush;
01724         BOOL bFirst = TRUE;
01725 
01726         AttrBrushType* pAttrBrush = NULL;
01727         Node* pBrush = NULL;
01728         while (pItem)
01729         {
01730             pBrush = pItem->pNode;
01731             if (pBrush)
01732             {
01733                 pAttrBrush = (AttrBrushType*)pBrush;
01734                 if (bFirst)
01735                 {
01736                     SelHandle = pAttrBrush->GetBrushHandle();
01737                     bFirst = FALSE;
01738                 }
01739                 else
01740                 {
01741                     // if we have different brushes then show the 'many' string
01742                     if (pAttrBrush->GetBrushHandle() != SelHandle)
01743                     {
01744                         SelHandle = BrushHandle_Many;
01745                         break;
01746                     }
01747                 }
01748             }
01749             pItem = (NodeListItem *)NodeList.GetNext(pItem);
01750         }
01751     }
01752     else
01753     {
01754         // see if we actually have anything in the selection
01755         SelRange* pSel = GetApplication()->FindSelection();
01756         if (pSel && pSel->IsEmpty())
01757         {
01758             if (pSelEmpty != NULL)
01759                 *pSelEmpty = TRUE;
01760         }
01761     }
01762     NodeList.DeleteAll();
01763     return SelHandle;
01764 }
01765 /********************************************************************************************
01766 
01767 >   BOOL FreeHandInfoBarOp::InitBrushList()
01768 
01769     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01770     Created:    23/3/2000
01771     Inputs:     -
01772     Returns:    true, unless we failed to get a new
01773     Purpose:    creates the brush list if it does not exist, if it already exists then we just 
01774                 empty it. Then we fill it with brush handles in the order that they exist in
01775                 the brush component.
01776 ********************************************************************************************/
01777 
01778 BOOL FreeHandInfoBarOp::InitBrushList()
01779 {
01780     if (m_pBrushList == NULL)
01781         m_pBrushList = new BrushList;
01782 
01783     if (m_pBrushList == NULL)
01784         return FALSE;
01785 
01786     m_pBrushList->clear();
01787 
01788     UINT32 NumBrushes = BrushComponent::GetNumberOfBrushes();
01789 
01790     for (UINT32 Index = 0; Index < NumBrushes; Index++)
01791     {
01792         BrushHandle Handle = Index;
01793         m_pBrushList->push_back(Handle);
01794     }
01795 
01796     return TRUE;
01797 }
01798 
01799 
01800 
01801 /********************************************************************************************
01802 
01803 >   BOOL FreeHandInfoBarOp::ReInitBrushList()
01804 
01805     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01806     Created:    23/3/2000
01807     Inputs:     -
01808     Returns:    true, unless something goes wrong
01809     Purpose:    This takes care of a situation where we might add a number of brushes at once
01810                 and want to update the brush list without forgetting the order of the list.
01811                 This kind of thing arises when we load in a new document.
01812                 Anyway what we do is compare the number of brushes with the number of items in the 
01813                 list, and if there is a mismatch we add the new ones to the end of the list
01814 ********************************************************************************************/
01815 
01816 BOOL FreeHandInfoBarOp::ReInitBrushList()
01817 {
01818     if (m_pBrushList == NULL)
01819         return InitBrushList();
01820 
01821     UINT32 NumBrushes = BrushComponent::GetNumberOfBrushes();
01822     UINT32 NumListBrushes = m_pBrushList->size();
01823 
01824     while (NumListBrushes < NumBrushes)
01825     {
01826         m_pBrushList->push_back(NumListBrushes);
01827         NumListBrushes++;
01828     }
01829     return TRUE;
01830 
01831 }
01832 
01833 /********************************************************************************************
01834 
01835 >   BOOL FreeHandInfoBarOp::SetBrushListToControl()
01836 
01837     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01838     Created:    23/3/2000
01839     Inputs:     -
01840     Returns:    true, unless we failed to get a new
01841     Purpose:    Goes through the brush list in order, creating attribute nodes from the brush
01842                 handles and setting them into the combo.
01843 ********************************************************************************************/
01844 
01845 BOOL FreeHandInfoBarOp::SetBrushListToControl()
01846 {
01847 //#ifdef BUILDNEWBRUSHES
01848     if (m_pBrushList == NULL)
01849         return TRUE; // not an error, we just can't do it
01850 
01851     // if we have no document then don't bother
01852     Document* pDoc  = Document::GetCurrent();
01853     if (pDoc == NULL)
01854         return TRUE;
01855 
01856     // wipe our existing control
01857 //  DeleteAllValues(_R(IDC_BRUSHTYPE));
01858     m_bgddBrushType.Clear();
01859     
01860     // need a pointer of type CustomComboBoxControlDataItem to insert items into
01861     // a custom combobox ....
01862 //  CustomComboBoxControlDataItem* theItem = NULL;
01863 
01864 //  UINT32 Counter = 1; // the combo's indexes start at 1
01865     
01866     BrushHandle Handle = BrushHandle_NoBrush;
01867 
01868     BrushList::const_iterator iter;
01869     for (iter = m_pBrushList->begin(); iter !=m_pBrushList->end(); iter++)
01870     {
01871         // get the next handle
01872         Handle = *iter;
01873         
01874         // ask the component to make a node for us
01875         if (Handle != BrushHandle_NoBrush)
01876         {
01877             AttrBrushType* pNewAttr = BrushComponent::CreateNode (Handle);
01878             
01879             if (pNewAttr != NULL)
01880                 m_bgddBrushType.AddItem(pNewAttr);
01881         }
01882         else
01883         {
01884             ERROR3("Default brush handle found in list in FreeHandInfoBarOp::SetBrushListToControl");
01885         }
01886     }
01887 
01888     return SetStrokesToControl() ;
01889 }
01890 
01891 /********************************************************************************************
01892 
01893 >   BOOL FreeHandInfoBarOp::SetStrokesToControl()
01894 
01895     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01896     Created:    23/3/2000
01897     Inputs:     -
01898     Returns:    true, unless we failed to get a new
01899     Purpose:    Creates stroke shape items and adds them to the stroke combo
01900 ********************************************************************************************/
01901 
01902 BOOL FreeHandInfoBarOp::SetStrokesToControl()
01903 {
01904 //  DeleteAllValues(_R(IDC_STROKETYPE));
01905     m_bgddStrokes.Clear();
01906 
01907     
01908 //  UINT32 index = 1;
01909 //  CustomComboBoxControlDataItem* theItem = NULL;
01910         
01911     // --- Simple constant-width line ------------------------------------------
01912     VariableWidthAttrValue *pAttr;
01913     pAttr = new VariableWidthAttrValue(NULL);
01914     VarWidthItem* pItem = new VarWidthItem(pAttr, String_64(TEXT("Constant")));
01915     m_bgddStrokes.AddItem(pItem);
01916 
01917     // --- Smooth Stroke SS_Fallout ------------------------------------------------
01918     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Fallout);
01919     pItem = new VarWidthItem(pAttr, String_64(TEXT("Fallout")));
01920     m_bgddStrokes.AddItem(pItem);
01921 
01922     // --- Smooth Stroke SS_Iron ------------------------------------------------
01923     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Iron);
01924     pItem = new VarWidthItem(pAttr, String_64(TEXT("Iron")));
01925     m_bgddStrokes.AddItem(pItem);
01926 
01927     // --- Ellipse -------------------------------------------------------------
01928     pAttr = new VariableWidthAttrValue(new ValueFunctionEllipse);
01929     pItem = new VarWidthItem(pAttr, String_64(TEXT("Ellipse")));
01930     m_bgddStrokes.AddItem(pItem);
01931 
01932     // --- Smooth Stroke SS_SlimBlip ------------------------------------------------
01933     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_SlimBlip);
01934     pItem = new VarWidthItem(pAttr, String_64(TEXT("Slim Blip")));
01935     m_bgddStrokes.AddItem(pItem);
01936 
01937     // --- Blip ----------------------------------------------------------------
01938     pAttr = new VariableWidthAttrValue(new ValueFunctionBlip);
01939     pItem = new VarWidthItem(pAttr, String_64(TEXT("Blip")));
01940     m_bgddStrokes.AddItem(pItem);
01941 
01942     // --- Smooth Stroke SS_Cigar ------------------------------------------------
01943     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar);
01944     pItem = new VarWidthItem(pAttr, String_64(TEXT("Cigar")));
01945     m_bgddStrokes.AddItem(pItem);
01946 
01947     // --- Smooth Stroke SS_Cigar2 ------------------------------------------------
01948     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar2);
01949     pItem = new VarWidthItem(pAttr, String_64(TEXT("Cigar 2")));
01950     m_bgddStrokes.AddItem(pItem);
01951 
01952     // --- Smooth Stroke SS_Cigar3 ------------------------------------------------
01953     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar3);
01954     pItem = new VarWidthItem(pAttr, String_64(TEXT("Cigar 3")));
01955     m_bgddStrokes.AddItem(pItem);
01956 
01957     // --- Smooth Stroke SS_Convex ------------------------------------------------
01958     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Convex);
01959     pItem = new VarWidthItem(pAttr, String_64(TEXT("Convex")));
01960     m_bgddStrokes.AddItem(pItem);
01961 
01962     // --- Simple S-shaped ramp with non-zero end width ------------------------------------------------
01963     pAttr = new VariableWidthAttrValue(new ValueFunctionRampS2);
01964     pItem = new VarWidthItem(pAttr, String_64(TEXT("Convex 2")));
01965     m_bgddStrokes.AddItem(pItem);
01966 
01967     // --- Simple S-shaped ramp ------------------------------------------------
01968     pAttr = new VariableWidthAttrValue(new ValueFunctionRampS);
01969     pItem = new VarWidthItem(pAttr, String_64(TEXT("Convex 3")));
01970     m_bgddStrokes.AddItem(pItem);
01971 
01972     // --- Smooth Stroke SS_Concave ------------------------------------------------
01973     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Concave);
01974     pItem = new VarWidthItem(pAttr, String_64(TEXT("Concave")));
01975     m_bgddStrokes.AddItem(pItem);
01976 
01977     // --- Simple linear ramp with non-zero end width --------------------------------------------------
01978     pAttr = new VariableWidthAttrValue(new ValueFunctionRampL2);
01979     pItem = new VarWidthItem(pAttr, String_64(TEXT("Concave 2")));
01980     m_bgddStrokes.AddItem(pItem);
01981 
01982     // --- Simple linear ramp --------------------------------------------------
01983     pAttr = new VariableWidthAttrValue(new ValueFunctionRampL);
01984     pItem = new VarWidthItem(pAttr, String_64(TEXT("Concave 3")));
01985     m_bgddStrokes.AddItem(pItem);
01986 
01987     // --- Teardrop CurvedEnd------------------------------------------------------------
01988     pAttr = new VariableWidthAttrValue(new ValueFunctionTeardropCurvedEnd);
01989     pItem = new VarWidthItem(pAttr, String_64(TEXT("Dab")));
01990     m_bgddStrokes.AddItem(pItem);
01991 
01992     // --- Teardrop ------------------------------------------------------------
01993     pAttr = new VariableWidthAttrValue(new ValueFunctionTeardrop);
01994     pItem = new VarWidthItem(pAttr, String_64(TEXT("Raindrop")));
01995     m_bgddStrokes.AddItem(pItem);
01996 
01997     // --- Smooth Stroke SS_Comet ------------------------------------------------
01998     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Comet);
01999     pItem = new VarWidthItem(pAttr, String_64(TEXT("Comet")));
02000     m_bgddStrokes.AddItem(pItem);
02001 
02002     // --- Smooth Stroke SS_Petal ------------------------------------------------
02003     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Petal);
02004     pItem = new VarWidthItem(pAttr, String_64(TEXT("Petal")));
02005     m_bgddStrokes.AddItem(pItem);
02006 
02007     // --- Smooth Stroke SS_Reed ------------------------------------------------
02008     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Reed);
02009     pItem = new VarWidthItem(pAttr, String_64(TEXT("Reed")));
02010     m_bgddStrokes.AddItem(pItem);
02011 
02012     // --- Smooth Stroke SS_Meteor ------------------------------------------------
02013     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Meteor);
02014     pItem = new VarWidthItem(pAttr, String_64(TEXT("Meteor")));
02015     m_bgddStrokes.AddItem(pItem);
02016 
02017     // --- Smooth Stroke SS_Torpedo ------------------------------------------------
02018     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Torpedo);
02019     pItem = new VarWidthItem(pAttr, String_64(TEXT("Torpedo")));
02020     m_bgddStrokes.AddItem(pItem);
02021 
02022     // --- Smooth Stroke SS_Missile ------------------------------------------------
02023     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Missile);
02024     pItem = new VarWidthItem(pAttr, String_64(TEXT("Missile")));
02025     m_bgddStrokes.AddItem(pItem);
02026 
02027     // --- Smooth Stroke SS_Goldfish ------------------------------------------------
02028     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Goldfish);
02029     pItem = new VarWidthItem(pAttr, String_64(TEXT("Goldfish")));
02030     m_bgddStrokes.AddItem(pItem);
02031 
02032     // --- Smooth Stroke SS_Yacht ------------------------------------------------
02033     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Yacht);
02034     pItem = new VarWidthItem(pAttr, String_64(TEXT("Yacht")));
02035     m_bgddStrokes.AddItem(pItem);
02036 
02037     // --- Smooth Stroke SS_Barb ------------------------------------------------
02038     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Barb);
02039     pItem = new VarWidthItem(pAttr, String_64(TEXT("Barb")));
02040     m_bgddStrokes.AddItem(pItem);
02041 
02042     // --- Smooth Stroke SS_OceanLiner ------------------------------------------------
02043     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_OceanLiner);
02044     pItem = new VarWidthItem(pAttr, String_64(TEXT("Ocean Liner")));
02045     m_bgddStrokes.AddItem(pItem);
02046 
02047     // --- Propeller ------------------------------------------------
02048     pAttr = new VariableWidthAttrValue(new ValueFunctionPropeller);
02049     pItem = new VarWidthItem(pAttr, String_64(TEXT("Propeller")));
02050     m_bgddStrokes.AddItem(pItem);
02051 
02052     // --- Double S-shaped ramp ------------------------------------------------
02053     pAttr = new VariableWidthAttrValue(new ValueFunctionDoubleRampS);
02054     pItem = new VarWidthItem(pAttr, String_64(TEXT("Bow Tie")));
02055     //pAttr2 = (NodeAttribute*) pItem->CreateNode ();
02056     m_bgddStrokes.AddItem(pItem);
02057 
02058     // --- BevelEnds ------------------------------------------------
02059     pAttr = new VariableWidthAttrValue(new ValueFunctionBevelEnds);
02060     pItem = new VarWidthItem(pAttr, String_64(TEXT("Bevel Ends")));
02061     m_bgddStrokes.AddItem(pItem);
02062 
02063     // --- SawTooth ------------------------------------------------
02064     pAttr = new VariableWidthAttrValue(new ValueFunctionSawTooth);
02065     pItem = new VarWidthItem(pAttr, String_64(TEXT("Saw Tooth")));
02066     //pAttr2 = (NodeAttribute*) pItem->CreateNode ();
02067     m_bgddStrokes.AddItem(pItem);
02068 
02069     // --- Intestine ------------------------------------------------
02070     pAttr = new VariableWidthAttrValue(new ValueFunctionIntestine);
02071     pItem = new VarWidthItem(pAttr, String_64(TEXT("Intestine")));
02072     m_bgddStrokes.AddItem(pItem);
02073 
02074     // --- Decay ------------------------------------------------
02075     pAttr = new VariableWidthAttrValue(new ValueFunctionDecay);
02076     pItem = new VarWidthItem(pAttr, String_64(TEXT("Decay")));
02077     m_bgddStrokes.AddItem(pItem);
02078 
02079 
02080     SetStrokeComboFromSelection();
02081     
02082     return TRUE;
02083 }
02084 
02085 
02086 
02087 /********************************************************************************************
02088 
02089 >   void FreeHandInfoBarOp::SetHeadOfListSelected()
02090     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02091     Created:    23/3/2000
02092     Inputs:     -
02093     Returns:    -
02094     Purpose:    asks the brush combo to make its top item appear selecte
02095 ********************************************************************************************/
02096 
02097 void FreeHandInfoBarOp::SetHeadOfListSelected()
02098 {
02099 //#ifdef BUILDNEWBRUSHES
02100     // if we have no document then don't bother
02101     Document* pDoc  = Document::GetCurrent();
02102     if (pDoc == NULL)
02103         return;
02104     if (m_pBrushList == NULL)
02105     {
02106         ERROR3("Brush list is NULL in FreeHandInfoBarOp::SetHeadOfListSelected");
02107         return;
02108     }
02109     
02110     // on start up we have not yet put anything in the list so make sure we're not empty,
02111     // however this may not be cause for an error
02112     if (!m_pBrushList->empty())
02113     {
02114         BrushHandle Handle = m_pBrushList->front();
02115     
02116 //      SetCustomComboGadgetValue(_R(IDC_BRUSHTYPE), NULL, 0, 2 );
02117         m_bgddBrushType.SetSelected(0);
02118         
02119         m_DisplayBrush = Handle;
02120         
02121     }
02122 //#endif
02123 }
02124 
02125 
02126 /********************************************************************************************
02127 
02128 >   void FreeHandInfoBarOp::SetDisplayBrush()
02129     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02130     Created:    23/3/2000
02131     Inputs:     -
02132     Returns:    -
02133     Purpose:    display the current display brush in the combo window (use this when display brush
02134                 is different from the head of the brush list)
02135 ********************************************************************************************/
02136 
02137 void FreeHandInfoBarOp::SetDisplayBrush()
02138 {
02139 //#ifdef BUILDNEWBRUSHES    
02140     // we need to find the index for our brush
02141     INT32 iIndex = GetControlIndexFromBrushHandle(m_DisplayBrush);
02142 
02143     m_bgddBrushType.SetSelected(iIndex);
02144 /*
02145     switch (Index)
02146     {
02147         case -1:
02148 //          SetCustomComboGadgetValue ( _R(IDC_BRUSHTYPE), NULL, TRUE, -2);
02149         //  TRACEUSER( "Diccon", _T("Display default brush\n"));
02150             break;
02151         case 0: // the zeroth index is the same as the head of our selected brushes list
02152             SetHeadOfListSelected();
02153         //  TRACEUSER( "Diccon", _T("Displayed head of list\n"));
02154             break;
02155         default:
02156             SetCustomComboGadgetValue(_R(IDC_BRUSHTYPE), NULL, 0, Index + 2);  // control indexes are +2 from the index into our list
02157         //  TRACEUSER( "Diccon", _T("Displayed display brush\n"));
02158             break;
02159     }
02160 */
02161 //#endif
02162 }
02163 
02164 
02165 /********************************************************************************************
02166 
02167 >   void FreeHandInfoBarOp::SetBrushComboFromSelection()
02168     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02169     Created:    23/3/2000
02170     Inputs:     -
02171     Returns:    -
02172     Purpose:    examines the selection and sets the appropriate brush in the brush combo
02173 
02174 ********************************************************************************************/
02175 
02176 void FreeHandInfoBarOp::SetBrushComboFromSelection()
02177 {
02178     /* there are a few different scenarios here:
02179        1) we have a single brush in the selection, in which case show it in the combo
02180        2) we have many different brushes in the selection, in which case show our most
02181        recently selected drawing brush
02182        3) we have no brushes in the selection, but the selection is not empty, in this case
02183        show a default line
02184        4) the selection is empty, in which case we show the selected drawing brush.
02185     */
02186 
02187     BOOL bSelectionEmpty = FALSE;
02188     BrushHandle SelHandle = GetBrushHandleFromSelection(&bSelectionEmpty);
02189 
02190     switch (SelHandle)
02191     {
02192         case BrushHandle_NoBrush: // display our currently selected brush for drawing
02193         {
02194             // if the selection is empty then show our drawing brush, if however we just don't
02195             // have any brushes in the selection then display the no-brush
02196             if (bSelectionEmpty)
02197             {
02198                 SetDisplayBrush();  
02199             }
02200             else
02201             {
02202                 // temporarily change the display brush and reflect it in the control
02203                 BrushHandle Temp = m_DisplayBrush;
02204                 m_DisplayBrush = SelHandle;
02205                 SetDisplayBrush();          
02206                 // restore the original display brush
02207                 m_DisplayBrush = Temp;
02208             }
02209         }
02210         break;
02211         case BrushHandle_Many: // display the 'many' string
02212         {
02213             // the only way to do this seems to be by sending a string to the control
02214             String_256 Many;
02215             Many.Load(_R(IDS_FILLTOOL_MANY));
02216             
02217             // call custom controls interface ....
02218 //          SelectCustomComboGadgetValueOnString (_R(IDC_BRUSHTYPE), &Many);
02219             m_bgddBrushType.SetSelected(-1);
02220             
02221         }
02222         break;
02223 
02224         default: // display the brush from the selection
02225         {
02226             // temporarily change the display brush and reflect it in the control
02227             BrushHandle Temp = m_DisplayBrush;
02228             m_DisplayBrush = SelHandle;
02229             SetDisplayBrush();          
02230             // restore the original display brush
02231             m_DisplayBrush = Temp;
02232         }
02233         break;
02234     }
02235 
02236 }
02237 
02238 
02239 /********************************************************************************************
02240 
02241 >   void FreeHandInfoBarOp::SetStrokeComboFromSelection()
02242     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02243     Created:    23/3/2000
02244     Inputs:     -
02245     Returns:    -
02246     Purpose:    examines the selection and sets the appropriate stroke in the stroke combo.
02247                 If there is no selection, or a multiple selection with different strokes then
02248                 we display the last selected stroke
02249 
02250 ********************************************************************************************/
02251 
02252 void FreeHandInfoBarOp::SetStrokeComboFromSelection()
02253 {
02254     Document* pDoc = Document::GetCurrent();
02255     
02256     // if we have no document then don't bother
02257     if (pDoc == NULL)
02258         return;
02259 
02260     // find out how many items there are in the selection
02261     SelRange* pSel = GetApplication()->FindSelection();
02262 //  INT32 NumSelItems = 0;
02263     INT32 SelectedStroke = m_SelectedStroke; // this is the index that we will end up setting to the control
02264 
02265     if (pSel)
02266     {
02267         Node* pNode = pSel->FindFirst();
02268         
02269         // declare some vars that we need in the loop
02270         AttrVariableWidth* pVarWidth = NULL;
02271         VariableWidthAttrValue* pVal = NULL;
02272         ValueFunction* pFunk = NULL;
02273         ValueFunctionID ID = ValueFunctionID_None;
02274 
02275         BOOL bFirst = TRUE;
02276         BOOL bDifferent = FALSE;
02277         INT32 NumItems = 0;
02278 
02279         // for each node check to get its applied variable width attribute, and then the value function
02280         // of the attribute.  If its the first node then record it, otherwise just check to see if its different
02281         // and if so then break out
02282         
02283         while (pNode)
02284         {
02285             NumItems++;
02286             
02287             // if its a noderenderable ink then check its applied attrvarwidth
02288             if (pNode->IsAnObject())
02289             {
02290                 // find the attribute
02291                 ((NodeRenderableInk*)pNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth),
02292                                             (NodeAttribute**)&pVarWidth);
02293 
02294                 if (pVarWidth)
02295                 {
02296                     // get the variable width function from the attribute (can be null)
02297                     pVal = (VariableWidthAttrValue*)pVarWidth->GetAttributeValue();
02298                     pFunk = pVal->GetWidthFunction();
02299 
02300                     // its the first one
02301                     if (bFirst)
02302                     {
02303                         if (pFunk)
02304                             ID = pFunk->GetUniqueID();
02305                         
02306                         // get the index into our combo corresponding to this ID
02307                         SelectedStroke = GetStrokeIndexFromValueFunctionID(ID);
02308 
02309                         bFirst = FALSE;
02310                     }
02311                     else
02312                     {
02313                         // check to see if it is different, if so set the flag and quit
02314                         if (pFunk && (pFunk->GetUniqueID() != ID))
02315                         {
02316                             bDifferent = TRUE;
02317                             break;
02318                         }
02319                     }
02320                 }
02321 
02322             }
02323             pNode = pSel->FindNext(pNode);
02324         }
02325 
02326         // if there were no items then display the current attribute
02327         if (NumItems == 0)
02328         {
02329             // get the current attribute from the attribute manager
02330             AttributeManager* pAttrMgr = &(pDoc->GetAttributeMgr());
02331             if (pAttrMgr == NULL)
02332             {
02333                 ERROR3("Unable to get attribute manager!");
02334                 return;
02335             }
02336             
02337             // may as well reuse this var
02338             pVarWidth = NULL;
02339             pVarWidth = (AttrVariableWidth*)pAttrMgr->GetCurrentAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
02340                                             CC_RUNTIME_CLASS(AttrVariableWidth));
02341             if (pVarWidth)
02342             {
02343                 VariableWidthAttrValue* pVal = (VariableWidthAttrValue*)pVarWidth->GetAttributeValue();
02344                 ValueFunction* pFunk = pVal->GetWidthFunction();
02345                 if (pFunk)
02346                 {
02347                     SelectedStroke = GetStrokeIndexFromValueFunctionID(pFunk->GetUniqueID());
02348                 }
02349                 else
02350                 {
02351                     SelectedStroke = CONSTANT;
02352                 }
02353             }
02354         }
02355         // if we have different strokes we need to say 'many', (what choo talkin' bout Willis!?)
02356         if (bDifferent)
02357         {
02358 /*          // the only way to do this seems to be by sending a string to the control
02359             String_256 Many;
02360             Many.Load(_R(IDS_FILLTOOL_MANY));
02361             
02362             // call custom controls interface ....
02363             SelectCustomComboGadgetValueOnString (_R(IDC_STROKETYPE), &Many);
02364 */
02365             // Select none in the stroke dropdown since we don't support placing "many" word
02366             // into the combobox.
02367             m_bgddStrokes.SetSelected(-1);
02368             return;
02369         }
02370 
02371     }
02372     
02373     // now set the index to the control
02374     m_bgddStrokes.SetSelected(SelectedStroke);
02375 }
02376 
02377 
02378 
02379 /********************************************************************************************
02380 
02381 >   INT32 FreeHandInfoBarOp::GetStrokeIndexFromValueFunctionID(ValueFunctionID ID)
02382 
02383     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02384     Created:    23/3/2000
02385     Inputs:     ID of the value function
02386     Returns:    the corresponding index of this stroke into the stroke combo, if we get an 
02387                 unrecognised ID to be on the safe side we will return CONSTANT
02388 
02389     Purpose:    Bit of a last minute bodge this, as we are trying to implement a small subset
02390                 of the value functions into the stroke combo at fixed indexes.  We will map
02391                 the ValueFunctionID used by the ValueFunctions to the index into the combo
02392 
02393 ********************************************************************************************/
02394 
02395 INT32 FreeHandInfoBarOp::GetStrokeIndexFromValueFunctionID(ValueFunctionID ID)
02396 {
02397     INT32 ReturnVal = CONSTANT;  // if we get an invalid ID we will just stick to this
02398     switch (ID)
02399     {
02400         case ValueFunctionID_None:
02401             break;
02402         case ValueFunctionID_Constant:
02403             break;
02404         case ValueFunctionID_RampS:
02405             ReturnVal = RAMPS;
02406             break;  
02407         case ValueFunctionID_RampS2:
02408             ReturnVal = RAMPS2;
02409             break;  
02410         case ValueFunctionID_Teardrop:
02411             ReturnVal = TEARDROP;
02412             break;
02413         case ValueFunctionID_Ellipse:
02414             ReturnVal = ELLIPSE;
02415             break;
02416         case ValueFunctionID_Blip:
02417             ReturnVal = BLIP;
02418             break;
02419         case ValueFunctionID_RampL:
02420             ReturnVal = RAMPL;
02421             break;
02422         case ValueFunctionID_RampL2:
02423             ReturnVal = RAMPL2;
02424             break;
02425         case ValueFunctionID_DoubleRampS:
02426             ReturnVal = DOUBLERAMPS;
02427             break;  
02428         case ValueFunctionID_TeardropCurvedEnd:
02429             ReturnVal = TEARDROPCURVEDEND;
02430             break;
02431         case ValueFunctionID_SawTooth:
02432             ReturnVal = SAWTOOTH;
02433             break;  
02434         case ValueFunctionID_Propeller:
02435             ReturnVal = PROPELLER;
02436             break;  
02437         case ValueFunctionID_Intestine:
02438             ReturnVal = INTESTINE;
02439             break;  
02440         case ValueFunctionID_Decay:
02441             ReturnVal = DECAY;
02442             break;  
02443         case ValueFunctionID_BevelEnds:
02444             ReturnVal = BEVELENDS;
02445             break;  
02446         case ValueFunctionID_SS_Yacht:
02447             ReturnVal = SS_Yacht;
02448             break;  
02449         case ValueFunctionID_SS_Iron:
02450             ReturnVal = SS_Iron;
02451             break;  
02452         case ValueFunctionID_SS_Reed:
02453             ReturnVal = SS_Reed;
02454             break;  
02455         case ValueFunctionID_SS_Meteor:
02456             ReturnVal = SS_Meteor;
02457             break;  
02458         case ValueFunctionID_SS_Petal:
02459             ReturnVal = SS_Petal;
02460             break;  
02461         case ValueFunctionID_SS_Comet:
02462             ReturnVal = SS_Comet;
02463             break;  
02464         case ValueFunctionID_SS_Fallout:
02465             ReturnVal = SS_Fallout;
02466             break;  
02467         case ValueFunctionID_SS_Torpedo:
02468             ReturnVal = SS_Torpedo;
02469             break;  
02470         case ValueFunctionID_SS_Missile:
02471             ReturnVal = SS_Missile;
02472             break;  
02473         case ValueFunctionID_SS_Convex:
02474             ReturnVal = SS_Convex;
02475             break;  
02476         case ValueFunctionID_SS_Concave:
02477             ReturnVal = SS_Concave;
02478             break;
02479         case ValueFunctionID_SS_SlimBlip:
02480             ReturnVal = SS_SlimBlip;
02481             break;  
02482         case ValueFunctionID_SS_Cigar:
02483             ReturnVal = SS_Cigar;
02484             break;  
02485         case ValueFunctionID_SS_Cigar2:
02486             ReturnVal = SS_Cigar2;
02487             break;  
02488         case ValueFunctionID_SS_Cigar3:
02489             ReturnVal = SS_Cigar3;
02490             break;  
02491         case ValueFunctionID_SS_OceanLiner:
02492             ReturnVal = SS_OceanLiner;
02493             break;  
02494         case ValueFunctionID_SS_Goldfish:
02495             ReturnVal = SS_Goldfish;
02496             break;  
02497         case ValueFunctionID_SS_Barb:
02498             ReturnVal = SS_Barb;
02499             break;  
02500 
02501         default:
02502             ERROR3("Illegal ValueFunction ID");
02503             break;
02504     }
02505 
02506     return ReturnVal;
02507 }
02508 
02509 
02510 /********************************************************************************************
02511 
02512 >   BrushHandle FreeHandInfoBarOp::GetBrushHandleFromControlIndex(BrushHandle Index)
02513 
02514     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02515     Created:    23/3/2000
02516     Inputs:     Index - the index selected from _R(IDC_BRUSHTYPE)
02517     Returns:    the brush handle in our 'most popular brushes' list
02518     Purpose:    Retrieves the brushhandle of the Indexth item in the list
02519 ********************************************************************************************/
02520 
02521 BrushHandle FreeHandInfoBarOp::GetBrushHandleFromControlIndex(BrushHandle Index)
02522 {
02523     BrushHandle RetVal = BrushHandle_NoBrush;
02524     if (m_pBrushList != NULL)
02525     {
02526         size_t i = (size_t)Index; // No, I don't know why it's declared to take a BrushHandle - bizarre - amb
02527         if (i<m_pBrushList->size())
02528         {
02529             BrushList::const_iterator iter = m_pBrushList->begin();
02530             for (size_t n=0; n<i; n++) iter++;
02531             return *iter;
02532         }
02533     }
02534     return RetVal;
02535 }
02536 
02537 
02538 /********************************************************************************************
02539 
02540 >   INT32 FreeHandInfoBarOp::GetControlIndexFromBrushHandle(BrushHandle Handle)
02541 
02542     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02543     Created:    23/3/2000
02544     Inputs:     Handle - the brush handle that we want to locate
02545     Returns:    the position of Handle within our brush list, or - 1 if its not there
02546     Purpose:    Retrieves the list position of the handle
02547 ********************************************************************************************/
02548 
02549 INT32 FreeHandInfoBarOp::GetControlIndexFromBrushHandle(BrushHandle Handle)
02550 {
02551     INT32 Retval = -1;
02552     if (m_pBrushList != NULL)
02553     {
02554         INT32 Counter = 0;
02555         BrushList::const_iterator iter;
02556         for (iter = m_pBrushList->begin(); iter != m_pBrushList->end(); iter++)
02557         {
02558             if (*iter == Handle)
02559             {
02560                 Retval = Counter;
02561                 break;
02562             }
02563             Counter++;
02564         }
02565     }
02566     return Retval;
02567 }
02568 
02569 /********************************************************************************************
02570 
02571 >   void FreeHandInfoBarOp::SetHeadOfList(BrushHandle Handle)
02572 
02573     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02574     Created:    23/3/2000
02575     Inputs:     handle - the handle to set at the head of the list
02576     Returns:    -
02577     Purpose:    Sets the given handle to the head of the 'most popular brush' list, also
02578                 goes through the rest of the list and removes other instances of it, so
02579                 as not to duplicate.
02580 ********************************************************************************************/
02581 
02582 void FreeHandInfoBarOp::SetHeadOfList(BrushHandle Handle)
02583 {
02584     if (Handle == BrushHandle_NoBrush)
02585     {
02586         ERROR3("Attempting to set BrushHandle_NoBrush to head of list in FreeHandInfoBarOp::SetHeadOfList");
02587         return;
02588     }
02589     
02590     if (m_pBrushList == NULL)
02591     {
02592         ERROR3("Brush list is NULL in FreeHandInfoBarOp::SetHeadOfList");
02593         return;
02594     }
02595     
02596     // go through the list replacing existing instances of Handle
02597     m_pBrushList->remove(Handle);
02598     // set Handle to the head of the list
02599     m_pBrushList->push_front(Handle);
02600     
02601 }
02602 
02603 
02604 
02605 /********************************************************************************************
02606 
02607 >   void FreeHandInfoBarOp::SetDefaultLineInCombo()
02608 
02609     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02610     Created:    23/3/2000
02611     Inputs:     -
02612     Returns:    -
02613     Purpose:    Sets the bitmap showing in the brush combo to be that of the default stroke
02614                 !!! Note - not actually working at the moment
02615 ********************************************************************************************/
02616 
02617 void FreeHandInfoBarOp::SetDefaultStrokeInCombo()
02618 {
02619 //#ifdef BUILDNEWBRUSHES
02620 //  SetCustomComboGadgetValue(_R(IDC_BRUSHTYPE), NULL, 0, 1);
02621     m_bgddBrushType.SetSelected(0);
02622 //#endif
02623 }
02624 
02625 /********************************************************************************************
02626 
02627 >   void FreeHandInfoBarOp::SetToolActiveState(BOOL IsToolActive)
02628 
02629     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02630     Created:    31/8/94
02631     Inputs:     IsToolActive - TRUE if the tool is becoming active, FALSE if it not
02632     Purpose:    Allows the info bar to know if it is valid or not
02633 
02634 ********************************************************************************************/
02635 
02636 void FreeHandInfoBarOp::SetToolActiveState(BOOL IsToolActive)
02637 {
02638     // Set the control state
02639     ControlsExist = IsToolActive;
02640 }
02641 
02642 
02643 
02644 /********************************************************************************************
02645 
02646 >   void FreeHandInfoBarOp::SetRetroState(BOOL CanRetroFit)
02647 
02648     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02649     Created:    30/8/94
02650     Inputs:     CanRetroFit - TRUE if we can currently retro fit the path, FALSE if not
02651     Purpose:    Sets the Flag CanRetroFit and gets the infobar to redraw the static
02652                 text item that says this.
02653 
02654 ********************************************************************************************/
02655 
02656 void FreeHandInfoBarOp::SetRetroState(BOOL CanFit)
02657 {
02658     // Set the Retro field to be empty by default
02659     CanRetroFit = CanFit;
02660 
02661     // Set the string in the info bar now
02662     SetRetroString();
02663 }
02664 
02665 
02666 /********************************************************************************************
02667 
02668 >   void FreeHandInfoBarOp::SetRetroString()
02669 
02670     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02671     Created:    30/8/94
02672     Purpose:    Sets the static text item in the freehand info bar to say either 'Retro' or
02673                 nothing, depending on the state of the flag CanRetroFit.
02674     SeeAlso:    FreeHandInfoBarOp::SetRetroState
02675 
02676 ********************************************************************************************/
02677 
02678 void FreeHandInfoBarOp::SetRetroString()
02679 {
02680     // go see if there is an info bar to use
02681     if (WindowID!=NULL)
02682     {
02683         if (CanRetroFit)
02684         {
02685             // Make the word Retro appear
02686             String_64 RetroWord;
02687             if (RetroWord.Load(_R(IDS_FHANDRETROTEXT)))
02688             {
02689                 // Set the contents of the field to indicate retro is possible
02690                 SetStringGadgetValue(_R(IDC_FREEHANDRETRO), RetroWord);
02691             }
02692         }
02693         else
02694         {
02695             // make the word retro not appear
02696             String_8 RetroWord(_T(""));
02697             SetStringGadgetValue(_R(IDC_FREEHANDRETRO), RetroWord);
02698         }
02699     }
02700 }
02701 
02702 
02703 
02704 /********************************************************************************************
02705 
02706 >   virtual void FreeHandInfoBarOp::UpdateState()
02707 
02708     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02709     Created:    21/1/97
02710 
02711     Purpose:    Sets the state of button on the bar to keep them up to date
02712 
02713 ********************************************************************************************/
02714 
02715 void FreeHandInfoBarOp::UpdateState()
02716 {
02717     // Don't try to set our controls when they're not there!
02718     if (!ControlsExist)
02719         return;
02720 
02721     // see if we're allowed to launch the brush dialog
02722     OpState State = CBrushEditDlg::GetState(NULL, NULL);
02723 //#ifdef BUILDNEWBRUSHES
02724     if (State.Greyed == FALSE) // && !BrushGadget.IsDialogOpen())
02725         EnableGadget(_R(IDC_EDITBRUSH), TRUE);
02726     else
02727         EnableGadget(_R(IDC_EDITBRUSH), FALSE);
02728 //#endif
02729     SelRange* pSel = GetApplication()->FindSelection();
02730     if (pSel != NULL)
02731     {
02732 //#ifdef BUILDNEWBRUSHES
02733         if (pSel->FindFirst() == NULL)
02734             EnableGadget(_R(IDC_CREATEBRUSH), FALSE);
02735         else
02736             EnableGadget(_R(IDC_CREATEBRUSH), TRUE);
02737 //#endif
02738     }
02739 
02740 // WEBSTER - markn 25/4/97
02741 // No pen stuff required in Webster
02742 // Taken out by vector stroking code Neville 2/10/97
02743 #ifdef VECTOR_STROKING
02744     // Set the state of the pressure button according to the Op's state.
02745     // Why buttons on infobars can't dynamically auto-connect to their ops is beyond me
02746     OpDescriptor *pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_TOGGLEPRESSURE);
02747     if (pOpDesc != NULL)
02748     {
02749         String_256 Why;
02750         OpState State = pOpDesc->GetOpsState(&Why);
02751         
02752         // stop this damn thing from falling over when there is no infobar ....
02753         
02754         CWindowID hGadget = DialogManager::GetGadget(GetReadWriteWindowID (), _R(IDC_FREEHANDPRESSURE));
02755         
02756         if (hGadget)
02757         {
02758             SetBoolGadgetSelected(_R(IDC_FREEHANDPRESSURE), (State.Ticked) ? 1 : 0);
02759             EnableGadget(_R(IDC_FREEHANDPRESSURE), (State.Greyed) ? 0 : 1);
02760         }
02761     }   
02762 #endif // VECTOR_STROKING
02763 
02764 
02765 
02766 }
02767 
02768 

Generated on Sat Nov 10 03:47:39 2007 for Camelot by  doxygen 1.4.4