ccolbar.cpp

Go to the documentation of this file.
00001 // $Id: ccolbar.cpp 1528 2006-07-25 13:43:14Z gerry $
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 // CColBar.cpp - implementation of the CColourBar class
00099 
00100 /*
00101 */
00102 
00103 
00104     /*  IMPORTANT NOTE!
00105      *  ===============
00106      *  
00107      *  When working on the Colour Bar, it is VITAL that you remember that it
00108      *  differs from much of Camelot in that it works exclusively on the
00109      *  SelectedDocument (rather than CurrentDocument).
00110      *  Thus, you need to be careful to ensure that Current == Selected if you
00111      *  add any subroutine calls, or else you may shaft everything.
00112      */
00113 
00114 
00115 
00116 #include "camtypes.h"
00117 
00118 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00120 #include "camelot.h"
00121 #include "ccolbar.h"
00122 #include "colcontx.h"
00123 #include "coldlog.h"
00124 #include "colmsg.h"
00125 #include "colormgr.h"
00126 #include "colourix.h"
00127 #include "colpick.h"
00128 #include "comattrmsg.h"
00129 //#include "cursor.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00130 //#include "ctrlhelp.h"
00131 #include "devcolor.h"
00132 //#include "doccolor.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00133 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00134 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00135 #include "dragmgr.h"
00136 //#include "galres.h"           // For drag cursors
00137 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00138 //#include "jason.h"
00139 #include "keypress.h"
00140 #include "lineattr.h"
00141 #include "linwthop.h"
00142 #include "camframe.h"
00143 #include "opgrad.h"
00144 #include "palman.h"
00145 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00146 //#include "resource.h"     // For push tool cursor
00147 #include "sgcolour.h"       // For AutoScroll preference
00148 #include "statline.h"
00149 #include "cartprov.h"
00150 
00151 // define this to disable use of DragManagerOp to drag colours
00152 //#define DISABLE_COLOUR_DRAGS
00153 
00154 // --------- ****
00155 // DocColours (doccolor.h) currently provide a special debugging form of MakeRef...
00156 // that trace usage of indexedcolours back to the file/line where they were first
00157 // referenced. However, the colourbar creates many temp. ref.s during redraws,
00158 // so we disable this debugging stuff for this file. This is fairly safe, as we
00159 // are reasonably sure that the colour bar treats IndexedColours with proper respect.
00160 #undef MakeRefToIndexedColour
00161 // ---------
00162 
00163 
00164 // Default preference styles for the colour bar (size of strip cells and scrollbar)
00165 // Note that the Create function reads the preference and clips it to 0..MAXDEFAULTSIZES range
00166 typedef struct
00167 {
00168     INT32 Cell;
00169     INT32 Scrollbar;
00170 } ColBarDefaultSizeInfo;
00171 
00172 const INT32 MAXDEFAULTSIZES = 4;
00173 ColBarDefaultSizeInfo ColBarDefaultSize[MAXDEFAULTSIZES] = 
00174 {
00175     {12, 0},    // Small (no scroll bar)
00176     {16, 0},    // Medium (no scroll bar)
00177     {16, 9},    // Medium
00178     {24, 11}    // Large
00179 };
00180 
00181 
00182 /********************************************************************************************
00183 
00184     Preference:     ColourBarMode
00185     Section:        Displays
00186     Range:          0..3
00187     Purpose:        Specifies the 'size' at which the colour bar is displayed, with
00188                     values of:
00189 
00190                     MonoOn
00191                         0   Small
00192                         1   Medium, no scrollbar
00193                         2   Medium with scrollbar (default)
00194                         3   Large
00195                     MonoOff
00196 
00197     Notes:          Normal preference, available from the options dialogue.
00198     SeeAlso:        ColourEditDlg
00199 
00200 ********************************************************************************************/
00201 
00202 static INT32 DefaultSizeIndex = 2;  // User preference 'ColourBarMode'- indexes the above array
00203 
00204 
00205 /********************************************************************************************
00206 
00207     Preference:     ColourCellsDivided
00208     Section:        Displays
00209     Range:          0 (off) or 1 (on)
00210     Purpose:        If set to 0, colour cells in the colour line will butt up against each
00211                     other. If set to 1, a single pixel grey line will be used to divide the
00212                     cells, to make them easier to distinguish.
00213 
00214 ********************************************************************************************/
00215 
00216 static INT32 ColourCellsDivided = 0;
00217 
00218 
00219 
00220 // Redraw Constants
00221 const INT32 SCROLLBUTTON_LEFT  = 0; // Scroll button identifiers
00222 const INT32 SCROLLBUTTON_RIGHT = 1;
00223 
00224 const INT32 CX_BORDER  = 2;         // Number of pixels of blank space around the edge
00225 const INT32 CY_BORDER  = 0;         // (On top of the default 1 pixel border)
00226 
00227 const INT32 InterControlGap = 2;        // The horizontal gap between the bar's 'controls'
00228 const INT32 ButtonWidth   = 11;     // Width of the scrollbar left/right buttons
00229 
00230 // The following variables are calculated and filled in by SetSizes(), but
00231 // I've put some reasonable defaults in. Note that on construction, CellSize
00232 // and ScrollHeight are passed to SetSizes in order to calculate the others.
00233 
00234 static INT32 BarHeight    = 25;     // Total height of the bar window in pixels
00235 static INT32 CellSize         = 16;     // Each Colour Cell is NxN pixels in size - preference
00236 static INT32 ScrollHeight     = 9;      // The mini scrollbar height in pixels
00237 
00238                                     // The No-Colour 'cell' is a normal cell size
00239 #define NoColourSize (CellSize)
00240 
00241                                     // Width and height of the edit button
00242 #define EditButtonSizeX (CellSize)
00243 #define EditButtonSizeY (CellSize)
00244 
00245 
00246 // Click values - this is; nothing, a colour index (0..?), or a scroll bar/arrow
00247 const INT32 CLICKED_NOTHING      = 10000;   // Nothing
00248 const INT32 CLICKED_INDICATORS   = 10001;   // Over the current colour indicators
00249 const INT32 CLICKED_LEFTSCROLL   = 10002;   // Over the left scroll arrow
00250 const INT32 CLICKED_RIGHTSCROLL  = 10003;   // Over the right scroll arrow
00251 const INT32 CLICKED_SCROLLBAR        = 10004;   // Over the scroll sausage
00252 const INT32 CLICKED_SCROLLBARLEFT    = 10005;   // Over the left end of the scrollbar
00253 const INT32 CLICKED_SCROLLBARRIGHT = 10006; // Over the right end of the scrollbar
00254 const INT32 CLICKED_SCROLLSTRIP  = 10007;   // Over the strip, with push modifier key
00255 const INT32 CLICKED_NOCOLOURCELL     = 10008;   // Over the 'No Colour' cell
00256 const INT32 CLICKED_EDITBUTTON   = 10009;   // Over the 'edit colour' button
00257 const INT32 CLICKED_NEWBUTTON        = 10010;   // Over the 'new colour' button
00258 
00259 
00260 // Cell values for special cell 'indices' (the no-colour cell, and no-cell-at-all-mate)
00261 const INT32 CELLINDEX_NOCOLOURCELL  = -1;
00262 const INT32 CELLINDEX_NOCELL            = -2;
00263 
00264 
00265 // Static member variables
00266 //ListComparator CColourBar::SortFunction = NULL;       // We have no sort mode by default
00267 CColourBar *CColourBar::TheColourBar = NULL;        // There is no bar currently available
00268 BOOL CColourBar::BarIsVisible = TRUE;               // Bars will default to being visible
00269 
00270 
00271 IMPLEMENT_DYNAMIC_CLASS(CColourBar, wxWindow)
00272 CC_IMPLEMENT_DYNAMIC(EditButtonDragTarget, OilDragTarget)
00273 CC_IMPLEMENT_DYNAMIC(ColourLineDragTarget, OilDragTarget)
00274 
00275 // Declare smart memory handling in Debug builds
00276 #define new CAM_DEBUG_NEW
00277 
00278 
00279 /********************************************************************************************
00280 
00281 >   inline Document *SetCurrentDoc(void)
00282 
00283     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    28/7/94
00285     Inputs:     -
00286     Outputs:    -
00287     Returns:    The old Current Document
00288 
00289     Purpose:    The ColourBar works exclusively on the SELECTED Doc.
00290                 Thus, on entry to any of its routines which call routines
00291                 outside this file (ccolbar.cpp), it must ensure that CurrentDoc
00292                 is equal to SelectedDoc.
00293                 This local macro inline does this, and returns the old setting of
00294                 CurrentDoc so that the caller can restore the previous CurrentDoc
00295                 on exit.
00296 
00297     Scope:      private (to winoil\ccolbar.cpp)
00298     SeeAlso:    RestoreCurrentDoc
00299 
00300 ********************************************************************************************/
00301 
00302 inline Document *SetCurrentDoc(void)
00303 {
00304     Document *OldCurrentDoc = Document::GetCurrent();
00305     Document *NewCurrentDoc = Document::GetSelected();
00306 
00307     if (NewCurrentDoc != NULL && NewCurrentDoc != OldCurrentDoc)
00308         NewCurrentDoc->SetCurrent();
00309 
00310     return(OldCurrentDoc);
00311 }
00312 
00313 
00314 
00315 /********************************************************************************************
00316 
00317 >   inline void RestoreCurrentDoc(Document *OldCurrentDoc)
00318 
00319     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00320     Created:    28/7/94
00321     Inputs:     The old current document to restore
00322     Outputs:    -
00323     Returns:    -
00324 
00325     Purpose:    The ColourBar works exclusively on the SELECTED Doc.
00326                 After calling SetCurrentDoc on entry to a routine, you should call
00327                 RestoreCurrentDoc on exit to restore the old current document./
00328 
00329     Scope:      private (to winoil\ccolbar.cpp)
00330     SeeAlso:    SetCurrentDoc
00331 
00332 ********************************************************************************************/
00333 
00334 inline void RestoreCurrentDoc(Document *OldCurrentDoc)
00335 {
00336     if (OldCurrentDoc != NULL)
00337         OldCurrentDoc->SetCurrent();
00338 }
00339 
00340 
00341 /********************************************************************************************
00342 
00343 >   void EditButtonDragTarget::EditButtonDragTarget() 
00344      
00345     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
00346     Created:    12/1/95       
00347     Inputs:     -
00348     Outputs:    -
00349     Returns:    -
00350     Purpose:    
00351     Errors:     -
00352     SeeAlso:    -
00353 
00354 ********************************************************************************************/
00355 EditButtonDragTarget::EditButtonDragTarget(wxWindow* TheWindow, wxRect *ClientArea)
00356     : OilDragTarget(TheWindow, ClientArea)
00357 {
00358 //  TRACEUSER("Gerry", _T("EditButtonDragTarget created")); 
00359 }
00360 
00361 
00362 
00363 /********************************************************************************************
00364 
00365 >   void EditButtonDragTarget::ProcessEvent(DragEventType Event,
00366                         DragInformation *pDragInfo,
00367                         wxPoint *pMousePos, KeyPress* pKeyPress) 
00368      
00369     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
00370     Created:    12/1/95       
00371     Inputs:     -
00372     Outputs:    -
00373     Returns:    -
00374     Purpose:    Event Handler for Edit Drag 
00375     Errors:     -
00376     SeeAlso:    -
00377 
00378 ********************************************************************************************/
00379 
00380 BOOL EditButtonDragTarget::ProcessEvent(DragEventType Event,
00381                         DragInformation *pDragInfo,
00382                         wxPoint *pMousePos, KeyPress* pKeyPress)
00383 {
00384 //  TRACEUSER("Gerry", _T("EditButtonDragTarget::ProcessEvent"));
00385 
00386     // Not a colour drag? That is kindof unexpected, but lets exit before
00387     // we embarrass ourselves
00388 
00389     if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
00390         return(FALSE);
00391 
00392     switch(Event)
00393     {
00394         case DRAGEVENT_COMPLETED:
00395             if (CColourBar::TheColourBar != NULL &&
00396                 CColourBar::TheColourBar->m_pCurrentColourList != NULL)
00397             {
00398                 if (CanDropHere(pDragInfo))
00399                 {
00400                     ColourDragInformation *CDI = (ColourDragInformation *) pDragInfo;
00401                     IndexedColour *Col = NULL;
00402 
00403                     if (CDI->IsLibraryColour())
00404                     {
00405                         // We must copy the library colour into the document, but first check with
00406                         // the user that this is what they intended.
00407                     #ifndef WEBSTER
00408                         // Camelot builds ask the user to check that this is what they want
00409                         if (InformError(_R(IDE_CANTEDITLIBCOLOUR), _R(IDS_COPYLIBCOLOUR), _R(IDS_CANCEL)) == 1)
00410                             Col = CDI->GetColourForDocument(Document::GetSelected());
00411                     #else
00412                         // Webster builds just do it. Simplify the UI for the user
00413                         Col = CDI->GetColourForDocument(Document::GetSelected());
00414                     #endif
00415                     }
00416                     else
00417                         Col = CDI->GetInitiallyDraggedColour();
00418 
00419                     if (Col != NULL)
00420                         CColourBar::TheColourBar->EditAColour(CColourBar::TheColourBar->m_pCurrentColourList, Col);
00421                     return(TRUE);
00422                 }
00423             }
00424             break;
00425 
00426 
00427         case DRAGEVENT_MOUSESTOPPED:
00428         case DRAGEVENT_MOUSEMOVED:
00429         case DRAGEVENT_MOUSEIDLE:
00430             // Return TRUE to claim the mouse while over our target area, so that
00431             // our cursor shape is used
00432             return(TRUE);
00433 
00434         default:
00435             break;
00436     }
00437 
00438     // Allow unknown/unwanted events to pass on to other targets
00439     return(FALSE);
00440 }
00441 
00442 
00443 
00444 /********************************************************************************************
00445 
00446 >   void EditButtonDragTarget::GetCursorID()
00447 
00448     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> (Rewritten, Jason)
00449     Created:    10/1/95 (25/3/96)
00450     Purpose:    Set cursor over this target
00451 
00452 ********************************************************************************************/
00453 
00454 UINT32 EditButtonDragTarget::GetCursorID()
00455 {
00456 //  TRACEUSER("Gerry", _T("EditButtonDragTarget::GetCursorID"));
00457 
00458     DragInformation *pDragInfo = DragManagerOp::GetCurrentDragInfo();
00459     if (CanDropHere(pDragInfo))
00460         return _R(IDC_CANDROP_EDITBUTTON);
00461 
00462     return 0;
00463 }
00464 
00465 
00466 
00467 /********************************************************************************************
00468 
00469 >   virtual BOOL EditButtonDragTarget::GetStatusLineText(String_256 * TheText)
00470 
00471     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> (Rewritten, Jason)
00472     Created:    15/1/95 (25/3/96)
00473     Returns:    Whether String is valid
00474     Purpose:    provide status line text for this target
00475    
00476 ********************************************************************************************/
00477 
00478 BOOL EditButtonDragTarget::GetStatusLineText(String_256 *TheText)
00479 {
00480 //  TRACEUSER("Gerry", _T("EditButtonDragTarget::GetStatusLineText"));
00481 
00482     ERROR2IF(TheText==NULL,FALSE,_T("NULL string in GetStatusLineText()"));
00483 
00484     // Call our helper function to find out if this can be dropped here
00485     DragInformation *pDragInfo = DragManagerOp::GetCurrentDragInfo();
00486     if (CanDropHere(pDragInfo))
00487     {
00488         String_256 DragString(_R(IDS_COLBAR_DRAGDROP));
00489         *TheText = DragString;
00490         return TRUE;
00491     }
00492 
00493     return FALSE;
00494 }
00495 
00496 
00497 
00498 /********************************************************************************************
00499 
00500 >   BOOL EditButtonDragTarget::CanDropHere(DragInformation *pDragInfo)
00501 
00502     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00503     Created:    25/3/96
00504 
00505     Returns:    Whether this is something that can be dropped on the edit button
00506 
00507     Purpose:    Internal helper function
00508    
00509 ********************************************************************************************/
00510 
00511 BOOL EditButtonDragTarget::CanDropHere(DragInformation *pDragInfo)
00512 {
00513 //  TRACEUSER("Gerry", _T("EditButtonDragTarget::CanDropHere"));
00514 
00515     if (Document::GetSelected() == NULL)        // No selected docuement? can't edit anything then
00516         return(FALSE);
00517 
00518     if (pDragInfo != NULL && pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
00519     {
00520         ColourDragInformation *CDInfo = (ColourDragInformation *) pDragInfo;
00521 
00522         // We always allow drops of library colours onto us
00523         if (CDInfo->IsLibraryColour())
00524             return(TRUE);
00525 
00526         // Get the dragged colour and the current colour list
00527         IndexedColour *Col  = CDInfo->GetInitiallyDraggedColour();
00528 
00529         if (Col != NULL)    // NULL means "no colour" or a library colour, which can't be edited
00530         {
00531             ColourList *ColList = NULL;
00532             if (CDInfo->GetParentDoc() != NULL)
00533                 ColList = CDInfo->GetParentDoc()->GetIndexedColours();
00534 
00535             return(ColourEditDlg::CanYouEditThis(ColList, Col));
00536         }
00537     }
00538 
00539     return(FALSE);
00540 }
00541 
00542 
00543 /********************************************************************************************
00544 
00545 >   void ColourLineDragTarget::ColourLineDragTarget() 
00546      
00547     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00548     Created:    20/11/95          
00549     Inputs:     -
00550     Outputs:    -
00551     Returns:    -
00552     Purpose:    
00553     Errors:     -
00554     SeeAlso:    -
00555 
00556 ********************************************************************************************/
00557 ColourLineDragTarget::ColourLineDragTarget(wxWindow* TheWindow, wxRect *ClientArea)
00558     : OilDragTarget(TheWindow, ClientArea)
00559 {
00560 //  TRACEUSER("Gerry", _T("ColourLineDragTarget created"));
00561 }
00562 
00563 
00564 
00565 /********************************************************************************************
00566 
00567 >   void ColourLineDragTarget::ProcessEvent(DragEventType Event,
00568                         DragInformation *pDragInfo,
00569                         wxPoint *pMousePos, KeyPress* pKeyPress) 
00570      
00571     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00572     Created:    20/11/95          
00573 
00574     Purpose:    Event Handler for Edit Drag - see the base class for details
00575 
00576     SeeAlso:    WinoilDragTarget::ProcessEvent
00577 
00578 ********************************************************************************************/
00579 
00580 BOOL ColourLineDragTarget::ProcessEvent(DragEventType Event,
00581                         DragInformation *pDragInfo,
00582                         wxPoint *pMousePos, KeyPress* pKeyPress)
00583 {
00584 //  TRACEUSER("Gerry", _T("ColourLineDragTarget::ProcessEvent"));
00585 
00586     // Not a colour drag? That is kindof unexpected, but lets exit before
00587     // we embarrass ourselves
00588     if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
00589         return(FALSE);
00590 
00591     CColourBar *pColourLine = CColourBar::TheColourBar;
00592 
00593     switch(Event)
00594     {
00595         case DRAGEVENT_COMPLETED:
00596             if (KeyPress::IsConstrainPressed() &&
00597                 pColourLine != NULL && pColourLine->m_pCurrentColourList != NULL)
00598             {
00599                 IndexedColour *Col = ((ColourDragInformation *) pDragInfo)->GetInitiallyDraggedColour();
00600 
00601                 // Check that the colour being dragged is in the current colour list
00602                 if (Col != NULL && pColourLine->m_pCurrentColourList->FindPosition(Col) < 0)
00603                     Col = NULL;
00604 
00605                 // If it's NULL, then it's "no colour", a library colour, or a colour we couldn't
00606                 // find in the current colour line display, so we ignore it
00607                 if (Col != NULL)
00608                 {
00609                     // The Colour 'Col' has been dragged and dropped into the colour line
00610                     // with the 'constrain' key held down. In this case, the user wants
00611                     // to rearrange the colour line, so we detect which colour the pointer
00612                     // is over, and insert 'Col' before/after that colour.
00613 
00614                     BOOL ToLeft = FALSE;
00615                     INT32 CellIndex = pColourLine->WhereIsMouse(*pMousePos, NULL, &ToLeft);
00616 
00617                     if (CellIndex >= 0)
00618                     {
00619                         // The colour was dropped onto a legal colour cell - move it
00620                         ColourList *TheList = pColourLine->m_pCurrentColourList;
00621                         ERROR3IF(TheList == NULL, _T("No current colour list!"));
00622                         
00623                         IndexedColour *Target = (IndexedColour *) TheList->GetUndeletedHead();
00624                         while (CellIndex > 0 && Target)
00625                         {
00626                             Target = (IndexedColour *) TheList->GetUndeletedNext(Target);
00627                             CellIndex--;
00628                         }
00629 
00630                         // Now move the item into the appropriate position
00631                         if (Target != NULL && Target != Col)
00632                         {
00633                             if (ToLeft)
00634                             {
00635                                 if (TheList->GetUndeletedNext(Col) != Target)
00636                                 {
00637                                     TheList->RemoveItem(Col);
00638                                     TheList->InsertBefore(Target, Col);
00639 
00640                                     // And inform the world (colour line, gallery, etc) of the change
00641                                     ColourManager::ColourListHasChanged(TheList);
00642                                 }
00643                             }
00644                             else
00645                             {
00646                                 if (TheList->GetUndeletedNext(Target) != Col)
00647                                 {
00648                                     TheList->RemoveItem(Col);
00649                                     TheList->InsertAfter(Target, Col);
00650 
00651                                     // And inform the world (colour line, gallery, etc) of the change
00652                                     ColourManager::ColourListHasChanged(TheList);
00653                                 }
00654                             }
00655                         }
00656                     }
00657                 }
00658 
00659                 return(TRUE);
00660             }
00661             break;
00662 
00663 
00664         case DRAGEVENT_MOUSESTOPPED:
00665         case DRAGEVENT_MOUSEMOVED:
00666         case DRAGEVENT_MOUSEIDLE:
00667             // Return TRUE to claim the mouse while over our target area, so that
00668             // our cursor shape is used
00669             return(TRUE);
00670 
00671         default:
00672             break;
00673     }
00674 
00675     // Allow unknown/unwanted events to pass on to other targets
00676     return(FALSE);
00677 }
00678 
00679 
00680 
00681 /********************************************************************************************
00682 
00683 >   void ColourLineDragTarget::GetCursorID()
00684 
00685     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00686     Created:    20/11/95
00687     Purpose:    Base Method to set cursor over this target
00688 
00689 
00690 ********************************************************************************************/
00691 
00692 UINT32 ColourLineDragTarget::GetCursorID()
00693 {
00694 //  TRACEUSER("Gerry", _T("ColourLineDragTarget::GetCursorID"));
00695 
00696     DragInformation * pDragInfo = DragManagerOp::GetCurrentDragInfo();
00697     if (pDragInfo != NULL && KeyPress::IsConstrainPressed())
00698     {
00699         if (pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
00700         {
00701             IndexedColour *Col = ((ColourDragInformation *) pDragInfo)->GetInitiallyDraggedColour();
00702 
00703             if (Col != NULL)
00704             {
00705                 if (CColourBar::TheColourBar != NULL)
00706                 {
00707                     BOOL CanDrop = FALSE;
00708 
00709                     // Determine if the mouse cursor should be "insert on left" or
00710                     // insert on right" of the colour under the pointer
00711                     BOOL ToLeft = FALSE;
00712                     wxPoint MousePos = wxGetMousePosition();
00713                     MousePos = CColourBar::TheColourBar->ScreenToClient(MousePos);
00714 
00715                     INT32 CellIndex = CColourBar::TheColourBar->WhereIsMouse(MousePos, NULL, &ToLeft);
00716                     if (CellIndex >= 0)
00717                     {
00718                         // The pointer is over a legal colour cell
00719                         ColourList *TheList = CColourBar::TheColourBar->m_pCurrentColourList;
00720                         ERROR3IF(TheList == NULL, _T("No current colour list!"));
00721                     
00722                         IndexedColour *Target = (IndexedColour *) TheList->GetUndeletedHead();
00723                         while (CellIndex > 0 && Target != NULL)
00724                         {
00725                             Target = (IndexedColour *) TheList->GetUndeletedNext(Target);
00726                             CellIndex--;
00727                         }
00728 
00729                         // Now, check that it is a position in which the colour can be dropped.
00730                         // We disallow any drop which will leave the colour where it was.
00731                         if (Target != NULL && Target != Col)
00732                         {
00733                             if (ToLeft)
00734                                 CanDrop = (TheList->GetUndeletedNext(Col) != Target);
00735                             else
00736                                 CanDrop = (TheList->GetUndeletedNext(Target) != Col);
00737                         }
00738 
00739                         // If we are sure it's OK to drop here, we return the cursor to use
00740                         if (CanDrop)
00741                         {
00742                             if (ToLeft)
00743                                 return _R(IDC_DROPLEFT);
00744 
00745                             return _R(IDC_DROPRIGHT);
00746                         }
00747 
00748                         // else drop out to "no-drop" cursor
00749                     }
00750                 }
00751             }
00752         }
00753     }
00754 
00755     // Ask for "can't drop here" cursor. Really ought to rename this resource ID soon!
00756     return _R(IDC_DRAGGING_COLOUR);
00757 }
00758 
00759 
00760 
00761 /********************************************************************************************
00762 
00763 >   virtual BOOL ColourLineDragTarget::GetStatusLineText(String_256 * TheText)
00764 
00765     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00766     Created:    20/11/95
00767     Returns:    Whether String is valid
00768     Purpose:    provide status line text for this target
00769    
00770 ********************************************************************************************/
00771 
00772 BOOL ColourLineDragTarget::GetStatusLineText(String_256 * TheText)
00773 {
00774 //  TRACEUSER("Gerry", _T("ColourLineDragTarget::GetStatusLineText"));
00775 
00776     ERROR2IF(TheText==NULL,FALSE,_T("NULL string in GetStatusLineText()"));
00777 
00778     DragInformation * pDragInfo = DragManagerOp::GetCurrentDragInfo();
00779 
00780     if (pDragInfo != NULL && CColourBar::TheColourBar != NULL)
00781     {
00782         if (pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
00783         {
00784             if (((ColourDragInformation *) pDragInfo)->GetInitiallyDraggedColour() != NULL)
00785             {
00786                 // If we are sure it's OK to drop here, we return the cursor to use
00787                 String_256 DragString(_R(IDS_COLBAR_REARRANGE));
00788                 *TheText = DragString;
00789                 return TRUE;
00790             }
00791         }
00792     }
00793 
00794     return FALSE;
00795 }
00796 
00797 
00798 
00799 BEGIN_EVENT_TABLE( CColourBar, wxWindow )
00800     EVT_LEFT_DOWN(      CColourBar::OnLButtonDown)
00801     EVT_LEFT_DCLICK(    CColourBar::OnLButtonDblClk)
00802     EVT_LEFT_UP(        CColourBar::OnLButtonUp)
00803     EVT_RIGHT_DOWN(     CColourBar::OnRButtonDown)
00804     EVT_RIGHT_DCLICK(   CColourBar::OnRButtonDblClk)
00805     EVT_RIGHT_UP(       CColourBar::OnRButtonUp)
00806     EVT_MOTION(         CColourBar::OnMouseMove)
00807     EVT_TIMER(      2,  CColourBar::OnTimer)
00808     EVT_PAINT(          CColourBar::OnPaint)
00809     EVT_SIZE(           CColourBar::OnSize)
00810 END_EVENT_TABLE()
00811 
00812 
00813 /********************************************************************************************
00814 
00815 >   CColourBar::CColourBar()
00816 
00817     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00818     Created:    17/6/94
00819     Inputs:     -
00820     Outputs:    -
00821     Returns:    -
00822     Purpose:    CColourBar constructor
00823     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
00824 
00825 ********************************************************************************************/
00826 
00827 CColourBar::CColourBar()
00828 {
00829     m_pCurrentColourList = NULL;
00830 
00831     LeftmostColour = 0;         // Initially, are at left end of the colourstrip
00832 
00833     LastLineCell = CELLINDEX_NOCELL;    // We have not drawn any indicator diamonds anywhere
00834     LastFillCell = CELLINDEX_NOCELL;
00835     LastEndCell  = CELLINDEX_NOCELL;
00836     LastDiamondShape = TRUE;
00837 
00838     IndentedButton = CLICKED_NOTHING;
00839 
00840     m_cxLeftBorder = 1;         // Automatic 1 pixel gap at left end of bar
00841     m_cyTopBorder = 0;
00842     m_cxRightBorder = 0;
00843     m_cyBottomBorder = 0;
00844 
00845     TheColourBar = this;
00846 
00847     MsgHandler = NULL;
00848 
00849     m_DragTimer.SetOwner(this, 2);
00850 
00851     DragInfo.TimerOn = 0;
00852     DragInfo.MouseCaptured = FALSE;
00853 
00854     PushCursor = NULL;
00855 
00856     OldBarHeight = 0;
00857 
00858     // We have no current colour gallery to access the fixed gallery section colours
00859     m_pColourGallery = NULL;
00860 }
00861 
00862 
00863 
00864 /********************************************************************************************
00865 
00866 >   BOOL CColourBar::~CColourBar()
00867 
00868     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00869     Created:    17/6/94
00870     Inputs:     -
00871     Outputs:    -
00872     Returns:    -
00873     Purpose:    Destroys the object, as one might expect.
00874     Notes:      IMPORTANT - After calling the destructor (delete ColourBar) it is
00875                 VITAL that you then call RecalcLayout() for the main frame window in
00876                 which the Colour Bar is appearing (the one you passed in to PB::Create().
00877                 If you don't do this, the bar won't disappear until the next time the main 
00878                 window is resized or a tool is chosen.
00879 
00880                 The ColourBar works exclusively on the SELECTED Doc. Change with care
00881 
00882 ********************************************************************************************/
00883 
00884 CColourBar::~CColourBar()
00885 {
00886     TheColourBar = NULL;    // There is no longer a colour bar around   
00887 
00888     if (MsgHandler != NULL)
00889         delete MsgHandler;  // Kill our message handler
00890 
00891     ReleaseAllClaims();     // Ensure all temp. window claims (mouse/timer) released
00892 
00893     if (PushCursor)
00894         delete PushCursor;
00895 }
00896 
00897 
00898 
00899 /********************************************************************************************
00900 
00901 >   BOOL CColourBar::InitPrefs(void)
00902 
00903     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00904     Created:    22/6/94
00905     Inputs:     -
00906     Outputs:    -
00907     Returns:    TRUE if the initialisation of the Colour bar prefs was successful.
00908     Purpose:    Initialisation of ColourBar preference option(s)
00909     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
00910 
00911 ********************************************************************************************/
00912 
00913 BOOL CColourBar::InitPrefs(void)
00914 {
00915     if (MsgHandler == NULL)
00916         MsgHandler = new ColourBarMsgHandler;
00917 
00918     if (MsgHandler == NULL)
00919         return(FALSE);
00920 
00921     Camelot.DeclareSection(TEXT("Displays"), 8);
00922     Camelot.DeclarePref(TEXT("Displays"), TEXT("ColourBarMode"), &DefaultSizeIndex);
00923     Camelot.DeclarePref(TEXT("Displays"), TEXT("ColourCellsDivided"), &ColourCellsDivided);
00924 
00925     return(TRUE);
00926 }
00927 
00928 
00929 
00930 /********************************************************************************************
00931 
00932 >   BOOL CColourBar::Create(CFrameWnd *ParentWnd,
00933                             DWORD dwstyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,
00934                             UINT32 nID = _R(AFX_IDW_STATUS_BAR));
00935 
00936     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00937     Created:    17/6/94
00938     Inputs:     ParentWnd - The parent frame window (in Camelot, there can be only one)
00939                 dwstyle, nID - you shouldn't have to mess with these (cf CStatusBar)
00940     Outputs:    -
00941     Returns:    TRUE if the initialisation of the Colour bar was successful.
00942     Purpose:    Creates a window and associates it with this CColourBar object. The window
00943                 appears at the bottom of the main frame window, just like the status bar.
00944 
00945     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
00946 
00947 ********************************************************************************************/
00948 
00949 BOOL CColourBar::Create(wxWindow* pParent, UINT32 id)
00950 {
00951     if (!wxWindow::Create(pParent, id, wxDefaultPosition, wxSize(BarHeight, BarHeight), wxNO_BORDER))
00952         return(FALSE);
00953 
00954 #if FALSE
00955     ASSERT_VALID(pParentWnd);   // must have a parent
00956 
00957     // Create a new WndClass- this should be identical to CControlBar's WndClass but
00958     // we also would kindof like double clicks if it isn't too much trouble, Mr MFC
00959     CString WndClassName = AfxRegisterWndClass(CS_DBLCLKS, NULL, //Cursor::Arrow->Handle(),
00960                                     (HBRUSH)(COLOR_BTNFACE + 1));
00961 
00962     // Do we want to show this bar after it's created?
00963     BOOL Show = dwStyle & WS_VISIBLE;
00964 
00965     // Make sure the style flags only has legal flags set (VC6 change)
00966     dwStyle &= CBRS_ALL;
00967 
00968 #if WIN32
00969     // this element of CControlBar does not exist in MFC 2.5 16-bit
00970     m_dwStyle = dwStyle;
00971 #endif
00972 
00973     // create the wxWindow*
00974     wxRect rect;
00975     rect.SetRectEmpty();
00976     if (!CWnd::Create(WndClassName, NULL, dwStyle, rect, pParentWnd, nID))
00977         return(FALSE);
00978         // NOTE: Parent must resize itself for control bar to be resized
00979 
00980     if (Show)
00981         ShowWindow(SW_SHOW);
00982 #endif
00983 
00984     InitPrefs();
00985     SetDisplayMode();
00986 
00987     InvalidateBestSize();
00988 
00989     IndentedButton = CLICKED_NOTHING;
00990 
00991     return(TRUE);
00992 }
00993 
00994 
00995 
00996 /********************************************************************************************
00997 
00998 >   wxSize CColourBar::DoGetBestSize() const
00999 
01000     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01001     Created:    10/03/06
01002     Inputs:     -
01003     Outputs:    -
01004     Returns:    Best size of this window
01005 
01006 ********************************************************************************************/
01007 
01008 wxSize CColourBar::DoGetBestSize() const
01009 {
01010     TRACEUSER("Gerry", _T("CColourBar::DoGetBestSize"));
01011     wxRect AvailableRect = GetParent()->GetClientRect();
01012     AvailableRect.height = BarHeight;
01013     INT32 Height = ((CColourBar*)this)->CalculateNewBarHeight(&AvailableRect);
01014     INT32 Width = GetParent()->GetClientSize().x;
01015 
01016     return(wxSize(Width, Height));
01017 }
01018 
01019 /********************************************************************************************
01020 
01021 >   void CColourBar::SetSizes(INT32 NewCellSize, INT32 NewScrollbarSize)
01022 
01023     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01024     Created:    22/6/94
01025     Inputs:     NewCellSize - The new size in pixels of the square colour cells
01026                 This should be an even number (it is truncated if necessary)
01027 
01028                 NewScrollbarSize - The new height of the scroll bar in pixels
01029 
01030     Outputs:    -
01031     Returns:    -
01032 
01033     Purpose:    Sets the base sizes of the colour strip and colour scroll bar
01034                 in the colour bar window. Other features of the bar are automatically
01035                 resized to fit the new sizing. The bar will be redrawn. If the 
01036                 combined height of the bar elements has now changed, the bar will
01037                 be resized (by calling the parent's RecalcLayout method).
01038 
01039     Notes:      Setting NewScrollBarSize == 0 enters a special mode where the scroll
01040                 sausage is not drawn, and the scroll arrows sit at either end of the
01041                 colour strip. In this size, it is recommended that
01042                 CellSize == ButtonWidth (i.e. about 10 pixels), to make the buttons
01043                 square and therefore not entirely disgusting looking
01044 
01045                 The ColourBar works exclusively on the SELECTED Doc. Change with care
01046 
01047 ********************************************************************************************/
01048 
01049 void CColourBar::SetSizes(INT32 NewCellSize, INT32 NewScrollbarSize)
01050 {
01051     ENSURE (NewCellSize >= 4 && NewCellSize <= 64,
01052         "Silly CellSize passed to CColourBar::SetSizes()");
01053 
01054     ENSURE (NewScrollbarSize == 0 ||
01055             (NewScrollbarSize >= 3 && NewScrollbarSize <= 24),
01056         "Silly ScrollbarSize passed to CColourBar::SetSizes()");
01057 
01058     NewCellSize &= ~1;      // Force Cellsize to be an even value
01059 
01060 //  BOOL ResizeFrame = (NewCellSize + NewScrollbarSize != CellSize + ScrollHeight);
01061 
01062     CellSize = NewCellSize;
01063     ScrollHeight = NewScrollbarSize;
01064 
01065     BarHeight = CellSize + ScrollHeight + (2 * CY_BORDER) +
01066                     m_cyTopBorder + m_cyBottomBorder + 1;
01067 
01068 //  if (ResizeFrame)
01069     {
01070         SetMinSize(wxSize(8, BarHeight));
01071 
01072         InvalidateBestSize();
01073         GetMainFrame()->UpdateFrameManager();
01074     }
01075 }
01076 
01077 
01078 
01079 /********************************************************************************************
01080 
01081 >   static void CColourBar::SetDisplayMode(INT32 NewDisplayMode = -1)
01082 
01083     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    25/10/94
01085 
01086     Inputs:     NewDisplayMode - The mode (0..3) or -1 to re-read the preference value
01087 
01088     Purpose:    Sets the Colour Bar display mode to the new value.
01089                 Current legal mode values are 0..3 (small, med, med+scroll, large)
01090                 Illegal values will cause it to resort to the default mode, medium+scroll (2)
01091                 The default value of -1 is used to mean 'use the preference setting'.
01092                 This allows the prefs dialogue to cause the ColourBar to sit up and
01093                 take notice of changed preference settings.
01094                 The preference setting ColourBarMode will be set to the new value
01095 
01096     Notes:      This static function may be called at any time. If a colour bar is not
01097                 open when the call is made, the new setting will be used for the next
01098                 colour bar created.
01099 
01100 ********************************************************************************************/
01101 
01102 void CColourBar::SetDisplayMode(INT32 NewDisplayMode)
01103 {
01104     if (NewDisplayMode == -1)
01105         NewDisplayMode = DefaultSizeIndex;
01106 
01107     if (NewDisplayMode < 0 || NewDisplayMode >= MAXDEFAULTSIZES)  
01108         NewDisplayMode = 2;
01109 
01110     DefaultSizeIndex = NewDisplayMode;      // Remember this as a preference setting
01111 
01112     if (TheColourBar != NULL)               // If there's a bar, set it to the new size
01113     {
01114         TheColourBar->SetSizes(ColBarDefaultSize[NewDisplayMode].Cell,
01115                                 ColBarDefaultSize[NewDisplayMode].Scrollbar);
01116         TheColourBar->Refresh();            // Force a redraw of the bar to ensure it's up to date
01117     }
01118 }
01119 
01120 
01121 
01122 
01123 /********************************************************************************************
01124 
01125 >   INT32 CColourBar::GetNumberOfColours()
01126 
01127     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01128     Created:    19/3/97
01129     Inputs:     -
01130     Returns:    The number of colours we wish to display on the bar.
01131     Purpose:    Determines the number of colours that we wish to display on the ColourBar.
01132 
01133 ********************************************************************************************/
01134 
01135 INT32 CColourBar::GetNumberOfColours()
01136 {
01137     INT32 total = 0;
01138     
01139     // Get the actually colours in the selected document
01140     INT32 DocColours = 0;
01141 
01142     // If the user has the preference set then include and hence show the document
01143     // colours
01144     if (ColourSGallery::ShowDocumentColours)
01145     {
01146         if (m_pCurrentColourList == NULL)
01147             m_pCurrentColourList = ColourManager::GetColourList();
01148 
01149         if (m_pCurrentColourList != NULL)
01150             DocColours = (INT32) m_pCurrentColourList->GetUndeletedCount();
01151 
01152         total += DocColours;
01153     }
01154 
01155 PORTNOTE("other","Removed ColourSGallery usage")
01156 #if !defined(EXCLUDE_FROM_XARALX)
01157     // try and add in any fixed sections required
01158     m_pColourGallery = ColourSGallery::GetInstance();
01159     if (m_pColourGallery != NULL)
01160     {
01161         // This will create the groups if they're not there yet
01162         m_pColourGallery->MakeSureGroupsHaveBeenCreated();
01163 
01164         // Find the Netscape palette library
01165         SGDisplayLibColGroup * pLibGroup = m_pColourGallery->GetFirstLibGroup();
01166         BOOL Found = FALSE;
01167         while (!Found && pLibGroup)
01168         {
01169             // Add in any items that are flagged as being required
01170             if (pLibGroup->DisplayInColourLine())
01171             {
01172                 // pLibGroup->DeVirtualise();   // This is dangerous as it may change things like current doc!
01173                                                 // Disabled as it causes problems during start up
01174                 total += pLibGroup->CountChildren();
01175             }
01176 
01177             pLibGroup = m_pColourGallery->GetNextLibGroup(pLibGroup);
01178         }
01179     }
01180 #endif
01181     return total;
01182 }
01183 
01184 /********************************************************************************************
01185 
01186 >   static BOOL CColourBar::EnsureLibraryColoursPresent()
01187 
01188     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01189     Created:    19/3/97
01190     Inputs:     -
01191     Returns:    True if worked correctly
01192     Purpose:    Ensures that any colour library sections we require are present.
01193 
01194 ********************************************************************************************/
01195 
01196 BOOL CColourBar::EnsureLibraryColoursPresent()
01197 {
01198 PORTNOTE("other","Removed ColourSGallery usage")
01199 #if !defined(EXCLUDE_FROM_XARALX)
01200     // try and ensure all our required colour gallery sections are present and de-virtilised
01201     ColourSGallery * pColourGallery = ColourSGallery::GetInstance();
01202     if (pColourGallery != NULL)
01203     {
01204         // This will create the groups if they're not there yet
01205         pColourGallery->MakeSureGroupsHaveBeenCreated();
01206 
01207         // Find the Netscape palette library
01208         SGDisplayLibColGroup * pLibGroup = pColourGallery->GetFirstLibGroup();
01209         while (pLibGroup)
01210         {
01211             // Add in any items that are flagged as being required
01212             if (pLibGroup->DisplayInColourLine())
01213             {
01214                 pLibGroup->DeVirtualise();
01215             }
01216 
01217             pLibGroup = pColourGallery->GetNextLibGroup(pLibGroup);
01218         }
01219 
01220         if (TheColourBar != NULL)           // If there's a bar, set it to the new size
01221         {
01222             // Force a redraw of the bar to ensure it's up to date
01223             // This checks that the size is correct
01224             PaletteHasChanged(NULL);
01225             //TheColourBar->Invalidate();       
01226         }
01227     }
01228 #endif
01229     return TRUE;
01230 }
01231 
01232 /********************************************************************************************
01233 
01234 >   BOOL CColourBar::IsColourPickerOverStripRect (wxWindow* colourPicker, wxPoint mousePt)
01235 
01236     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
01237     Created:    22/10/99
01238     Inputs:     colourPicker - The wxWindow* of the claimed colour picker control
01239                 mousePt - the current mouse location that the colour picker is supplying
01240     Returns:    True if mousePt is in StripRect
01241                 False otherwise
01242                 Throws ENSURE error if colourPicker is NOT a colour picker control
01243     Purpose:    This function helps to determin how colour picker controls should
01244                 behave when they are over the colour bar
01245 
01246 ********************************************************************************************/
01247 
01248 BOOL CColourBar::IsColourPickerOverStripRect (wxWindow* colourPicker, wxPoint mousePt)
01249 {
01250     return((colourPicker == this) && StripRect.Inside(mousePt));
01251 
01252 #if FALSE
01253     // firstly, lets check for obvious insanity
01254     String_256 ClassNameStr;  // The control type
01255 
01256     // Find out the class type of the gadget
01257     GetClassName (colourPicker, (TCHAR*) ClassNameStr, 255);
01258 
01259     //BOOL returnVal = FALSE;
01260 
01261     if (ClassNameStr == String_8(TEXT("cc_colPicker")))
01262     {
01263         if (StripRect.PtInRect(mousePt))
01264         {
01265             return (TRUE);
01266         }
01267         else
01268         {
01269             return (FALSE);
01270         }
01271     }
01272 
01273     ENSURE(FALSE, _T("IsColourPickerOverStripRect called for invalid colour picker control"));
01274     return (FALSE);
01275 #endif
01276 }
01277 
01278 /********************************************************************************************
01279 
01280 >   BOOL DoColourPickerColour (wxWindow* colourPicker, wxPoint mousePt, IndexedColour ** pTheCol=NULL)
01281 
01282     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
01283     Created:    22/10/99
01284     Inputs:     colourPicker - The wxWindow* of the claimed colour picker control
01285     Returns:    True if success
01286                 False otherwise
01287                 Throws ENSURE error if colourPicker is NOT a colour picker control
01288     Purpose:    Instruct the colour edit dialog to use that colour on the colour bar (of which
01289                 the colour picker is over).
01290 
01291 ********************************************************************************************/
01292 
01293 BOOL CColourBar::DoColourPickerColour (wxWindow* colourPicker, wxPoint mousePt, IndexedColour **pTheCol/*=NULL*/)
01294 {
01295     if (colourPicker == this)
01296     {
01297         UINT32 ColourCell = WhereIsMouse (mousePt);
01298         static UINT32 lastColourCell = (UINT32)-1;
01299 
01300         if ((((INT32)ColourCell) >= 0)/* && (lastColourCell != ColourCell)*/)       // we are over a valid colour
01301         {
01302             BOOL validColour = FALSE;
01303             
01304             if (m_pCurrentColourList == NULL)       // Ensure the current ColourList pointer is valid
01305             {
01306                 m_pCurrentColourList = ColourManager::GetColourList();
01307             }
01308 
01309             IndexedColour *TheColour = NULL;
01310 
01311             // If the user has the preference set then include and hence show the document
01312             // colours
01313             if (ColourSGallery::ShowDocumentColours)
01314             {
01315                 TheColour = FindColourByIndex(ColourCell);
01316             }
01317 
01318             if (TheColour != NULL)
01319             {
01320                 validColour = TRUE;
01321             }
01322             else
01323             {
01324                 // We didn't find the colour in the document colours section
01325                 // so check any library sections that may be present
01326                 SGDisplayLibColour *pLibColour = NULL;
01327                 DocColour * pTheDocColour = FindLibColourByIndex(ColourCell, &pLibColour);
01328                 TheColour = ColourManager::GenerateNewUnnamedColour (m_pCurrentColourList, pTheDocColour);
01329 
01330                 if (pTheDocColour && pLibColour)
01331                 {
01332                     validColour = TRUE;
01333                 }
01334             }
01335 
01336             if (validColour && pTheCol)
01337                 *pTheCol = TheColour;
01338             
01339             if ((lastColourCell != ColourCell) && validColour)
01340             {
01341                 ColourEditDlg* pColourEditDlg = ColourEditDlg::GetColourEditDlg ();
01342                 ASSERT (pColourEditDlg);
01343 
01344                 pColourEditDlg->SetEditingColour (TheColour);
01345                 lastColourCell = ColourCell;
01346             }
01347             
01348             return (TRUE);
01349         }
01350         else
01351         {
01352             return (TRUE);
01353         }
01354     }
01355 
01356     ENSURE(FALSE, "DoColourPickerColour called for invalid colour picker control");
01357 
01358     return (FALSE);
01359 }
01360 
01361 
01362 /********************************************************************************************
01363 
01364 >   BOOL CColourBar::HasNoScrollBar(INT32 DisplayedColours, INT32 MaxColours,
01365                                     wxRect *pStripRect = NULL)
01366 
01367     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01368     Created:    22/7/94
01369 
01370     Inputs:     DisplayedColours - -1 or the number of colours that can be displayed in
01371                 the bar
01372                 MaxColours - -1 or the number of colours available for display
01373                 (these values will be calculated for you if you pass in -1, but
01374                 if you've already calculated them it's silly to reinvent the wheel)
01375 
01376                 pStripRect - NULL to use the precalculated CColourBar StripRect, or
01377                 a pointer to a wxRect that holds a StripRect. (Used when calculating
01378                 things based on a projected window size rather than the current
01379                 cached window size)
01380 
01381     Returns:    TRUE if there is no need for a scroll bar
01382     Purpose:    Determines if the ColourBar actually need bother with a scrollbar
01383                 (It does not need one if it can display all the available colours)
01384 
01385     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01386 
01387 ********************************************************************************************/
01388 
01389 BOOL CColourBar::HasNoScrollBar(INT32 DisplayedColours, INT32 MaxColours, wxRect *pStripRect)
01390 {
01391     if (BarHeight == 0)             // In small mode, always has arrows
01392         return(FALSE);
01393 
01394     if (pStripRect == NULL)         // By default, use our 'global' strip rectangle
01395         pStripRect = &StripRect;
01396 
01397     if (DisplayedColours < 0)
01398         DisplayedColours = pStripRect->width / CellSize;
01399 
01400     if (MaxColours < 0)
01401     {
01402         MaxColours = GetNumberOfColours();
01403 
01404         /* FIXEDCOLOURS
01405         if (m_pCurrentColourList == NULL)
01406             m_pCurrentColourList = ColourManager::GetColourList();
01407 
01408         if (m_pCurrentColourList == NULL)
01409             return(FALSE);
01410 
01411         MaxColours = (INT32) m_pCurrentColourList->GetUndeletedCount();
01412         */
01413     }
01414 
01415     return(MaxColours <= DisplayedColours);
01416 }
01417 
01418 
01419 
01420 /********************************************************************************************
01421 
01422 >   void CColourBar::CalculateRects(void)
01423 
01424     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01425     Created:    17/6/94
01426     Inputs:     -
01427     Outputs:    The following data members are calculated on exit:
01428                 WindowRect      - The usable client-are of the ColourBar window
01429                 StripRect       - The area in which the colour cells are drawn
01430                 IndicatorRect   - The area the current colour indicator is drawn in
01431                 ScrollBarRect   - The area in which the scrollbar is drawn
01432                 EditButtonRect  - The area in which the Edit Button is drawn
01433                 NewButtonRect   - The area in which the New Button is drawn [DEFUNCT]
01434     
01435     Returns:    -
01436     Purpose:    Calculates various useful rectangular regions to be found within the
01437                 Colour Bar window. Returns the screen rectangles ready for redraw.
01438 
01439     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01440 
01441                 IMPORTANT: If you change the rect calculations, be sure to change the 2
01442                 occurences of a related calculation in CColBar::CalculateNewBarHeight, below
01443 
01444     SeeAlso:    CColourBar::CalculateScrollButtonRects;
01445                 CColourBar::CalculateRectsInternal
01446 
01447 ********************************************************************************************/
01448 
01449 void CColourBar::CalculateRects(void)
01450 {
01451     // Calculate inside of window area
01452     WindowRect = GetClientRect();
01453 
01454     CalculateRectsInternal(&WindowRect,
01455                             &StripRect, &IndicatorRect, &ScrollBarRect,
01456                             &EditButtonRect, &NewButtonRect);
01457 
01458     // Now, calculate the inside rect (the area of the window which lies inside the borders
01459     // which have been drawn by the base class DoPaint() function). The only things that
01460     // should be using this rectangle (rather than the rects calculated above) should be
01461     // the 2 bits in the DoPaint method which fill undrawn areas of the bar with grey.
01462 //  CalcInsideRect(&WindowRect);
01463 }
01464 
01465 
01466 
01467 /********************************************************************************************
01468 
01469 >   void CColourBar::CalculateRectsInternal(wxRect *pWindowRect,
01470                         wxRect *pStripRect, wxRect *pIndicatorRect, wxRect *pScrollBarRect,
01471                         wxRect *pEditButtonRect, wxRect *pNewButtonRect)
01472 
01473     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01474     Created:    17/6/94
01475     Inputs:     pWindowRect     - The usable client-area of the ColourBar window
01476 
01477     Outputs:    pStripRect      - The area in which the colour cells are drawn
01478                 pIndicatorRect  - The area the current colour indicator is drawn in
01479                 pScrollBarRect  - The area in which the scrollbar is drawn
01480                 pEditButtonRect - The area in which the Edit Button is drawn
01481                 pNewButtonRect  - The area in which the New Button is drawn [DEFUNCT]
01482 
01483                 NONE of these inputs/outputs may be NULL!
01484     
01485     Returns:    -
01486     Purpose:    Calculates various useful rectangular regions to be found within the
01487                 Colour Bar window. Returns the screen rectangles ready for redraw.
01488 
01489                 Identical to the CalculateRects function, but you pass in the rects for
01490                 it to plonk the results into. WindowRect is untouched. All other rects
01491                 are updated from WindowRect. The contents on entry of all but WindowRect
01492                 are unimportant.
01493 
01494     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01495 
01496                 USE CalculateRects UNLESS ABSOLUTELY NECESSARY
01497 
01498     SeeAlso:    CColourBar::CalculateRects
01499 
01500 ********************************************************************************************/
01501 
01502 void CColourBar::CalculateRectsInternal(wxRect *pWindowRect,
01503                         wxRect *pStripRect, wxRect *pIndicatorRect, wxRect *pScrollBarRect,
01504                         wxRect *pEditButtonRect, wxRect *pNewButtonRect)
01505 {
01506     ERROR3IF(pWindowRect == NULL || pStripRect == NULL || pIndicatorRect == NULL ||
01507              pScrollBarRect == NULL || pEditButtonRect == NULL || pNewButtonRect == NULL,
01508                 _T("NULL parameter passed to CColourBar::CalculateRectsInternal"));
01509     
01510     wxRect TempRect(*pWindowRect);
01511 
01512 //  CalcInsideRect(&TempRect);
01513     TempRect.Inflate(-CX_BORDER, -CY_BORDER);
01514 
01515     // Calculate the current-colour indicator rectangle, and ensure it's a square
01516     *pIndicatorRect = TempRect;
01517     pIndicatorRect->width = pIndicatorRect->height;
01518 
01519     // Subtract the indicator width from the available space. We now always make the indicator
01520     // 'BarHeight' pixels wide: This means that there is a gap to its right when there is
01521     // no scrollbar (because the square indicator shrinks), but this means the colourstrip
01522     // width is not dependant on whether or not it has a scrollbar (which in turn is dependant
01523     // upon the colourstrip width - a nasty circular reference!)
01524     TempRect.x += BarHeight + InterControlGap;
01525     TempRect.width -= BarHeight + InterControlGap;
01526 
01527     // Calculate the new and edit button positions
01528     *pNewButtonRect = TempRect;
01529     pNewButtonRect->width = EditButtonSizeX;
01530     pNewButtonRect->height = EditButtonSizeY;
01531 
01532     *pEditButtonRect = *pNewButtonRect;
01533     // The new button isn't current present so make the edit button the same
01534 //  pEditButtonRect->x += EditButtonSizeX + InterControlGap;
01535 
01536     // Subtract new, edit, and no-colour buttons from the TempRect
01537     TempRect.x += NoColourSize + EditButtonSizeX + (InterControlGap * 2);
01538     TempRect.width -= NoColourSize + EditButtonSizeX + (InterControlGap * 2);
01539 
01540     // Calculate scrollbar and colour strip rectangles in the remaining space
01541     *pStripRect = TempRect;
01542 
01543     // This may be called fairly early on so if no colour list then get out immediately
01544     if (m_pCurrentColourList == NULL)       // No colours, so give safe default and exit
01545     {
01546         *pScrollBarRect = TempRect;
01547         return;
01548     }
01549 
01550     // INT32 MaxColours = (INT32) m_pCurrentColourList->GetUndeletedCount(); FIXED COLOURS
01551     INT32 MaxColours = GetNumberOfColours();
01552     // Removed 4/8/97 Neville as causes a redraw problem when switching from document with two colours
01553     // in to one with none in.
01554 /*  if (MaxColours <= 0)
01555     {
01556         pScrollBarRect->CopyRect(&TempRect);
01557         return;
01558     } */
01559 
01560     INT32 Width = pStripRect->width;
01561 
01562     // Normally, the buttons are flush with the ends of the colourstrip, but in
01563     // this mode, they sit outside the ends of the colourstrip instead
01564     if (ScrollHeight == 0)
01565         Width -= 2 * (ButtonWidth + 1);
01566 
01567     if (MaxColours * CellSize < Width)
01568         pStripRect->width = MaxColours * CellSize;
01569     else
01570         pStripRect->width = Width - (Width % CellSize);
01571 
01572     if (ScrollHeight == 0)
01573     {
01574         // We want no scroll bar, just arrows on either end of the colourstrip
01575         // As the arrows are drawn on either end (outside) of the scroll rect,
01576         // we must now move both rects one scroll button width to the right
01577 
01578         pStripRect->Offset(ButtonWidth + 1, 0);
01579         *pScrollBarRect = *pStripRect;
01580 
01581         // And then make the scroll bar rect slightly bigger so there is a small
01582         // gap between the buttons and the strip
01583         pScrollBarRect->Inflate(2, 0);
01584     }
01585     else
01586     {
01587         // If there is no need for a scrollbar, StripRect expands to fill the space
01588         if (HasNoScrollBar(-1, MaxColours))
01589         {
01590             // For now we will force the strip rect to only be CellSize high
01591             // because the window resizing code isn't working properly
01592             pStripRect->height = CellSize;
01593             return;
01594         }
01595 
01596         *pScrollBarRect = *pStripRect;
01597         // ScrollBarRect is only ScrollHeight pixels high.
01598         // We also subtract off the space for the scroll arrows
01599         pScrollBarRect->y = pScrollBarRect->y + pScrollBarRect->height - ScrollHeight;
01600         pScrollBarRect->height = ScrollHeight;
01601         pScrollBarRect->Inflate(-(ButtonWidth-1), 0);
01602 
01603         // Colour strip is immediately above scroll rect: same width, CellSize height
01604         pStripRect->height = CellSize;
01605         pStripRect->y = pScrollBarRect->y - CellSize;
01606     }
01607 }
01608 
01609 
01610 
01611 /********************************************************************************************
01612 
01613 >   BOOL CColourBar::CalculateSausageRect(wxRect *Result)
01614 
01615     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01616     Created:    27/6/94
01617     Inputs:     -
01618     Outputs:    If successful, Result contains the sausage rect
01619     Returns:    TRUE if it succeeds, FALSE if the scrollbar/sausage is non existent
01620     Purpose:    Calculates the scroll sausage area within the scroll bar rectangle
01621     Notes:      You must call CalculateRects and cache the value of TotalNumColours
01622                 prior to calling this function - see DoPaint for everything that needs
01623                 to be done.
01624                 The ColourBar works exclusively on the SELECTED Doc. Change with care
01625 
01626 ********************************************************************************************/
01627 
01628 BOOL CColourBar::CalculateSausageRect(wxRect *Result)
01629 {
01630     // If the scroll bar hasn't got enough room to exist, it does not appear
01631     if (ScrollBarRect.width < 5)
01632         return(FALSE);
01633 
01634     // If we are in Med/Large mode and have no scrollbar, it doesn't appear
01635     if (HasNoScrollBar(-1, -1))
01636         return(FALSE);
01637 
01638     *Result = ScrollBarRect;
01639 
01640     UINT32 NumDisplayedColours = StripRect.width / CellSize;
01641     Result->Inflate(-1, -1);
01642 
01643     if (NumDisplayedColours < TotalNumColours)
01644     {
01645         UINT32 BarWidth = Result->width;
01646         // Calculate the midpoint and width of the scroll 'sausage'
01647         //   MidPointColour = LeftmostColour + NumDisplayedColours/2;
01648         //   Mid = (MidPointColour / TotalColours) * BarWidth;
01649         // We calculate everything at *2 magnification to avoid rounding errors
01650         UINT32 Mid = (((LeftmostColour * 2) + NumDisplayedColours) * BarWidth) /
01651                                 (TotalNumColours * 2);
01652 
01653         BarWidth = (BarWidth * NumDisplayedColours) / TotalNumColours;
01654 
01655         if (BarWidth < (UINT32)4)
01656             BarWidth = 4;           // Try to keep some sausage visible!
01657 
01658         Result->x += Mid - (BarWidth / 2);
01659         Result->width = BarWidth;
01660 
01661         // Clip the values in case of rounding errors causing a pixel or 2 error
01662         if (Result->x <= ScrollBarRect.x)
01663             Result->x = ScrollBarRect.x + 1;
01664 
01665         // Clip rounding error, also make sure that errors don't make bar 1 pixel
01666         // short when at the very rightmost scroll position (this douubles up the
01667         // black lines around scroll sausage/arrow and looks bad)
01668         if (Result->GetRight() >= ScrollBarRect.GetRight() ||
01669             TotalNumColours-NumDisplayedColours <= LeftmostColour)
01670             Result->SetRight(ScrollBarRect.GetRight() - 1);
01671     }
01672 
01673     return(TRUE);
01674 }
01675 
01676 
01677 
01678 /********************************************************************************************
01679 
01680 >   void CColourBar::CalculateNoColourCellRect(wxRect *Rect)
01681 
01682     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01683     Created:    15/7/94
01684     Inputs:     -
01685     Outputs:    Rect - will be filled in with the caclculated rect
01686     Returns:    -
01687     Purpose:    Calculates the 'NoColour' colour cell position, just to the left of
01688                 the ColourStrip
01689     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01690 
01691 ********************************************************************************************/
01692 
01693 void CColourBar::CalculateNoColourCellRect(wxRect *Rect)
01694 {
01695     *Rect = StripRect;
01696     if (ScrollHeight == 0)              // If in 'small' mode, correct for scroll arrow
01697         Rect->x -= ButtonWidth;
01698 //  else if (!HasNoScrollBar(-1, -1))   // otherwise if there IS a scroll bar
01699 //      Rect->Offset(0,1);              // then move the rectangle down a pixel
01700 
01701     Rect->x -= NoColourSize + InterControlGap;
01702     Rect->width = NoColourSize;
01703     Rect->height = NoColourSize;
01704 }
01705 
01706 
01707 
01708 /********************************************************************************************
01709 
01710 >   static void Paint3dPlinth(wxDC* pDC, wxRect *rect, BOOL Indent)
01711 
01712     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01713     Created:    17/6/94
01714     Inputs:     pDC - The DC to draw into
01715                 rect - The rectangle to draw around the OUTSIDE of with a plinth 
01716                 PlinthOut - FALSE to indent, TRUE to pop-out the plinth.
01717     Outputs:    -
01718     Returns:    -
01719     Purpose:    Draws a rectangular 3d plinth around the edge of the given rectangle
01720 
01721 ********************************************************************************************/
01722 
01723 static void Paint3dPlinth(wxDC* pDC, wxRect *rect, BOOL PlinthOut)
01724 {
01725     wxPen Black(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW));
01726     wxPen White(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT));
01727 
01728     wxPoint Points[3];
01729     pDC->SetPen((PlinthOut) ? White : Black);
01730     Points[0] = wxPoint(rect->x, rect->GetBottom());
01731     Points[1] = wxPoint(rect->x, rect->y);
01732     Points[2] = wxPoint(rect->x + rect->width, rect->y);
01733     pDC->DrawLines(3, Points);
01734 
01735     pDC->SetPen((PlinthOut) ? Black : White);
01736     Points[0] = wxPoint(rect->GetRight(), rect->y + 1); // Ensure corner pixel is correct
01737     Points[1] = wxPoint(rect->GetRight(), rect->GetBottom());
01738     Points[2] = wxPoint(rect->x, rect->GetBottom());
01739     pDC->DrawLines(3, Points);
01740 
01741     pDC->SetPen(wxNullPen);
01742 }
01743 
01744 
01745 
01746 /********************************************************************************************
01747 
01748 >   void CColourBar::PaintEditOrNewButton(wxDC *pDC, BOOL Normal, BOOL IsEditButton)
01749 
01750     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01751     Created:    14/9/94
01752     Inputs:     -
01753     Outputs:    pDC - The DC into which to draw
01754                 Normal - FALSE for an indented button, TRUE for normal (raised)
01755                 IsEditButton - TRUE to draw the Edit button, FALSE to draw the New button
01756     Returns:    -
01757     Purpose:    Draws the colour bar "edit colour" or "new colour" button
01758     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01759 
01760 ********************************************************************************************/
01761 
01762 void CColourBar::PaintEditOrNewButton(wxDC *pDC, BOOL Normal, BOOL IsEditButton)
01763 {
01764     wxRect TheRect;                                 // Determine the rect to draw
01765     if (IsEditButton)
01766         TheRect = EditButtonRect;
01767     else
01768 #if FALSE
01769         TheRect = NewButtonRect;
01770 #else
01771     {
01772         ERROR3(_T("Attempt to paint 'new colour' button, which no longer exists!"));
01773         return;
01774     }
01775 #endif
01776 
01777     wxPen FramePen(wxColour(0,0,0));
01778     pDC->SetPen(FramePen);
01779     wxBrush TransBrush(wxColour(0,0,0), wxTRANSPARENT);
01780     pDC->SetBrush(TransBrush);
01781     pDC->DrawRectangle(TheRect);
01782     pDC->SetPen(wxNullPen);
01783     pDC->SetBrush(wxNullBrush);
01784 
01785     TheRect.Inflate(-1, -1);                    // ...with a plinth inside it
01786     Paint3dPlinth(pDC, &TheRect, Normal);
01787 
01788     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
01789     pDC->SetPen(TransPen);
01790     wxBrush GreyBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));   // Fill with default colour
01791     TheRect.Inflate(-1, -1);
01792     pDC->SetBrush(GreyBrush);
01793     pDC->DrawRectangle(TheRect);
01794     pDC->SetBrush(wxNullBrush);
01795     pDC->SetPen(wxNullPen);
01796 
01797     ResourceID bitmap = 0;
01798 
01799     INT32 BmpSize = (CellSize > 15) ? 12 : 8;           // size of glyph bitmaps (8x8 and 12x12)
01800         
01801     if (IsEditButton)                               // Load appropriate glyph bitmap
01802     {
01803         if (CellSize > 15)
01804             bitmap=_R(IDB_LEDITCOL);        // 12x12 Edit glyph
01805         else
01806             bitmap=_R(IDB_EDITCOL);         // 8x8 Edit glyph
01807     }
01808     else
01809     {
01810         if (CellSize > 15)
01811             bitmap=_R(IDB_LNEWCOL);         // 12x12 New glyph
01812         else
01813             bitmap=_R(IDB_NEWCOL);          // 8x8 New glyph
01814     }
01815 
01816     wxBitmap * pBitmap = CamArtProvider::Get()->FindBitmap(bitmap);
01817 
01818     TheRect.Inflate((BmpSize - TheRect.GetWidth())/2, (BmpSize - TheRect.GetHeight())/2);
01819 
01820     // Blit the glyph to screen, including its grey mask areas
01821     if (pBitmap)
01822         pDC->DrawBitmap(*pBitmap, TheRect.GetLeft(), TheRect.GetTop(), TRUE);
01823 }
01824 
01825 
01826 
01827 /********************************************************************************************
01828 
01829 >   void CColourBar::PaintScrollButton(wxDC *pDC, INT32 ButtonID, BOOL Indented)
01830 
01831     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01832     Created:    22/6/94
01833     Inputs:     -
01834     Outputs:    pDC - The DC into which to draw
01835                 ButtonID - SCROLLBUTTON_LEFT or _RIGHT: specifies which one to draw
01836                 Normal - FALSE for an indented button, TRUE for normal (raised)
01837     Returns:    -
01838     Purpose:    Draws a scroll button at the appropriate end of the scroll bar
01839                 The button is scaled to fit into (ButtonWidth x ScrollHeight)
01840     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
01841 
01842 ********************************************************************************************/
01843 
01844 void CColourBar::PaintScrollButton(wxDC *pDC, INT32 ButtonID, BOOL Normal)
01845 {
01846     wxRect ButtonRect(ScrollBarRect);
01847 
01848     if (ButtonID == SCROLLBUTTON_LEFT)
01849         ButtonRect.x -= ButtonWidth - 1;
01850     else
01851         ButtonRect.x += ButtonRect.width - 1;
01852 
01853     ButtonRect.width = ButtonWidth;
01854 
01855     wxPen FramePen(wxColour(0,0,0));
01856     pDC->SetPen(FramePen);
01857     wxBrush TransBrush(wxColour(0,0,0), wxTRANSPARENT);
01858     pDC->SetBrush(TransBrush);
01859     pDC->DrawRectangle(ButtonRect);
01860 
01861     pDC->SetPen(wxNullPen);
01862     pDC->SetBrush(wxNullBrush);
01863 
01864     // Paint the button border plinth just inside the black outline
01865     ButtonRect.Inflate(-1, -1);
01866     Paint3dPlinth(pDC, &ButtonRect, Normal);
01867 
01868     // Calculate the left/right scroll arrow position
01869     INT32 CenterX = ButtonRect.x + (ButtonRect.width / 2);
01870     INT32 CenterY = ButtonRect.y + (ButtonRect.height / 2);
01871     INT32 offset  = (ButtonID == SCROLLBUTTON_LEFT) ? -1 : 1;
01872 
01873     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
01874     pDC->SetPen(TransPen);
01875 
01876     // Fill the button face area with the user preference colour
01877     wxBrush GreyBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
01878     ButtonRect.Inflate(-1, -1);
01879     pDC->SetBrush(GreyBrush);
01880     pDC->DrawRectangle(ButtonRect);
01881 
01882     // Paint the left/right scroll arrow (will overwrite the border if small bar)
01883     wxPoint Triangle[3];
01884     Triangle[0].x = CenterX - offset;
01885     Triangle[0].y = CenterY + 2;
01886     Triangle[1].x = CenterX + offset;
01887     Triangle[1].y = CenterY;
01888     Triangle[2].x = CenterX - offset;
01889     Triangle[2].y = CenterY - 2;
01890 
01891     wxBrush FrameBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWFRAME));
01892     pDC->SetBrush(FrameBrush);
01893     pDC->SetPen(FramePen);
01894     pDC->DrawPolygon(3, Triangle);
01895 
01896     pDC->SetBrush(wxNullBrush);
01897     pDC->SetPen(wxNullPen);
01898 }
01899 
01900 
01901 
01902 /********************************************************************************************
01903 
01904 >   void CColourBar::PaintScrollBar(wxDC *pDC)
01905 
01906     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01907     Created:    20/6/94
01908     Inputs:     pDC - The DC to paint into
01909                 ScrollBarRect - The rectangle into which the s.b. should be painted
01910     Outputs:    -
01911     Returns:    -
01912     Purpose:    Redraws the ColourBar window's mini proportional scroll bar
01913     Notes:      You must call CalculateRects and cache the value of TotalNumColours
01914                 prior to calling this function - see DoPaint for everything that needs
01915                 to be done.
01916 
01917                 The scrollbar rect is painted *totally* i.e. all contained pixels are
01918                 overwritten with colour, so it can be used in updates to redraw without
01919                 any flicker (When invalidating the rect, pass FALSE to stop it filling
01920                 with grey first)
01921 
01922                 The ColourBar works exclusively on the SELECTED Doc. Change with care
01923 
01924     SeeAlso:    CColourBar::DoPaint
01925 
01926 ********************************************************************************************/
01927 
01928 void CColourBar::PaintScrollBar(wxDC *pDC)
01929 {
01930     ERROR3IF(m_pCurrentColourList == NULL,
01931             _T("CColourBar::PaintScrollBar entered with NULL Current Colour List"));
01932 
01933     wxRect SausageRect;
01934     BOOL HasSausage = CalculateSausageRect(&SausageRect);
01935 
01936     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
01937 
01938     if (HasSausage && ScrollHeight != 0)
01939     {
01940         // Paint the scrollbar outline rectangle
01941         wxPen FramePen(wxColour(0,0,0));
01942         wxBrush TransBrush(wxColour(0,0,0), wxTRANSPARENT);
01943         pDC->SetBrush(TransBrush);
01944         pDC->SetPen(FramePen);
01945         pDC->DrawRectangle(ScrollBarRect);
01946 
01947         // Paint the grey fill on either side of the sausage
01948         wxBrush GreyBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
01949         pDC->SetBrush(GreyBrush);
01950         pDC->SetPen(TransPen);
01951 
01952         wxRect TheRect(SausageRect);
01953         TheRect.x = ScrollBarRect.x + 1;
01954         TheRect.width = SausageRect.x - TheRect.x;          // Area left of sausage
01955         if (TheRect.width > 0)
01956             pDC->DrawRectangle(TheRect);
01957 
01958         TheRect.x = SausageRect.x + SausageRect.width;      // Area right of sausage
01959         TheRect.width = ScrollBarRect.GetRight() - TheRect.x;
01960         if (TheRect.width > 0)
01961             pDC->DrawRectangle(TheRect);
01962 
01963         // Fill the center of the sausage plinth with btnface grey as well
01964         if (SausageRect.width > 1)
01965         {
01966             TheRect = SausageRect;
01967             TheRect.x++;
01968             TheRect.width--;
01969             TheRect.y++;
01970             TheRect.height--;
01971             pDC->DrawRectangle(TheRect);
01972         }
01973 
01974         // Ensure it has a black line at each end to make it visible
01975         SausageRect.Inflate(1, 1);
01976         pDC->SetPen(FramePen);
01977         pDC->DrawRectangle(SausageRect);
01978 
01979         pDC->SetPen(wxNullPen);
01980         pDC->SetBrush(wxNullBrush);
01981 
01982         // Paint the Sausage plinth
01983         SausageRect.Inflate(-1, -1);
01984         Paint3dPlinth(pDC, &SausageRect, TRUE);
01985     }
01986 
01987     if (HasSausage || ScrollHeight == 0)
01988     {
01989         // Now paint on the scroll buttons
01990         PaintScrollButton(pDC, SCROLLBUTTON_LEFT, TRUE);
01991         PaintScrollButton(pDC, SCROLLBUTTON_RIGHT, TRUE);
01992     }
01993 }
01994 
01995 
01996 
01997 /********************************************************************************************
01998 
01999 >   wxBrush *CColourBar::GetColourBrush(COLORREF rgb)
02000 
02001     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02002     Created:    28/6/94
02003     Inputs:     rgb - An RGB ScreenWord for passing to GDI or GBrush in order to create
02004                 a brush of the desired colour.
02005     Outputs:    -
02006     Returns:    A pointer to a wxBrush for the given colour. NOTE that it is up to the caller
02007                 to dispose of this brush using delete.
02008                 This pointer will be NULL if the brush could not be created
02009     Purpose:    Calculates a logical brush for use in painting. If GDraw is available
02010                 via CColourBar::GDrawBrush, GDraw will be used. If not, GDI will be used.
02011     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02012 
02013 ********************************************************************************************/
02014 
02015 wxBrush *CColourBar::GetColourBrush(COLORREF rgb)
02016 {
02017     wxBrush* pBrush = NULL;
02018 
02019     if (GDrawBrush.Available())
02020     {
02021         pBrush = new wxBrush;
02022 
02023         if (pBrush != NULL)
02024         {
02025             GDrawBrush.GetLogBrush(rgb, pBrush);
02026         }
02027     }
02028     else
02029         pBrush = new wxBrush(rgb);
02030 
02031     return pBrush;
02032 }
02033 
02034 
02035 
02036 /********************************************************************************************
02037 
02038 >   void CColourBar::PaintColourCell(wxDC *pDC, wxRect *Rect, DocColour *RectCol)
02039 
02040     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02041     Created:    20/6/94
02042     Inputs:     pDC - The DC to draw into
02043                 rect - The rectangle to plot the colour cell into
02044                 RectCol - The colour with which to fill the rectangle, or NULL
02045                 if the cell is to be filled to represent 'no' colour or 'many'
02046                 colours in a selection.
02047     Outputs:    -
02048     Returns:    -
02049     Purpose:    Draws the given rectangle as a 'Colour cell' for the given DocColour.
02050                 The top half of the rect is solid-filled with the colour, while the
02051                 bottom 2 quarters are filled with the colour as it would appear on top
02052                 of a white background and black bgnd respectively
02053                 (if the col isn't fractionally transparent, rect is just solid filled)
02054 
02055     Notes:      If GBrush has been initialised before calling this function, it will be
02056                 used to plot the colour cells.
02057                 The ColourBar works exclusively on the SELECTED Doc. Change with care
02058 
02059     SeeAlso:    CColourBar::PaintColourStrip; CColourBar::DoPaint
02060 
02061 ********************************************************************************************/
02062 
02063 void CColourBar::PaintColourCell(wxDC *pDC, wxRect *Rect, DocColour *RectCol)
02064 {          
02065     Document *ScopeDoc = Document::GetSelected();
02066     if (ScopeDoc == NULL) return;
02067 
02068     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
02069     pDC->SetPen(TransPen);
02070 
02071     if (RectCol == NULL)        // No colour (eg 'many' colours in selection)
02072     {
02073 //      pDC->SetBkColor(RGB(255,255,255));              // ensure white background
02074         wxBrush HatchBrush(wxColour(0,0,0), wxBDIAGONAL_HATCH); // Fill with black/white hatch
02075         pDC->SetBrush(HatchBrush);
02076         pDC->DrawRectangle(*Rect);
02077         pDC->SetPen(wxNullPen);
02078         pDC->SetBrush(wxNullBrush);
02079         return;
02080     }
02081 
02082     if (RectCol->IsTransparent())
02083     {
02084 //      pDC->SetBkColor(RGB(255,255,255));              // ensure white background
02085         wxBrush HatchBrush(wxColour(0,0,0), wxCROSSDIAG_HATCH); // Fill with black/white hatch
02086         pDC->SetBrush(HatchBrush);
02087         pDC->DrawRectangle(*Rect);
02088         pDC->SetPen(wxNullPen);
02089         pDC->SetBrush(wxNullBrush);
02090         return;
02091     }
02092 
02093     // Find a context to render with. We'll use the Selected View's context if possible,
02094     // so that we render using the same colour correction/separation mode. If there
02095     // is no selected view, then we will look for a global context.
02096     ColourContextRGBT *CCrgbt = (ColourContextRGBT *)
02097                 ColourManager::GetColourContext(COLOURMODEL_RGBT, DocView::GetSelected());
02098 
02099     ERROR3IF(CCrgbt == NULL, _T("Can't find an RGB colour context to render with!"));
02100 
02101     DWORD ScreenWord = ConvertColourToTransScreenWord(CCrgbt, RectCol);
02102     
02103     wxBrush *Brush = GetColourBrush((COLORREF) (ScreenWord & 0x00ffffff));
02104 
02105     IndexedColour *Parent = RectCol->FindParentIndexedColour();
02106 // Webster shows spots as normal library colours
02107 #ifndef WEBSTER
02108     if (Parent != NULL && Parent->IsSpotOrTintOfSpot())
02109     {
02110         // Spot colours are shown as circular swatches in order to make them more obvious
02111         // (First we must fill the background with BTNFACE to clear the corners)
02112         wxBrush BackBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
02113         pDC->SetBrush(BackBrush);
02114         pDC->DrawRectangle(*Rect);
02115 
02116         // Try to make the rectangle more square, so we always render a circle
02117         wxRect Square(*Rect);
02118         if (Square.width > Square.height)
02119             Square.Inflate(-(Square.width - Square.height) / 2, 0);
02120         else if (Square.width < Square.height)
02121             Square.Inflate(0, -(Square.height - Square.width) / 2);
02122 
02123         pDC->SetBrush(*Brush);
02124         pDC->DrawEllipse(Square);
02125     }
02126     else
02127 #endif // WEBSTER
02128     {
02129         // Process colours are shown as rectangles
02130         pDC->SetBrush(*Brush);
02131         pDC->DrawRectangle(*Rect);
02132 
02133         if (ColourCellsDivided)
02134         {
02135             // If the user wants a grey line between the colour cells to make them easier
02136             // to distinguish, draw a line.
02137             wxBrush GreyBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
02138             wxRect LineRect(*Rect);
02139             LineRect.x = LineRect.GetRight();
02140             LineRect.width = 1;
02141             pDC->SetBrush(GreyBrush);
02142             pDC->DrawRectangle(LineRect);
02143         }
02144     }
02145 
02146     pDC->SetPen(wxNullPen);
02147     pDC->SetBrush(wxNullBrush);
02148     delete Brush;
02149 }
02150 
02151 
02152 
02153 /********************************************************************************************
02154 
02155 >   void CColourBar::PaintNoColourCell(wxDC *pDC)
02156 
02157     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02158     Created:    14/7/94
02159     Inputs:     pDC - The DC to draw into
02160     Outputs:    -
02161     Returns:    -
02162     Purpose:    Draws the 'NoColour' colour cell just to the left of the ColourStrip
02163     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02164     SeeAlso:    CColourBar::DoPaint
02165 
02166 ********************************************************************************************/
02167 
02168 void CColourBar::PaintNoColourCell(wxDC *pDC)
02169 {          
02170     wxRect Rect;
02171     CalculateNoColourCellRect(&Rect);
02172 
02173     wxPen FramePen(wxColour(0,0,0));
02174     pDC->SetPen(FramePen);
02175     wxBrush TransBrush(wxColour(0,0,0), wxTRANSPARENT);
02176     pDC->SetBrush(TransBrush);
02177     pDC->DrawRectangle(Rect);
02178 
02179     Rect.Inflate(-1, -1);
02180 
02181     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
02182     pDC->SetPen(TransPen);
02183 
02184 //  pDC->SetBkColor(RGB(255,255,255));              // ensure white background
02185     wxBrush HatchBrush(wxColour(0,0,0), wxCROSSDIAG_HATCH); // Fill with black/white hatch
02186     pDC->SetBrush(HatchBrush);
02187     pDC->DrawRectangle(Rect);
02188 
02189     pDC->SetBrush(wxNullBrush);
02190     pDC->SetPen(wxNullPen);
02191 
02192     // Check if the current line/fill colours are 'no colour', and if so, draw diamonds
02193     // as appropriate on the 'no colour' cell.
02194     DocColour *LineColour;
02195     DocColour *FillColour;
02196     DocColour *EndColour;
02197     BOOL DiamondType = ColourManager::GetCurrentLineAndFillColours(&LineColour,
02198                                                                 &FillColour, &EndColour);
02199 
02200     // If the linecolour is transparent, plot a line diamond
02201     if (LineColour != NULL && LineColour->IsTransparent())
02202         PaintIndicatorDiamond(pDC, Rect, CBCOLOUR_LINE, CELLINDEX_NOCOLOURCELL, DiamondType);
02203 
02204     // Plot a fill diamond (flat fill) or 1 or 2 grad fill 'arrows'
02205     if (FillColour != NULL && FillColour->IsTransparent())
02206     {
02207         CBColourType TheType = CBCOLOUR_FILL;                   // It is a flat fill
02208         if (EndColour != NULL && EndColour->IsTransparent())
02209             TheType = CBCOLOUR_START;                           // Er..no it's a start gradfill
02210 
02211         PaintIndicatorDiamond(pDC, Rect, TheType, CELLINDEX_NOCOLOURCELL, DiamondType);
02212     }
02213 
02214     if (EndColour != NULL && EndColour->IsTransparent())
02215         PaintIndicatorDiamond(pDC, Rect, CBCOLOUR_END, CELLINDEX_NOCOLOURCELL, DiamondType);
02216 }
02217 
02218 
02219 /********************************************************************************************
02220 
02221 >   void CColourBar::PaintLibColourCell(wxDC *pDC, wxRect *Rect, DocColour *RectCol, BOOL SpotColour = FALSE)
02222 
02223     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> Humprhys
02224     Created:    20/3/97
02225     Inputs:     pDC - The DC to draw into
02226                 rect - The rectangle to plot the colour cell into
02227                 RectCol - The colour with which to fill the rectangle.
02228                 SpotColour - falg to say if the colour should be rendered as a spot colour or not
02229     Outputs:    -
02230     Returns:    -
02231     Purpose:    Draws the given rectangle as a 'Colour cell' for the given DocColour.
02232     SeeAlso:    CColourBar::PaintColourCell; CColourBar::DoPaint
02233 
02234 ********************************************************************************************/
02235 
02236 void CColourBar::PaintLibColourCell(wxDC *pDC, wxRect *Rect, DocColour *RectCol, BOOL SpotColour)
02237 {          
02238     Document *ScopeDoc = Document::GetSelected();
02239     if (ScopeDoc == NULL) return;
02240 
02241     if (RectCol == NULL)        // No colour (eg 'many' colours in selection)
02242     {
02243 //      pDC->SetBkColor(RGB(255,255,255));              // ensure white background
02244         wxBrush HatchBrush(wxColour(0,0,0), wxBDIAGONAL_HATCH); // Fill with black/white hatch
02245         pDC->SetBrush(HatchBrush);
02246         pDC->DrawRectangle(*Rect);
02247         pDC->SetBrush(wxNullBrush);
02248         return;
02249     }
02250 
02251     // Find a context to render with. We'll use the Selected View's context if possible,
02252     // so that we render using the same colour correction/separation mode. If there
02253     // is no selected view, then we will look for a global context.
02254     ColourContextRGBT *CCrgbt = (ColourContextRGBT *)
02255                 ColourManager::GetColourContext(COLOURMODEL_RGBT, DocView::GetSelected());
02256 
02257     ERROR3IF(CCrgbt == NULL, _T("Can't find an RGB colour context to render with!"));
02258 
02259     DWORD ScreenWord = ConvertColourToTransScreenWord(CCrgbt, RectCol);
02260     
02261     wxBrush *Brush = GetColourBrush((COLORREF) (ScreenWord & 0x00ffffff));
02262 
02263     // Library colours are shown as diamond swatches in order to make them more obvious
02264     // (First we must fill the background with BTNFACE to clear the corners)
02265     wxBrush BackBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
02266     pDC->SetBrush(BackBrush);
02267     pDC->DrawRectangle(*Rect);
02268 
02269     // Try to make the rectangle more square, so we always render a circle
02270     wxRect Square(*Rect);
02271     if (Square.width > Square.height)
02272         Square.Inflate(-(Square.width - Square.height) / 2, 0);
02273     else if (Square.width < Square.height)
02274         Square.Inflate(0, -(Square.height - Square.width) / 2);
02275 
02276     // Generate a polygon definition of the diamond shape
02277     // When plotting gradfill start/end colour, the top/bottom point is flattened
02278     // to make an up or down arrow shape
02279     INT32 MidY = Square.y + (Square.height / 2);
02280     INT32 MidX = Square.x + (Square.width / 2);
02281     wxPoint Diamond[4];
02282     Diamond[0].x = MidX;
02283     Diamond[0].y = Square.y;
02284     Diamond[1].x = Square.x + Square.width;
02285     Diamond[1].y = MidY;
02286     Diamond[2].x = MidX;
02287     Diamond[2].y = Square.y + Square.height;
02288     Diamond[3].x = Square.x;
02289     Diamond[3].y = MidY;
02290 
02291     // plot it
02292     if (!SpotColour)
02293     {
02294         // Non spot colour so render the colour into the diamond
02295         pDC->SetBrush(*Brush);
02296         pDC->DrawPolygon(4, Diamond);
02297         pDC->SetBrush(wxNullBrush);
02298     }
02299     else
02300     {
02301         // Spot colour so render a black diamond and then the usual spot colour
02302         // render a black diamond
02303         wxBrush BlackBrush(wxColour(0,0,0));
02304         pDC->SetBrush(BlackBrush);
02305         pDC->DrawPolygon(4, Diamond);
02306         pDC->SetBrush(wxNullBrush);
02307 
02308         // Try to make the rectangle more square, so we always render a circle
02309         // 1 - 0.707 = 0.293  where 0.707 is cos and sin 45
02310         //INT32 QuarterX = (INT32)(0.2 * (double)((Rect->right - Rect->left)/2));
02311         //INT32 QuarterY = (INT32)(0.2 * (double)((Rect->top - Rect->bottom)/2));
02312         // But we could do this a lot quicker with this rough approximation
02313         //INT32 QuarterX = (INT32)((Square.right - Square.left)/10.0 + 0.5);
02314         //INT32 QuarterY = (INT32)((Square.top - Square.bottom)/10.0 + 0.5);
02315         INT32 QuarterX = Square.width / 10;
02316         INT32 QuarterY = Square.height / 10;
02317         wxRect EllipseSquare(Square.x + QuarterX, Square.y + QuarterY,
02318                             Square.width - (QuarterX * 2), Square.height - (QuarterY * 2));
02319 
02320         // render a spot colour ellipse
02321         pDC->SetBrush(*Brush);
02322         pDC->DrawEllipse(EllipseSquare);
02323         pDC->SetBrush(wxNullBrush);
02324     }
02325 
02326     // clear out the brush we created
02327     delete Brush;
02328 }
02329 
02330 /********************************************************************************************
02331 
02332 >   void CColourBar::PaintIndicators(wxDC *pDC)
02333 
02334     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02335     Created:    21/6/94
02336     Inputs:     pDC - The DC to paint into
02337                 ColPalette - The list of colours displayed in the colour strip
02338     Outputs:    -
02339     Returns:    -
02340     Purpose:    Redraws the ColourBar colour indicators (current fg/bg colours)
02341     Notes:      You must call CalculateRects and cache the value of TotalNumColours
02342                 prior to calling this function - see DoPaint for everything that needs
02343                 to be done.
02344                 If GBrush has been initialised before calling this function, it will be
02345                 used to plot the colour cells.
02346                 The ColourBar works exclusively on the SELECTED Doc. Change with care
02347     SeeAlso:    CColourBar::DoPaint
02348 
02349 ********************************************************************************************/
02350 
02351 void CColourBar::PaintIndicators(wxDC *pDC)
02352 {
02353     // Save the current ColourCellsDivided preference state and set it to OFF
02354     INT32 OldCellState = ColourCellsDivided;
02355     ColourCellsDivided = FALSE;
02356 
02357 
02358     // Find the current line/fill colours to plot...
02359     DocColour *LineColour;
02360     DocColour *FillColour;
02361     DocColour *EndGradColour;
02362     ColourManager::GetCurrentLineAndFillColours(&LineColour, &FillColour, &EndGradColour);
02363 
02364     // Plot the line colour as a large colour cell filling IndicatorRect
02365     // pass NULL for many colours
02366     PaintColourCell(pDC, &IndicatorRect, LineColour);
02367 
02368     // Work out where the inside rectangle is, and plot it as a colour cell
02369     // (If you change this calculation, fix the other calc. of 'DeflateBy' below)
02370     wxRect InnerRect(IndicatorRect);
02371     INT32 DeflateBy = (INT32) (abs(IndicatorRect.height) * 2) / 5;
02372     if (DeflateBy < 4)
02373         DeflateBy = 4;  // Line indicator is min. of 2 pixels wide
02374     InnerRect.Inflate(-DeflateBy / 2, -DeflateBy / 2);
02375 
02376     if (EndGradColour != NULL)
02377     {
02378         // We want to display the start and end colours for a grad fill, so split the
02379         // fill indicator square into 2 rectangles, one above the other
02380         wxRect TopRect(InnerRect);
02381         TopRect.height = TopRect.height / 2;
02382         InnerRect.y += TopRect.height;
02383         InnerRect.height -= TopRect.height;
02384 
02385         // And paint the end colour at the bottom
02386         PaintColourCell(pDC, &TopRect, EndGradColour);
02387     }
02388 
02389     // And fill the remaining part of inner rect with the fill (or grad-fill start) colour
02390     PaintColourCell(pDC, &InnerRect, FillColour);
02391 
02392     // And restore the saved preference state
02393     ColourCellsDivided = OldCellState;
02394 }
02395 
02396 
02397 
02398 /********************************************************************************************
02399 
02400 >   void CColourBar::PaintIndicatorDiamond(wxDC *pDC, const wxRect &CellRect,
02401                                             CBColourType ColourType, INT32 CellIndex, BOOL DiamondType)
02402 
02403     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02404     Created:    23/6/94
02405     Inputs:     pDC - The DC to paint into
02406 
02407                 CellRect - The Colour Cell to paint the indicator into
02408 
02409                 ColourType - Indicates where and how to plot the diamond (different places
02410                 and shapes are used for lines, files, and gradfills)
02411 
02412                 CellIndex - The index of the cell (or CELLINDEX_NOCOLOURCELL) which
02413                 is being redrawn (this is cached to remember where the diamond is
02414                 for future updates of the diamond position)
02415 
02416                 DiamondType - FALSE for 'diamond', TRUE for 'plus' shape
02417                 (pluses are used to indicate colours when there is no selection, and
02418                 we are thus displaying the current default attrs, not the selected colours)
02419 
02420     Outputs:    -
02421     Returns:    -
02422     Purpose:    Draws a small diamond in the top left/right corner of a colour cell
02423                 to indicate that the given cell is the current line/fill colour
02424 
02425     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02426 
02427     SeeAlso:    CColourBar::DoPaint
02428 
02429 ********************************************************************************************/
02430 
02431 void CColourBar::PaintIndicatorDiamond(wxDC *pDC, const wxRect &CellRect,
02432                                         CBColourType ColourType, INT32 CellIndex, BOOL DiamondType)
02433 {
02434     // Calculate the position to plot the diamond (top left or top right corner)
02435     INT32 MidY = CellRect.y + (CellRect.height / 4);
02436     INT32 MidX;
02437     if (ColourType == CBCOLOUR_LINE)
02438         MidX = CellRect.x + (CellRect.width * 3 / 4);
02439     else
02440         MidX = CellRect.x + (CellRect.width / 4);
02441 
02442     if (DiamondType)
02443     {
02444         // Plot the plus shape
02445         wxBrush TransBrush(wxColour(0,0,0), wxTRANSPARENT);
02446         pDC->SetBrush(TransBrush);
02447         wxPen WhitePen(wxColour(255, 255, 255));
02448         wxRect VertRect(MidX - 3, MidY - 1, 7, 3);
02449         wxRect HorzRect(MidX - 1, MidY - 3, 3, 7);
02450         pDC->SetPen(WhitePen);
02451         pDC->DrawRectangle(VertRect);
02452         pDC->DrawRectangle(HorzRect);
02453 
02454         wxPen BlackPen(wxColour(0, 0, 0));
02455         pDC->SetPen(BlackPen);
02456         pDC->DrawLine(MidX - 2, MidY, MidX + 3, MidY);
02457         pDC->DrawLine(MidX, MidY - 2, MidX, MidY + 3);
02458         pDC->SetPen(wxNullPen);
02459         pDC->SetBrush(wxNullBrush);
02460     }
02461     else
02462     {
02463         // Generate a polygon definition of the diamond shape
02464         // When plotting gradfill start/end colour, the top/bottom point is flattened
02465         // to make an up or down arrow shape
02466         wxPoint Diamond[4];
02467         Diamond[0].x = MidX - 3;
02468         Diamond[0].y = MidY;
02469         Diamond[1].x = MidX;
02470         Diamond[1].y = MidY - ((ColourType == CBCOLOUR_START) ? 0 : 3);
02471         Diamond[2].x = MidX + 3;
02472         Diamond[2].y = MidY;
02473         Diamond[3].x = MidX;
02474         Diamond[3].y = MidY + ((ColourType == CBCOLOUR_END) ? 0 : 3);
02475 
02476         // plot it
02477         wxPen WhitePen(wxColour(255, 255, 255));
02478         wxBrush BlackBrush(wxColour(0, 0, 0));
02479         pDC->SetPen(WhitePen);
02480         pDC->SetBrush(BlackBrush);
02481         pDC->DrawPolygon(4, Diamond);
02482         pDC->SetPen(wxNullPen);
02483         pDC->SetBrush(wxNullBrush);
02484     }
02485 
02486     // Remember where we plotted this diamond
02487     switch (ColourType)
02488     {
02489         case CBCOLOUR_LINE:
02490             LastLineCell = CellIndex;
02491             break;
02492         
02493         case CBCOLOUR_END:
02494             LastEndCell  = CellIndex;
02495             break;
02496 
02497         case CBCOLOUR_FILL:
02498         case CBCOLOUR_START:
02499             LastFillCell = CellIndex;
02500             break;
02501 
02502         default:
02503             ERROR3(_T("Unknown colour type"));
02504             break;
02505     }
02506 
02507     LastDiamondShape = DiamondType;
02508 }
02509 
02510 
02511 
02512 /********************************************************************************************
02513 
02514 >   void CColourBar::PaintColourStrip(wxDC *pDC, const wxRect &ClipRect)
02515 
02516     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02517     Created:    21/6/94
02518     Inputs:     pDC - The DC to paint into
02519                 ClipRect - The rectangle into which we're drawing. Cells outside this
02520                 rectangle will not be rendered, to improve renderintg speed.
02521     Outputs:    -
02522     Returns:    -
02523     Purpose:    Redraws the ColourBar colour strip
02524     Notes:      You must call CalculateRects and cache the value of TotalNumColours
02525                 prior to calling this function - see DoPaint for everything that needs
02526                 to be done.
02527                 If GBrush has been initialised before calling this function, it will be
02528                 used to plot the colour cells.
02529 
02530                 The ColourBar works exclusively on the SELECTED Doc. Change with care
02531 
02532     SeeAlso:    CColourBar::DoPaint
02533 
02534 ********************************************************************************************/
02535 
02536 void CColourBar::PaintColourStrip(wxDC *pDC, const wxRect &ClipRect)
02537 {
02538     // Find pointers to the fill/line IndexedColours so we will know when we hit
02539     // them as we draw, and can then draw indicator diamonds on the colour cells.
02540     IndexedColour *CurrentLineColour = NULL;
02541     IndexedColour *CurrentFillColour = NULL;    // FlatFill colour or GradFill Start colour
02542     IndexedColour *CurrentEndColour = NULL;     // GradFill End colour
02543     BOOL DiamondType;
02544 
02545     BOOL IsAGradFill = FALSE;                   // True if FillColour is the Gradfill Start colour
02546 
02547     {
02548         DocColour *LineColour = NULL;
02549         DocColour *FillColour = NULL;
02550         DocColour *EndColour  = NULL;
02551         DiamondType = ColourManager::GetCurrentLineAndFillColours(&LineColour,
02552                                                             &FillColour, &EndColour);
02553         if (LineColour)
02554             CurrentLineColour = LineColour->FindParentIndexedColour();
02555 
02556         if (FillColour)
02557             CurrentFillColour = FillColour->FindParentIndexedColour();  
02558 
02559         if (EndColour)
02560         {
02561             IsAGradFill = TRUE;
02562             CurrentEndColour  = EndColour->FindParentIndexedColour();
02563         }
02564     }
02565 
02566     // Calculate the screen rectangle of the leftmost visible cell
02567     wxRect CellRect(StripRect);
02568     CellRect.width = CellSize;
02569 
02570     INT32 CellIndex = (INT32) LeftmostColour;   // keep track of each cell's index as we draw
02571 
02572     // Draw the colours in the strip
02573     BOOL RedrawFinished = FALSE;
02574     // If the user has the preference set then include and hence show the document
02575     // colours
02576     if (ColourSGallery::ShowDocumentColours)
02577     {
02578         // Find the leftmost displayed colour in the DisplayList sequence
02579         DocColour Temp;
02580         IndexedColour *TheColour = FindColourByIndex((UINT32) LeftmostColour);
02581         while (TheColour != NULL)
02582         { 
02583             // Paint the colour cell, but only bother if it's in the invalid region
02584             // This speeds up redraw, especially when ScrollTheStrip only wishes to redraw
02585             // a few colour cells at one end of the strip.
02586             if ((CellRect.x + CellRect.width) >= ClipRect.x)
02587             {
02588                 Temp.MakeRefToIndexedColour(TheColour);
02589 
02590                 PaintColourCell(pDC, &CellRect, &Temp); // Paint this Cell
02591 
02592                 if (TheColour == CurrentLineColour)     // Paint current LineCol indicator
02593                     PaintIndicatorDiamond(pDC, CellRect, CBCOLOUR_LINE, CellIndex, DiamondType);
02594 
02595                 if (TheColour == CurrentFillColour)     // Paint Current Fill/Start indicator
02596                     PaintIndicatorDiamond(pDC, CellRect,
02597                                           (IsAGradFill) ? CBCOLOUR_START : CBCOLOUR_FILL,
02598                                           CellIndex, DiamondType);
02599 
02600                 if (TheColour == CurrentEndColour)      // Paint Current End indicator
02601                     PaintIndicatorDiamond(pDC, CellRect, CBCOLOUR_END,  CellIndex, DiamondType);
02602             }
02603 
02604             CellRect.x += CellSize;                 // Move on to next Cell
02605 
02606             // if no more room in the strip for painting, or have updated the clip
02607             // rectangle fully, we can stop redrawing
02608             if ((CellRect.x + CellRect.width) > (StripRect.x + StripRect.width) || 
02609                 CellRect.x > (ClipRect.x + ClipRect.width))
02610             {
02611                 RedrawFinished = TRUE;
02612                 break;
02613             }
02614 
02615             CellIndex++;        // Increment the current cell index
02616 
02617             // And find the next colour
02618             TheColour = m_pCurrentColourList->GetUndeletedNext(TheColour);
02619         }
02620 
02621         // If the redraw is finished then return now rather than doing extra work
02622         if (RedrawFinished)
02623             return;
02624     }
02625 
02626     // Now go through the library colours that we have been asked to display
02627     // A bit of similar code to the above may be recognised here!!!!
02628     SGDisplayLibColour *pLibColour = NULL;
02629     DocColour * pRedrawCol = FindLibColourByIndex(CellIndex, &pLibColour);
02630     while (pRedrawCol != NULL && pLibColour != NULL)
02631     {
02632         // Paint the colour cell, but only bother if it's in the invalid region
02633         // This speeds up redraw, especially when ScrollTheStrip only wishes to redraw
02634         // a few colour cells at one end of the strip.
02635         if ((CellRect.x + CellRect.width) >= ClipRect.x)
02636         {
02637             // Paint this Cell
02638 #ifndef WEBSTER
02639             // In Camelot use a special colour library item drawing routine
02640             PaintLibColourCell(pDC, &CellRect, pRedrawCol, pLibColour->IsASpotColour());
02641 #else
02642             // In Webster draw spots as standard library colours
02643             PaintLibColourCell(pDC, &CellRect, pRedrawCol, FALSE);
02644 #endif
02645         }
02646 
02647         CellRect.x += CellSize;                 // Move on to next Cell
02648 
02649         // if no more room in the strip for painting, or have updated the clip
02650         // rectangle fully, we can stop redrawing
02651         if ((CellRect.x + CellRect.width) > (StripRect.x + StripRect.width) || 
02652             CellRect.x > (ClipRect.x + ClipRect.width))
02653         {
02654             RedrawFinished = TRUE;
02655             break;
02656         }
02657 
02658         CellIndex++;        // Increment the current cell index
02659 
02660         // And find the next colour
02661         // This could be speeded up but is ok for now
02662         pRedrawCol = FindLibColourByIndex(CellIndex, &pLibColour);
02663     }
02664 }
02665 
02666 
02667 /*********************************************************************************************
02668 >   afx_msg void CColourBar::OnPaint()
02669 
02670     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02671     Created:    ages ago
02672     Inputs:     -
02673     Outputs:    -
02674     Returns:    -
02675     Purpose:    Redraws the colour bar
02676     Errors:     -
02677 
02678 **********************************************************************************************/ 
02679 void CColourBar::OnPaint( wxPaintEvent &evnt )
02680 {
02681     // Always create this so that the area is validated
02682     wxPaintDC dc(this);
02683 
02684     if (!CCamApp::IsDisabled())
02685     {
02686         DoPaint(&dc);
02687     }
02688 }
02689 
02690 
02691 
02692 /********************************************************************************************
02693 
02694 >   void CColourBar::DoPaint(wxDC* pDC)
02695 
02696     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02697     Created:    17/6/94
02698     Inputs:     pDC - The DC to paint into
02699     Outputs:    -
02700     Returns:    -
02701     Purpose:    Redraws the ColourBar window contents
02702 
02703     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02704 
02705 ********************************************************************************************/
02706 
02707 void CColourBar::DoPaint(wxDC* pDC)
02708 {
02709     // If we're in the middle of doing something important (having a bit of an error)
02710     // then we just pretend that we redraw, and abort, to save going re-entrant.
02711     if (CCamApp::IsDisabled())
02712     {
02713         TRACE( _T("Colour bar repaint has been aborted: the system is disabled (due to an error/ensure?)\n"));
02714         // The paint condition will have been cleared by the creation of the wxPaintDC
02715 //      ::ValidateRect(m_hWnd, NULL);                               // Clear paint condition
02716         return;
02717     }
02718 
02719 //  ASSERT_VALID(this);
02720 //  ASSERT_VALID(pDC);
02721 
02722     Error::RenderThreadIn();        // Handle errors/exceptions during rendering properly
02723 
02724 //  CControlBar::DoPaint(pDC);      // draw border
02725 
02726     Document *OldCurrentDoc = SetCurrentDoc();
02727 
02728     // Get the current colour list, and calculate the rects to be redrawn
02729     m_pCurrentColourList = ColourManager::GetColourList();
02730     CalculateRects();
02731 
02732     wxPen TransPen(wxColour(0,0,0), 1, wxTRANSPARENT);
02733     pDC->SetPen(TransPen);
02734 
02735     wxBrush GreyBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
02736 
02737     if (m_pCurrentColourList == NULL)// || m_pCurrentColourList->GetUndeletedCount() == 0)
02738     {
02739         // No colours, so just fill the entire bar with grey
02740         pDC->SetBrush(GreyBrush);
02741         pDC->DrawRectangle(WindowRect);
02742         pDC->SetBrush(wxNullBrush);
02743         pDC->SetPen(wxNullPen);
02744         RestoreCurrentDoc(OldCurrentDoc);
02745 
02746         Error::RenderThreadOut();
02747         return;
02748     }
02749 
02750     wxRect ClipRect;
02751     pDC->GetClippingBox(&ClipRect.x, &ClipRect.y, &ClipRect.width, &ClipRect.height);
02752 
02753     if (ClipRect.IsEmpty())
02754         ClipRect = GetClientRect();
02755 
02756     // Fill everything to the right of the colourstrip with BTNFACE grey, to ensure we 
02757     // overwrite any stuff that might have been drawn there and not erased (on some updates
02758     // we purposely do not bother with erasing the background, to reduce flicker)
02759     wxRect TheRect(WindowRect);
02760     INT32 OffsetLeft = StripRect.x + StripRect.width - TheRect.x;
02761     TheRect.x += OffsetLeft;
02762     TheRect.width -= OffsetLeft;
02763     pDC->SetBrush(GreyBrush);
02764     pDC->DrawRectangle(TheRect);
02765     pDC->SetBrush(wxNullBrush);
02766     pDC->SetPen(wxNullPen);
02767 
02768 //  TotalNumColours = m_pCurrentColourList->GetUndeletedCount(); // FIXEDCOLOURS
02769     TotalNumColours = GetNumberOfColours();
02770     if ((ScrollHeight == 0 || !HasNoScrollBar(-1, (INT32) TotalNumColours)))
02771     {
02772         wxRect AllScrollBarRect(ScrollBarRect);             // ScrollBarRect does not include the
02773         AllScrollBarRect.x -= ButtonWidth + 1;              // scroll arrows, which extend outside
02774         AllScrollBarRect.width += (ButtonWidth + 1) * 2;    // this rect by ButtonWidth + 1 pixels
02775 
02776         if (ClipRect.Intersects(AllScrollBarRect))
02777             PaintScrollBar(pDC);
02778     }
02779 
02780     PaintNoColourCell(pDC);
02781     if (ClipRect.Intersects(EditButtonRect))
02782         PaintEditOrNewButton(pDC, (IndentedButton != CLICKED_EDITBUTTON), TRUE);
02783 
02784 #if FALSE
02785     if (ClipRect.Intersects(NewButtonRect))
02786         PaintEditOrNewButton(pDC, (IndentedButton != CLICKED_NEWBUTTON), FALSE);
02787 #endif
02788 
02789     // Set up palette and GBrush for Spiffy redraw
02790 //  CPalette * OldPal = NULL;
02791 //  if (PaletteManager::UsePalette())
02792 //  {
02793 //      OldPal = PaletteManager::StartPaintPalette(pDC);
02794 //  }
02795 
02796     GDrawBrush.Init(pDC);
02797     GDrawBrush.Start();
02798 
02799     // Draw Indicators and colour strip, using GBrush if possible
02800     if (ClipRect.Intersects(IndicatorRect))
02801         PaintIndicators(pDC);
02802 
02803     if (ClipRect.Intersects(StripRect))
02804         PaintColourStrip(pDC, ClipRect);
02805 
02806     // Finish with GBrush
02807     GDrawBrush.Stop();
02808 //  if (OldPal)
02809 //      PaletteManager::StopPaintPalette(pDC, OldPal);
02810 
02811     Error::RenderThreadOut();
02812 
02813     RestoreCurrentDoc(OldCurrentDoc);
02814 }
02815 
02816 
02817 
02818 /********************************************************************************************
02819 
02820 >   void CColourBar::ForceRedrawOfRect(const wxRect &RectToDraw)
02821 
02822     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02823     Created:    23/6/94
02824     Inputs:     RectToDraw - The rectangle to force-redraw. This should be
02825                 one of the member rectangles (ScrollBarRect, StripRect, IndicatorRect)
02826     Outputs:    -
02827     Returns:    -
02828     Purpose:    Causes the given portion of the colour bar to be redrawn
02829     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02830 
02831 ********************************************************************************************/
02832 
02833 void CColourBar::ForceRedrawOfRect(const wxRect &RectToDraw)
02834 {
02835     wxRect OffsetRectToDraw(RectToDraw);
02836     wxRect RealWindowRect;
02837     
02838     // Convert the screen rectangle coords into window *offsets*
02839     RealWindowRect = GetClientRect();
02840     OffsetRectToDraw.Offset(-RealWindowRect.x, -RealWindowRect.y);
02841 
02842     RefreshRect(OffsetRectToDraw, false);
02843 }
02844 
02845 
02846 
02847 /********************************************************************************************
02848 
02849 >   INT32 CColourBar::WhereIsMouse(wxPoint MousePos, wxRect *TheRectItIsIn = NULL,
02850                                     BOOL *ToLeft = NULL)
02851 
02852     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02853     Created:    22/6/94
02854 
02855     Inputs:     MousePos - The point you wish to check
02856 
02857     Outputs:    TheRectItIsIn - if non-NULL, this rect is filled in with a copy of
02858                 the rectangle in which the mouse pointer lies. This is indeterminate
02859                 in the case of a CLICKED_NOTHING return value.
02860 
02861                 ToLeft - if non-NULL, and if the mouse was over a colour cell, this
02862                 boolean is filled in TRUE if the pointer is over the left side of the
02863                 cell, or FALSE if over the right. Used for drag'n'drop to determine
02864                 which side of a colour to insert a dropped colour into.
02865 
02866     Returns:    A positive (0..MaxColours) value indicates the given position
02867                 lies over a colour cell of that index.
02868                 A negative value indicates one of the special 'controls' in the
02869                 window (scroll bar, colour indicators etc) - see the constants
02870                 CLICKED_XXXX defined at the top of ccolbar.cpp
02871 
02872     Purpose:    Checks which part of the ColourBar the given point lies over (if
02873                 any) and returns a value indicating where it is.
02874 
02875     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
02876 
02877 ********************************************************************************************/
02878 
02879 INT32 CColourBar::WhereIsMouse(wxPoint MousePos, wxRect *TheRectItIsIn, BOOL *ToLeft)
02880 {
02881     if (ToLeft != NULL)     // Sensible default output
02882         *ToLeft = TRUE;
02883 
02884     if (StripRect.Inside(MousePos))     // Check ColourStrip - MUST be checked first!
02885     {
02886         if (TheRectItIsIn != NULL)
02887             *TheRectItIsIn = StripRect;
02888 
02889         // If necessary, determine if the pointer is in the left or right half of the colour cell
02890         if (ToLeft != NULL)
02891         {
02892             if ( (MousePos.x - StripRect.x) % CellSize >= CellSize / 2)
02893             {
02894                 // The pointer is in the right hand side of the cell, so return ToLeft=FALSE
02895                 *ToLeft = FALSE;
02896             }
02897         }
02898 
02899         return((INT32) (((MousePos.x - StripRect.x) / CellSize) + LeftmostColour));
02900     }
02901 
02902     if (IndicatorRect.Inside(MousePos)) // Check Indicator patch
02903     {
02904         if (TheRectItIsIn != NULL)
02905             *TheRectItIsIn = IndicatorRect;
02906         return(CLICKED_INDICATORS);
02907     }
02908 
02909     if (EditButtonRect.Inside(MousePos))
02910     {
02911         if (TheRectItIsIn != NULL)
02912             *TheRectItIsIn = EditButtonRect;
02913         return(CLICKED_EDITBUTTON);
02914     }
02915 
02916 #if FALSE
02917 /*
02918     if (NewButtonRect.Inside(MousePos))
02919     {
02920         if (TheRectItIsIn != NULL)
02921             *TheRectItIsIn = NewButtonRect;
02922         return(CLICKED_NEWBUTTON);
02923     }
02924 */
02925 #endif
02926 
02927     wxRect TheRect;
02928 
02929     if (!HasNoScrollBar(-1, -1))            // Check Scrollbar rectangle (if any)
02930     {
02931         if (ScrollHeight != 0 && ScrollBarRect.Inside(MousePos) &&
02932             CalculateSausageRect(&TheRect))
02933         {
02934             if (TheRectItIsIn != NULL)
02935                 *TheRectItIsIn = TheRect;
02936 
02937             if (MousePos.x < TheRect.x) // Left of the sausage
02938             {
02939                 if (TheRectItIsIn != NULL)
02940                 {
02941                     TheRectItIsIn->x = ScrollBarRect.x;
02942                     TheRectItIsIn->width = (TheRect.x - 1 - TheRectItIsIn->x);
02943                 }
02944 
02945                 return(CLICKED_SCROLLBARLEFT);
02946             }
02947 
02948             if (MousePos.x > (TheRect.x + TheRect.width))   // Right of the sausage
02949             {
02950                 if (TheRectItIsIn != NULL)
02951                 {
02952                     TheRectItIsIn->x = TheRect.x + TheRect.width + 1;
02953                     TheRectItIsIn->width = ScrollBarRect.x + ScrollBarRect.x - TheRectItIsIn->x;
02954                 }
02955                 return(CLICKED_SCROLLBARRIGHT);
02956             }
02957 
02958             return(CLICKED_SCROLLBAR);      // Middle of the sausage
02959         }
02960 
02961         TheRect = ScrollBarRect;            // Check left scroll button
02962         TheRect.x -= ButtonWidth;
02963         TheRect.width = ButtonWidth;
02964         if (TheRect.Inside(MousePos))
02965         {
02966             if (TheRectItIsIn != NULL)
02967                 *TheRectItIsIn = TheRect;
02968             return(CLICKED_LEFTSCROLL);
02969         }
02970 
02971         TheRect = ScrollBarRect;            // Check right scroll button
02972         TheRect.x += TheRect.width;
02973         TheRect.width = ButtonWidth;
02974         if (TheRect.Inside(MousePos))
02975         {
02976             if (TheRectItIsIn != NULL)
02977                 *TheRectItIsIn = TheRect;
02978             return(CLICKED_RIGHTSCROLL);
02979         }
02980     }
02981 
02982     CalculateNoColourCellRect(&TheRect);    // Check NoColour cell
02983     if (TheRect.Inside(MousePos))
02984     {
02985         if (TheRectItIsIn != NULL)
02986             *TheRectItIsIn = TheRect;
02987         return(CLICKED_NOCOLOURCELL);
02988     }
02989 
02990     return(CLICKED_NOTHING);                // Not over anything important
02991 }
02992 
02993 
02994 
02995 /********************************************************************************************
02996 
02997 >   void CColourBar::ScrollTheStrip(INT32 ScrollBy, BOOL RedrawAlways = FALSE)
02998 
02999     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03000     Created:    23/6/94
03001     Inputs:     ScrollBy - The number of cells (eg +1, -1) by which to scroll the strip
03002                 RedrawAlways - TRUE to always redraw the strip & scrollbar, even if the
03003                 scroll position does not change.
03004     Outputs:    -
03005     Returns:    -
03006     Purpose:    Scrolls the colour strip to the left or right. Does not allow scrolling
03007                 past the ends of the available list. Causes the window to be redrawn.
03008 
03009     Notes:      Passing in ScrollBy=0 has the effect of ensuring that the current scroll
03010                 position is legal for the current colour list - if not, it will be
03011                 corrected and the bar will be redrawn. This can thus be used to ensure
03012                 the bar is updated correctly when paging to a different colour list
03013 
03014                 This recalculates the layout rects and recaches the current colour list
03015                 for itself, so may be called at any time.
03016 
03017                 The ColourBar works exclusively on the SELECTED Doc. Change with care
03018 
03019 ********************************************************************************************/
03020 
03021 void CColourBar::ScrollTheStrip(INT32 ScrollBy, BOOL RedrawAlways)
03022 {
03023     Document *OldCurrentDoc = SetCurrentDoc();
03024 
03025     m_pCurrentColourList = ColourManager::GetColourList();
03026     if (m_pCurrentColourList == NULL)
03027     {
03028         RestoreCurrentDoc(OldCurrentDoc);
03029         return;
03030     }
03031 
03032     INT32 NewLeftmost = (INT32) (LeftmostColour + ScrollBy);
03033 
03034     CalculateRects();
03035 
03036     // INT32 MaxColours = (INT32) m_pCurrentColourList->GetUndeletedCount(); // FIXEDCOLOURS
03037     INT32 MaxColours = GetNumberOfColours();
03038 
03039     INT32 DisplayedColours = StripRect.width / CellSize;
03040 
03041     if (NewLeftmost > MaxColours - DisplayedColours)
03042         NewLeftmost = MaxColours - DisplayedColours;
03043 
03044     if (NewLeftmost < 0)
03045         NewLeftmost = 0;
03046 
03047     if ((UINT32) NewLeftmost != LeftmostColour || RedrawAlways)
03048     {
03049         ScrollBy = (INT32) (NewLeftmost - LeftmostColour); // Calculate REAL ScrollBy
03050 
03051         LeftmostColour = NewLeftmost;               // Update the scroll position
03052         if (ScrollHeight != 0)                      // If there is a scroll bar...
03053             ForceRedrawOfRect(ScrollBarRect);       // ...force redraw it
03054 
03055 PORTNOTE("other","Removed ScrollWindowEx usage")
03056 #if !defined(EXCLUDE_FROM_XARALX)
03057         if (abs(ScrollBy) < DisplayedColours)
03058         {
03059             // Scroll the StripRect using ScrollWindowEx (this blits the existing
03060             // window contents across, then invalidates the bit that needs redrawing)
03061             wxRect RectToScroll(StripRect);
03062             if (ScrollBy < 0)
03063                 RectToScroll.width += -ScrollBy * CellSize;
03064             else
03065             {
03066                 RectToScroll.x -= ScrollBy * CellSize;
03067                 RectToScroll.width += ScrollBy * CellSize;
03068             }
03069 
03070             ScrollWindow(-ScrollBy * CellSize, 0);
03071             Update();
03072         }
03073         else
03074 #endif
03075             ForceRedrawOfRect(StripRect);   // Force redraw the entire colour strip
03076     }
03077 
03078     RestoreCurrentDoc(OldCurrentDoc);
03079 }
03080 
03081 
03082 
03083 /********************************************************************************************
03084 
03085 >   void CColourBar::ApplyColour(IndexedColour *TheColour, BOOL SetLineColour)
03086 
03087     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03088     Created:    5/10/94 (separated from CellClicked() - originally written 23/6/94)
03089     Inputs:     TheColour - The IndexedColour to apply, or NULL to apply 'no colour' (complete
03090                             transparency)
03091                 SetLineColour - TRUE to set this as a line colour, FALSE to set as a fill colour
03092 
03093     Purpose:    Applies the given IndexedColour as a stroke/fill colour attribute to the
03094                 selected objects. This also makes the colour the 'current' attribute, etc,
03095                 if desired by the user.
03096 
03097     Scope:      private
03098 
03099     Notes:      Works on CurrentDoc, so ensure Current == Selected before calling this function
03100 
03101 ********************************************************************************************/
03102 
03103 void CColourBar::ApplyColour(IndexedColour *TheColour, BOOL SetLineColour)
03104 {
03105     NodeAttribute *Attrib = NULL;
03106     DocColour ColourToApply(COLOUR_TRANS);
03107 
03108     if (TheColour != NULL)
03109         ColourToApply.MakeRefToIndexedColour(TheColour);
03110 
03111     if (SetLineColour)
03112     {
03113         // Line colour selected so create a line colour attribute
03114         Attrib = new AttrStrokeColourChange;
03115         if (Attrib == NULL)
03116             return;
03117 
03118         ((AttrStrokeColourChange *)Attrib)->SetStartColour(&ColourToApply);
03119 
03120         // AttributeSelected knows what to do with a selected attribute
03121         AttributeManager::AttributeSelected(NULL, Attrib); 
03122 
03123 /*
03124         // Bodge Alert !!
03125         // To make blends work properly, we need to set the line transparecy.
03126         // We set it to Max if the colour is 'Tranaparent' or zero otherwise
03127         Attrib = new AttrStrokeTranspChange;
03128         if (Attrib == NULL)
03129             return;
03130 
03131         UINT32 Transp;
03132 
03133         if (ColourToApply.IsTransparent())
03134             Transp = 255;
03135         else
03136             Transp = 0;
03137 
03138         ((AttrStrokeTranspChange *)Attrib)->SetStartTransp(&Transp);
03139 
03140         // AttributeSelected knows what to do with a selected attribute
03141         AttributeManager::AttributeSelected(NULL, Attrib); 
03142 */
03143     }
03144     else
03145     {   
03146         // Rather than setting the flat fill colour, we do an AttrColourChange, which
03147         // (I assume) will handle things like selected grad fill points, etc.
03148         Attrib = new AttrColourChange;
03149         if (Attrib == NULL)
03150             return;
03151 
03152         ((AttrColourChange *)Attrib)->SetStartColour(&ColourToApply);
03153 
03154         // AttributeSelected knows what to do with a selected attribute
03155         AttributeManager::AttributeSelected(NULL, Attrib); 
03156     }
03157 
03158     // Note: Redraw of affected parts of the colour bar (indicator diamonds, etc) will
03159     // automatically occur as a result of the message which the AttributeManager will
03160     // broadcast in the above call. Thus we need do no more.
03161 }
03162 
03163 
03164 /********************************************************************************************
03165 
03166 >   void CColourBar::CellClicked(INT32 CellIndex, BOOL SetLineColour)
03167 
03168     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03169     Created:    23/6/94
03170     Inputs:     CellIndex - The index of the clicked colour cell (0..MaxColours)
03171                 SetLineColour - TRUE to set the line colour to the given colour
03172                 FALSE to set the fill color to the given colour
03173     Outputs:    -
03174     Returns:    -
03175     Purpose:    Processes a click on a given colour cell by setting the line/fill
03176                 colour of the selected objects, or if nothing is selected, setting
03177                 the default line/fill colour.
03178 
03179     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03180 
03181                 If you add code to this routine, note the way in which we return - the
03182                 selected order must always be deselected before exit
03183 
03184 ********************************************************************************************/
03185 
03186 void CColourBar::CellClicked(INT32 CellIndex, BOOL SetLineColour)
03187 {
03188     if ((CellIndex >= CLICKED_NOTHING && CellIndex != CLICKED_NOCOLOURCELL) ||
03189             m_pCurrentColourList == NULL)
03190         return;
03191 
03192     // Ensure that CurrentDoc == SelectedDoc
03193     Document *OldCurrentDoc = SetCurrentDoc();
03194 
03195     // Create an attribute of the correct type
03196     IndexedColour *TheColour  = NULL;
03197     if (CellIndex != CLICKED_NOCOLOURCELL)
03198     {
03199         // If the user has asked for document colours in the colour line then check these first
03200         if (ColourSGallery::ShowDocumentColours)
03201             TheColour = FindColourByIndex(CellIndex);
03202 
03203         // If we didn't find it there check the library colours
03204         if (TheColour == NULL)
03205         {
03206             // FIXED COLOURS
03207             // It is not one of the standard document colours so check the fixed library colours
03208             // If it finds the correct one then this will create an indexed colour and add it to
03209             // the currently selected document
03210             TheColour = FindLibIndexedColourByIndex(CellIndex);
03211             if (TheColour == NULL)
03212             {
03213                 // It is an unknown colour so just exit
03214                 // Before exiting the function, we must always restore CurrentDoc
03215                 RestoreCurrentDoc(OldCurrentDoc);
03216                 return;
03217             }
03218         }
03219     }
03220 
03221     ApplyColour(TheColour, SetLineColour);      // Apply this colour to the selection
03222 
03223     RestoreCurrentDoc(OldCurrentDoc);           // Restore previous CurrentDoc value
03224 }
03225 
03226 
03227 
03228 /********************************************************************************************
03229 
03230 >   TCHAR *CColourBar::HelpCallbackHandler(wxWindow* Window, INT32 Item, void *UserData)
03231 
03232     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03233     Created:    2/5/94 (moved to new CColourBar from ColourBar 23/6/94)
03234     Inputs:     Window - The window handle for which bubble help is required (ignored)
03235                 Item - The item (in our case the colour index) on which we want help
03236                 UserData - user data passed on to us by the help system - ignored
03237 
03238     Purpose:    Callback handler for providing Bubble help over the Colour Bar window.
03239 
03240     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03241 
03242 ********************************************************************************************/
03243 
03244 TCHAR *CColourBar::HelpCallbackHandler(wxWindow* Window, INT32 Item, void *UserData)
03245 {
03246     static String_64 HelpStringStore;
03247     StringBase *HelpString = NULL;
03248 
03249     if (TheColourBar == NULL || Item == CLICKED_NOTHING)
03250         return(NULL);
03251 
03252 //  ASSERT_VALID(TheColourBar);
03253 
03254     if (Item >= CLICKED_NOTHING)
03255     {
03256         switch(Item)
03257         {
03258             case CLICKED_SCROLLBAR:         // 'Drag to scroll'
03259                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HSCROLL));
03260                 HelpString = &HelpStringStore;
03261                 break;
03262 
03263             case CLICKED_SCROLLBARLEFT:     // 'Click to scroll'
03264             case CLICKED_SCROLLBARRIGHT:
03265             case CLICKED_LEFTSCROLL:
03266             case CLICKED_RIGHTSCROLL:
03267                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HBUTTONS));
03268                 HelpString = &HelpStringStore;
03269                 break;
03270 
03271             case CLICKED_INDICATORS:        // 'Current line/fill colours'
03272                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HINDICATOR));
03273                 HelpString = &HelpStringStore;
03274                 break;
03275 
03276             case CLICKED_NOCOLOURCELL:
03277                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HNOCOLOUR));
03278                 HelpString = &HelpStringStore;
03279                 break;
03280 
03281             case CLICKED_EDITBUTTON:
03282                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HEDITBUTTON));
03283                 HelpString = &HelpStringStore;
03284                 break;
03285 
03286 #if FALSE
03287             case CLICKED_NEWBUTTON:
03288                 HelpStringStore.MakeMsg(_R(IDS_COLBAR_HNEWBUTTON));
03289                 HelpString = &HelpStringStore;
03290                 break;
03291 #endif
03292         }
03293     }
03294     else
03295     {
03296         // We are over a colour cell - bubble-help its name
03297         IndexedColour *TheColour = NULL;
03298         // If the user has the preference set then include and hence show the document
03299         // colours
03300         if (ColourSGallery::ShowDocumentColours)
03301             TheColour = TheColourBar->FindColourByIndex(Item);
03302 
03303         if (TheColour != NULL)
03304         {
03305             HelpStringStore = *(TheColour->GetName());
03306             HelpString = &HelpStringStore;
03307         }
03308         else
03309         {
03310 PORTNOTE("other","Removed ColourSGallery usage")
03311 #if !defined(EXCLUDE_FROM_XARALX)
03312             // Check to see if its a colour library item
03313             SGDisplayLibColour *pLibColour = NULL;
03314             DocColour * pTheColour = TheColourBar->FindLibColourByIndex(Item, &pLibColour);
03315             if (pTheColour && pLibColour)
03316             {
03317                 // Get the name of the item from the LibColour gallery item
03318                 // which is keeping it safe for us
03319                 String_256 Buffer;
03320                 pLibColour->GetNameText(&Buffer);
03321                 HelpStringStore = Buffer;
03322                 HelpString = &HelpStringStore;
03323             }
03324 #endif
03325         }
03326     }
03327 
03328     if (HelpString != NULL)
03329         return((TCHAR *) *HelpString);
03330 
03331     return(NULL);
03332 }
03333 
03334 
03335 
03336 /********************************************************************************************
03337 
03338 >   static void CColourBar::PaletteHasChanged(ColourList *ChangedList)
03339 
03340     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03341     Created:    23/6/94
03342     Inputs:     ChangedList - NULL if the list has been paged to a different one,
03343                 or a pointer to the list in which a change has been made.
03344                 
03345     Purpose:    This will cause the colourbar to redraw itself with the new list
03346                 if necessary, and cache new values for the new current list.
03347 
03348     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03349 
03350 ********************************************************************************************/
03351 
03352 void CColourBar::PaletteHasChanged(ColourList *ChangedList)
03353 {
03354     if (TheColourBar == NULL)       // There is no colour bar!
03355         return;
03356 
03357     // Scroll (if necessary) to show the current colour indicators properly
03358     TheColourBar->SelectionHasChangedInternal();
03359 
03360     //   a) Scroll the strip by 0 cells to ensure it is scrolled to a legal position
03361     TheColourBar->ScrollTheStrip(0);
03362 
03363     //   b) Force redraw the window. We pass FALSE so the window does not flicker as
03364     //      it is updated (as the Paint() function completely fills the window anyway)
03365     //   c) If the bar needs to add/remove a scrollbar, force a layout recalculation
03366     wxRect TheRect = TheColourBar->GetClientRect();
03367     INT32 NewBarHeight = TheColourBar->CalculateNewBarHeight(&TheRect);
03368 
03369     TheColourBar->OldBarHeight = TheColourBar->GetCurrentBarHeight();
03370 
03371     if (NewBarHeight == TheColourBar->OldBarHeight)
03372         TheColourBar->Refresh(false);       // Redraw, but don't erase bground (stops flicker)
03373     else
03374     {
03375         TheColourBar->Refresh(true);        // Redraw (clear to grey for tidier resize)
03376         GetMainFrame()->UpdateFrameManager();   // Resize to add/remove the scrollbar
03377     }
03378 }
03379 
03380 
03381 
03382 /********************************************************************************************
03383 
03384 >   INT32 CColourBar::CalculateColourCellIndex(IndexedColour *TheColour)
03385 
03386     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03387     Created:    6/7/94
03388     Inputs:     TheColour - The colour to find the index of
03389     Returns:    The index (0..NumColours-1) of the colour cell containing the
03390                 colour, or CELLINDEX_NOCELL (-2) if the colour wasn't found
03391 
03392     Purpose:    Searches the colour list to find the given colour, returning its
03393                 index in the list if it is found, or a negative value if it is not.
03394 
03395     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03396 
03397 ********************************************************************************************/
03398 
03399 INT32 CColourBar::CalculateColourCellIndex(IndexedColour *TheColour)
03400 {
03401     m_pCurrentColourList = ColourManager::GetColourList();
03402 
03403     if (TheColour == NULL || m_pCurrentColourList == NULL)
03404         return(CELLINDEX_NOCELL);
03405 
03406     INT32 Index = 0;
03407 
03408     // If the user has asked for document colours in the colour line then check these first
03409     // Indexed Colours are document colours and so can never exist in the library groups.
03410     if (ColourSGallery::ShowDocumentColours)
03411     {
03412         IndexedColour *TestColour = m_pCurrentColourList->GetUndeletedHead();
03413 
03414         while (TestColour != NULL)
03415         { 
03416             if (TheColour == TestColour)
03417                 return((INT32) Index);
03418 
03419             TestColour = m_pCurrentColourList->GetUndeletedNext(TestColour);
03420             Index++;
03421         }
03422     }
03423 
03424     // Didn't find a match for this colour in the list
03425     return(CELLINDEX_NOCELL);
03426 }
03427 
03428 
03429 
03430 /********************************************************************************************
03431 
03432 >   INT32 CColourBar::CalculateColourCellIndex(DocColour *TheColour)
03433 
03434     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03435     Created:    14/7/94
03436     Inputs:     TheColour - the colour whose Cell index you wish to calculate
03437     Returns:    CELLINDEX_NOCOLOURCELL, CELLINDEX_NOCELL, or the index of the given colour
03438 
03439     Purpose:    Given a DocColour, will determine which *visible* colour cell, if any,
03440                 is displaying that colour, anmd return its Cell Index.
03441 
03442     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03443 
03444 ********************************************************************************************/
03445 
03446 INT32 CColourBar::CalculateColourCellIndex(DocColour *TheColour)
03447 {
03448     if (TheColour == NULL)
03449         return(CELLINDEX_NOCELL);
03450 
03451     if (TheColour->IsTransparent())
03452         return(CELLINDEX_NOCOLOURCELL);
03453 
03454     return (CalculateColourCellIndex(TheColour->FindParentIndexedColour()));
03455 }
03456 
03457 
03458 
03459 /********************************************************************************************
03460 
03461 >   void CColourBar::ForceRedrawOfCell(INT32 CellIndex)
03462 
03463     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03464     Created:    6/7/94
03465     Inputs:     CellIndex - Index of the colour cell to redraw
03466     Purpose:    Forces a redraw of the given Cell in the colour strip. The index is from
03467                 the first colour in the list - if this is outside the displayed portion of
03468                 the colour strip, no action will be taken
03469     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03470 
03471 ********************************************************************************************/
03472 
03473 void CColourBar::ForceRedrawOfCell(INT32 CellIndex)
03474 {
03475     if (CellIndex == CELLINDEX_NOCOLOURCELL)        // Redraw No-colour cell
03476     {
03477         wxRect Rect;
03478         CalculateNoColourCellRect(&Rect);
03479 
03480         ForceRedrawOfRect(Rect);
03481         return;
03482     }
03483 
03484     if (CellIndex < (INT32)LeftmostColour)          // Cell is not visible (off left of strip)
03485         return;
03486 
03487     // Calculate position of the colour cell in the strip...
03488     wxRect RedrawRect(StripRect);                   // Copy the striprect
03489 
03490                                                     // Calculate left edge of the cell
03491     RedrawRect.x += CellSize * (CellIndex - LeftmostColour);
03492     if (RedrawRect.x > (StripRect.x + StripRect.width)) // Cell is not visible (off right of strip)
03493         return;
03494 
03495     RedrawRect.width = CellSize;                    // Set width of the cell
03496     ForceRedrawOfRect(RedrawRect);                  // redraw the sucker
03497 }
03498 
03499 
03500 
03501 /********************************************************************************************
03502 
03503 >   void CColourBar::SelectionHasChangedInternal(void)
03504 
03505     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03506     Created:    6/7/94
03507     Purpose:    This will cause the colourbar to redraw any necessary portions of the
03508                 colour strip and indicators to indicate the colour of the selection
03509                 (or the default line/fill colours if there is no selection)
03510 
03511     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03512 
03513 ********************************************************************************************/
03514 
03515 void CColourBar::SelectionHasChangedInternal(void)
03516 {
03517     static Document *LastDocument = NULL;
03518     static INT32 LastClickedLineCell = CELLINDEX_NOCELL;
03519     static INT32 LastClickedFillCell = CELLINDEX_NOCELL;
03520     static INT32 LastClickedEndCell  = CELLINDEX_NOCELL;
03521 
03522     // If the user has not asked for document colours in the colour line then 
03523     // no need to do any of the checks below
03524     if (!ColourSGallery::ShowDocumentColours)
03525     {
03526         ForceRedrawOfRect(TheColourBar->IndicatorRect);         // And redraw the colour indicators
03527         return;
03528     }
03529 
03530     // If swapped documents then forget the last clicked cells
03531     if (LastDocument != Document::GetSelected())
03532     {
03533         LastClickedFillCell = LastClickedEndCell = LastClickedLineCell = CELLINDEX_NOCELL;
03534         LastDocument = Document::GetSelected();
03535     }
03536 
03537     DocColour *LineColour;
03538     DocColour *FillColour;
03539     DocColour *EndColour;
03540 
03541     BOOL DiamondShape = ColourManager::GetCurrentLineAndFillColours(&LineColour,
03542                                                                 &FillColour, &EndColour);
03543     INT32 MinorScrollTo = CELLINDEX_NOCELL;
03544     INT32 MajorScrollTo = CELLINDEX_NOCELL;
03545 
03546     // Determine if we're changing from flatfill display to gradfill or vice-versa. In this case,
03547     // the Fill diamond will change between arow and diamond - if the fill happens to be the same
03548     // colour, this will leave the screen state incorrect, so we must forceredraw it.
03549     BOOL MustRedrawFill = FALSE;
03550     if (EndColour != NULL)
03551     {
03552         if (LastEndCell == CELLINDEX_NOCELL)                    // Change from flat to grad
03553             MustRedrawFill = TRUE;
03554     }
03555     else
03556     {
03557         if (LastEndCell != CELLINDEX_NOCELL)                    // Change from grad to flat
03558             MustRedrawFill = TRUE;
03559     }
03560 
03561     // Now redraw (only as necessary) the line, fill and end-fill cells, and determine
03562     // the major and minor cell positions to autoscroll to.
03563     if (LineColour == NULL)                                     // Is there a line colour?
03564     {
03565         ForceRedrawOfCell((INT32) LastLineCell);                    // No - Remove the old indicator diamond
03566         LastLineCell = CELLINDEX_NOCELL;                        // ... and remember it is not displayed
03567     }
03568     else
03569     {
03570         INT32 CellIndex = CalculateColourCellIndex(LineColour);
03571 
03572         if (CellIndex != LastClickedLineCell)                   // Set Minor scroll position, and
03573             MinorScrollTo = LastClickedLineCell = CellIndex;    // remember where we last put diamond
03574 
03575         if (MinorScrollTo == CELLINDEX_NOCOLOURCELL)            // NoColour doesn't cause scrolling
03576             MinorScrollTo = CELLINDEX_NOCELL;
03577 
03578         // If selected cell changed (or diamond shape has changed)...
03579         if (CellIndex != LastLineCell || LastDiamondShape != DiamondShape)
03580         {
03581             ForceRedrawOfCell((INT32)LastLineCell);             // Redraw old colour cell
03582             ForceRedrawOfCell(CellIndex);                       // Redraw new colour cell
03583             LastLineCell = CELLINDEX_NOCELL;
03584             // (LastLineCell will be automagically updated by the PaintDiamond code)
03585         }
03586     }
03587 
03588     if (FillColour == NULL)                                     // is there a Fill colour?
03589     {
03590         ForceRedrawOfCell((INT32)LastFillCell);                 // No- Remove the old indicator diamond
03591         LastFillCell = CELLINDEX_NOCELL;                        // ... and remember it is not displayed
03592     }
03593     else
03594     {
03595         INT32 CellIndex = CalculateColourCellIndex(FillColour);
03596 
03597         if (CellIndex != LastClickedFillCell)                   // Set Major scroll position, and
03598             MajorScrollTo = LastClickedFillCell = CellIndex;    // remember where we last put diamond
03599 
03600         if (MajorScrollTo == CELLINDEX_NOCOLOURCELL)            // NoColour doesn't cause scrolling
03601             MajorScrollTo = CELLINDEX_NOCELL;
03602 
03603         // If selected cell changed (or diamond shape has changed)...
03604         if (CellIndex != LastFillCell || LastDiamondShape != DiamondShape || MustRedrawFill)
03605         {
03606             ForceRedrawOfCell((INT32)LastFillCell);             // Redraw old colour cell
03607             ForceRedrawOfCell(CellIndex);                       // Redraw new colour cell
03608             LastFillCell = CELLINDEX_NOCELL;
03609             // (LastFillCell will be automagically updated by the PaintDiamond code)
03610         }
03611     }
03612 
03613     if (EndColour == NULL)
03614     {
03615         ForceRedrawOfCell((INT32)LastEndCell);                  // No- Remove the old indicator diamond
03616         LastEndCell = CELLINDEX_NOCELL;                         // ... and remember it is not displayed
03617     }
03618     else
03619     {
03620         INT32 OtherMajor = CELLINDEX_NOCELL;
03621         INT32 CellIndex = CalculateColourCellIndex(EndColour);
03622 
03623         if (CellIndex != LastClickedEndCell)                    // Set alternat major scroll position, and
03624             OtherMajor = LastClickedEndCell = CellIndex;        // remember where we last put diamond
03625 
03626         if (OtherMajor == CELLINDEX_NOCOLOURCELL)               // NoColour doesn't cause scrolling
03627             OtherMajor = CELLINDEX_NOCELL;
03628 
03629         // If selected cell changed (or diamond shape has changed)...
03630         if (CellIndex != LastEndCell || LastDiamondShape != DiamondShape)
03631         {
03632             ForceRedrawOfCell((INT32)LastEndCell);              // Redraw old colour cell
03633             ForceRedrawOfCell(CellIndex);                       // Redraw new colour cell
03634             LastEndCell = CELLINDEX_NOCELL;
03635             // (LastEndCell will be automagically updated by the PaintDiamond code)
03636         }
03637 
03638         // And now decide which of the 3 colours are most important, and decide on major and minor
03639         // scroll-to positions. By default this is already set up to be Fill,Line, but if the end-grad
03640         // colour is not no-colour, it may override the line colour
03641         if (OtherMajor != CELLINDEX_NOCELL)
03642         {
03643             if (MajorScrollTo == CELLINDEX_NOCELL)
03644                 MajorScrollTo = OtherMajor;         // There's only one non-transparent fill, so use it
03645             else
03646             {
03647                 if (MinorScrollTo == CELLINDEX_NOCELL)
03648                     MinorScrollTo = OtherMajor;     // There's no line colour, so just make it the minor
03649                 else
03650                 {
03651                     // We have 3 colours - we will remove the middle one, to maximise the chance of
03652                     // them all being shown (if left/right are visible, the middle must also be visible)
03653 
03654                     if (MinorScrollTo < MajorScrollTo)
03655                     {
03656                         if (OtherMajor < MinorScrollTo)
03657                             MinorScrollTo = OtherMajor;
03658                         else if (OtherMajor > MajorScrollTo)
03659                             MajorScrollTo = OtherMajor;
03660                     }
03661                     else
03662                     {
03663                         if (OtherMajor > MinorScrollTo)
03664                             MinorScrollTo = OtherMajor;
03665                         else if (OtherMajor < MajorScrollTo)
03666                             MajorScrollTo = OtherMajor;
03667                     }
03668                 }
03669             }
03670         }
03671     }
03672 
03673     
03674     // OK, let's autoscroll - Preferably both Major and Minor can be shown, but if not, it is better
03675     // to show Major (fill) than Minor (line).
03676 
03677     if (MajorScrollTo == CELLINDEX_NOCELL)  // Only one diamond, so make it the major one
03678     {
03679         MajorScrollTo = MinorScrollTo;
03680         MinorScrollTo = CELLINDEX_NOCELL;
03681     }
03682 
03683     if (MajorScrollTo != CELLINDEX_NOCELL)
03684     {
03685         // We have 1 or 2 cells that we'd really like visible in the bar if possible.
03686         // The MajorScrollTo is the most important one, so we ensure it is visible, and
03687         // then shift slightly from that scroll pos, if possible, to get the minor in too
03688         // It's also important to minimise scrolling (i.e if the targets can all be seen
03689         // already then we will not move them)
03690 
03691         // Calculate how many colour cells are visible
03692         INT32 NumDisplayedColours = StripRect.width / CellSize;
03693 
03694         BOOL TwoDiamonds = TRUE;            // There are either 1 or 2 diamonds to try to show
03695 
03696         // Convert the cell index into a desired scroll offset from current pos (scroll-by)
03697         MajorScrollTo -= LeftmostColour;
03698         if (MinorScrollTo == CELLINDEX_NOCELL)
03699         {
03700             MinorScrollTo = MajorScrollTo;  // Ensure we scroll to Major one only
03701             TwoDiamonds = FALSE;            // There is only one diamond to try to show
03702         }
03703         else
03704             MinorScrollTo -= LeftmostColour;
03705 
03706         // If one of the 2 diamonds is not already visible, we need to scroll
03707         if (MajorScrollTo < 0 || MajorScrollTo >= NumDisplayedColours ||
03708             MinorScrollTo < 0 || MinorScrollTo >= NumDisplayedColours)
03709         {
03710             INT32 ScrollBy = 0;
03711 
03712             // One or both diamonds are not visible, so we'll have to try scrolling...
03713             if (TwoDiamonds && abs(MajorScrollTo - MinorScrollTo) <= NumDisplayedColours)
03714             {
03715                 if (abs(MajorScrollTo - MinorScrollTo) >= NumDisplayedColours - 1)
03716                 {
03717                     // The diamonds fit exactly at the left/right ends of the bar. We must
03718                     // special case this (rounding errors in the average may get the posn
03719                     // one cell out in this case) - scroll the leftmost diamond to the
03720                     // left end of the bar.
03721 
03722                     ScrollBy = min(MinorScrollTo, MajorScrollTo);
03723                 }
03724                 else
03725                 {
03726                     // Both diamonds should fit on if we just scroll to the average position
03727                     ScrollBy = (MajorScrollTo + MinorScrollTo) / 2;
03728                     ScrollBy -= NumDisplayedColours / 2;        // Turn into center-relative scroll
03729                 }
03730             }
03731             else
03732             {
03733                 // There is only one diamond, or we can only fit one of the diamonds
03734                 // on, so scroll to the major one
03735                 ScrollBy = MajorScrollTo - NumDisplayedColours / 2; // Turn into center-relative scroll
03736             }
03737 
03738 #ifndef EXCLUDE_GALS
03739             if (
03740                 ColourSGallery::AutoScrollSelection && 
03741                 ScrollBy != 0)
03742             {
03743                 ScrollTheStrip(ScrollBy);
03744             }
03745 #endif
03746         }
03747     }
03748 
03749     ForceRedrawOfRect(TheColourBar->IndicatorRect);         // And redraw the colour indicators
03750 }
03751 
03752 
03753 
03754 /********************************************************************************************
03755 
03756 >   static void CColourBar::SelectionHasChanged(void)
03757 
03758     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03759     Created:    6/7/94
03760     Purpose:    This will cause the colourbar to redraw any necessary portions of the
03761                 colour strip and indicators to indicate the colour of the selection
03762                 (or the default line/fill colours if there is no selection)
03763 
03764     Notes:      This is just a veneer. It is a static function which finds the current
03765                 ColourBar (if any) and passes the call onto its SelectionHasChangedInternal
03766                 function
03767                 The ColourBar works exclusively on the SELECTED Doc. Change with care
03768 
03769 ********************************************************************************************/
03770 
03771 void CColourBar::SelectionHasChanged(void)
03772 {
03773     if (TheColourBar != NULL)
03774         TheColourBar->SelectionHasChangedInternal();
03775 }
03776 
03777 
03778 
03779 /********************************************************************************************
03780 
03781 >   void CColourBar::ReleaseAllClaims(void)
03782 
03783     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03784     Created:    27/6/94
03785     Inputs:     -
03786     Purpose:    Ensures that all our temporary claims (timers, mouse capture) are
03787                 released.
03788 
03789     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03790                 
03791 ********************************************************************************************/
03792 
03793 void CColourBar::ReleaseAllClaims(void)
03794 {
03795     if (DragInfo.TimerOn)
03796     {
03797         m_DragTimer.Stop();
03798         DragInfo.TimerOn = FALSE;
03799     }
03800 
03801     if (HasCapture())
03802     {
03803         ReleaseMouse();
03804     }
03805     DragInfo.MouseCaptured = FALSE;
03806 }
03807 
03808 
03809 
03810 /********************************************************************************************
03811 
03812 >   void CColourBar::SetATimer(BOOL Delay)
03813 
03814     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03815     Created:    27/6/94
03816     Inputs:     Delay - TRUE if this is initial keyboard-delay-before-autorepeat,
03817                 FALSE for auto-repeat
03818 
03819     Purpose:    Sets a timer to cause a timer message to be sent to us after
03820                 the keyboard auto-repeat delay. 
03821                 If we are already waiting for a timer event, the current timer will
03822                 be replaced by the new one.
03823 
03824     Notes:      Delay is currently ignored, because Charles didn't like it (and I
03825                 agree with him).
03826 
03827     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03828                 
03829 ********************************************************************************************/
03830 
03831 void CColourBar::SetATimer(BOOL Delay)
03832 {
03833     if (DragInfo.TimerOn)
03834         m_DragTimer.Stop();
03835 
03836     UINT32 CallbackTime = 1000;
03837     UINT32 RepsPerSec = 5;
03838 
03839 #if FALSE
03840     if (Delay)
03841     {
03842         ::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &RepsPerSec, 0);
03843 
03844         RepsPerSec = 4 - RepsPerSec;
03845     }
03846     else
03847     {
03848         ::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &RepsPerSec, 0);
03849 
03850         RepsPerSec++;
03851     }
03852 #endif
03853 
03854     if (RepsPerSec > 1)
03855         CallbackTime = (UINT32) 1000 / RepsPerSec;
03856 
03857     m_DragTimer.Start(CallbackTime);
03858     DragInfo.TimerOn = TRUE;
03859 }
03860 
03861 
03862 
03863 /********************************************************************************************
03864 
03865 >   void CColourBar::CaptureTheMouse(void)
03866 
03867     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03868     Created:    27/6/94
03869     Inputs:     -
03870     Purpose:    Captures the mouse for drags/autorepeat. Nothing will be done if
03871                 we already have mouse capture.
03872 
03873     Notes:      When capturing the mouse, you should also set the value of
03874                 DragInfo.CaptureRect to the area within which the mouse was captured.
03875                 This allows the other handlers to determine if the mouse strays
03876                 out of the relevant area (in which case scrolling/autorepeat will
03877                 cease). If not set, this will cause odd effects.
03878 
03879                 The ColourBar works exclusively on the SELECTED Doc. Change with care
03880 
03881 ********************************************************************************************/
03882 
03883 void CColourBar::CaptureTheMouse(void)
03884 {
03885     TRACEUSER("Gerry", _T("CColourBar::CaptureTheMouse"));
03886 
03887     if (DragInfo.MouseCaptured)
03888     {
03889         TRACEUSER("Gerry", _T("Already got capture"));
03890         return;
03891     }
03892 
03893     CaptureMouse();
03894     DragInfo.MouseCaptured = TRUE;
03895 }
03896 
03897 
03898 
03899 /********************************************************************************************
03900 
03901 >   void CColourBar::EditAColour(ColourList *DisplayList, IndexedColour *TheColour,
03902                                     BOOL LineColour = FALSE)
03903 
03904     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03905     Created:    28/6/94
03906     Inputs:     DisplayList - The ColourList in which the colour resides.
03907                 TheColour - The Colour to be edited
03908                 LineColour - TRUE if this should be the line colour (ignored unless
03909                             TheColour and DisplayList are both non-NULL)
03910     Outputs:    -
03911     Returns:    -
03912     Purpose:    Edits the given colour.
03913 
03914     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03915 
03916     Scope:      private
03917     Errors:     -
03918     SeeAlso:    ColourPicker::EditColour
03919 
03920 ********************************************************************************************/
03921 
03922 void CColourBar::EditAColour(ColourList *DisplayList, IndexedColour *TheColour,
03923                                 BOOL LineColour)
03924 {
03925     ColourPicker ColPicker;
03926 
03927     if (DisplayList == NULL || TheColour == NULL)
03928         ColPicker.EditColour(NULL, NULL, LineColour);   // Open, but don't edit anything
03929     else
03930         ColPicker.EditColour(DisplayList, TheColour);
03931 }
03932 
03933 
03934 
03935 /********************************************************************************************
03936 
03937 >   static void CColourBar::RedrawGBrushAreas(void)
03938 
03939     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03940     Created:    29/6/94
03941     Purpose:    Force-redraws all areas of the colourbar that depend upon GBrush
03942                 for their rendering. Used by winoil\gbrush.cpp when GBrush rendering
03943                 is enabled or disabled in order to redraw the colourbar.
03944 
03945     Notes:      The ColourBar works exclusively on the SELECTED Doc. Change with care
03946 
03947 ********************************************************************************************/
03948 
03949 void CColourBar::RedrawGBrushAreas(void)
03950 {
03951     if (TheColourBar == NULL)
03952         return;
03953 
03954     TheColourBar->CalculateRects();
03955     TheColourBar->ForceRedrawOfRect(TheColourBar->StripRect);   
03956     TheColourBar->ForceRedrawOfRect(TheColourBar->IndicatorRect);   
03957     TheColourBar->Update();
03958 }
03959 
03960 
03961 
03962 /********************************************************************************************
03963 
03964 >   IndexedColour *CColourBar::FindColourByIndex(UINT32 Index)
03965 
03966     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03967     Created:    4/8/94
03968     Returns:    NULL, or a pointer to the IndexedColour we are interested in.
03969 
03970     Purpose:    Given the current Display List, finds the 'Index'th item, and
03971                 dereferences it to find the actual IndexedColour that lies
03972                 at that list position in the current colour bar display order.
03973 
03974     Notes:      Ensures that m_pCurrentColourList is up to date. If no list can be found,
03975                 it returns NULL.
03976 
03977                 Ignores 'deleted' colours held in the colour list
03978 
03979     Scope:      private (to ccolourbar)
03980 
03981 ********************************************************************************************/
03982 
03983 IndexedColour *CColourBar::FindColourByIndex(UINT32 Index)
03984 {
03985     if (m_pCurrentColourList == NULL)
03986         m_pCurrentColourList = ColourManager::GetColourList();
03987 
03988     if (m_pCurrentColourList == NULL)
03989     {
03990         ERROR3(_T("CColourBar::FindColourByIndex can't handle NULL Colour Lists"));
03991         return(NULL);
03992     }
03993 
03994     // First, check if the index is in the main colour list
03995     UINT32 DocColours = (UINT32) m_pCurrentColourList->GetUndeletedCount();
03996     if (Index < DocColours)
03997         return(m_pCurrentColourList->FindUndeletedItem(Index));
03998     
03999     // not in this list so return NULL
04000     return NULL;
04001 }
04002 
04003 /********************************************************************************************
04004 
04005 >   DocColour * CColourBar::FindLibColourByIndex(UINT32 Index, SGDisplayLibColour **ppLibColour = NULL)
04006 
04007     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
04008     Created:    19/3/97
04009     Inputs:     The index of the item required
04010                 An optional SGDisplayLibColour pointer, defaults to null.
04011     Returns:    NULL, or a pointer to the DocColour we are interested in.
04012     Purpose:    Given the current Display List, finds the 'Index'th item, and
04013                 dereferences it to find the actual DocColour that lies
04014                 at that list position in the current colour bar display order.
04015                 This will only look through the Library colours and hence returns DocColours
04016                 rather than indexed colours.
04017 
04018 ********************************************************************************************/
04019 
04020 DocColour * CColourBar::FindLibColourByIndex(UINT32 Index, SGDisplayLibColour **ppLibColour)
04021 {
04022     // First, check if the index is in the main colour list
04023     UINT32 DocColours = 0;
04024     // If the user has the preference set then include and hence show the document
04025     // colours
04026     if (ColourSGallery::ShowDocumentColours)
04027     {
04028         DocColours = (UINT32) m_pCurrentColourList->GetUndeletedCount();
04029         if (Index < DocColours)
04030             return NULL;
04031     }
04032 
04033 PORTNOTE("other","Removed ColourSGallery usage")
04034 #if !defined(EXCLUDE_FROM_XARALX)
04035     // The new index count has to have these doc colours removed from the original index
04036     UINT32 NewIndex = Index - DocColours;
04037 
04038     // Index is beyond the colours in the current document and so try the colour libraries
04039     m_pColourGallery = ColourSGallery::GetInstance();
04040     UINT32 items = 0;
04041     if (m_pColourGallery != NULL)
04042     {
04043         // This will create the groups if they're not there yet
04044         m_pColourGallery->MakeSureGroupsHaveBeenCreated();
04045 
04046         // Find the Netscape palette library
04047         SGDisplayLibColGroup * pLibGroup = m_pColourGallery->GetFirstLibGroup();
04048         BOOL Found = FALSE;
04049         while (!Found && pLibGroup)
04050         {
04051             // Add in any items that are flagged as being required
04052             if (pLibGroup->DisplayInColourLine())
04053             {
04054                 // pLibGroup->DeVirtualise();   // This is dangerous as it may change current doc!
04055                                                 // Disabled as it causes problems during start up
04056                 items = pLibGroup->CountChildren();
04057                 if (NewIndex < items)
04058                 {
04059                     return pLibGroup->GetItemColour(NewIndex, ppLibColour);
04060                 }
04061                 else
04062                 {
04063                     // remove these items from the count
04064                     NewIndex -= items;
04065                 }
04066             }
04067 
04068             pLibGroup = m_pColourGallery->GetNextLibGroup(pLibGroup);
04069         }
04070     }
04071 #endif
04072     // Nothing found
04073     return NULL;
04074 } 
04075 
04076 /********************************************************************************************
04077 
04078 >   IndexedColour * CColourBar::FindLibIndexedColourByIndex(UINT32 Index)
04079 
04080     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
04081     Created:    19/3/97
04082     Inputs:     The index of the item required
04083     Returns:    NULL, or a pointer to the IndexedColour we are interested in.
04084     Purpose:    Given the current Display List, finds the 'Index'th item, and
04085                 dereferences it to find the actual DocColour that lies
04086                 at that list position in the current colour bar display order.
04087                 This will only look through the Library colours and hence finds DocColours
04088                 rather than indexed colours. This versions is the same as above but then
04089                 goes and creates an IndexedColour in the current document and returns this.
04090 
04091 ********************************************************************************************/
04092 
04093 IndexedColour * CColourBar::FindLibIndexedColourByIndex(UINT32 Index)
04094 {
04095     // If we have no current colour list then nothing doing
04096     if (m_pCurrentColourList == NULL)
04097         return NULL;
04098 
04099     IndexedColour *pNewCol = NULL;
04100 
04101     SGDisplayLibColour *pLibColour = NULL;
04102     DocColour * pTheColour = FindLibColourByIndex(Index, &pLibColour);
04103 
04104     if (pTheColour == NULL || pLibColour == NULL)
04105         return NULL;
04106 
04107     // We have discovered a library DocColour - we must copy it into the document before trying to apply it
04108     // Make a temporary IndexedColour from the library colour
04109     pNewCol = new IndexedColour(*pTheColour);
04110 
04111     if (pNewCol != NULL)
04112     {
04113         // Set the colour's name to the same as the library item (but make sure it's unique)
04114         String_256 Buffer;
04115         pLibColour->GetNameText(&Buffer);
04116         pNewCol->SetName(Buffer);
04117 // If we do this then the EnsureColourIsInDocument wont do all its work.
04118 // It will handle duplicate names for us
04119 //      if (m_pCurrentColourList->GenerateUniqueColourName(pNewCol->GetName(), (String_64 *) &Buffer))
04120 //          pNewCol->SetName(Buffer);
04121 
04122         // If it's a spot colour, make it so
04123         if (pLibColour->IsASpotColour())
04124             pNewCol->SetLinkedParent(NULL, COLOURTYPE_SPOT);
04125 
04126         // Copy the colour into the destination document (merging it with existing
04127         // colours so we won't keep creating new copies of the same colour as it's applied)
04128         DocColour ColourToApply;
04129         ColourToApply.MakeRefToIndexedColour(pNewCol);
04130         ColourManager::EnsureColourIsInDocument(NULL, Document::GetSelected(), &ColourToApply);
04131 
04132         // Delete the temporary IndexedColour we used
04133         delete pNewCol;
04134 
04135         // And remember the new colour we've just made
04136         pNewCol = ColourToApply.FindParentIndexedColour();
04137     }
04138 
04139     // return the result to the caller
04140     return pNewCol;
04141 }
04142 
04143 
04144 
04145 /********************************************************************************************
04146 
04147 >   static void CColourBar::Show(BOOL ShowOrHide = TRUE)
04148 
04149     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04150     Created:    5/10/94
04151     Inputs:     HideOrShow - TRUE to Show the window (the default)
04152                              FALSE to hide the window
04153 
04154     Purpose:    Tells the colour bar to show or hide itself. The bar will remain
04155                 visible/hidden until the next call to this method. If no colour bar
04156                 currently exists, the desired state will be remembered and used
04157                 on creation of any new bar.
04158 
04159     Scope:      public
04160 
04161 ********************************************************************************************/
04162 
04163 void CColourBar::Show(BOOL ShowOrHide)
04164 {
04165     BarIsVisible = ShowOrHide;                  // Remember our current state
04166 
04167     if (TheColourBar != NULL)                   // If a colour bar exists...
04168     {
04169         if (BarIsVisible)
04170             TheColourBar->Show(true);           // Show or hide the window
04171         else
04172             TheColourBar->Show(false);
04173 
04174         GetMainFrame()->UpdateFrameManager();   // And ensure it places itself usefully!
04175     }
04176 }
04177 
04178 
04179 /********************************************************************************************
04180 
04181 >   void CColourBar::OnSize(wxSizeEvent &event)
04182 
04183     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04184     Created:    22/6/94
04185     Inputs:     all ignored
04186     Purpose:    Handle resizing of our window. This ensures that the scroll offset
04187                 is within the new bounds of the colour strip, and forces a redraw.
04188 
04189 ********************************************************************************************/
04190 
04191 void CColourBar::OnSize(wxSizeEvent &event)
04192 {
04193 //  TRACEUSER("Gerry", _T("CColourBar::OnSize(%d, %d)\n"), event.m_size.x, event.m_size.y);
04194     if (m_pCurrentColourList == NULL)
04195     {
04196         Refresh();      // No colour list - just ensure we're redrawn OK, and exit
04197         return;
04198     }
04199 
04200     INT32 NewWidth = event.GetSize().x;
04201     INT32 NewHeight = event.GetSize().y;
04202 
04203     // Calculate what the new window rect is going to be (width is all the it really needs
04204     // to know) and from it, calculate where ther striprect is going to be placed. From
04205     // this, we can calculate how many colours will be displayed at the new window size.
04206     wxRect AvailableRect(0, 0, NewWidth, NewHeight);
04207 
04208     wxRect tStripRect;      // Temporary lookalikes to the global cached rects
04209     wxRect tIndicatorRect;
04210     wxRect tScrollBarRect;
04211     wxRect tEditButtonRect;
04212     wxRect tNewButtonRect;  // Warning - this button is now defunct
04213 
04214     CalculateRectsInternal(&AvailableRect,
04215                             &tStripRect, &tIndicatorRect, &tScrollBarRect,
04216                             &tEditButtonRect, &tNewButtonRect);
04217 
04218     INT32 NewDisplayedColours = tStripRect.width / CellSize;
04219     
04220     //INT32 MaxColours = (INT32) m_pCurrentColourList->GetUndeletedCount(); // FIXEDCOLOURS
04221     INT32 MaxColours = (INT32)GetNumberOfColours();
04222 
04223     // If height of bar unchanged, we may not need to redraw (stop solid-drag flicker)...
04224     if (NewHeight == OldBarHeight)
04225     {
04226         INT32 OldDisplayedColours = StripRect.width / CellSize;
04227 
04228         // If we can display exactly the same number of colours, no need to redraw
04229         if (NewDisplayedColours == OldDisplayedColours)
04230             return;
04231 
04232         // if all colours were & still-are displayed, then we need not redraw
04233         if (NewDisplayedColours >= MaxColours && OldDisplayedColours >= MaxColours)
04234             return;
04235     }
04236 
04237     // Ensure the scroll position is valid (similar to ScrollTheStrip(0))
04238     INT32 NewLeftmost = (INT32)LeftmostColour;
04239 
04240     if (NewLeftmost > MaxColours - NewDisplayedColours)
04241         NewLeftmost = MaxColours - NewDisplayedColours;
04242     if (NewLeftmost < 0)
04243         NewLeftmost = 0;
04244 
04245     LeftmostColour = (UINT32) NewLeftmost;
04246 
04247     Refresh(false);         // Force-redraw the entire window
04248 
04249     // Finally, remember the new size of the bar so we don't unnecessarily redraw
04250     // if we are resized again soon (i.e. solid drag)
04251     OldBarHeight = NewHeight;
04252 }
04253 
04254 
04255 
04256 /********************************************************************************************
04257 
04258 >   static INT32 CColourBar::GetCurrentBarHeight(void)
04259 
04260     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04261     Created:    27/3/96
04262 
04263     Returns:    The height, in pixels, the bar is currently taking on screen
04264                 If there is no colour bar currently displayed, the return value is 0
04265 
04266     Purpose:    Determine how high the colour bar currently is
04267 
04268     SeeAlso:    CColourBar::CalculateNewBarHeight; CColourBar::OnSize
04269 
04270 ********************************************************************************************/
04271 
04272 INT32 CColourBar::GetCurrentBarHeight(void)
04273 {
04274     if (TheColourBar == NULL || !TheColourBar->BarIsVisible)
04275         return(0);
04276 
04277     wxRect ClientRect = TheColourBar->GetClientRect();
04278     return(ClientRect.height);
04279 }
04280 
04281 
04282 
04283 /********************************************************************************************
04284 
04285 >   INT32 CColourBar::CalculateNewBarHeight(wxRect *AvailableRect)
04286 
04287     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04288     Created:    15/9/94
04289 
04290     Inputs:     AvailableRect - The space available for the colourbar to fit into.
04291                 Only the available x space is significant.
04292     Outputs:    -
04293     Returns:    The height, in pixels, the bar will need to be at this width in order to
04294                 contain all its 'controls'.
04295 
04296     Purpose:    Determine how high the colour bar should be - this is difficult, because
04297                 the height depends upon whether we want a scrollbar, and this in turn
04298                 depends upon how wide the colourstrip is.
04299 
04300     Notes:      AvailableRect is now preserved by this call
04301 
04302     SeeAlso:    CColourBar::GetCurrentBarHeight; CColourBar::OnSize
04303 
04304 ********************************************************************************************/
04305 
04306 INT32 CColourBar::CalculateNewBarHeight(wxRect *AvailableRect)
04307 {
04308     TRACEUSER("Gerry", _T("CColourBar::CalculateNewBarHeight"));
04309 
04310     if (ScrollHeight == 0)                      // Has no scroll bar, so always the same height
04311     {
04312         TRACEUSER("Gerry", _T("   returning %d"), BarHeight);
04313         return(BarHeight);
04314     }
04315 
04316     // Work out how many colours we want to display in the window.
04317     // Removed this line so that FullScreen mode (which destroys and recreates the colour 
04318     // gallery) does not leave us with a cached pointer to garbage memory.
04319     // if (m_pCurrentColourList == NULL)
04320         m_pCurrentColourList = ColourManager::GetColourList();
04321 
04322     if (m_pCurrentColourList == NULL)               // No colours; we won't display anything anyway
04323     {
04324 //      TRACEUSER("Gerry", _T("   returning %d"), BarHeight - ScrollHeight);
04325 //      return(BarHeight - ScrollHeight);
04326         return(CellSize + 4);
04327     }
04328 
04329     // Calculate where all the rectangles are going to be placed if the window is resized
04330     // to the 'AvailableRect'. From this, we get the projected StripRect size, which allows
04331     // us to project the number of colours we will be able to display.
04332     
04333     wxRect tStripRect;      // Temporary lookalikes to the global cached rects
04334     wxRect tIndicatorRect;
04335     wxRect tScrollBarRect;
04336     wxRect tEditButtonRect;
04337     wxRect tNewButtonRect;      // Warning - this button is now defunct
04338 
04339     CalculateRectsInternal(AvailableRect,
04340                             &tStripRect, &tIndicatorRect, &tScrollBarRect,
04341                             &tEditButtonRect, &tNewButtonRect);
04342 
04343     INT32 DisplayedColours = tStripRect.width / CellSize;
04344 
04345     // We can display all the colours, we don't need a scrollbar, so only need CellSize+4 pixels
04346     //if ((INT32) m_pCurrentColourList->GetUndeletedCount() <= DisplayedColours) // FIXEDCOLOURS
04347     if ((INT32)GetNumberOfColours() <= DisplayedColours)
04348     {
04349 //      TRACEUSER("Gerry", _T("   returning %d"), BarHeight - ScrollHeight);
04350 //      return(BarHeight - ScrollHeight);
04351         return(CellSize + 4);
04352     }
04353 
04354     // We can't display all colours, so we need the desired BarHeight, which includes the
04355     // size of the colourstrip and the scrollbar (if enabled)
04356     TRACEUSER("Gerry", _T("   returning %d"), BarHeight);
04357     return(BarHeight);
04358 }
04359 
04360 
04361 
04362 /********************************************************************************************
04363 
04364 >   LRESULT CColourBar::OnSizeParent(WPARAM, LPARAM lParam)
04365 
04366     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04367     Created:    22/6/94
04368     Inputs:     dunno really. WPARAM and LPARAM as per normal for this sorta thing
04369     Purpose:    Handle resizing of our parent - ask for the amount of client
04370                 space we want to occupy. This is done by setting a member
04371                 variable and then calling up to a base class method.
04372 
04373     Notes:      This function is implemented differently for MFC 2 and 3.
04374                 Remember to change both sections as appropriate when editing it.
04375 
04376 ********************************************************************************************/
04377 #if FALSE
04378 LRESULT CColourBar::OnSizeParent(WPARAM, LPARAM lParam)
04379 {
04380     INT32 HeightOfBar = 0;          // By default, bar height = 0 (for standalone code)
04381 
04382     // Ask for the amount of room we desire.
04383     // This must be done differently for MFC versions 2 and 3
04384 // ---------------------------------------------------------------------
04385 #if _MFC_VER < 0x300
04386 
04387 #ifndef STANDALONE                          // The standalone version leaves HeightOfBar = 0 (no bar)
04388     if ((m_dwStyle & WS_VISIBLE) != 0)      // If visible, we want to grab some space
04389     {
04390         AFX_SIZEPARENTPARAMS FAR* lpLayout = (AFX_SIZEPARENTPARAMS FAR*)lParam;
04391 
04392         wxRect AvailableRect;               // The available space for us to fill
04393         AvailableRect.CopyRect(&lpLayout->rect);
04394 
04395         HeightOfBar = CalculateNewBarHeight(&AvailableRect);    // (corrupts AvailableRect)
04396     }
04397 #endif
04398 
04399     m_sizeFixedLayout.cy = HeightOfBar;     // Set the desired height of the bar
04400 
04401     return (CControlBar::OnSizeParent((WPARAM)0, lParam));  // invoke normal method
04402 
04403 #else
04404 // _MFC_VER >= 0x300 ---------------------------------------------------
04405 
04406     AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
04407 
04408     // resize and reposition this control bar based on styles
04409     DWORD dwStyle = (m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) |
04410         (GetStyle() & WS_VISIBLE);
04411 
04412     if ((dwStyle & WS_VISIBLE) && (dwStyle & CBRS_ALIGN_ANY) != 0)
04413     {
04414         // align the control bar
04415         wxRect rect;
04416         rect.CopyRect(&lpLayout->rect);
04417 
04418 #ifndef STANDALONE      // The standalone version leaves HeightOfBar = 0
04419         {
04420             wxRect AvailableRect(rect);
04421             HeightOfBar = CalculateNewBarHeight(&AvailableRect);    // (corrupts AvailableRect)
04422         }
04423 #endif
04424 
04425         CSize sizeAvail = rect.Size();  // maximum size available
04426 
04427         // get maximum requested size
04428         CSize size = CalcFixedLayout(lpLayout->bStretch, 
04429                                     (dwStyle & CBRS_ORIENT_HORZ) ? TRUE : FALSE);
04430 
04431         size.cx = min(size.cx, sizeAvail.cx);
04432         size.cy = HeightOfBar;
04433 
04434         lpLayout->sizeTotal.cy += size.cy;
04435         lpLayout->sizeTotal.cx = max(lpLayout->sizeTotal.cx, size.cx);
04436         rect.top = rect.bottom - size.cy;
04437         lpLayout->rect.bottom -= size.cy;
04438 
04439         rect.right = rect.left + size.cx;
04440         rect.bottom = rect.top + size.cy;
04441 
04442         // only resize the window if doing layout and not just rect query
04443         if (lpLayout->hDWP != NULL)
04444             AfxRepositionWindow(lpLayout, m_hWnd, &rect);
04445     }
04446 
04447     return 0;
04448 #endif
04449 // ---------------------------------------------------------------------
04450 }
04451 #endif
04452 
04453 
04454 /********************************************************************************************
04455 
04456 >   inline BOOL GetModifierKeyState(void)
04457 
04458     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04459     Created:    27/6/94
04460     Returns:    TRUE if the ColourBar push-mode modifier key ('Alt'ernative) is down
04461 
04462     Purpose:    Checks if the modifier key for the colour bar's push-the-strip
04463                 mode is down. This is an inline macro to make it easy to change
04464                 the key at later date. (Now uses KeyPress::IsAlternativePressed)
04465 
04466     Scope:      private (to ccolbar.cpp)
04467 
04468     SeeAlso:    KeyPress::IsAlternativePressed
04469 
04470 ********************************************************************************************/
04471 
04472 inline BOOL GetModifierKeyState(void)
04473 {
04474     return(KeyPress::IsAlternativePressed());
04475 }
04476 
04477 
04478 
04479 /********************************************************************************************
04480 
04481 >   inline BOOL ShiftIsDown(void)
04482 
04483     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04484     Created:    11/11/94
04485     Returns:    TRUE if the 'Adjust' (shift) key is held is down at present
04486 
04487     Purpose:    Checks if SHIFT is held down - used to convert shift-left-clicks into
04488                 "right clicks". (Now uses KeyPress::IsAdjustPressed() to determine this)
04489     
04490     Scope:      private (to ccolbar.cpp)
04491 
04492     SeeAlso:    KeyPress::IsAdjustPressed
04493 
04494 ********************************************************************************************/
04495 
04496 inline BOOL ShiftIsDown(void)
04497 {
04498     return(KeyPress::IsAdjustPressed());
04499 }
04500 
04501 
04502 
04503 /********************************************************************************************
04504 
04505 >   void CColourBar::OnAnyButtonDown(const wxPoint &point, INT32 Modifier)
04506 
04507     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04508     Created:    22/6/94
04509     Inputs:     point - co-ordinate of the click point
04510                 Modifier - +1 if select click, -1 if adjust click
04511     Purpose:    Handle button clicks in the colour bar. Called by the LButton
04512                 and RButton handlers to share the code somewhat
04513 
04514 ********************************************************************************************/
04515 
04516 void CColourBar::OnAnyButtonDown(const wxPoint &point, INT32 Modifier)
04517 {
04518     if (DragInfo.MouseCaptured)                 // Ignore clicks during drags
04519         return;
04520 
04521     // Remove bubble help whenever the user clicks
04522 //  ControlHelper::BubbleHelpDisable();
04523 
04524     if (m_pCurrentColourList == NULL)       // Ensure the current ColourList pointer is valid
04525         m_pCurrentColourList = ColourManager::GetColourList();
04526 
04527     if (m_pCurrentColourList == NULL)       // No DOCUMENT! No Colours! Exit immediately!
04528         return;
04529 
04530     wxRect RectMouseIsIn;
04531     INT32 MousePos = WhereIsMouse(point, &RectMouseIsIn);
04532 
04533     DragInfo.Adjust = (Modifier < 0);
04534     DragInfo.LastMousePos = point;              // Remember last point mouse was at
04535     DragInfo.DragItem = MousePos;               // and last item it was over
04536 
04537 
04538     if (MousePos < CLICKED_NOTHING)
04539     {
04540         BOOL ModifierKeyDown = GetModifierKeyState();
04541 
04542         if (ModifierKeyDown)
04543         {
04544             // If Right ALT down, allow 'push tool' dragging mode on colourstrip
04545             CaptureTheMouse();
04546             DragInfo.DragItem = CLICKED_SCROLLSTRIP;
04547 
04548             // AnchorOffset is now the colour cell being dragged
04549             DragInfo.AnchorOffset = (INT32) (LeftmostColour +
04550                                     ((point.x - StripRect.x) / CellSize));
04551             return;
04552         }
04553         else
04554         {
04555 #ifdef DISABLE_COLOUR_DRAGS
04556             CellClicked(MousePos, (Modifier < 0));
04557 #else
04558             // Find the clicked colour, and start a drag of it
04559             IndexedColour *TheColour = NULL;
04560             ColourDragInformation *DragCol = NULL;
04561             // If the user has the preference set then include and hence show the document
04562             // colours
04563             if (ColourSGallery::ShowDocumentColours)
04564                 TheColour = FindColourByIndex(MousePos);
04565 
04566             if (TheColour != NULL)
04567             {
04568                 DragCol = new ColourDragInformation(TheColour, (Modifier < 0),
04569                                                         Document::GetSelected());
04570             }
04571             else
04572             {
04573 PORTNOTE("other","Removed ColourSGallery usage")
04574 #if !defined(EXCLUDE_FROM_XARALX)
04575                 // FIXED COLOURS
04576                 // We didn't find the colour in the document colours section
04577                 // so check any library sections that may be present
04578                 SGDisplayLibColour *pLibColour = NULL;
04579                 DocColour * pTheDocColour = FindLibColourByIndex(MousePos, &pLibColour);
04580                 if (pTheDocColour && pLibColour)
04581                 {
04582                     // Start up a DocColour drag which should give us what we want
04583                     String_256 Buffer;
04584                     pLibColour->GetNameText(&Buffer);
04585                     DragCol = new ColourDragInformation(pTheDocColour, (Modifier < 0),
04586                                                         &Buffer, pLibColour->IsASpotColour());
04587                 }
04588 #endif
04589             }
04590 
04591             DragManagerOp::StartDrag(DragCol, this);
04592 #endif
04593             return;
04594         }
04595     }
04596 
04597     switch(MousePos)
04598     {
04599         case CLICKED_NOCOLOURCELL:              // Set 'no colour'
04600 #ifdef DISABLE_COLOUR_DRAGS
04601             CellClicked(MousePos, (Modifier < 0));
04602 #else
04603             // Create an attribute of the correct type
04604 
04605             ColourDragInformation * DragCol;
04606             DragCol = new ColourDragInformation(NULL, (Modifier < 0),
04607                                                 Document::GetSelected());
04608             DragManagerOp::StartDrag(DragCol, this);
04609 #endif
04610             break;
04611 
04612         case CLICKED_INDICATORS:
04613 #ifndef DISABLE_COLOUR_DRAGS
04614             {
04615                 // Have clicked the line/fill colour indicator, so drag them if possible
04616                 wxRect InnerRect(IndicatorRect);
04617                 INT32 DeflateBy = (abs(IndicatorRect.height) * 2) / 5;
04618                 if (DeflateBy < 4)
04619                     DeflateBy = 4;  // Line indicator is min. of 2 pixels wide
04620                 InnerRect.Inflate(-DeflateBy / 2, -DeflateBy / 2);
04621 
04622                 // Resort to dragging 'no colour' if a better colour can't be found
04623                 IndexedColour *IndexedColToDrag = NULL;
04624 
04625                 DocColour *LineColour;
04626                 DocColour *FillColour;
04627                 DocColour *EndColour;
04628                 ColourManager::GetCurrentLineAndFillColours(&LineColour, &FillColour, &EndColour);
04629 
04630                 DocColour *DocColourToUse = NULL;
04631 
04632                 if (InnerRect.Inside(point))
04633                 {
04634                     if (EndColour != NULL && point.y <= (InnerRect.y + (InnerRect.height / 2)))
04635                         DocColourToUse = EndColour;
04636                     else
04637                         DocColourToUse = FillColour;
04638                 }
04639                 else
04640                     DocColourToUse = LineColour;
04641 
04642                 // If we found a doc colour to be dragged, find its IndexedColour parent (or if necessary,
04643                 // create a new local colour to be dragged from the immediate-doccolour definition)
04644                 if (DocColourToUse != NULL)
04645                 {
04646                     IndexedColToDrag = DocColourToUse->FindParentIndexedColour();
04647 
04648                     // If the DocColour was an immediate colour (non-transparent, but
04649                     // with no parent IndexedColour) then we'll need to create a local IndexedColour
04650                     // to represent the colour to be dragged, or else it'll drag 'no colour'!
04651                     // This may return NULL, but we're quite happy with that.
04652                     if (IndexedColToDrag == NULL && !DocColourToUse->IsTransparent())
04653                     {
04654                         IndexedColToDrag = ColourManager::GenerateNewUnnamedColour(
04655                                                             m_pCurrentColourList, DocColourToUse);
04656                     }
04657                 }
04658 
04659                 ColourDragInformation *DragCol;
04660                 DragCol = new ColourDragInformation(IndexedColToDrag, (Modifier < 0),
04661                                                     Document::GetSelected());
04662                 DragManagerOp::StartDrag(DragCol, this);
04663             }
04664 #endif
04665             break;
04666 
04667         case CLICKED_LEFTSCROLL:
04668             ScrollTheStrip(-Modifier);          // Scroll once
04669             CaptureTheMouse();                  // And start an autorepeat 'drag'
04670             SetATimer(TRUE);
04671             break;
04672 
04673         case CLICKED_RIGHTSCROLL:
04674             ScrollTheStrip(Modifier);           // Scroll once
04675             CaptureTheMouse();                  // And start an autorepeat 'drag'
04676             SetATimer(TRUE);
04677             break;
04678 
04679         case CLICKED_SCROLLBARLEFT:             // PageRight once
04680             {
04681                 UINT32 NumDisplayedColours = StripRect.width / CellSize;
04682                 ScrollTheStrip((INT32) ((-Modifier) * NumDisplayedColours));
04683                 CaptureTheMouse();              // And start an autorepeat 'drag'
04684                 SetATimer(TRUE);
04685             }
04686             break;
04687 
04688         case CLICKED_SCROLLBARRIGHT:            // PageLeft once
04689             {
04690                 UINT32 NumDisplayedColours = StripRect.width / CellSize;
04691                 ScrollTheStrip((INT32) (Modifier * NumDisplayedColours));
04692                 CaptureTheMouse();              // And start an autorepeat 'drag'
04693                 SetATimer(TRUE);
04694             }
04695             break;
04696 
04697         case CLICKED_SCROLLBAR:
04698             CaptureTheMouse();                  // Start drag (on MouseMoves, not Timers)
04699 
04700             // AnchorOffset is now the distance (pixels) of the drag anchor from
04701             // the center of the scroll sausage
04702             DragInfo.AnchorOffset = point.x -
04703                                     (RectMouseIsIn.x + (RectMouseIsIn.width / 2));
04704             break;
04705 
04706         case CLICKED_EDITBUTTON:
04707             {
04708                 if (IndentedButton == CLICKED_NOTHING)      // Indent button while mouse down
04709                 {
04710                     TRACEUSER("Gerry", _T("Edit Clicked"));
04711                     IndentedButton = CLICKED_EDITBUTTON;
04712                     ForceRedrawOfRect(EditButtonRect);
04713                     Update();                           // Force immediate redraw
04714                     CaptureMouse();                         // And grab all mouse events
04715                 }                                           // until the button is released
04716 
04717 #if FALSE
04718 /*
04719     // No longer needed - we want the editor to pop up in "local" mode.
04720                 DocColour *LineColour;
04721                 DocColour *FillColour;
04722 
04723                 ERROR3IF(m_pCurrentColourList == NULL,
04724                         _T("Unexpected NULL ColourList pointer in CColourBar::OnAnyButtonDown"));
04725 
04726                 ColourManager::GetCurrentLineAndFillColours(&LineColour, &FillColour);
04727 
04728                 // Edit the appropriate colour. If there is none, EditAColour just beeps
04729                 // and returns without getting upset
04730 
04731                 IndexedColour *ColToEdit = NULL;
04732                 if (Modifier < 0)
04733                 {
04734                     if (LineColour != NULL)
04735                         ColToEdit = LineColour->FindParentIndexedColour();
04736                 }
04737                 else
04738                 {
04739                     if (FillColour != NULL)
04740                         ColToEdit = FillColour->FindParentIndexedColour();
04741                 }
04742 
04743                 EditAColour(m_pCurrentColourList, ColToEdit);
04744 */
04745 #else
04746                 EditAColour(NULL, NULL, (Modifier < 0));
04747 #endif
04748             }
04749             break;
04750 
04751 
04752 #if FALSE
04753 /*
04754         case CLICKED_NEWBUTTON:
04755             {
04756                 if (IndentedButton == CLICKED_NOTHING)      // Indent button while mouse down
04757                 {
04758                     IndentedButton = CLICKED_NEWBUTTON;
04759                     ForceRedrawOfRect(NewButtonRect);
04760                     UpdateWindow();                         // Force immediate redraw
04761                     SetCapture();                           // And grab all mouse events
04762                 }                                           // until the button is released
04763 
04764                 ERROR3IF(m_pCurrentColourList == NULL,
04765                         _T("Unexpected NULL ColourList pointer in CColourBar::OnAnyButtonDown"));
04766 
04767                 IndexedColour *NewCol = NULL;
04768 
04769                 // Create a new colour, in the current colour list, copied from the
04770                 // current attribute/selection if possible.
04771                 ColourList *CurrentDocColours = ColourManager::GetColourList();
04772                 ERROR3IF(CurrentDocColours == NULL, _T("No colour list present?!"));
04773 
04774                 if (CurrentDocColours != NULL)
04775                 {
04776                     NewCol = ColourManager::GenerateNewNamedColour(CurrentDocColours, NULL);
04777 
04778                     if (NewCol != NULL)
04779                     {
04780                         ApplyColour(NewCol, (Modifier < 0));    // Apply col to selection
04781                         EditAColour(m_pCurrentColourList, NewCol);  // And open editor
04782                     }
04783                 }
04784             }
04785             break;  
04786 */
04787 #endif
04788     }
04789 }
04790 
04791 
04792 
04793 /********************************************************************************************
04794 
04795 >   void CColourBar::OnLButtonDown(wxMouseEvent& event)
04796 
04797     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04798     Created:    22/6/94
04799     Inputs:     nFlags - unused
04800                 point - co-ordinate of the click point
04801     Purpose:    Handle left-button clicks in the colour bar
04802                 Note that a shift-click is converted into the equivalent of a right-click
04803                 by this function.
04804     SeeAlso:    CColourBar::OnAnyButtonDown
04805 
04806 ********************************************************************************************/
04807 
04808 void CColourBar::OnLButtonDown(wxMouseEvent& event)
04809 {
04810     TRACEUSER("Gerry", _T("CColourBar::OnLButtonDown"));
04811     OnAnyButtonDown(event.GetPosition(), (ShiftIsDown() ? -1 : +1));
04812 }
04813 
04814 
04815 
04816 /********************************************************************************************
04817 
04818 >   void CColourBar::OnRButtonDown(wxMouseEvent& event)
04819 
04820     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04821     Created:    22/6/94
04822     Inputs:     nFlags - unused
04823                 point - co-ordinate of the click point
04824     Purpose:    Handle right-button clicks in the Colour Bar
04825     SeeAlso:    CColourBar::OnAnyButtonDown
04826 
04827 ********************************************************************************************/
04828 
04829 void CColourBar::OnRButtonDown(wxMouseEvent& event)
04830 {
04831     TRACEUSER("Gerry", _T("CColourBar::OnRButtonDown"));
04832     OnAnyButtonDown(event.GetPosition(), -1);
04833 }
04834 
04835 
04836 
04837 /********************************************************************************************
04838 
04839 >   void CColourBar::OnAnyButtonDblClk(wxPoint point, INT32 Modifier)
04840 
04841     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04842     Created:    28/6/94
04843     Inputs:     point - co-ordinate of the click point
04844                 Modifier - should be +1 (Select) or -1 (Adjust)
04845 
04846     Purpose:    Handle double clicks in the colour bar. This brings up the colour
04847                 picker on the given colour. This works on any colour cell, including
04848                 the current colour indicators. Double clicks on scroll arrows are
04849                 passed on to the normal single-click handler (otherwise every second
04850                 click, when repeating fast, is lost)
04851 
04852 ********************************************************************************************/
04853 
04854 void CColourBar::OnAnyButtonDblClk(wxPoint point, INT32 Modifier)
04855 {
04856     if (m_pCurrentColourList == NULL)
04857         return;
04858 
04859     INT32 ColourCell = WhereIsMouse(point);
04860 
04861     if (ColourCell == CLICKED_INDICATORS)
04862     {
04863         // Have double-clicked the line/fill colour indicator, so edit them if possible
04864         wxRect InnerRect(IndicatorRect);
04865         INT32 DeflateBy = (abs(IndicatorRect.height) * 2) / 5;
04866         if (DeflateBy < 4)
04867             DeflateBy = 4;  // Line indicator is min. of 2 pixels wide
04868         InnerRect.Inflate(-DeflateBy / 2, -DeflateBy / 2);
04869 
04870 //      IndexedColour *IndexedColToEdit = NULL;
04871 
04872         DocColour *LineColour;
04873         DocColour *FillColour;
04874         DocColour *EndColour;
04875         ColourManager::GetCurrentLineAndFillColours(&LineColour, &FillColour, &EndColour);
04876 
04877         if (InnerRect.Inside(point))
04878         {
04879             if (EndColour != NULL && point.y <= (InnerRect.y + (InnerRect.height / 2)))
04880                 FillColour = EndColour;
04881 
04882             if (FillColour!= NULL)
04883             {
04884                 // Find the fill colour. If it's unnamed, then we'll use NULL so that we
04885                 // edit the local colour properly instead of doing the wrong thing
04886                 IndexedColour *IxColour = FillColour->FindParentIndexedColour();
04887                 if (IxColour != NULL && !IxColour->IsNamed())
04888                     IxColour = NULL;
04889 
04890                 EditAColour(m_pCurrentColourList, IxColour, FALSE);
04891             }
04892             else
04893                 EditAColour(NULL, NULL, FALSE);
04894         }
04895         else
04896         {
04897             if (LineColour != NULL)
04898             {
04899                 // Find the line colour. If it's unnamed, then we'll use NULL so that we
04900                 // edit the local colour properly instead of doing the wrong thing
04901                 IndexedColour *IxColour = LineColour->FindParentIndexedColour();
04902                 if (IxColour != NULL && !IxColour->IsNamed())
04903                     IxColour = NULL;
04904 
04905                 EditAColour(m_pCurrentColourList, IxColour, TRUE);
04906             }
04907             else
04908                 EditAColour(NULL, NULL, TRUE);
04909         }
04910     }
04911     else if (ColourCell == CLICKED_LEFTSCROLL || ColourCell == CLICKED_RIGHTSCROLL)
04912     {
04913         // As double-clicks are enabled, Windows weeds out every second click if the
04914         // user clicks repeatedly at high speed. Thus, we respond to a double-click
04915         // on the scroll arrows as if it were just a second ordinary click.
04916         OnAnyButtonDown(point, Modifier);
04917     }
04918 }
04919 
04920 
04921 
04922 /********************************************************************************************
04923 
04924 >   void CColourBar::OnLButtonDblClk(wxMouseEvent& event)
04925 
04926     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04927     Created:    28/6/94
04928     Inputs:     nFlags - unused
04929                 point - co-ordinate of the click point
04930     Purpose:    Handle left-button double clicks in the colour bar
04931 
04932 ********************************************************************************************/
04933 
04934 void CColourBar::OnLButtonDblClk(wxMouseEvent& event)
04935 {
04936     OnAnyButtonDblClk(event.GetPosition(), (ShiftIsDown() ? -1 : +1));
04937 }
04938 
04939 
04940 
04941 /********************************************************************************************
04942 
04943 >   void CColourBar::OnRButtonDblClk(wxMouseEvent& event)
04944 
04945     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04946     Created:    28/6/94
04947     Inputs:     nFlags - unused
04948                 point - co-ordinate of the click point
04949     Purpose:    Handle right-button double clicks in the Colour Bar
04950 
04951 ********************************************************************************************/
04952 
04953 void CColourBar::OnRButtonDblClk(wxMouseEvent& event)
04954 {
04955     OnAnyButtonDblClk(event.GetPosition(), -1);
04956 }
04957 
04958 
04959 
04960 /********************************************************************************************
04961 
04962 >   void CColourBar::OnMouseMove(wxMouseEvent& event)
04963 
04964     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04965     Created:    22/6/94
04966     Inputs:     nflags - Ignored
04967                 point - The mouse position
04968 
04969     Purpose:    Processes all mouse moves over the colour bar. This currently involves
04970                 providing bubble help and updating during drags of the scroll sausage.
04971                 Other 'drag' updates (button autorepeats) are handled by OnTimer()
04972 
04973     SeeAlso:    CControlBar::OnTimer
04974 
04975 ********************************************************************************************/
04976 
04977 void CColourBar::OnMouseMove(wxMouseEvent& event)
04978 {
04979 //  TRACEUSER("Gerry", _T("CColourBar::OnMouseMove"));
04980 
04981     if (m_pCurrentColourList == NULL)       // Ensure the current ColourList pointer is valid
04982         m_pCurrentColourList = ColourManager::GetColourList();
04983 
04984     if (m_pCurrentColourList == NULL)       // No DOCUMENT! No Colours! Exit immediately!
04985         return;
04986 
04987     wxPoint point = event.GetPosition();
04988     DragInfo.LastMousePos = point;  // Remember new mouse position for OnTimer code
04989 
04990     // Check if the push-mode modifier key is down, and if so, swap to the push cursor
04991     BOOL ModifierKeyDown = GetModifierKeyState();
04992 
04993     if (StripRect.Inside(point) && ModifierKeyDown)
04994     {
04995         // Set the cursor to the push hand shape
04996         if (!PushCursor)
04997             PushCursor = new Cursor(_R(IDC_PUSHTOOLCURSOR));
04998 
04999         if (PushCursor)
05000             PushCursor->SetActive();
05001     }
05002     else
05003     {
05004         Cursor::Arrow->SetActive();
05005         if (PushCursor)
05006         {
05007             delete PushCursor;
05008             PushCursor = NULL;
05009         }
05010     }
05011 
05012 
05013     if (DragInfo.MouseCaptured)
05014     {
05015         // We are dragging something
05016         if (DragInfo.DragItem == CLICKED_SCROLLBAR && ScrollHeight != 0)
05017         {
05018             // We are dragging the scrollbar sausage
05019             wxRect SausageRect;
05020             if (CalculateSausageRect(&SausageRect))
05021             {
05022                 // We want to scroll the AnchorOffset point under the mouse posn.
05023                 INT32 DistToScroll = point.x -
05024                                     ((SausageRect.x + (SausageRect.width / 2)) +
05025                                     DragInfo.AnchorOffset);
05026 
05027                 ENSURE(ScrollBarRect.width > 0,
05028                         "Serious problem with the ColourBar's ScrollBarRect");
05029 
05030                 INT32 ColoursToScroll = ((INT32)TotalNumColours * DistToScroll) / ScrollBarRect.width;
05031 
05032                 ScrollTheStrip(ColoursToScroll);
05033             }
05034         }
05035         else if (DragInfo.DragItem == CLICKED_SCROLLSTRIP)
05036         {
05037             ENSURE(StripRect.width > 0,
05038                     "Serious problem with the ColourBar's StripRect");
05039 
05040             INT32 NewAnchorCellIndex = (INT32) ((INT32)LeftmostColour +
05041                                     ((INT32)(point.x - StripRect.x) / (INT32)CellSize));
05042             ScrollTheStrip((INT32) (DragInfo.AnchorOffset - NewAnchorCellIndex));
05043         }
05044     }
05045     else
05046 
05047     {
05048         // Not dragging, so do Bubble & StatusBar Help on the thing under the mouse,
05049         // but only if the colour bar is active (we have a colour display list)
05050         if (ColourManager::GetColourList() != NULL)
05051         {
05052             String_256 HelpText(_T(""));
05053 
05054             if (GetStatusLineText(&HelpText))
05055             {
05056                 StatusLine *pStatusLine = GetApplication()->GetpStatusLine();
05057                 if (pStatusLine)
05058                     pStatusLine->UpdateText(&HelpText, STATUSLINE_SELDESC_COLBAR);
05059 
05060 //              TRACEUSER("Gerry", _T("CColourBar updating status to '%s'"), (LPCTSTR)HelpText);
05061             }
05062 
05063             INT32 MousePos = WhereIsMouse(point);
05064 
05065             // Do bubble help for the colour cells and assorted icons
05066             if (MousePos == CLICKED_NOTHING)
05067             {
05068                 // Remove bubble help, as they're over no man's land
05069                 // This should no longer completely disable bubble help over our window,
05070                 // but merely turn off the bubble while the pointer is not over anything
05071                 // of any interest.
05072 //              ControlHelper::BubbleHelpDisable();
05073             }
05074             else
05075             {
05076 PORTNOTE("other","Removed ControlHelper bubblehelp usage")
05077 #if !defined(EXCLUDE_FROM_XARALX)
05078                 ControlHelper::DoBubbleHelpOn(m_hWnd, MousePos,
05079                                                 HelpCallbackHandler, this);
05080 #endif
05081             }
05082         }
05083 //      else
05084 //          ControlHelper::BubbleHelpDisable(); // No colourstrip, so no help
05085     }
05086 
05087     event.Skip();
05088 }
05089 
05090 
05091 
05092 /*********************************************************************************************
05093 
05094 >   void CColourBar::OnAnyButtonUp(const wxPoint &point)
05095 
05096     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05097     Created:    27/6/94
05098     Inputs:     point - the point where the mouse was released
05099     Outputs:    -
05100     Returns:    -
05101     Purpose:    Processes any button-released event. This stops auto-repeat and
05102                 drags, and releases any claims (timers, drags) we might have
05103     Errors:     -
05104 
05105 **********************************************************************************************/ 
05106 
05107 void CColourBar::OnAnyButtonUp(const wxPoint &point)
05108 {
05109     DragInfo.LastMousePos = point;
05110     ReleaseAllClaims();
05111 
05112     if (IndentedButton == CLICKED_EDITBUTTON)
05113         ForceRedrawOfRect(EditButtonRect);
05114 #if FALSE
05115     else if (IndentedButton == CLICKED_NEWBUTTON)
05116         ForceRedrawOfRect(NewButtonRect);
05117 #endif
05118 
05119     if (IndentedButton != CLICKED_NOTHING)
05120     {
05121         IndentedButton = CLICKED_NOTHING;       // Remember that nothing is indented
05122     }
05123 }
05124 
05125 
05126 
05127 /*********************************************************************************************
05128 >   afx_msg void CColourBar::OnLButtonUp(wxMouseEvent& event)
05129 
05130     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05131     Created:    27/6/94
05132     Inputs:     nFlags - A bit-field describing which buttons and keys were down
05133                 when the message was generated
05134                 point - the position of the mouse cursor.
05135     Outputs:    -
05136     Returns:    -
05137     Purpose:    Processes a left-button-released message
05138     Errors:     -
05139 
05140 **********************************************************************************************/ 
05141 
05142 void CColourBar::OnLButtonUp(wxMouseEvent& event)
05143 {
05144     TRACEUSER("Gerry", _T("CColourBar::OnLButtonUp"));
05145     OnAnyButtonUp(event.GetPosition());
05146 }
05147 
05148 
05149 
05150 /*********************************************************************************************
05151 
05152 >   afx_msg void CColourBar::OnRButtonUp(wxMouseEvent& event)
05153 
05154     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05155     Created:    27/6/94
05156     Inputs:     nFlags - A bit-field describing which buttons and keys were down
05157                 when the message was generated
05158                 point - the position of the mouse cursor.
05159     Outputs:    -
05160     Returns:    -
05161     Purpose:    Processes a right-button-released message
05162     Errors:     -
05163 
05164 **********************************************************************************************/ 
05165 
05166 void CColourBar::OnRButtonUp(wxMouseEvent& event)
05167 {
05168     TRACEUSER("Gerry", _T("CColourBar::OnLButtonUp"));
05169     OnAnyButtonUp(event.GetPosition());
05170 }
05171 
05172 
05173 
05174 /*********************************************************************************************
05175 
05176 >   afx_msg void CColourBar::OnTimer(wxTimerEvent& event)
05177 
05178     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05179     Created:    27/6/94
05180     Inputs:     nIDEvent - The ID number of the elapsed timer (not used)
05181     Outputs:    -
05182     Returns:    -
05183     Purpose:    Responds to the triggering of the timer which we set when a click
05184                 or drag first occurred, in order to check for auto-repeat of buttons.
05185                 This currently processes the scroll left/right and page left/right areas
05186                 Dragging the scroll sausage is handled in OnMouseMove
05187 
05188     SeeAlso:    CColourbar::OnMouseMove
05189                 
05190 **********************************************************************************************/ 
05191 
05192 void CColourBar::OnTimer(wxTimerEvent& event)
05193 {
05194     // We aren't dragging, or this is not the timer we set
05195     if (!DragInfo.MouseCaptured)
05196         return;
05197 
05198     SetATimer(FALSE);   // Replace the repeat-delay timer with a repeat-speed timer
05199 
05200     INT32 NewMouseItem = WhereIsMouse(DragInfo.LastMousePos);
05201 
05202     if (NewMouseItem == DragInfo.DragItem)
05203     {
05204         switch(DragInfo.DragItem)
05205         {
05206             case CLICKED_LEFTSCROLL:
05207                 ScrollTheStrip((DragInfo.Adjust) ? +1 : -1);
05208                 break;
05209 
05210             case CLICKED_RIGHTSCROLL:
05211                 ScrollTheStrip((DragInfo.Adjust) ? -1 : +1);
05212                 break;
05213 
05214             case CLICKED_SCROLLBARLEFT:
05215                 {
05216                     UINT32 NumDisplayedColours = StripRect.width / CellSize;
05217                     ScrollTheStrip((INT32) (((DragInfo.Adjust) ? 1 : -1) * NumDisplayedColours));
05218                 }
05219                 break;
05220 
05221             case CLICKED_SCROLLBARRIGHT:
05222                 {
05223                     UINT32 NumDisplayedColours = StripRect.width / CellSize;
05224                     ScrollTheStrip((INT32) (((DragInfo.Adjust) ? -1 : 1) * NumDisplayedColours));
05225                 }
05226                 break;
05227         }
05228     }
05229 }
05230 
05231 
05232 
05233 /*********************************************************************************************
05234 >   afx_msg void CColourBar::OnCancelMode(void)
05235 
05236     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05237     Created:    27/6/94
05238     Inputs:     -
05239     Outputs:    -
05240     Returns:    -
05241     Purpose:    Responds to a WM_CANCELMODE message sent by Windows, whenever the active
05242                 application loses the focus via some method which doesn;t directly involve
05243                 the user, eg. because a dialogue box from some background app has popped up.
05244                 The main purpose of the routine is to make sure that if the mouse has been
05245                 captured it is released, and if a timer has been allocated, it is freed.
05246 
05247 **********************************************************************************************/ 
05248 
05249 PORTNOTE("other","Removed CancelMode")
05250 #if !defined(EXCLUDE_FROM_XARALX)
05251 
05252 void CColourBar::OnCancelMode(void)
05253 {
05254     CControlBar::OnCancelMode();
05255     ReleaseAllClaims();
05256 }
05257 #endif
05258 
05259 
05260 /********************************************************************************************
05261 
05262 >   void CColourBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHandler)
05263 
05264     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05265     Created:    17/6/94
05266     Inputs:     pTarget - 
05267                 bDisableIfNoHandler - 
05268     Outputs:    -
05269     Returns:    -
05270 
05271     Purpose:    I'm not really sure... Some sort of mystical MFC thingummy.
05272 
05273     Notes:      I'm not entirely sure how much of this is necessary, but it doesn't seem
05274                 to do any harm, and things didn't work properly until I put it in...
05275 
05276                 The ColourBar works exclusively on the SELECTED Doc. Change with care
05277 
05278 ********************************************************************************************/
05279 
05280 PORTNOTE("other","Removed OnUpdateCmdUI")
05281 #if !defined(EXCLUDE_FROM_XARALX)
05282 void CColourBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHandler)
05283 {
05284     CCmdUI state;
05285     state.m_pOther = this;
05286     state.m_nIndexMax = (UINT32)m_nCount;
05287 
05288     for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
05289       state.m_nIndex++)
05290     {
05291         state.m_nID = 0;
05292         state.DoUpdate(pTarget, bDisableIfNoHandler);
05293     }
05294 
05295     // update the dialog controls added to the status bar (of which there are none)
05296     UpdateDialogControls(pTarget, bDisableIfNoHandler);
05297 }
05298 #endif
05299 
05300 
05301 /********************************************************************************************
05302 
05303 >   static BOOL CColourBar::GetStatusLineText(String_256 *Result)
05304 
05305     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05306     Created:    2/1/95
05307     
05308     Inputs:     -
05309     Outputs:    Result - If the mouse pointer is currently over the colour line, this is
05310                 returned containing appropriate help text, otherwise this is left untouched.
05311     Returns:    TRUE if the Result string was updated with valid help text
05312 
05313     Purpose:    To retrieve help text for use by the status line system
05314 
05315 ********************************************************************************************/
05316 
05317 BOOL CColourBar::GetStatusLineText(String_256 *Result)
05318 {
05319     if (TheColourBar == NULL)       // There is no colour bar!
05320         return(FALSE);
05321 
05322     if (TheColourBar->m_pCurrentColourList == NULL) // No Colours! Exit immediately!
05323         return(FALSE);
05324 
05325 //  ASSERT_VALID(TheColourBar);
05326     ERROR3IF(Result == NULL, _T("CColourBar::GetStatusLineText - NULL Result parameter is bad"));
05327 
05328     wxPoint ScreenPos = ::wxGetMousePosition();
05329 
05330     if (::wxChildWindowFromPoint(ScreenPos, false, -1) != TheColourBar)
05331         return(FALSE);
05332 
05333     wxPoint ClientPos = TheColourBar->ScreenToClient(ScreenPos);    // make relative to window
05334 
05335     static String_64 HelpStringStore;
05336 //  StringBase *HelpString = NULL;
05337 
05338     INT32 Item = TheColourBar->WhereIsMouse(ClientPos);
05339     if (Item >= CLICKED_NOTHING)
05340     {
05341         switch(Item)
05342         {
05343             case CLICKED_SCROLLBAR:
05344             case CLICKED_SCROLLBARLEFT:
05345             case CLICKED_SCROLLBARRIGHT:
05346             case CLICKED_LEFTSCROLL:
05347             case CLICKED_RIGHTSCROLL:
05348                 Result->MakeMsg(_R(IDS_COLBAR_SSCROLL));
05349                 break;
05350 
05351             case CLICKED_INDICATORS:
05352                 Result->MakeMsg(_R(IDS_COLBAR_HINDICATOR));
05353                 break;
05354 
05355             case CLICKED_NOCOLOURCELL:
05356                 Result->MakeMsg(_R(IDS_COLBAR_SNOCOLOUR));
05357                 break;
05358 
05359             case CLICKED_EDITBUTTON:
05360                 {
05361                     // "Click to edit the current colour"
05362                     Result->MakeMsg(_R(IDS_COLBAR_SEDITBUTTON));
05363 
05364                     // If there is a selection, then chnage to using:
05365                     // "Click to edit colour of ellipse"
05366                     SelRange *Selection = GetApplication()->FindSelection();
05367                     if (Selection != NULL)
05368                     {
05369                         if (Selection->Count() > 0)
05370                         {
05371                             String_256 Desc = Selection->Describe(MENU);
05372                             Result->MakeMsg(_R(IDS_COLBAR_SEDITBUTTON2), (TCHAR *)Desc);
05373                         }
05374                     }                   
05375                 }
05376                 break;
05377             
05378 #if FALSE
05379             case CLICKED_NEWBUTTON:
05380                 Result->MakeMsg(_R(IDS_COLBAR_SNEWBUTTON));
05381                 break;
05382 #endif
05383 
05384             case CLICKED_NOTHING:       // No useful help - return nothing
05385                 return(FALSE);
05386         }
05387     }
05388     else
05389     {
05390         if (AttrFillGeometry::SelectionCount > 0)
05391             Result->Load(_R(IDS_COLBAR_SSTRIPGRAD));    // Set grad fill handle colours
05392         else
05393             Result->Load(_R(IDS_COLBAR_SSTRIPFLAT));    // Set normal flat fill colours
05394     }
05395 
05396     return(TRUE);
05397 }
05398 
05399 
05400 
05401 
05402 
05403 
05404 CC_IMPLEMENT_DYNAMIC(ColourBarMsgHandler, MessageHandler)
05405 
05406 #define new CAM_DEBUG_NEW
05407 
05408 /********************************************************************************************
05409 
05410 >   ColourBarMsgHandler::ColourBarMsgHandler()
05411 
05412     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05413     Created:    05/05/94
05414     Purpose:    Constructs a ColourBarMsgHandler, an object which, surprisingly,
05415                 handles messages for its parent CColourBar.
05416     Errors:     -
05417     SeeAlso:    MessageHandler
05418 
05419 ********************************************************************************************/
05420 
05421 ColourBarMsgHandler::ColourBarMsgHandler()
05422   : MessageHandler(CC_RUNTIME_CLASS(MessageHandler), TRUE)
05423 {
05424 }
05425 
05426 
05427 
05428 /********************************************************************************************
05429 
05430 >   virtual MsgResult ColourBarMsgHandler::Message(Msg* Message)
05431 
05432     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05433     Created:    05/05/94
05434     Inputs:     Message: The message
05435     Outputs:    -
05436     Returns:    -
05437     Purpose:    Process messages sent to the Colour Bar
05438     Errors:     -
05439     SeeAlso:    MessageHandler
05440 
05441 ********************************************************************************************/
05442 
05443 MsgResult ColourBarMsgHandler::Message(Msg* Message)
05444 {
05445     if (MESSAGE_IS_A(Message, ColourChangingMsg))
05446     {
05447         ColourChangingMsg *Msg = (ColourChangingMsg *) Message;
05448         switch ( Msg->State )
05449         {
05450             case ColourChangingMsg::LISTDESELECTED:
05451             case ColourChangingMsg::SELVIEWCONTEXTCHANGE:
05452                 CColourBar::PaletteHasChanged(NULL);
05453                 break;
05454 
05455             case ColourChangingMsg::LISTPAGED:
05456             case ColourChangingMsg::LISTUPDATED:
05457             case ColourChangingMsg::COLOURUPDATED:
05458                 CColourBar::PaletteHasChanged(Msg->NewColourList);
05459                 break;
05460 
05461             default:
05462                 break;
05463         }
05464     }
05465     // The new CommonAttrsChanged msg replaces these two messages. It handles 
05466     // a change in the Current Attribute group associated with a tool as well !
05467     // what a bargain !
05468     /*
05469     else if (MESSAGE_IS_A(Message, SelChangingMsg))
05470     {
05471         SelChangingMsg *Msg = (SelChangingMsg *) Message;
05472         switch ( Msg->State )
05473         {
05474             case SelChangingMsg::SelectionState::COLOURATTCHANGED:
05475             case SelChangingMsg::SelectionState::SELECTIONCHANGED:
05476             case SelChangingMsg::SelectionState::NODECHANGED:
05477                 CColourBar::SelectionHasChanged();
05478                 break;
05479         }
05480     }
05481     else if (MESSAGE_IS_A(Message, CurrentAttrChangedMsg))
05482     {
05483         CColourBar::SelectionHasChanged();
05484     }
05485     */
05486     else if (MESSAGE_IS_A(Message, CommonAttrsChangedMsg))
05487     {
05488         CColourBar::SelectionHasChanged();
05489     }
05490     else if (MESSAGE_IS_A(Message,DragMessage))
05491     {
05492         DragMessage *Msg = (DragMessage *) Message;
05493         
05494         if (Msg->State == DragMessage::DRAGSTARTED)
05495         {
05496             if (Msg->pInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation)))
05497             {
05498                 ColourDragInformation *CDI = (ColourDragInformation *)Msg->pInfo;
05499 
05500                 if (CDI->IsLibraryColour() || CDI->GetParentDoc() == Document::GetSelected())
05501                 {
05502                     // Create drag targets to recieve colour drags. We don't really care if this fails,
05503                     // and the drag system will clean up any mess afterwards.
05504                     EditButtonDragTarget *ButtonTarget;
05505                     ButtonTarget = new EditButtonDragTarget(CColourBar::TheColourBar,
05506                                                          &CColourBar::TheColourBar->EditButtonRect);
05507 
05508                     // Check that the colour being dragged is in the current colour list
05509                     IndexedColour *Col = ((ColourDragInformation *) Msg->pInfo)->GetInitiallyDraggedColour();
05510                     if (Col != NULL && CColourBar::TheColourBar->m_pCurrentColourList->FindPosition(Col) < 0)
05511                         Col = NULL;
05512 
05513                     // And if it is in the list, then allow it to be rearranged in the list
05514                     if (Col != NULL)
05515                     {
05516                         ColourLineDragTarget *LineTarget;
05517                         LineTarget = new ColourLineDragTarget(CColourBar::TheColourBar,
05518                                                              &CColourBar::TheColourBar->StripRect);
05519                     }
05520                 }
05521             }
05522         }
05523     }
05524     else if (MESSAGE_IS_A(Message, DocViewMsg))
05525     {
05526         DocViewMsg *Msg = (DocViewMsg *) Message;
05527 
05528         if (Msg->State == DocViewMsg::SELCHANGED)
05529         {
05530             // Selected DocView is changing - redraw to use the new DocView's colour context
05531             BOOL DoRedraw = TRUE;
05532             if (Msg->pOldDocView != NULL && Msg->pNewDocView != NULL)
05533             {
05534                 // If we know the old & new views, then see if they have the same colour
05535                 // context attached - if they do, there's no need to redraw. This eliminates
05536                 // flicker when swapping normal views (the most common view-swap action)
05537                 // We only check the RGB context because we assume the screen is always RGB
05538                 ColourContext *OldCC = Msg->pOldDocView->GetColourContext(COLOURMODEL_RGBT, TRUE);
05539                 ColourContext *NewCC = Msg->pNewDocView->GetColourContext(COLOURMODEL_RGBT, TRUE);
05540 
05541                 if (OldCC == NewCC)
05542                     DoRedraw = FALSE;
05543             }
05544 
05545             if (DoRedraw)
05546                 CColourBar::PaletteHasChanged(NULL);
05547         }
05548     }
05549 
05550     return OK; 
05551 }
05552 
05553 

Generated on Sat Nov 10 03:48:15 2007 for Camelot by  doxygen 1.4.4