colpick.cpp

Go to the documentation of this file.
00001 // $Id: colpick.cpp 1350 2006-06-22 13:20:47Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // colpick.cpp - Colour picker dialogue
00100 
00101 /*
00102 */
00103 
00104 
00105 #include "camtypes.h"
00106 
00107 #include "dlgmgr.h"
00108 #include "colcontx.h"
00109 #include "coldlog.h"
00110 #include "collist.h"
00111 #include "colormgr.h"
00112 #include "colourix.h"
00113 #include "colpick.h"
00114 //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 #include "scunit.h"
00116 #include "ctrlhelp.h"
00117 //#include "jason.h"
00118 //#include "reshlpid.h"
00119 //#include "richard3.h"
00120 //#include "ed.h"
00121 
00122 wxSize ColourPicker::s_LastSize = wxDefaultSize;
00123 wxSize ColourPicker::s_UserSize = wxSize(245,245);
00124 wxSize ColourPicker::s_MinSize = wxSize(180,100);
00125 BOOL ColourPicker::s_InColourDialogLayout = FALSE;
00126 BOOL ColourPicker::s_JustCreated = FALSE;
00127 INT32 ColourPicker::s_IdleCounter = 0;
00128 
00129 CC_IMPLEMENT_MEMDUMP(ColourPicker, CCObject)
00130 
00131 #define new CAM_DEBUG_NEW
00132 
00133 
00134 // The colour picker can supply two types of picker - the standard OS picker
00135 // or a special Camelot picker. The latter allows true editing of colours in
00136 // several colour models, while the former may (does under windows) force the
00137 // colour to RGB or something. The OS picker is included so a) finikity users
00138 // can use a crap picker if they are shy of meeting new dialogues, and b) so
00139 // we can pick new colours/edit existing colours without having to wait for
00140 // a complete picker implementation to roll up...
00141 //static BOOL UseOSPicker = FALSE;
00142 
00143 
00144 // Static buffer for storing bubble help from the colour editor's picker area
00145 // until the bubble-help callback mechanism is called back.
00146 static String_128 PickerBubbleBuffer("");
00147 static String_256 StatusHelpBuffer("");
00148 
00149 
00150 /********************************************************************************************
00151 
00152 >   ColourPicker::ColourPicker()
00153 
00154     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00155     Created:    13/5/94
00156     Inputs:     -
00157     Outputs:    -
00158     Returns:    -
00159     Purpose:    Creates a colourpicker object
00160     Scope:      private
00161     Errors:     -
00162     SeeAlso:    -
00163 
00164 ********************************************************************************************/
00165 
00166 ColourPicker::ColourPicker()
00167 {
00168 }
00169 
00170 
00171 
00172 /********************************************************************************************
00173 
00174 >   ColourPicker::~ColourPicker()
00175 
00176     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00177     Created:    13/5/94
00178     Inputs:     -
00179     Outputs:    -
00180     Returns:    -
00181     Purpose:    Destructor for a Colour Picker
00182     Scope:      private
00183     Errors:     -
00184     SeeAlso:    -
00185 
00186 ********************************************************************************************/
00187 
00188 ColourPicker::~ColourPicker()
00189 {
00190 }
00191 
00192 
00193 /********************************************************************************************
00194 
00195 >   static INT32 ColourValueToByte(const ColourValue &Col)
00196 
00197     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00198     Created:    13/5/94
00199     Inputs:     -
00200     Outputs:    -
00201     Returns:    -
00202     Purpose:    Converts a ColourValue (0.0 to 1.0) into a byte (0..255) with clipping
00203                 to handle out-of-gamut values.
00204 
00205     Notes:      This function is not as efficient as it could be. If it ever becomes
00206                 critical in any way, it should be optimised. See comments in the function.
00207 
00208     Scope:      private
00209     Errors:     -
00210     SeeAlso:    -
00211 
00212 ********************************************************************************************/
00213 /*
00214     === This code has been rewritten to use centralised functions. It is UNTESTED ===
00215 
00216 static INT32 ColourValueToByte(const ColourValue &Col)
00217 {
00218     // We want to use the centralised ColourContext::PackColour function to do this for us
00219     // However, it's protected. The easiest way of accessing the functionality is to
00220     // create a DocColour containing the value, then read back the 0..255 value.
00221     // This is more work than strictly necessary, but then again, this function is non critical.
00222 
00223     DocColour Dummy(Col, Col, Col);
00224 
00225     INT32 Red;
00226     INT32 Green;
00227     INT32 Blue;
00228     Dummy.GetRGBValue(&Red, &Green, &Blue);
00229 
00230     return(Red);
00231 }
00232 */
00233 
00234 
00235 /********************************************************************************************
00236 
00237 >   BOOL ColourPicker::EditColour(ColourList *ParentList, IndexedColour *SourceAndResult,
00238                                     BOOL PreferLineColour = FALSE)
00239 
00240     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00241     Created:    13/5/94
00242     Inputs:     ParentList - The list in which the colour resides
00243                     May be NULL if you want to just show the picker for whatever
00244                     local colour is appropriate.
00245                     SourceAndResult must also be NULL in this case
00246 
00247                 SourceAndResult - The colour to be edited. If the user changes
00248                 the colour, this will be set to the new definition.
00249                     May be NULL if you want to just show the picker for whatever
00250                     local colour is appropriate.
00251                     ParentList must also be NULL in this case
00252 
00253                 PreferLineColour - TRUE if you'd like to edit line colours rather than
00254                 fill colours in local mode, FALSE to edit fill colours. This flag is
00255                 ignored unless ParentList == SourceAndResult == NULL. (Implementation
00256                 note: This calls ColourEditDlg::ForceLineOrFillMode)
00257 
00258     Outputs:    -
00259     Returns:    -
00260     Purpose:    The main colour picker function. Given an IndexedColour, sets up
00261                 a colour picker showing that colour, allows the user to edit it,
00262                 and returns the new colour in said IndexedColour. If the colour is
00263                 changed, an appropriate ColourChangingMsg will be broadcast.
00264 
00265     Notes:      The IndexedColour is actually copied into another for editing. The
00266                 change, if OK'd is then applied using the ColourManager::ChangeColour
00267                 function, which provides an undo record of the event.
00268 
00269     Scope:      private
00270     Errors:     -
00271     SeeAlso:    ColourEditDlg::InvokeDialog
00272 
00273 ********************************************************************************************/
00274 
00275 void ColourPicker::EditColour(ColourList *ParentList, IndexedColour *SourceAndResult,
00276                                 BOOL PreferLineColour)
00277 {
00278 #if FALSE
00279 /*
00280 // **** DEBUG - use Windows Picker if SHIFT NOT held down on entry,
00281 //              else use the Camelot Picker
00282     if (ForceNativePicker)
00283         UseOSPicker = TRUE;
00284     else
00285         UseOSPicker = (::GetAsyncKeyState(CAMKEY(SHIFT)) & 0x8000) ? TRUE : FALSE;
00286 // ****
00287     if (UseOSPicker)
00288     {
00289         IndexedColour *UndoBuffer = new IndexedColour(*SourceAndResult);
00290         if (UndoBuffer == NULL)     // Fail gracefully. Well... Don't crash, anyway
00291             return;
00292 
00293         ColourGeneric *TheColour = UndoBuffer->SourceColourPtr();
00294 
00295         Document *ScopeDoc = Document::GetSelected();
00296         if (ScopeDoc == NULL)
00297             return;
00298 
00299         ColourContext *ccRGB = ScopeDoc->GetDefaultColourContexts()->Context[COLOURMODEL_RGBT];
00300         ENSURE(ccRGB != NULL, "Default RGBT context can't be found!");
00301 
00302         ColourContext *ccSource = ScopeDoc->GetDefaultColourContexts()->Context[UndoBuffer->GetColourModel()];
00303         if (ccSource == NULL)
00304         {
00305             ENSURE(FALSE, "Unsupported source colour context - I can't edit that colour");
00306             return;
00307         }
00308 
00309         // Convert the given colour into RGB, using 'pure' contexts (logical rather than physica
00310         // conversion, i.e. no colour correction en-route)
00311         ColourRGBT TheColourRGB;
00312         ccRGB->ConvertColour(ccSource, TheColour, (ColourGeneric *) &TheColourRGB);
00313 
00314 
00315         // Now set up, and call the Windows colour picker to edit the colour...
00316         CHOOSECOLOR cc;
00317 
00318         // Set initial colour for the colour picker to use
00319         cc.rgbResult = RGB( ColourValueToByte(TheColourRGB.Red),
00320                             ColourValueToByte(TheColourRGB.Green),
00321                             ColourValueToByte(TheColourRGB.Blue) );
00322 
00323 
00324         // Set the default set of available colours (a greyscale for the time being)
00325         // (it is static so that if the user changes any of the colours they will get
00326         // the changed palette back next time around)
00327         static COLORREF acrCustClr[16] =
00328             {
00329                 RGB(255, 255, 255), RGB(239, 239, 239),
00330                 RGB(223, 223, 223), RGB(207, 207, 207),
00331                 RGB(191, 191, 191), RGB(175, 175, 175),
00332                 RGB(159, 159, 159), RGB(143, 143, 143),
00333                 RGB(127, 127, 127), RGB(111, 111, 111),
00334                 RGB(95, 95, 95),    RGB(79, 79, 79),
00335                 RGB(63, 63, 63),    RGB(47, 47, 47),
00336                 RGB(31, 31, 31),    RGB(15, 15, 15)
00337             };
00338 
00339         cc.lStructSize = sizeof(CHOOSECOLOR);
00340         cc.hwndOwner = AfxGetApp()->m_pMainWnd->m_hWnd; // 'owner' window
00341         cc.lpCustColors = (LPDWORD) acrCustClr;         // List of default colours
00342         cc.Flags = CC_RGBINIT | CC_FULLOPEN;            // Use cc.rgbResult to init picker...
00343                                                         // and picker appears fully opened - Geez that
00344                                                         // 'define wossnames' button is a pain in the butt!!!
00345 
00346         if (ChooseColor(&cc))       // Invoke Windows colour picker (if it qualifies as a colour picker!)
00347         {
00348             // User chose a colour and hit OK - read out the return value (always RGB)
00349             UndoBuffer->SetSourceColourModel(COLOURMODEL_RGBT);
00350             ((ColourRGBT *)TheColour)->Red   = ((double) GetRValue(cc.rgbResult)) / 256.0;
00351             ((ColourRGBT *)TheColour)->Green = ((double) GetGValue(cc.rgbResult)) / 256.0;
00352             ((ColourRGBT *)TheColour)->Blue  = ((double) GetBValue(cc.rgbResult)) / 256.0;
00353             ((ColourRGBT *)TheColour)->Transparent = 0;
00354 
00355             Document::GetSelected()->SetCurrent();      // Make this document the current one
00356 
00357             // This swallows UndoBuffer into the undo system - we must NOT delete it
00358             ColourManager::ChangeColour(ParentList, UndoBuffer, SourceAndResult);
00359         }
00360         else
00361             delete UndoBuffer;  // UndoBuffer not used - delete it
00362     }
00363     else
00364 */
00365 #endif
00366     {
00367 #ifndef STANDALONE
00368         // If we are asking to edit an appropriate local colour, state our preference
00369         // for either fill or line colour.
00370         if (SourceAndResult == NULL)
00371             ColourEditDlg::ForceLineOrFillMode(PreferLineColour);
00372 
00373         ColourEditDlg::InvokeDialog(ParentList, SourceAndResult);
00374 #endif
00375     }
00376 }
00377 
00378 
00379 
00380 /********************************************************************************************
00381 
00382 >   static BOOL ColourPicker::GetStatusLineText(ColourEditDlg *Editor, UINT32 GadgetID,
00383                                                     String_256 *Result)
00384 
00385     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00386     Created:    25/5/95
00387 
00388     Inputs:     Editor - points to the current editor
00389                 GadgetID - indicates the gadget for which you desire help
00390 
00391     Outputs:    If return value is TRUE, Result is updated with an appropriate help string
00392 
00393     Returns:    TRUE if it changed Result, FALSE if it can offer no help
00394 
00395     Purpose:    Bodge to get around the fact that DialogOps don't plug into the status
00396                 line help system. Returns help for the colour editor. Must go via the
00397                 winoil, as we have to read the mouse position and find the window it's in.
00398 
00399     SeeAlso:    ColourEditDlg::GetStatusLineText
00400 
00401 ********************************************************************************************/
00402 
00403 BOOL ColourPicker::GetStatusLineText(ColourEditDlg *Editor, UINT32 GadgetID, String_256 *Result)
00404 {
00405 #ifndef STANDALONE
00406 
00407     IndexedColour *Bob = Editor->EditingColour;
00408     if (Bob == NULL)
00409     {
00410         *Result = String_256(_R(IDS_EDITST_NOCOLOUR));
00411         return(TRUE);
00412     }
00413 
00414     ColourContext *cc = ColourContext::GetGlobalDefault(ColourEditDlg::DisplayModel);
00415 
00416     // Set the default help
00417     *Result = String_256(_R(IDS_EDITST_DEFAULT));
00418 
00419     if (FALSE) {}
00420 //  else if (GadgetID == _R(IDCANCEL))
00421 //  {
00422 //      *Result = String_256(_R(IDS_EDITST_CANCEL));
00423 //  }
00424     else if (GadgetID == _R(IDC_EDIT_DROPMENU))
00425     {
00426         *Result = String_256(_R(IDS_EDITST_MENU));
00427     }
00428     else if (GadgetID == _R(IDC_EDIT_COMPONENT1))
00429     {
00430         if (ColourEditDlg::DisplayModel == COLOURMODEL_HSVT)
00431         {
00432             *Result = String_256(_R(IDS_EDITST_COMP1));
00433         }
00434         else
00435         {
00436             if (cc != NULL)
00437             {
00438                 String_64 CompName;
00439                 cc->GetComponentName(1, &CompName, TRUE);
00440                 Result->MakeMsg(_R(IDS_EDITST_COMP234), (TCHAR *)CompName);
00441             }
00442         }
00443     }
00444     else if (GadgetID == _R(IDC_EDIT_COMPONENT2))
00445     {
00446         if (cc != NULL)
00447         {
00448             String_64 CompName;
00449             cc->GetComponentName(2, &CompName, TRUE);
00450             Result->MakeMsg(_R(IDS_EDITST_COMP234), (TCHAR *)CompName);
00451         }
00452     }
00453     else if (GadgetID == _R(IDC_EDIT_COMPONENT3))
00454     {
00455         if (cc != NULL)
00456         {
00457             String_64 CompName;
00458             cc->GetComponentName(3, &CompName, TRUE);
00459             Result->MakeMsg(_R(IDS_EDITST_COMP234), (TCHAR *)CompName);
00460         }
00461     }
00462 // WEBSTER - markn 14/12/96
00463 #ifndef WEBSTER
00464     else if (GadgetID == _R(IDC_EDIT_COMPONENT4))
00465     {
00466         if (cc != NULL)
00467         {
00468             String_64 CompName;
00469             cc->GetComponentName(4, &CompName, TRUE);
00470             Result->MakeMsg(_R(IDS_EDITST_COMP234), (TCHAR *)CompName);
00471         }
00472     }
00473     else if (GadgetID == _R(IDC_EDIT_COLMODEL))
00474     {
00475         *Result = String_256(_R(IDS_EDITST_COLMODEL));
00476     }
00477     else if (GadgetID == _R(IDC_EDIT_NAMEMENU))
00478     {
00479         *Result = String_256(_R(IDS_EDITST_NAME));
00480     }
00481     else if (GadgetID == _R(IDC_EDIT_COLTYPE))
00482     {
00483         *Result = String_256(_R(IDS_EDITST_COLTYPE));
00484     }
00485     else if ((GadgetID == _R(IDC_EDIT_INHERIT1)) ||
00486              (GadgetID == _R(IDC_EDIT_INHERIT2)) ||
00487              (GadgetID == _R(IDC_EDIT_INHERIT3)) ||
00488              (GadgetID == _R(IDC_EDIT_INHERIT4)))
00489     {
00490         *Result = String_256(_R(IDS_EDITST_INHERIT));
00491     }
00492 //  else if ((GadgetID == _R(IDC_EDIT_PATCH)) ||
00493 //           (GadgetID == _R(IDC_EDIT_PARENTPATCH)))
00494 //  {
00495 //      *Result = String_256(_R(IDS_EDITST_PARENTPATCH));
00496 //  }
00497     else if ((GadgetID == _R(IDC_EDIT_PARENTCOL)) ||
00498              (GadgetID == _R(IDC_EDIT_PARENTNAME)))
00499     {
00500         *Result = String_256(_R(IDS_EDITST_PARENTCOL));
00501     }
00502     else if ((GadgetID == _R(IDC_EDIT_TINT)) ||
00503              (GadgetID == _R(IDC_EDIT_TINTSLIDER)))
00504     {
00505         if (Bob->GetType() == COLOURTYPE_TINT && !Bob->TintIsShade())
00506             *Result = String_256(_R(IDS_EDITST_TINT1));     // It's a tint
00507         else
00508             *Result = String_256(_R(IDS_EDITST_TINT2));     // It's a shade
00509     }
00510     else if (GadgetID == _R(IDC_EDIT_SHADE))
00511     {
00512         *Result = String_256(_R(IDS_EDITST_TINT2));         // It's a shade
00513     }
00514     else if (GadgetID == _R(IDC_EDIT_ADVANCED))
00515     {
00516         if (Editor->Folded)
00517             *Result = String_256(_R(IDS_EDITST_ADVANCED1));
00518         else
00519             *Result = String_256(_R(IDS_EDITST_ADVANCED2));
00520     }
00521     else if (GadgetID == _R(IDC_EDIT_3D))
00522     {
00523         *Result = String_256(_R(IDS_EDITST_3D));
00524     }
00525     else if (GadgetID == _R(IDC_EDIT_MAKESTYLE))
00526     {
00527         *Result = String_256(_R(IDS_EDITST_MAKESTYLE));
00528     }
00529 #endif // WEBSTER
00530     else if (GadgetID == _R(IDC_EDIT_PICKER))
00531     {
00532         if (!StatusHelpBuffer.IsEmpty())
00533             *Result = StatusHelpBuffer;
00534         else
00535         {
00536             switch(Bob->GetType())
00537             {
00538             // WEBSTER - markn 14/12/96
00539             #ifndef WEBSTER
00540                 case COLOURTYPE_TINT:
00541                     if (Editor->Folded)
00542                         *Result = String_256(_R(IDS_EDITST_PICKER1));
00543                     else
00544                         *Result = String_256(_R(IDS_EDITST_PICKER2));
00545                     break;
00546 
00547                 case COLOURTYPE_LINKED:
00548                     *Result = String_256(_R(IDS_EDITST_PICKER3));
00549                     break;
00550             #endif // WEBSTER
00551 
00552                 case COLOURTYPE_NORMAL:
00553                 case COLOURTYPE_SPOT:
00554                 default:
00555                     *Result = String_256(_R(IDS_EDITST_PICKER4));
00556                     break;
00557             }
00558         }
00559     }   
00560     else if (GadgetID == _R(IDC_EDIT_216ONLY))
00561     {
00562         *Result = String_256(_R(IDS_EDITST_216ONLY));
00563     }   
00564     else if (GadgetID == _R(IDC_COLOURPICKER))
00565     {
00566         *Result = String_256(_R(IDS_STATICCOLOURPICKERTOOLHELP));
00567     }
00568     else if (GadgetID == _R(IDC_MAKE_LOCAL))
00569     {
00570         *Result = String_256(_R(IDS_EDITST_MAKE_LOCAL));
00571     }
00572     else if (GadgetID == _R(IDC_EDIT_NOCOLOUR))
00573     {
00574         *Result = String_256(_R(IDS_EDITST_SETNOCOLOUR));
00575     }
00576     else if (GadgetID == _R(IDC_EDIT_RENAME))
00577     {
00578         *Result = String_256(_R(IDS_EDITST_RENAME));
00579     }
00580     else if (GadgetID == _R(IDC_EDIT_LINEFILL))
00581     {
00582         *Result = String_256(_R(IDS_EDITST_LINEFILL));
00583     }
00584 #endif
00585     return(TRUE);
00586 }
00587 
00588 
00589 
00590 /********************************************************************************************
00591 
00592 >   static BOOL ColourPicker::GetStatusLineText(String_256 *Result)
00593 
00594     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00595     Created:    25/5/95
00596 
00597     Outputs:    If return value is TRUE, Result is updated with an appropriate help string
00598 
00599     Returns:    TRUE if it changed Result, FALSE if it can offer no help
00600 
00601     Purpose:    Bodge to get around the fact that DialogOps don't plug into the status
00602                 line help system. Returns help for the colour editor. Must go via the
00603                 winoil, as we have to read the mouse position and find the window it's in.
00604 
00605     Notes:      This is a huge bodge:
00606                     1) DialogOp should do this for us
00607                     2) I'm on holiday in a day's time, I don't have time to do it properly
00608                     3) It only gives help for the picker control because I can't work out
00609                         a quick & easy way ofgetting WindowID and GadgetID
00610 
00611     SeeAlso:    ColourEditDlg::GetStatusLineText
00612 
00613 ********************************************************************************************/
00614 
00615 #ifndef STANDALONE
00616 static UINT32 GadgetList[] = 
00617     {
00618 //      IDCANCEL,
00619         _R(IDC_EDIT_DROPMENU),
00620         _R(IDC_EDIT_COMPONENT1),
00621         _R(IDC_EDIT_COMPONENT2),
00622         _R(IDC_EDIT_COMPONENT3),
00623         _R(IDC_EDIT_COMPONENT4),
00624         _R(IDC_EDIT_COLMODEL),
00625         _R(IDC_EDIT_NAMEMENU),
00626         _R(IDC_EDIT_COLTYPE),
00627         _R(IDC_EDIT_INHERIT1),
00628         _R(IDC_EDIT_INHERIT2),
00629         _R(IDC_EDIT_INHERIT3),
00630         _R(IDC_EDIT_INHERIT4),
00631         _R(IDC_EDIT_PICKER),
00632         _R(IDC_EDIT_PATCH),
00633         _R(IDC_EDIT_PARENTPATCH),
00634         _R(IDC_EDIT_PARENTCOL),
00635         _R(IDC_EDIT_TINT),
00636         _R(IDC_EDIT_SHADE),
00637         _R(IDC_EDIT_ADVANCED),
00638         _R(IDC_EDIT_PARENTNAME),
00639 //      _R(IDC_EDIT_TINTSLIDER),
00640 //      _R(IDC_EDIT_PICKERBORDER),
00641         _R(IDC_EDIT_3D),
00642         _R(IDC_EDIT_MAKESTYLE),
00643 
00644         _R(IDC_EDIT_NOCOLOUR),
00645         _R(IDC_EDIT_LINEFILL),
00646         _R(IDC_EDIT_216ONLY),
00647         _R(IDC_MAKE_LOCAL),
00648         _R(IDC_EDIT_RENAME),
00649         _R(IDC_COLOURPICKER),
00650         0
00651     };
00652 #endif
00653 
00654 
00655 BOOL ColourPicker::GetStatusLineText(String_256 *Result)
00656 {
00657 #ifndef STANDALONE
00658 
00659     ERROR3IF(Result == NULL, "Illegal NULL param");
00660     
00661     ColourEditDlg *Editor = ColourEditDlg::TheEditor;
00662     if (Editor == NULL)
00663         return(FALSE);
00664 
00665     // Find the main editor window
00666     CWindowID TheWindow = (CWindowID)Editor->WindowID;
00667     if (TheWindow == NULL)
00668         return(FALSE);
00669 
00670     wxPoint mousepos = ::wxGetMousePosition();
00671     wxWindow * window=::wxChildWindowFromPoint(TheWindow, mousepos, FALSE, -1);
00672     if ((!window) || (window!=::wxChildWindowFromPoint(mousepos, FALSE, -1))) // second check to ensure it is not obscured
00673         return FALSE;
00674 
00675     return GetStatusLineText(Editor, window->GetId(), Result);
00676 #else
00677     return(TRUE);
00678 #endif
00679 }
00680 
00681 
00682 
00683 /********************************************************************************************
00684 
00685 >   TCHAR *ColourPicker::HelpCallbackHandler(CWindowID Window, UINT32 Item, void *UserData)
00686 
00687     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00688     Created:    27/9/95
00689 
00690     Inputs:     Window - identifies the window to get help for
00691                 Item   - identifies the control to get help for
00692                 UserData - User-supplied data (not used)
00693 
00694     Returns:    The bubble help string to use, or NULL if no help is available
00695 
00696     Purpose:    Help callback handler to provide bubble help for the colour editor
00697 
00698     SeeAlso:    ColourPicker::UpdateBubbleHelpAndPointer
00699 
00700 ********************************************************************************************/
00701 
00702 TCHAR *ColourPicker::HelpCallbackHandler(CWindowID Window, UINT32 Item, void *UserData)
00703 {
00704 #ifndef STANDALONE
00705     static String_256 HelpStringStore;
00706     BOOL ReturnVal = FALSE;
00707 
00708     ColourEditDlg *Editor = ColourEditDlg::TheEditor;
00709     if (Editor == NULL)
00710         return(NULL);
00711 
00712     IndexedColour *Bob = Editor->EditingColour;
00713 
00714     ColourContext *cc = NULL;
00715     if (Bob != NULL)
00716         cc = ColourContext::GetGlobalDefault(ColourEditDlg::DisplayModel);
00717 
00718     if (FALSE) {}
00719     else if (Item == _R(IDC_EDIT_DROPMENU))
00720     {
00721         HelpStringStore = String_256(_R(IDS_EDITBH_MENU));
00722         ReturnVal = TRUE;
00723     }
00724     else if ((Item == _R(IDC_EDIT_PATCH1))  ||  // Fake ID for current colour patch to give it a unique ID
00725              (Item == _R(IDC_EDIT_PATCH2)) ||   // Fake ID for current colour patch to give it a unique ID
00726              (Item == _R(IDC_EDIT_PATCH)) ||
00727              (Item == _R(IDC_EDIT_PICKER)))
00728     {
00729         // NOTE: This gives help for "Original/Current colour" patch
00730         // We will only get called for this if it is necessary (pointer in correct region of control)
00731         HelpStringStore = PickerBubbleBuffer; //String_256(_R(IDS_EDITBH_PARENTPATCH));
00732         ReturnVal = TRUE;
00733     }   
00734 
00735     else if (Item == _R(IDC_EDIT_COMPONENT1))
00736     {
00737         if (cc)
00738             ReturnVal = GetComponentHelp(cc, 1, HelpStringStore);
00739     }
00740     else if (Item == _R(IDC_EDIT_COMPONENT2))
00741     {
00742         if (cc)
00743             ReturnVal = GetComponentHelp(cc, 2, HelpStringStore);
00744     }
00745     else if (Item == _R(IDC_EDIT_COMPONENT3))
00746     {
00747         if (cc)
00748             ReturnVal = GetComponentHelp(cc, 3, HelpStringStore);
00749     }
00750     else if (Item == _R(IDC_EDIT_COMPONENT4))
00751     {
00752         if (cc)
00753             ReturnVal = GetComponentHelp(cc, 4, HelpStringStore);
00754     }
00755 #if 0
00756     {
00757         if (ColourEditDlg::DisplayModel == COLOURMODEL_HSVT)
00758         {
00759             HelpStringStore = String_256(_R(IDS_EDITBH_COMP1));
00760             ReturnVal = TRUE;
00761         }
00762         else
00763         {
00764             if (cc != NULL)
00765             {
00766                 String_64 CompName;
00767                 cc->GetComponentName(1, &CompName, TRUE);
00768                 HelpStringStore.MakeMsg(_R(IDS_EDITBH_COMP234), (TCHAR *)CompName);
00769                 ReturnVal = TRUE;
00770             }
00771         }
00772     }
00773 
00774     else if (Item == _R(IDC_EDIT_COMPONENT2))
00775     {
00776         if (cc != NULL)
00777         {
00778             String_64 CompName;
00779             cc->GetComponentName(2, &CompName, TRUE);
00780             HelpStringStore.MakeMsg(_R(IDS_EDITBH_COMP234), (TCHAR *)CompName);
00781             ReturnVal = TRUE;
00782         }
00783     }   
00784 
00785     else if (Item == _R(IDC_EDIT_COMPONENT3))
00786     {
00787         if (cc != NULL)
00788         {
00789             String_64 CompName;
00790             cc->GetComponentName(3, &CompName, TRUE);
00791             HelpStringStore.MakeMsg(_R(IDS_EDITBH_COMP234), (TCHAR *)CompName);
00792             ReturnVal = TRUE;
00793         }
00794     }   
00795 
00796     else if (Item == _R(IDC_EDIT_COMPONENT4))
00797     {
00798         if (cc != NULL)
00799         {
00800             String_64 CompName;
00801             cc->GetComponentName(4, &CompName, TRUE);
00802             HelpStringStore.MakeMsg(_R(IDS_EDITBH_COMP234), (TCHAR *)CompName);
00803             ReturnVal = TRUE;
00804         }
00805     }   
00806 
00807 #endif
00808     else if (Item == _R(IDC_EDIT_COLMODEL))
00809     {
00810         HelpStringStore = String_256(_R(IDS_EDITBH_COLMODEL));
00811         ReturnVal = TRUE;
00812     }   
00813     else if (Item == _R(IDC_EDIT_NAMEMENU))
00814     {
00815         HelpStringStore = String_256(_R(IDS_EDITBH_NAME));
00816         ReturnVal = TRUE;
00817     }
00818     else if (Item == _R(IDC_EDIT_WEBHEX))
00819     {
00820         HelpStringStore = String_256(_R(IDS_EDITBH_WEBHEX));
00821         ReturnVal = TRUE;
00822     }
00823     else if (Item == _R(IDC_EDIT_COLTYPE))
00824     {
00825         HelpStringStore = String_256(_R(IDS_EDITBH_COLTYPE));
00826         ReturnVal = TRUE;
00827     }
00828     else if ((Item == _R(IDC_EDIT_INHERIT1)) ||
00829              (Item == _R(IDC_EDIT_INHERIT2)) ||
00830              (Item == _R(IDC_EDIT_INHERIT3)) ||
00831              (Item == _R(IDC_EDIT_INHERIT4)) )
00832     {
00833         HelpStringStore = String_256(_R(IDS_EDITBH_INHERIT));
00834         ReturnVal = TRUE;
00835     }
00836     else if ((Item == _R(IDC_EDIT_PARENTCOL)) ||
00837              (Item == _R(IDC_EDIT_PARENTNAME)))
00838     {
00839         HelpStringStore = String_256(_R(IDS_EDITBH_PARENTCOL));
00840         ReturnVal = TRUE;
00841     }
00842     else if ((Item == _R(IDC_EDIT_TINT)) ||
00843              (Item == _R(IDC_EDIT_TINTSLIDER)))
00844     {
00845         if (Bob != NULL && Bob->GetType() == COLOURTYPE_TINT && !Bob->TintIsShade())
00846             HelpStringStore = String_256(_R(IDS_EDITBH_TINT1));     // It's a tint
00847         else
00848             HelpStringStore = String_256(_R(IDS_EDITBH_TINT2));     // It's a shade
00849         ReturnVal = TRUE;
00850     }   
00851     else if (Item == _R(IDC_EDIT_SHADE))
00852     {
00853         HelpStringStore = String_256(_R(IDS_EDITBH_TINT2));         // It's a shade
00854         ReturnVal = TRUE;
00855     }   
00856     else if (Item == _R(IDC_EDIT_ADVANCED))
00857     {
00858         if (Editor->Folded)
00859             HelpStringStore = String_256(_R(IDS_EDITBH_ADVANCED1));
00860         else
00861             HelpStringStore = String_256(_R(IDS_EDITBH_ADVANCED2));
00862         ReturnVal = TRUE;
00863     }
00864     else if (Item == _R(IDC_EDIT_3D))
00865     {
00866         HelpStringStore = String_256(_R(IDS_EDITBH_3D));
00867         ReturnVal = TRUE;
00868     }
00869     else if (Item == _R(IDC_EDIT_MAKESTYLE))
00870     {
00871         HelpStringStore = String_256(_R(IDS_EDITBH_MAKESTYLE));
00872         ReturnVal = TRUE;
00873     }
00874     else if (Item == _R(IDC_EDIT_NOCOLOUR))
00875     {
00876         HelpStringStore = String_256(_R(IDS_COLBAR_HNOCOLOUR));
00877         ReturnVal = TRUE;
00878     }
00879     else if (Item == _R(IDC_MAKE_LOCAL))
00880     {
00881         HelpStringStore = String_256(_R(IDS_EDITBH_MAKE_LOCAL));
00882         ReturnVal = TRUE;
00883     }
00884     else if (Item == _R(IDC_EDIT_RENAME))   
00885     {
00886         HelpStringStore = String_256(_R(IDS_EDITBH_RENAME));
00887         ReturnVal = TRUE;
00888     }
00889     else if (Item == _R(IDC_EDIT_LINEFILL))
00890     {
00891         HelpStringStore = String_256(_R(IDS_EDITBH_LINEFILL));
00892         ReturnVal = TRUE;
00893     }
00894     else if (Item == _R(IDC_EDIT_216ONLY))
00895     {
00896         HelpStringStore = String_256(_R(IDS_EDITBH_216ONLY));
00897         ReturnVal = TRUE;
00898     }   
00899     else if (Item == _R(IDC_COLOURPICKER))
00900     {
00901         HelpStringStore = String_256(_R(IDS_STATICCOLOURPICKERTOOLHELP));
00902         ReturnVal = TRUE;
00903     }
00904 
00905     if (ReturnVal)
00906         return((TCHAR *) HelpStringStore);
00907 
00908 #endif
00909 
00910     return(NULL);
00911 }
00912 
00913 /********************************************************************************************
00914 
00915 >   void ColourPicker::SetBubbleHelp(CGadgetID * GadgetList)
00916 
00917     Author:     Alex Bligh <alex@alex.org.uk>
00918     Created:    31/5/2006
00919 
00920     Inputs:     GadgetList - NULL terminated list of gadgets
00921 
00922     Returns:    -
00923 
00924     Purpose:    Set all the bubble help up for the colour picker
00925 
00926     SeeAlso:    -
00927 
00928 ********************************************************************************************/
00929 
00930 void ColourPicker::SetBubbleHelp(CGadgetID * GadgetList)
00931 {
00932     ColourEditDlg *Editor = ColourEditDlg::TheEditor;
00933     if (Editor == NULL)
00934         return;
00935 
00936     CGadgetID i;
00937     while ((i=*(GadgetList++))) // assignment
00938     {
00939         wxWindow * pGadget = DialogManager::GetGadget(Editor->WindowID, i);
00940         wxString s;
00941         if (pGadget)
00942         {
00943             if (pGadget->IsEnabled() && pGadget->IsShown())
00944             {
00945                 // This is OK because HelpCallbackHandler uses a disgusting static. Not my doing
00946                 TCHAR * pHelp = HelpCallbackHandler(Editor->WindowID, i, NULL);
00947                 if (pHelp)
00948                     s=wxString(pHelp);
00949             }
00950             if (!s.IsEmpty())
00951                 pGadget->SetToolTip(s);
00952             else
00953                 pGadget->SetToolTip(NULL);
00954         }
00955     }
00956 }
00957 
00958 /********************************************************************************************
00959 
00960 >   BOOL ColourPicker::GetComponentHelp(ColourContext* const pSourceContext, 
00961                 const UINT32 ComponentIndex, StringBase& HelpString)
00962 
00963     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00964     Created:    31/05/96
00965 
00966     Inputs:     pSourceContext - the ColourContext in which the component is
00967                 ComponentIndex - the index of the component in the colour context
00968                 (1..GetComponentCount())
00969     Outputs:    HelpString - a string to be displayed as help for the given component
00970     Returns:    TRUE : If help string constructed correctly
00971                 FALSE : otherwise
00972     Purpose:    Subprocedure for HelpCallbackHandler providing help for each of the colour
00973                 components.
00974     Errors:     ERROR2IF's if invalid paramters given
00975                 ERROR3IF's for corrupt data structures
00976     SeeAlso:    ColourPicker::HelpCallbackHandler
00977 
00978 ********************************************************************************************/
00979 BOOL ColourPicker::GetComponentHelp(ColourContext* const pSourceContext, const UINT32 ComponentIndex, StringBase& HelpString)
00980 {
00981     ERROR2IF(pSourceContext == NULL, FALSE, "NULL parameters not allowed");
00982     ERROR3IF(!pSourceContext->IS_KIND_OF(ColourContext), "ColourPicker::GetComponentHelp() - pSourceContext isn't");
00983     ERROR2IF((ComponentIndex < 1) || (ComponentIndex > pSourceContext->GetComponentCount()), FALSE,
00984                 "Component index out of bounds");
00985 
00986     // Create a string of the form "Red (0..100%)" using the colour component's name and the limits defined for
00987     // the component's unit
00988     UnitGroup* pUnitGroup = pSourceContext->GetComponentUnitGroup(ComponentIndex);
00989     if (pUnitGroup == NULL)
00990     {
00991         ERROR3("ColourPicker::GetComponentHelp - Model has no units");
00992         return FALSE;
00993     }
00994     ERROR3IF(!pUnitGroup->IS_KIND_OF(UnitGroup), "ColourPicker::GetComponentHelp() - pUnitGroup isn't");
00995     ScaleUnit* pUnit = pUnitGroup->GetDefaultUnit();
00996     if (pUnit == NULL)
00997     {
00998         ERROR3("ColourPicker::GetComponentHelp - No default units");
00999         return FALSE;
01000     }
01001     ERROR3IF(!pUnit->IS_KIND_OF(ScaleUnit), "ColourPicker::GetComponentHelp() - pUnit isn't");
01002 
01003     String_64 CompName;
01004     pSourceContext->GetComponentName(ComponentIndex, &CompName, TRUE);
01005 
01006     String_32 LowerLimit;
01007     Convert::DoubleToString(pUnit->GetMin(), (StringBase*)&LowerLimit, pUnit->GetDPtoShow());
01008 
01009     String_32 UpperLimit;
01010     Convert::DoubleToString(pUnit->GetMax(), (StringBase*)&UpperLimit, pUnit->GetDPtoShow());
01011 
01012     String_32 QualifierToken;
01013     const Qualifier* pQualifier = pUnit->GetQualifier();
01014     if (pQualifier == NULL)
01015     {
01016         ERROR3("ColourPicker::GetComponentHelp - No qualifier");
01017         return FALSE;
01018     }
01019     ERROR3IF(!pQualifier->IS_KIND_OF(Qualifier), "ColourPicker::GetComponentHelp - Qualifier isn't");
01020 
01021     if (pQualifier->IsShown())
01022     {
01023         QualifierToken = pQualifier->GetToken();
01024     }
01025 
01026     HelpString.MakeMsg(_R(IDS_EDITBH_COMP234), (TCHAR *)CompName, (TCHAR *)LowerLimit, (TCHAR *)UpperLimit, 
01027                         (TCHAR *)QualifierToken);
01028 
01029     return TRUE;
01030 }
01031 
01032 
01033 /********************************************************************************************
01034 
01035 >   static void ColourPicker::UpdateBubbleHelpAndPointer(void)
01036 
01037     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01038     Created:    28/9/95
01039 
01040     Purpose:    Called on Idle (or MouseMove) events to provide bubble help and update
01041                 the mouse pointer while it is over the colour editor dialogue.
01042 
01043     Notes:      This is basically a bodge until a proper dialogue bubblehelp system is
01044                 available to do everything I need to do in the colour editor.
01045 
01046     SeeAlso:    ColourEditDlg::GetStatusLineText
01047 
01048 ********************************************************************************************/
01049 
01050 void ColourPicker::UpdateBubbleHelpAndPointer(void)
01051 {
01052 PORTNOTE("other", "Disabled ColourPicker::UpdateBubbleHelpAndPointer()")
01053 #ifndef EXCLUDE_FROM_XARALX
01054 #ifndef STANDALONE
01055     ColourEditDlg *Editor = ColourEditDlg::TheEditor;
01056     if (Editor == NULL)
01057         return;
01058 
01059     static CWindowID TheWindow = NULL;
01060     
01061     if (TheWindow == NULL)
01062         TheWindow = (CWindowID)Editor->WindowID;
01063 
01064     if (TheWindow == NULL)
01065         return;
01066 
01067     // We will update the bubble help every time we are called. However, we will only
01068     // bother checking through all the gadgets in the window a maximum of 10 times
01069     // per second. This stops the colour editor making a CPU interference buzzing noise
01070     // in my headphones while the pointer is idling over it!!
01071     static MonotonicTime LastUpdate;
01072     static UINT32 MousePos = 0;
01073 
01074     if (LastUpdate.Elapsed(100))
01075     {
01076         // Remember when we last checked
01077         LastUpdate.Sample();
01078 
01079         // Default to the mouse being "nowhere special" again
01080         TheWindow = (CWindowID)Editor->WindowID;
01081         MousePos = 0;
01082 
01083         POINT MouseScreenPos;
01084         if (::GetCursorPos(&MouseScreenPos))
01085         {
01086             // Only continue processing if the window under the pointer is the colour editor
01087             // or a child thereof. My machine makes a funny CPU buzz in my earphones when the
01088             // pointer is in the editor window, and it was doing this even when I had another
01089             // application maximised in front of camelot! ChildWindowFromPoint does not
01090             // determine if the child window is actually *visible*!
01091 
01092             CWindowID WindowUnder = ::WindowFromPoint(MouseScreenPos);
01093 
01094             if (WindowUnder != NULL &&
01095                 (WindowUnder == TheWindow || ::GetParent(WindowUnder) == TheWindow))
01096             {
01097                 POINT TempPos;
01098                 TempPos.x = MouseScreenPos.x;
01099                 TempPos.y = MouseScreenPos.y;
01100 
01101                 // Convert to client coords in the main window
01102                 ::ScreenToClient(TheWindow, &TempPos);
01103 
01104                 CPoint Pos(TempPos);
01105                 CWindowID WindowUnderPointer = ::ChildWindowFromPoint(TheWindow, Pos);
01106                 if (WindowUnderPointer != NULL && IsWindowVisible(WindowUnderPointer))
01107                 {
01108                     // Make sure that hidden windows do not provide status help!
01109                     INT32 WindowStyle = ::GetWindowLong(WindowUnderPointer, GWL_STYLE);
01110                     if ((WindowStyle & WS_VISIBLE) != 0)
01111                     {
01112                         CWindowID hGadget;
01113                         INT32 i = 0;
01114                         while (GadgetList[i] && MousePos)
01115                         {
01116                             hGadget = DialogManager::GetGadget(TheWindow, GadgetList[i]);
01117                             if (WindowUnderPointer == hGadget)
01118                             {
01119                                 MousePos = (UINT32)GadgetList[i];
01120                                 TheWindow = hGadget;
01121                             }
01122                             i++;
01123                         }
01124                     }
01125                 }
01126 
01127                 // Special check for Picker control (BODGE is a more accurate term!)
01128                 // We look to see if the pointer is vaguely over the area of the picker used
01129                 // to display the current/original colour patch, and only give help for that
01130                 // region!
01131 
01132                 if (MousePos == _R(IDC_EDIT_PICKER))
01133                 {
01134                     MousePos =0;    // Default to no help if anything goes wrong
01135 
01136                     // Set up a ReDrawInfoType containing the click position info, and information
01137                     // that will come in handy (size of the gadget, and screen DPI)
01138                     ReDrawInfoType ExtraInfo;
01139 
01140                     ExtraInfo.pDC = NULL;       // No redraw info for mouse events
01141                     ExtraInfo.pClipRect = NULL;
01142 
01143                     // Get the screen DPI
01144                     HDC ScreenDC = CreateCompatibleDC(NULL);
01145                     if (ScreenDC == NULL)
01146                     {
01147                         ERROR3("ColourPicker: Unable to create screen DC");
01148                         return;
01149                     }
01150                     ExtraInfo.Dpi = GetDeviceCaps(ScreenDC, LOGPIXELSY);
01151                     DeleteDC(ScreenDC);
01152 
01153                     // Calculate how big the window is, in MILLIPOINTS
01154                     RECT WindowSize;
01155                     if (!GetClientRect(TheWindow, &WindowSize))
01156                     {
01157                         ERROR3("GetClientRect failed in ColourPicker");
01158                         return;
01159                     }
01160 
01161                     ExtraInfo.dx = (((INT32)WindowSize.right)*72000) / ExtraInfo.Dpi;
01162                     ExtraInfo.dy = (((INT32)WindowSize.bottom)*72000) / ExtraInfo.Dpi;
01163 
01164                     // Work out the MILLIPOINT coordinates of the mouse position
01165                     // Note that the Y value is flipped, as the kernel-origin is at the bottom left
01166                     // and we have to first convert the screen mouse position into client coords
01167                     ScreenToClient(TheWindow, &MouseScreenPos);
01168 
01169                     INT32 XPos = (INT32) MouseScreenPos.x;
01170                     INT32 YPos = (INT32) MouseScreenPos.y;
01171 
01172                     DocCoord MouseInfo;
01173                     MouseInfo.x = (XPos * 72000) / ExtraInfo.Dpi;
01174                     MouseInfo.y = ExtraInfo.dy - ((YPos * 72000) / ExtraInfo.Dpi);
01175                     ExtraInfo.pMousePos = &MouseInfo;
01176 
01177                     // Now call the colour editor to handle the mouse position - it will
01178                     // set the pointer shape as appropriate and also return us some bubble help.
01179                     PickerBubbleBuffer = String_128("");
01180                     StatusHelpBuffer = String_256("");
01181                     Editor->HandleIdlePointer(&ExtraInfo, &PickerBubbleBuffer, &StatusHelpBuffer, &MousePos);
01182 
01183                     if (MousePos)
01184                         ControlHelper::BubbleHelpDisable();     // On non-helpful bit of picker - cancel bubble help
01185                 }
01186             }
01187         }
01188     }
01189 
01190     // Finally, tell the bubble help system what help we want, if any
01191     if (MousePos)
01192     {
01193         // Set up our callback handler to show the help if/when necessary
01194         ControlHelper::DoBubbleHelpOn(TheWindow, MousePos, ColourPicker::HelpCallbackHandler, NULL);
01195     }
01196 #endif
01197 #endif
01198 }
01199 
01200 
01201 
01202 
01203 
01204 
01205 /********************************************************************************************
01206 
01207 >   static BOOL ColourPicker::GetComponentAsString(IndexedColour *Source,
01208                                                 ColourContext *DestContext, INT32 ComponentIndex,
01209                                                 String_8 *Result)
01210 
01211     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01212     Created:    11/11/94
01213     Inputs:     Source - The colour from which you wish to extract the component
01214                 DestContext - The colour context in which you want the resulting component
01215                 ComponentIndex - The component you wish to extract (1..4)
01216                 
01217     Outputs:    Result - returns containing a decimal (0.0 .. 100.0) string representing
01218                 the value of the given component of the colour as it is defined in the
01219                 given colour model (Note: HSV Hue is done as 0..360).
01220 
01221     Returns:    TRUE if the value converted was out of gamut.
01222 
01223     Purpose:    Retrieves the colour definition of the given colour, converts it to the
01224                 given colour model, and returns the desired component of the definition
01225                 in that model as a decimal string appropriate for placing into a colour
01226                 editor dialogue gadget.
01227 
01228     Notes:      At present, this function clips the value to lie within the legal 0.0 to 1.0
01229                 gamut range.
01230 
01231     Scope:      private
01232 
01233     SeeAlso:    ColourPicker::SetComponentFromDouble;
01234                 ColourPicker::SetComponentFromString
01235 
01236 **************************