00001 // $Id: sgcolour.cpp 1282 2006-06-09 09:46:49Z 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 // SGColour.cpp - Colour SuperGallery classes - ColourSGallery and SGDisplayColour 00099 00100 #include "camtypes.h" 00101 00102 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 #include "colcomp.h" 00106 #include "collist.h" 00107 #include "colourix.h" 00108 #include "colormgr.h" 00109 #include "colpick.h" 00110 #include "comattrmsg.h" 00111 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "dragcol.h" 00113 #include "dragmgr.h" 00114 #include "fileutil.h" 00115 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 //#include "galres.h" 00118 //#include "galstr.h" 00119 //#include "isetres.h" 00120 //#include "jason.h" 00121 #include "lineattr.h" 00122 //#include "markn.h" 00123 //#include "newcol.h" 00124 //#include "resdll.h" 00125 //#include "resource.h" // For _R(IDS_CANCEL) 00126 #include "sgcolour.h" 00127 #include "sgdrag.h" 00128 #include "sginit.h" 00129 #include "sgliboil.h" 00130 #include "sgmenu.h" 00131 00132 #include "ccdc.h" // For render-into-dialogue support 00133 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00134 #include "grnddib.h" 00135 //#include "richard2.h" // resources to remove naughty inline strings 00136 #include "ccolbar.h" // EnsureLibraryColoursPresent 00137 #include "backgrnd.h" // OpBackground 00138 00139 // WEBSTER - markn 31/1/97 00140 #include "helpuser.h" 00141 //#include "xshelpid.h" 00142 //#include "helppath.h" 00143 00144 // Implement the dynamic class bits... 00145 CC_IMPLEMENT_DYNCREATE(ColourSGallery, SuperGallery) 00146 CC_IMPLEMENT_DYNAMIC(SGDisplayColour, SGDisplayItem) 00147 CC_IMPLEMENT_DYNAMIC(SGDisplayLibColour, SGDisplayColour) 00148 CC_IMPLEMENT_DYNAMIC(SGDisplayColourGroup, SGDisplayGroup) 00149 CC_IMPLEMENT_DYNAMIC(SGDisplayLibColGroup, SGDisplayColourGroup) 00150 CC_IMPLEMENT_DYNCREATE(OpDisplayColourGallery, Operation) 00151 CC_IMPLEMENT_DYNCREATE(GalleryColourDragInfo, ColourDragInformation) 00152 CC_IMPLEMENT_DYNAMIC(SGColourDragTarget, SGListDragTarget); 00153 CC_IMPLEMENT_DYNCREATE(ColourNameDlg, DialogOp) 00154 CC_IMPLEMENT_MEMDUMP(ColourNameParam, OpParam) 00155 00156 00157 // This line mustn't go before any CC_IMPLEMENT_... macros 00158 #define new CAM_DEBUG_NEW 00159 00160 00161 // Nasty PANTONE bodge - after any change of ordering in any library, the 00162 // Pantone library no longer puts line breaks after every 9th item. 00163 static BOOL LibraryHasBeenSorted = FALSE; 00164 00165 const INT32 SG_ColourNameWidth = 127000; // Width of colour name field (just long enough 00166 // for "Pantone Process Magenta CV"!!) 00167 00168 // This always points to the colour gallery, or NULL if it doesn't exist. 00169 ColourSGallery* ColourSGallery::m_pTheGallery = NULL; 00170 00171 /******************************************************************************************** 00172 00173 Preference: AutoScrollColGal 00174 Section: Displays 00175 Range: TRUE or FALSE 00176 Purpose: If TRUE, the colour gallery will automatically scroll its display list 00177 to show the currently selected line and fill colours whenever the 00178 selection changes. If FALSE, these colours will still become selected, 00179 but the gallery will not be scrolled. 00180 00181 This is because it can be annoying that the gallery keeps scrolling 00182 away from a colour which you were about to apply to the selection (though 00183 you'd be better off dragging the colour, rather than selecting different 00184 objects in this case) 00185 00186 Notes: Normal preference, available from the options dialogue. 00187 SeeAlso: ColourSGallery 00188 00189 ********************************************************************************************/ 00190 00191 #ifdef WEBSTER 00192 // In Webster don't scroll to the selected colour by default 00193 INT32 ColourSGallery::AutoScrollSelection = FALSE; 00194 #else 00195 // In Camelot do scroll to the selected colour by default 00196 INT32 ColourSGallery::AutoScrollSelection = TRUE; 00197 #endif 00198 00199 00200 /******************************************************************************************** 00201 00202 Preference: ColourDisplayMode 00203 Section: Displays 00204 Range: 0..2 00205 Purpose: Memory of the current colour gallery display mode, saved between 00206 sessions for convenience. Not shown in the options dialogue. 00207 SeeAlso: ColourSGallery 00208 00209 ********************************************************************************************/ 00210 00211 INT32 ColourSGallery::DefaultDisplayMode = 0; 00212 00213 /******************************************************************************************** 00214 00215 Preference: ShowDocumentColours 00216 Section: ColourLine 00217 Range: TRUE, FALSE (0,1) 00218 Purpose: Memory of the current state of showing document colours in the colour 00219 line. 00220 SeeAlso: ColourSGallery 00221 00222 ********************************************************************************************/ 00223 00224 // Webster and Camelot's default should be the same (True). 00225 BOOL ColourSGallery::ShowDocumentColours = TRUE; 00226 00227 00228 /******************************************************************************************** 00229 00230 Preference: ShowNetscapeColours 00231 Section: ColourLine 00232 Range: TRUE, FALSE (0,1) 00233 Purpose: Memory of the current state of showing Netscape colours in the colour 00234 line. 00235 Webster needs to default to True. 00236 SeeAlso: ColourSGallery 00237 00238 ********************************************************************************************/ 00239 00240 // True if want Netscape colours being shown in colour line 00241 // Webster only at present 00242 BOOL ColourSGallery::ShowNetscapeColours = TRUE; 00243 00244 /******************************************************************************************** 00245 00246 Preference: Path 00247 Section: Palette 00248 Range: 0 .. 256 characters 00249 Purpose: The path to load the palettes from. Defaults to blank which means alongside 00250 the exe. 00251 SeeAlso: ColourSGallery 00252 00253 ********************************************************************************************/ 00254 00255 String_256 ColourSGallery::PalettePath = TEXT(""); 00256 00257 00258 /******************************************************************************************** 00259 00260 > SGColourDragTarget::SGColourDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL) 00261 00262 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00263 Created: 20/3/95 00264 Inputs: TheDialog - The kernel dialog in which the target exists 00265 TheGadget - The gadget within that dialogue which is the target 00266 00267 Purpose: Constructor 00268 00269 ********************************************************************************************/ 00270 00271 SGColourDragTarget::SGColourDragTarget(DialogOp *TheDialog, CGadgetID TheGadget) 00272 : SGListDragTarget(TheDialog, TheGadget) 00273 { 00274 ERROR3IF(!TheDialog->IsKindOf(CC_RUNTIME_CLASS(ColourSGallery)), 00275 "You can only use SGColourDragTargets with ColourSGallery dialogues!"); 00276 } 00277 00278 00279 00280 /******************************************************************************************** 00281 00282 BOOL SGColourDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo, 00283 OilCoord *pMousePos, KeyPress* pKeyPress) 00284 00285 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00286 Created: 20/3/95 00287 Inputs: Event - Indicates what has happened 00288 pDragInfo - points to drag information describing this drag. This 00289 should be a ColourDragInformation or derivation thereof 00290 pMousePos - points to information on the current mouse position, in OIL coords 00291 pKeyPress - NULL, or if for a keypress event, keypress information 00292 00293 Returns: TRUE to claim the event, FALSE to let it through to other targets 00294 00295 Purpose: Event Handler for SuperGallery listitem drag events. Overrides the 00296 base class handler to enable it to sort out the node being dragged 00297 for colour drags. 00298 00299 ********************************************************************************************/ 00300 00301 BOOL SGColourDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo, 00302 OilCoord *pMousePos, KeyPress* pKeyPress) 00303 { 00304 if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(ColourDragInformation))) 00305 return(FALSE); 00306 00307 SGDisplayNode *DraggedNode = NULL; 00308 BOOL IsSimpleColourDrag = FALSE; 00309 00310 if (IS_A(pDragInfo, ColourDragInformation)) 00311 { 00312 ColourDragInformation *ColourDragInfo = (ColourDragInformation *) pDragInfo; 00313 00314 SuperGallery *ParentGallery = (SuperGallery *)TargetDialog; 00315 00316 IsSimpleColourDrag = TRUE; 00317 00318 // Search the display tree for an item which displays the dragged IndexedColour 00319 IndexedColour *DraggedColour = ColourDragInfo->GetInitiallyDraggedColour(); 00320 00321 // If the colour is NULL, it's "no colour" (or possibly some weird library colour which 00322 // we didn't start the drag of, because we'd use a GalleryColourDragInfo), so ignore it 00323 if (DraggedColour == NULL) 00324 return(FALSE); 00325 00326 SGDisplayRoot *DisplayTree = ParentGallery->GetDisplayTree(); 00327 if (DisplayTree == NULL) // No tree?! 00328 return(FALSE); 00329 00330 // Scan the display tree for the document in which the colour resides, to find 00331 // the display item that references the colour. If we weren't given a parent 00332 // document, then we'll scan the entire thing. 00333 // If we find it, we exit this bit with DraggedNode pointing at the relevant 00334 // SGDisplayNode item for it, and drop through to the regular handler 00335 BOOL Found = FALSE; 00336 00337 SGDisplayNode *TheGroup = NULL; // Find an appropriate group to start searching 00338 if (ColourDragInfo->GetParentDoc() != NULL) 00339 { 00340 TheGroup = DisplayTree->FindSubtree(ParentGallery, 00341 ((ColourDragInformation *) pDragInfo)->GetParentDoc(), NULL); 00342 } 00343 else 00344 TheGroup = DisplayTree->GetChild(); 00345 00346 DocColour *TheDocCol; 00347 while (TheGroup != NULL && !Found) 00348 { 00349 DraggedNode = TheGroup->GetChild(); 00350 while (DraggedNode != NULL) 00351 { 00352 TheDocCol = ((SGDisplayColour *)DraggedNode)->GetDisplayedColour(); 00353 if (TheDocCol != NULL && TheDocCol->FindParentIndexedColour() == DraggedColour) 00354 { 00355 Found = TRUE; 00356 break; 00357 } 00358 00359 DraggedNode = DraggedNode->GetNext(); 00360 } 00361 00362 TheGroup = TheGroup->GetNext(); 00363 } 00364 00365 if (!Found) // No colour matching that description is in the gallery 00366 return(FALSE); 00367 } 00368 else if (IS_A(pDragInfo, GalleryColourDragInfo)) 00369 { 00370 DraggedNode = ((GalleryColourDragInfo *)pDragInfo)->GetDraggedColour(); 00371 } 00372 // else ignore the drag (as DraggedNode will still be NULL) 00373 00374 if (DraggedNode != NULL) 00375 { 00376 switch(Event) 00377 { 00378 case DRAGEVENT_COMPLETED: 00379 HandleDragCompleted((SuperGallery *) TargetDialog, 00380 DraggedNode, pMousePos, IsSimpleColourDrag); 00381 return(TRUE); 00382 00383 00384 case DRAGEVENT_MOUSESTOPPED: 00385 case DRAGEVENT_MOUSEMOVED: 00386 case DRAGEVENT_MOUSEIDLE: 00387 // Call a subroutine to work out and set our current cursor shape 00388 return(DetermineCursorShape((SuperGallery *) TargetDialog, 00389 DraggedNode, pMousePos)); 00390 default: 00391 break; 00392 } 00393 } 00394 00395 // Otherwise, we aren't interested in the event, so we don't claim it 00396 return(FALSE); 00397 } 00398 00399 00400 00401 00402 00403 00404 00405 00406 00407 /******************************************************************************************** 00408 00409 > void GalleryColourDragInfo::GalleryColourDragInfo() 00410 00411 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00412 Created: 16/2/95 00413 00414 Purpose: Default constructor - do not call this constructor 00415 00416 ********************************************************************************************/ 00417 00418 GalleryColourDragInfo::GalleryColourDragInfo() 00419 { 00420 ERROR3("Default GalleryColourDragInfo constructor called"); 00421 } 00422 00423 00424 00425 /******************************************************************************************** 00426 00427 > GalleryColourDragInfo::GalleryColourDragInfo(Document *pDocument, SGDisplayColour *pSourceItem, 00428 SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, 00429 BOOL IsAdjust = FALSE) 00430 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00431 Created: 16/2/95 00432 00433 Inputs: pDocument - The document in which the colour lives 00434 pSourceItem - The gallery item from which the drag originated 00435 pMouseInfo - The mouse info which made the item start the drag 00436 pMiscInfo - The MiscInfo which accompanied the mouse event 00437 IsAdjust - TRUE if this is an adjust drag 00438 00439 Purpose: Constructor - use this one for "document colours" - ones that already live 00440 in a document. The Display item's colour MUST reference an IndexedColour. 00441 00442 ********************************************************************************************/ 00443 00444 GalleryColourDragInfo::GalleryColourDragInfo(Document *pDocument, SGDisplayColour *pSourceItem, 00445 SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, 00446 BOOL IsAdjust) 00447 : ColourDragInformation(pSourceItem->GetDisplayedColour()->FindParentIndexedColour(), 00448 IsAdjust, pDocument) 00449 { 00450 ERROR3IF(pSourceItem == NULL || pMouseInfo == NULL || pMiscInfo == NULL, 00451 "GalleryColourDragInfo constructor: Illegal NULL param"); 00452 00453 SourceItem = pSourceItem; // Copy the source item pointer 00454 00455 MouseInfo = *pMouseInfo; // Duplicate the structures (they may cease to exist 00456 MiscInfo = *pMiscInfo; // soon after the drag is started) 00457 } 00458 00459 00460 00461 /******************************************************************************************** 00462 00463 > GalleryColourDragInfo::GalleryColourDragInfo(SGDisplayColour *pSourceItem, 00464 SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, 00465 BOOL IsAdjust = FALSE) 00466 00467 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00468 Created: 16/2/95 00469 00470 Inputs: pSourceItem - The gallery item from which the drag originated 00471 pMouseInfo - The mouse info which made the item start the drag 00472 pMiscInfo - The MiscInfo which accompanied the mouse event 00473 IsAdjust - TRUE if this is an adjust drag 00474 00475 Purpose: Constructor - use this for drags of "library colours" (ones with 00476 no parent document) 00477 00478 ********************************************************************************************/ 00479 00480 GalleryColourDragInfo::GalleryColourDragInfo(SGDisplayColour *pSourceItem, 00481 SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, 00482 BOOL IsAdjust) 00483 : ColourDragInformation(pSourceItem->GetDisplayedColour(), IsAdjust, 00484 NULL, pSourceItem->IsASpotColour()) 00485 { 00486 ERROR3IF(pSourceItem == NULL || pMouseInfo == NULL || pMiscInfo == NULL, 00487 "GalleryColourDragInfo constructor: Illegal NULL param"); 00488 00489 // Fill in the base class' name member, which we passed NULL for in the construction above 00490 String_256 Bob; 00491 pSourceItem->GetNameText(&Bob); 00492 Bob.Left(&ColourName, 63); 00493 00494 SourceItem = pSourceItem; // Copy the source item pointer 00495 00496 MouseInfo = *pMouseInfo; // Duplicate the structures (they may cease to exist 00497 MiscInfo = *pMiscInfo; // soon after the drag is started) 00498 } 00499 00500 00501 00502 /******************************************************************************************** 00503 00504 > virtual void GalleryColourDragInfo::OnClick(INT32 Flags, POINT Point) 00505 00506 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00507 Created: 12/1/95 00508 Inputs: - 00509 Outputs: - 00510 Returns: - 00511 Purpose: This is called if a drag was attempted but never started because it was a 00512 click all along. It calls back the SourceItem SGDisplayColour, to get it 00513 to handle the click. 00514 Errors: - 00515 SeeAlso: - 00516 00517 ********************************************************************************************/ 00518 00519 void GalleryColourDragInfo::OnClick(INT32 Flags, POINT Point) 00520 { 00521 if (SourceItem != NULL) 00522 SourceItem->DragWasReallyAClick(&MouseInfo, &MiscInfo); 00523 } 00524 00525 00526 00527 00528 00529 00530 00531 00532 00533 /*********************************************************************************************** 00534 00535 > SGDisplayColour::SGDisplayColour() 00536 00537 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00538 Created: 28/10/94 00539 00540 Purpose: SGDisplayColour constructor 00541 DON'T call this constructor. Call the other constructor 00542 00543 ***********************************************************************************************/ 00544 00545 SGDisplayColour::SGDisplayColour() 00546 { 00547 // We don't like people calling this constructor, but we have to put up with it 00548 // now that we have a derived class. 00549 } 00550 00551 00552 00553 /*********************************************************************************************** 00554 00555 > SGDisplayColour::SGDisplayColour(IndexedColour *ColourToDisplay) 00556 00557 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00558 Created: 28/10/94 00559 00560 Inputs: ColourToDisplay - The colour this item will display 00561 00562 Purpose: SGDisplayColour constructor 00563 00564 ***********************************************************************************************/ 00565 00566 SGDisplayColour::SGDisplayColour(IndexedColour *ColourToDisplay) 00567 { 00568 TheColour.MakeRefToIndexedColour(ColourToDisplay); 00569 } 00570 00571 00572 00573 /*********************************************************************************************** 00574 00575 > virtual INT32 SGDisplayColour::CompareTo(SGDisplayNode *Other, INT32 SortKey) 00576 00577 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00578 Created: 10/4/95 00579 00580 Inputs: Other - the Colour to compare this Colour to 00581 SortKey - An integer identifying how to compare the items 00582 0 = No sorting (always returns 0) 00583 1 = Sort-by-name 00584 2 = Sort-by-hue 00585 3 = Sort-by-intensity 00586 4 = Sort-by-model 00587 00588 Returns: negative (I am lesser), 0 (we are equal), or positive (I am greater) 00589 00590 Purpose: Compares this Colour to the 'other' Colour, to determine their relative positions 00591 in the display tree. Returns a value which usually indicates that the other 00592 Colour should be inserted before (-1, or 0) or after (+1) this item. 00593 00594 SeeAlso: SGDisplayNode::CompareTo 00595 00596 ***********************************************************************************************/ 00597 00598 const INT32 SGSORTKEY_BYHUE = 2; 00599 const INT32 SGSORTKEY_BYINTENSITY = 3; 00600 const INT32 SGSORTKEY_BYMODEL = 4; 00601 00602 INT32 SGDisplayColour::CompareTo(SGDisplayNode *Other, INT32 SortKey) 00603 { 00604 ERROR3IF(Other == NULL, "Illegal NULL parameter"); 00605 00606 ERROR3IF(!Other->IsKindOf(CC_RUNTIME_CLASS(SGDisplayColour)), 00607 "SGDisplayColour::CompareTo - The other item's not a colour!"); 00608 00609 DocColour *OtherCol = ((SGDisplayColour *)Other)->GetDisplayedColour(); 00610 DocColour *ThisCol = GetDisplayedColour(); 00611 00612 switch (SortKey) 00613 { 00614 case SGSORTKEY_BYNAME: 00615 { 00616 IndexedColour *OtherColIx = OtherCol->FindParentIndexedColour(); 00617 IndexedColour *ThisColIx = ThisCol->FindParentIndexedColour(); 00618 00619 // Safety check - if either colour is NULL, then return "equal" 00620 if (OtherColIx == NULL || ThisColIx == NULL) 00621 return(0); 00622 00623 // We override the base class name comparison, because it is forced to 00624 // actually copy the names first! This one just compares them in-place 00625 return(ThisColIx->GetName()->CompareTo( (TCHAR *) (*(OtherColIx->GetName())) ) ); 00626 } 00627 break; 00628 00629 00630 case SGSORTKEY_BYHUE: 00631 { 00632 ColourContextHSVT *ColContext; 00633 ColourHSVT ResultCol; 00634 ColourValue Hue1; 00635 00636 Document *ParentDoc = ((SGDisplayGroup *)GetParent())->GetParentDocument(); 00637 00638 // Get a default context, or if ParentDoc != NULL, the current context for the doc. 00639 ColContext = (ColourContextHSVT *) ColourManager::GetColourContext(COLOURMODEL_HSVT, ParentDoc); 00640 if (ColContext == NULL) 00641 return(0); 00642 00643 // Convert the 2 colours to HSV and compare their Hue values 00644 ColContext->ConvertColour(ThisCol, (ColourGeneric *) &ResultCol); 00645 Hue1 = ResultCol.Hue; 00646 00647 ColContext->ConvertColour(OtherCol, (ColourGeneric *) &ResultCol); 00648 00649 if (Hue1 < ResultCol.Hue) 00650 return(-1); 00651 00652 return((Hue1 == ResultCol.Hue) ? 0 : 1); 00653 } 00654 00655 00656 case SGSORTKEY_BYINTENSITY: 00657 { 00658 ColourContextGreyT *ColContext; 00659 ColourGreyT ResultCol; 00660 ColourValue Intensity1; 00661 00662 Document *ParentDoc = ((SGDisplayGroup *)GetParent())->GetParentDocument(); 00663 00664 // Get a default context, or if ParentDoc != NULL, the current context for the doc. 00665 ColContext = (ColourContextGreyT *) ColourManager::GetColourContext(COLOURMODEL_GREYT, ParentDoc); 00666 if (ColContext == NULL) 00667 return(0); 00668 00669 // Convert the 2 colours to Greyscale and compare their intensity values 00670 ColContext->ConvertColour(ThisCol, (ColourGeneric *) &ResultCol); 00671 Intensity1 = ResultCol.Intensity; 00672 00673 ColContext->ConvertColour(OtherCol, (ColourGeneric *) &ResultCol); 00674 00675 if (Intensity1 < ResultCol.Intensity) 00676 return(-1); 00677 00678 return((Intensity1 == ResultCol.Intensity) ? 0 : 1); 00679 } 00680 00681 00682 case SGSORTKEY_BYMODEL: 00683 return((INT32)ThisCol->GetColourModel() - (INT32)OtherCol->GetColourModel()); 00684 } 00685 00686 // No sorting (SGSORTKEY_NONE - 0), or unknown 00687 return(SGDisplayItem::CompareTo(Other, SortKey)); 00688 } 00689 00690 00691 00692 /******************************************************************************************** 00693 00694 > virtual void SGDisplayColour::GetNameText(String_256 *Result) 00695 00696 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00697 Created: 9/3/95 00698 00699 Outputs: On exit, the string pointed at by Result will contain either a blank 00700 string, or the name text associated with this item (if any) 00701 00702 Purpose: To determine a name string for this node. Generally, this is used for 00703 a simple mechanism which searches for display items whose names match 00704 given search parameters in some way. It is also used in libraries to 00705 provide default redraw methods. 00706 00707 SeeAlso: SGDisplayColour::GetFullInfoText 00708 00709 ********************************************************************************************/ 00710 00711 void SGDisplayColour::GetNameText(String_256 *Result) 00712 { 00713 ERROR3IF(Result == NULL, "Illegal NULL param"); 00714 00715 IndexedColour *ParentCol = TheColour.FindParentIndexedColour(); 00716 if (ParentCol != NULL) 00717 *Result = *(ParentCol->GetName()); 00718 else 00719 Result->MakeMsg(_R(IDS_UNNAMEDCOLOUR)); 00720 } 00721 00722 00723 00724 /******************************************************************************************** 00725 00726 > virtual void SGDisplayColour::GetFullInfoText(String_256 *Result) 00727 00728 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00729 Created: 9/3/95 00730 00731 Outputs: On exit, the string pointed at by Result will contain either a blank 00732 string, or the full-information text associated with this item (if any) 00733 00734 Purpose: To determine a full-info string for this node. Generally, this is used for 00735 a simple mechanism which searches for display items whose info matches 00736 given search parameters in some way. It is also used in libraries to 00737 provide default redraw methods. 00738 00739 SeeAlso: SGDisplayColour::GetNameText 00740 00741 ********************************************************************************************/ 00742 00743 void SGDisplayColour::GetFullInfoText(String_256 *Result) 00744 { 00745 ERROR3IF(Result == NULL, "Illegal NULL param"); 00746 00747 *Result = TEXT(""); // Set a safe default 00748 00749 // Generate an info string of the form: 00750 // <ColModel> (<components>) [, <tint/link/spot information>] [, not in use] 00751 // e.g. "HSV(324, 80, 75), Linked to Red" 00752 00753 String_256 Info(TEXT("")); 00754 00755 ColourContext *cc = ColourContext::GetGlobalDefault(TheColour.GetColourModel()); 00756 ERROR3IF(cc == NULL, "Default colour context is NULL!?"); 00757 00758 ColourGeneric col; 00759 TheColour.GetSourceColour(&col); 00760 cc->GetModelName(&Info); 00761 00762 String_128 TempStr(TEXT("(")); 00763 String_16 CompStr; 00764 if (cc->GetComponentName(1, NULL)) 00765 { 00766 double CompVal; 00767 if (TheColour.GetColourModel() == COLOURMODEL_HSVT) 00768 CompVal = (col.Component1.MakeDouble()) * 360.0; 00769 else 00770 CompVal = (col.Component1.MakeDouble()) * 100.0; 00771 00772 // Convert it to a string rounded to 1 decimal place accuracy 00773 Convert::DoubleToString(CompVal, &CompStr, 1); 00774 00775 TempStr += CompStr; 00776 } 00777 00778 if (cc->GetComponentName(2, NULL)) 00779 { 00780 Convert::DoubleToString(col.Component2.MakeDouble() * 100.0, &CompStr, 1); 00781 TempStr += TEXT(", "); 00782 TempStr += CompStr; 00783 } 00784 00785 if (cc->GetComponentName(3, NULL)) 00786 { 00787 Convert::DoubleToString(col.Component3.MakeDouble() * 100.0, &CompStr, 1); 00788 TempStr += TEXT(", "); 00789 TempStr += CompStr; 00790 } 00791 00792 if (cc->GetComponentName(4, NULL)) 00793 { 00794 Convert::DoubleToString(col.Component4.MakeDouble() * 100.0, &CompStr, 1); 00795 TempStr += TEXT(", "); 00796 TempStr += CompStr; 00797 } 00798 00799 TempStr += TEXT(")"); 00800 Info += TempStr; 00801 00802 IndexedColour *ParentCol = TheColour.FindParentIndexedColour(); // If this refs an IndexedColour... 00803 if (ParentCol != NULL) 00804 { 00805 switch(ParentCol->GetType()) 00806 { 00807 case COLOURTYPE_SPOT: 00808 TempStr.MakeMsg(_R(IDS_COLGAL_ISPOT)); 00809 Info += TempStr; 00810 break; 00811 00812 case COLOURTYPE_TINT: 00813 { 00814 ERROR3IF(ParentCol->FindLinkedParent() == NULL, 00815 "A tint without a parent colour? Oh bums!"); 00816 00817 if (ParentCol->TintIsShade()) 00818 { 00819 TempStr.MakeMsg(_R(IDS_COLGAL_ISHADE), 00820 (TCHAR *) *(ParentCol->FindLinkedParent()->GetName())); 00821 } 00822 else 00823 { 00824 TempStr.MakeMsg(_R(IDS_COLGAL_ITINT), 00825 (INT32) ((ParentCol->GetTintValue().MakeDouble() + 0.005)*100), 00826 (TCHAR *) *(ParentCol->FindLinkedParent()->GetName())); 00827 } 00828 Info += TempStr; 00829 } 00830 break; 00831 00832 case COLOURTYPE_LINKED: 00833 { 00834 ERROR3IF(ParentCol->FindLinkedParent() == NULL, 00835 "A linked colour without a parent colour? Oh bums!"); 00836 00837 TempStr.MakeMsg(_R(IDS_COLGAL_ILINKED), 00838 (TCHAR *) *(ParentCol->FindLinkedParent()->GetName())); 00839 Info += TempStr; 00840 } 00841 break; 00842 00843 default: 00844 break; 00845 } 00846 00847 00848 SGDisplayGroup *DocumentGroup = (SGDisplayGroup *) GetParent(); 00849 ERROR3IF(DocumentGroup == NULL, "SGallery DisplayTree linkage corruption detected"); 00850 00851 Document *ScopeDoc = DocumentGroup->GetParentDocument(); 00852 ERROR3IF(ScopeDoc == NULL, "SGallery group is not for a document! Unimplemented! Eek!"); 00853 00854 ColourList *ParentColList = ScopeDoc->GetIndexedColours(); 00855 ERROR3IF(ParentColList == NULL, "A document with no colour list? Now I've seen it all"); 00856 00857 if (!ParentColList->IsColourInUseInDoc(ParentCol, TRUE)) 00858 { 00859 // Add ' (not in use)' for any colour not currently used in the 00860 // document, or as a linked-colour parent 00861 TempStr.MakeMsg(_R(IDS_COLGAL_INOTUSED)); 00862 Info += TempStr; 00863 } 00864 } 00865 00866 *Result = Info; 00867 } 00868 00869 00870 00871 /*********************************************************************************************** 00872 00873 > virtual BOOL SGDisplayColour::IsALibraryColour(void) const 00874 00875 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00876 Created: 7/8/96 00877 00878 Inputs: - 00879 Returns: FALSE if this is a base-class SGDisplayColour (IndexedColour) 00880 TRUE if this is a derived class SGDisplayLibColour (library DocColour) 00881 00882 Purpose: Proper virtual-function method for differentiating between IndexedColour 00883 and library DocColour gallery display items. 00884 00885 Notes: Always returns FALSE 00886 00887 ***********************************************************************************************/ 00888 00889 BOOL SGDisplayColour::IsALibraryColour(void) const 00890 { 00891 return(FALSE); 00892 } 00893 00894 00895 00896 /*********************************************************************************************** 00897 00898 > virtual BOOL SGDisplayColour::IsASpotColour(void) 00899 00900 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00901 Created: 2/9/96 00902 00903 Inputs: - 00904 Returns: FALSE if this is a normal colour 00905 TRUE if this is a spot colour 00906 00907 Purpose: Determine if the displayed colour is a normal or spot colour 00908 00909 ***********************************************************************************************/ 00910 00911 BOOL SGDisplayColour::IsASpotColour(void) 00912 { 00913 if (TheColour.FindParentIndexedColour() != NULL) 00914 { 00915 if (TheColour.FindParentIndexedColour()->IsSpotOrTintOfSpot()) 00916 return(TRUE); 00917 } 00918 00919 return(FALSE); 00920 } 00921 00922 00923 00924 /*********************************************************************************************** 00925 00926 > void SGDisplayColour::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo) 00927 00928 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00929 Created: 13/1/95 00930 00931 Inputs: FormatInfo - The formatting info from which to calculate my position/size 00932 MiscInfo - The MiscInfo, as usual 00933 00934 Outputs: member variable FormatRect - is returned filled in with the size/position of 00935 this colour item's display area. This is dependent upon the current display 00936 mode and format state 00937 00938 Purpose: Shared code for colour items to calculate where they will appear in the 00939 grand scheme of things 00940 00941 Scope: private (to sgcolour.cpp, for use of SGDisplayColour class only) 00942 00943 ***********************************************************************************************/ 00944 00945 void SGDisplayColour::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo) 00946 { 00947 const INT32 SGC_FullInfoWidth = SG_InfiniteWidth; //300000; 00948 00949 INT32 XSize; 00950 INT32 YSize; 00951 00952 // Note: The text is usually something like 9 point, so a minimum Y size to fit text 00953 // in is going to be around 12 point (12000 millipoints) 00954 00955 switch (MiscInfo->DisplayMode) 00956 { 00957 case 1: // 1 - Full Info 00958 XSize = GridLock(MiscInfo, SGC_FullInfoWidth); 00959 YSize = GridLock(MiscInfo, SG_DefaultSmallIcon); 00960 break; 00961 00962 case 2: // 2 - Icon only, no text at all 00963 XSize = YSize = GridLock(MiscInfo, SG_DefaultLargeIcon); 00964 break; 00965 00966 default: // 0 (Default) - Small icon with name 00967 XSize = GridLock(MiscInfo, SG_ColourNameWidth); 00968 YSize = GridLock(MiscInfo, SG_DefaultSmallIcon); 00969 break; 00970 } 00971 00972 CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize); 00973 } 00974 00975 00976 /*********************************************************************************************** 00977 00978 > void DrawCircle(RenderRegion *Renderer, DocRect &BoundRect) 00979 00980 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00981 Created: 16/6/96 00982 00983 Inputs: Renderer - The render region to render into 00984 BoundRect - The bounding rectangle to draw the circle into 00985 00986 Purpose: Draws a circle filling the width of the given rectangle, 00987 using the current render region attributes. 00988 00989 Scope: private 00990 00991 ***********************************************************************************************/ 00992 00993 void DrawCircle(RenderRegion *Renderer, DocRect &BoundRect) 00994 { 00995 // WEBSTER - markn 23/1/97 00996 // No Circles required. 00997 // 00998 #ifndef WEBSTER 00999 const INT32 CircleSize = BoundRect.Width() / 2; 01000 const INT32 CPDist = (const INT32) ( ((double)CircleSize) * 0.552 ); 01001 01002 Path Circle; 01003 Circle.Initialise(12, 12); 01004 Circle.FindStartOfPath(); 01005 01006 DocCoord Center(BoundRect.lo.x + BoundRect.Width()/2, 01007 BoundRect.lo.y + BoundRect.Height()/2); 01008 01009 Circle.InsertMoveTo(DocCoord(Center.x+CircleSize, Center.y)); 01010 Circle.InsertCurveTo(DocCoord(Center.x+CircleSize, Center.y+CPDist), 01011 DocCoord(Center.x+CPDist, Center.y+CircleSize), 01012 DocCoord(Center.x, Center.y+CircleSize)); 01013 Circle.InsertCurveTo(DocCoord(Center.x-CPDist, Center.y+CircleSize), 01014 DocCoord(Center.x-CircleSize, Center.y+CPDist), 01015 DocCoord(Center.x-CircleSize, Center.y)); 01016 Circle.InsertCurveTo(DocCoord(Center.x-CircleSize, Center.y-CPDist), 01017 DocCoord(Center.x-CPDist, Center.y-CircleSize), 01018 DocCoord(Center.x, Center.y-CircleSize)); 01019 Circle.InsertCurveTo(DocCoord(Center.x+CPDist, Center.y-CircleSize), 01020 DocCoord(Center.x+CircleSize, Center.y-CPDist), 01021 DocCoord(Center.x+CircleSize, Center.y)); 01022 01023 Circle.IsFilled = TRUE; 01024 01025 Renderer->DrawPath(&Circle); // and draw it 01026 #endif // WEBSTER 01027 } 01028 01029 01030 01031 /*********************************************************************************************** 01032 01033 > virtual void SGDisplayColour::HandleRedraw(SGRedrawInfo *RedrawInfo, 01034 SGFormatInfo *FormatInfo) 01035 01036 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01037 Created: 13/1/95 01038 01039 Inputs: RedrawInfo - The information on the kernel-rendered redraw area 01040 FormatInfo - The formatting information structure 01041 01042 member variable FormatRect should be set up (before calling this method) 01043 to be the rectangle in which to draw this item 01044 01045 Purpose: SGDisplayColour item redraw method - removed from the main HandleEvent 01046 method merely to make the code tidier. 01047 01048 Scope: private 01049 01050 ***********************************************************************************************/ 01051 01052 void SGDisplayColour::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo) 01053 { 01054 StartRendering(RedrawInfo, MiscInfo); 01055 01056 DocRect MyRect(FormatRect); 01057 01058 RenderRegion *Renderer = RedrawInfo->Renderer; 01059 01060 INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1); 01061 INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2); 01062 01063 DocRect IconRect(MyRect); // Create a square icon at the left end of our rectangle 01064 IconRect.hi.x = IconRect.lo.x + IconRect.Height(); 01065 MyRect.lo.x = IconRect.hi.x + TwoPixels; 01066 01067 // Redraw the icon 01068 GridLockRect(MiscInfo, &IconRect); 01069 01070 Renderer->SetLineWidth(0); 01071 Renderer->SetLineColour(RedrawInfo->Transparent); 01072 01073 // If selected, we have a 3-pixel-thick selection border 01074 // Otherwise (as is now the case) we have a single-pixel black border 01075 // We draw border "lines" using rectangle fills, else it screws pixel alignment 01076 if (!Flags.Selected) 01077 IconRect.Inflate(-TwoPixels); 01078 01079 IndexedColour *IxCol = TheColour.FindParentIndexedColour(); 01080 01081 // Draw (selection border and) border 01082 // The patch is normally a square (process colour), but for spot colours 01083 // is drawn as a circle, in order to make the distinction more obvious 01084 // 01085 // WEBSTER - markn 23/1/97 01086 // No Circles required. 01087 // 01088 DocColour black(COLOUR_BLACK); 01089 Renderer->SetFillColour(black); 01090 #ifndef WEBSTER 01091 if (IsASpotColour()) 01092 { 01093 IconRect.Inflate(-OnePixel); 01094 DrawCircle(Renderer, IconRect); 01095 } 01096 else 01097 #endif // WEBSTER 01098 Renderer->DrawRect(&IconRect); // And draw it 01099 01100 // Now deflate further, to get inside the selection & border... 01101 IconRect.Inflate((Flags.Selected) ? -(TwoPixels+OnePixel) : -OnePixel); 01102 01103 // Draw the colour patch (icon) 01104 // Save and restore the context while using TheColour to fill with. This is so that 01105 // the renderer no longer references the IndexedColour, so that GetFullInfoText will 01106 // put the text '(not in use)' on the end of colours which aren't used in the document! 01107 Renderer->SaveContext(); 01108 Renderer->SetFillColour(TheColour); // Fill with colour to display 01109 01110 // The patch is normally a square (process colour), but for spot colours 01111 // is drawn as a circle, in order to make the distinction more obvious 01112 // 01113 // WEBSTER - markn 23/1/97 01114 // No Circles required. 01115 // 01116 #ifndef WEBSTER 01117 if (IsASpotColour()) 01118 DrawCircle(Renderer, IconRect); 01119 else 01120 #endif // WEBSTER 01121 Renderer->DrawRect(&IconRect); // And draw it 01122 Renderer->RestoreContext(); 01123 01124 // Redraw the name text, if there is room to the right of the icon 01125 if (MyRect.lo.x < MyRect.hi.x) 01126 { 01127 GridLockRect(MiscInfo, &MyRect); 01128 01129 // IndexedColour *ParentCol = TheColour.FindParentIndexedColour(); 01130 01131 if (Flags.Selected) 01132 { 01133 // Fill the entire background with the 'selected' colour, so we don't 01134 // get gaps between bits of text or uneven rectangles in multiple selections 01135 Renderer->SetFillColour(RedrawInfo->SelBackground); 01136 Renderer->DrawRect(&MyRect); 01137 01138 Renderer->SetFixedSystemTextColours(&RedrawInfo->SelForeground, &RedrawInfo->SelBackground); 01139 01140 if (IxCol != NULL) // Only do this for IndexedColours (i.e. not derived class Library colours) 01141 { 01142 // If this item represents the current line colour, then place a vertical line between the icon 01143 // and the text to indicate this fact. 01144 DocColour *LineCol; 01145 ColourManager::GetCurrentLineAndFillColours(&LineCol, NULL); 01146 01147 if (LineCol != NULL && LineCol->FindParentIndexedColour() == TheColour.FindParentIndexedColour()) 01148 { 01149 // This item is selected and is the current line colour. Put a mark in to indicate this 01150 DocColour black(COLOUR_BLACK); 01151 Renderer->SetLineColour(black); 01152 Renderer->SetLineWidth(TwoPixels); 01153 Renderer->DrawLine(MyRect.lo, DocCoord(MyRect.lo.x, MyRect.hi.y)); 01154 } 01155 } 01156 } 01157 else 01158 Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background); 01159 01160 MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text begins 01161 01162 String_256 Name; 01163 GetNameText(&Name); // Get the name string 01164 01165 if (MiscInfo->DisplayMode == 1) // If in Full Info mode... 01166 { 01167 DocRect TextRect(MyRect); 01168 01169 // Reserve space for the name (clip it if it won't fit) 01170 if (TextRect.hi.x - TextRect.lo.x > SG_ColourNameWidth) 01171 TextRect.hi.x = TextRect.lo.x + SG_ColourNameWidth; 01172 01173 // Draw the name text next to the icon 01174 Renderer->DrawFixedSystemText(&Name, TextRect); 01175 01176 // Move to the right, to fill the remaining space with information 01177 // (Leave a 6-pixel gap in case the name didn't all fit in the available space) 01178 TextRect.lo.x = TextRect.hi.x + DevicePixels(MiscInfo, 6); 01179 TextRect.hi.x = MyRect.hi.x; 01180 if (TextRect.lo.x < TextRect.hi.x) // If any room left for info... 01181 { 01182 // Get the full info description, and render it 01183