#include <colormgr.h>
Inheritance diagram for ColourManager:
Public Member Functions | |
ColourManager () | |
Constructs a ColourManager object. | |
Static Public Member Functions | |
static BOOL | Init (void) |
Initialises the entire colour system. This includes the colour manager, colour contexts, and colour dialogues, etc. Notes: Should only be called once ever. Called by Application::Init(). | |
static void | Deinit (void) |
De-Initlialises the entire colour system. This includes the colour manager, colour contexts, and colour dialogues, etc. Notes: Should only be called once ever. Called by Application::Deinit(). | |
static ColourList * | GetColourList (BOOL InvalidateCache=FALSE) |
To obtain the ColourList of IndexedColours in the SelectedDocument (the colours which the user can use within the document; this is the set of colours displayed by the colour bar and edited by the ColourMgrDlg) Note that an ordered list is used so that multiple display orders can be used (e.g. for the ColourMgrDlg and ColourBar, etc). | |
static ColourList * | GetCurrentColourList (void) |
To obtain the ColourList of IndexedColours in the CurrentDocument. | |
static ColourContext * | GetColourContext (ColourModel Model, Document *ScopeDocument=NULL) |
To easily find an appropriate colour context to use when converting colours. There are global contexts, but in order to supply special document-specific colour corrections etc, each document actually has its own private set of contexts. Thus, you should call this function to determine the most appropriate context to use. | |
static ColourContext * | GetColourContext (ColourModel Model, View *ScopeView) |
To easily find an appropriate colour context to use when converting colours. There are global contexts, but in order to supply special view-specific colour corrections etc, each document view actually has its own private set of contexts. Thus, you should call this function to determine the most appropriate context to use. | |
static void | SelViewContextHasChanged (void) |
To redraw all windows which depend upon the Selected View's colour context. i.e. The selected view, and also the colour editor, gallery, & line. (and maybe other windows in the future, e.g. object properties, grad fill editors, etc). | |
static void | ColourHasChanged (Document *ScopeDoc, ColourList *ColList, IndexedColour *Col) |
Indicates to all interested parties that the given IndexedColour has been changed (sends a COLOURUPDATED message) e.g. Causes the ColourBar and document to redraw themselves. | |
static void | ColourHasChangedInvisible (Document *ScopeDoc, ColourList *ColList, IndexedColour *Col) |
Indicates to all interested parties that the given IndexedColour has been changed (sends a COLOURUPDATEDINVISIBLE message) e.g. Causes the ColourBar to redraw itself. | |
static void | ColourListHasChanged (ColourList *ColList) |
To inform all interested parties that the given list of IndexedColours has changed by item(s) being added, deleted, or moved to a new position. e.g This causes the ColourBar and ColourMgrDlg to update their displays to reflect the new state of the list, if the list is the one which they are currently displaying. | |
static BOOL | HideColours (ColourList *ColList, IndexedColour **ColourArray, BOOL ForceDelete) |
This 'deletes' colours by creating an undoable operation to hide them. It is assumed that the colours are not in use by the time you call this function - An ENSURE failure will occur if any are. After invoking the 'hide' operation, this function calls ColourListHasChanged. | |
static BOOL | UnHideColours (ColourList *ColList, IndexedColour **ColourArray) |
This un-'deletes' colours by creating an undoable operation to unhide them. This is used when creating a new colour to 'unhide' it (which has no immediate effect on the colour) - this creates an undo record that will hide the colour if the 'new' is undone. | |
static BOOL | ChangeColour (ColourList *ColList, IndexedColour *NewDefn, IndexedColour *Target, BOOL ChangeisInvisible=FALSE) |
This changes the colour 'Target' to be the same as 'NewDefn'. To achieve undo of this operation, the data members of the two colours are swapped (as the colour being changed must stay at the same memory location), and the NewDefn is used again as the undo record of this colour. Whenever the colour is changed, including during the execution of this funciton, and also by undo/redo, a ColourChangingMsg will be broadcast (either COLOURUPDATED or COLOURUPDATEDINVISIBLE, depending on the state of the ChangeIsInvisible flag). | |
static void | ForceRedrawOfChangedColours (Document *ScopeDoc, IndexedColour **Colours) |
Scans the document tree of the given scope document, and causes a redraw of all objects which are affected by any attributes which contain references to any of the colours in the given NULL-terminated list of colours. If none of the colours are in use in the document tree, nothing should result. (i.e. it force redraws any areas of the document containing any of the given colours). | |
static IndexedColour * | GenerateNewNamedColour (ColourList *ParentList, IndexedColour *SourceColour) |
Creates a new named IndexedColour. If possible, this colour is copied from the given SourceColour, but if this is not available, an attempt to find a useful colour to copy will be made - if this fails, a battleship grey will be created. i.e. apart from abject failure, this always creates a new colour. | |
static IndexedColour * | GenerateNewUnnamedColour (ColourList *ParentList, DocColour *SourceColour) |
Creates a new named IndexedColour. If possible, this colour is copied from the given SourceColour, but if this is not available, an attempt to find a useful colour to copy will be made - if this fails, a battleship grey will be created. i.e. apart from abject failure, this always creates a new colour. | |
static void | EnsureColourIsInDocument (Document *SourceDoc, Document *DestDoc, DocColour *SourceAndResultCol) |
Ensures that the given DocColour references a "safe" colour to use within the given document. This may mean doing nothing to the colour, or it may be necessary to copy the colour (and possibly linked parent colour(s) as well!) into the DestDoc. Whatever happens, ResultCol will be filled in with something that you can use with confidence. | |
static BOOL | GetCurrentLineAndFillAttrs (AttrStrokeColour **LineAttr, AttrFillGeometry **FillAttr) |
Determines the current line and fill colour attributes. These are the default ones, or if there is a selection, the attrs which are common to all selected objects. If there are many different attributes of the same type associated with the selection, NULL is returned. Notes: The ColourBar works exclusively on the SELECTED Doc. Change with care This function ensures that Current == Selected during its operation. | |
static BOOL | GetCurrentLineAndFillColours (DocColour **LineCol, DocColour **FillCol, DocColour **EndGradFill=NULL) |
Finds the current line and fill attributes, and dereferences them to find the current line and fill DocColours. These may be returned NULL if there are no current attributes (no document/many colours selected). | |
static void | FindColourOfInterestToUser (IndexedColour **ResultCol, ColourList **ResultList=NULL) |
Several things (Colour editor whenever the selection changes, generation of a new colour) need to know a 'useful' colour to display/copy. Rather than just showing the current default colour or something, they need to interactively update to show an appropriate colour from the selection and suchlike. | |
static void | FindColourOfInterestToUser (DocColour *ResultCol, ColourList **ResultList=NULL, BOOL WantLineColour=FALSE) |
Several things (Colour editor whenever the selection changes, generation of a new colour) need to know a 'useful' colour to display/copy. Rather than just showing the current default colour or something, they need to interactively update to show an appropriate colour from the selection and suchlike. | |
Protected Member Functions | |
MsgResult | Message (Msg *Msg) |
Process messages sent to the ColourManager Some messages (DocChanging) will cause new broadcasts indicating that the colour system has changed (new colour list has been paged in, etc). | |
Static Protected Attributes | |
static ColourList * | CurrentColourList |
static Document * | ScopeDocument |
This is the Indexed Colour list for the SelectedDocument (if any). It is displayed by the colour bar, and/or edited by the Colour Manager Dialogue.
Find a suitable global or document-specific colour context to use
Handle colour system state changes
Messages are sent whenever the current list changes. This happens when:
1) A colour is inserted/deleted/edited in the SelectedDocument,
2) The SelectedDocument changes,
3) The Colour List is deselected (i.e. when there is no SelectedDocument, there is no available list)
These messages allow the colour manager dialogues and colour bar (and other clients) to update their contents (or hide, etc) when such changes occur.
Other processing (invalidating colour caches, etc) may also occur in some cases. This is all handled internally by the ColourManager.
Copy or create new colours
Find "Useful" colours for the editor to edit and the colour line/gallery to display.
Miscellaneous other useful functions. See colormgr.h for details of currently available functions
Definition at line 168 of file colormgr.h.
|
Constructs a ColourManager object.
Definition at line 168 of file colormgr.cpp. 00169 : MessageHandler(CC_RUNTIME_CLASS(MessageHandler), TRUE) 00170 { 00171 }
|
|
This changes the colour 'Target' to be the same as 'NewDefn'. To achieve undo of this operation, the data members of the two colours are swapped (as the colour being changed must stay at the same memory location), and the NewDefn is used again as the undo record of this colour. Whenever the colour is changed, including during the execution of this funciton, and also by undo/redo, a ColourChangingMsg will be broadcast (either COLOURUPDATED or COLOURUPDATEDINVISIBLE, depending on the state of the ChangeIsInvisible flag).
Definition at line 2124 of file colormgr.cpp. 02127 { 02128 #if !defined(EXCLUDE_FROM_RALPH) 02129 ERROR3IF(ColList == NULL || NewDefn == NULL || Target == NULL, 02130 "ColourManager::ChangeColour - illegal NULL param(s)"); 02131 02132 OpDescriptor* OpDesc = 02133 OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpColourChange)); 02134 02135 if (OpDesc != NULL) 02136 { 02137 ColourChangeInfo Param; 02138 02139 Param.ParentList = ColList; 02140 Param.Target = Target; 02141 Param.NewDefn = NewDefn; 02142 Param.InvisibleChange = ChangeIsInvisible; 02143 02144 OpDesc->Invoke((OpParam *) &Param); 02145 } 02146 #endif 02147 return(TRUE); 02148 }
|
|
Indicates to all interested parties that the given IndexedColour has been changed (sends a COLOURUPDATED message) e.g. Causes the ColourBar and document to redraw themselves.
Notes: If you are recieving messages, and wish to act on COLOURUPDATEDINVISIBLE, you should sit on BOTH COLOURUPDATED messages. Otherwise, you should only sit on COLOURUPDATED messages. The ColourManager will force-redraw the parst of the ScopeDoc which rely on the changed colour, or any colour liked to the changed colour. If ColList == the current colour list then entities such as the colour bar will redraw themselves to show the new state of this colour.
Definition at line 1867 of file colormgr.cpp. 01869 { 01870 ERROR3IF(ScopeDoc == NULL || ColList == NULL || Col == NULL, 01871 "ColourManager::ColourHasChanged - NULL parameters are illegal!\n"); 01872 01873 ColList->InvalidateInheritanceCache(); 01874 01875 BROADCAST_TO_ALL(ColourChangingMsg(ScopeDoc, ColList, Col, 01876 ColourChangingMsg::COLOURUPDATED)); 01877 }
|
|
Indicates to all interested parties that the given IndexedColour has been changed (sends a COLOURUPDATEDINVISIBLE message) e.g. Causes the ColourBar to redraw itself.
If 'visible' information has changed, use ColourHasChanged instead. Notes: If you are recieving messages, and wish to act on COLOURUPDATEDINVISIBLE, you should sit on BOTH COLOURUPDATED messages. ColList really should point to the list in which the colour resides. If ColList == NULL or ColList == the current colour list, then entities such as the colour bar will redraw themselves to show the new state of this colour. If ColList is not NULL, then all its sort orders will be marked invalid so that they are re-sorted the next time they are used. (If an incorrect pointer (or NULL) is passed in, unnecessary redraws of colour bars etc may take place, so it is most preferable that you pass in the correct list pointer if you know it)
Definition at line 1924 of file colormgr.cpp. 01926 { 01927 ColList->InvalidateInheritanceCache(); 01928 BROADCAST_TO_ALL(ColourChangingMsg(ScopeDoc, ColList, Col, 01929 ColourChangingMsg::COLOURUPDATEDINVISIBLE)); 01930 }
|
|
To inform all interested parties that the given list of IndexedColours has changed by item(s) being added, deleted, or moved to a new position. e.g This causes the ColourBar and ColourMgrDlg to update their displays to reflect the new state of the list, if the list is the one which they are currently displaying.
Definition at line 1959 of file colormgr.cpp. 01960 { 01961 ERROR3IF(ColList == NULL, "ColourManager::ColourListHasChanged: NULL parameter is illegal"); 01962 01963 // Inform the colour gallery ahead of everyone else 01964 // ColourGallery::ColourListHasChanged(ColList); 01965 01966 // And inform the plebs 01967 ColList->InvalidateInheritanceCache(); 01968 01969 Document *ParentDoc = (Document *) ColList->GetParentDocument(); 01970 BROADCAST_TO_ALL(ColourChangingMsg(ParentDoc, ColList, NULL, 01971 ColourChangingMsg::LISTUPDATED)); 01972 }
|
|
De-Initlialises the entire colour system. This includes the colour manager, colour contexts, and colour dialogues, etc. Notes: Should only be called once ever. Called by Application::Deinit().
Definition at line 233 of file colormgr.cpp. 00234 { 00235 // shut down the colour contexts 00236 ColourContextList::DeinitColourContexts(); 00237 }
|
|
Ensures that the given DocColour references a "safe" colour to use within the given document. This may mean doing nothing to the colour, or it may be necessary to copy the colour (and possibly linked parent colour(s) as well!) into the DestDoc. Whatever happens, ResultCol will be filled in with something that you can use with confidence.
ResultCol - should point at a DocColour defining the colour you want to put in this document. It may be an immediate DocColour, or a reference to an IndexedColour. (this param may NOT be NULL)
What do you mean this should be in the colour manager? Have you seen how many files it rebuilds?! Eeek! (OK, so I've moved it now)
Definition at line 1784 of file colormgr.cpp. 01786 { 01787 ERROR3IF(ResultCol == NULL || DestDoc == NULL, "Illegal NULL param"); 01788 01789 if (SourceDoc == DestDoc) // Completely safe - into the same doc 01790 return; 01791 01792 // Find the indexed colour (if any) that the given colour references 01793 IndexedColour *ColourToApply = ResultCol->FindParentIndexedColour(); 01794 01795 if (ColourToApply == NULL) // It's a simple DocColour, so safe 01796 return; 01797 01798 // It's an IndexedColour. We must copy it to the dest doc, and use the copy. 01799 if (DestDoc != NULL) 01800 { 01801 // We're applying the colour into a different document! 01802 // We must duplicate (with merging) this colour into the dest doc before applying 01803 ColourListComponent *ColComp = (ColourListComponent *) 01804 DestDoc->GetDocComponent(CC_RUNTIME_CLASS(ColourListComponent)); 01805 01806 // Start the copy 01807 if (ColComp != NULL && ColComp->StartComponentCopy()) 01808 { 01809 DocColour RefCol; 01810 RefCol.MakeRefToIndexedColour(ColourToApply); 01811 01812 // Copy this colour (and any linked parents if necessary). RefCol now 01813 // references the destination colour, so we point ColourToApply at it 01814 ColComp->CopyColourAcross(&RefCol); 01815 ColourToApply = RefCol.FindParentIndexedColour(); 01816 01817 // And clean up, merging the colour into the other document's colour list 01818 ColComp->EndComponentCopy(NULL, FALSE); 01819 01820 // We've got an IndexedColour, so set ResultCol on it, and return 01821 ResultCol->MakeRefToIndexedColour(ColourToApply); 01822 return; 01823 } 01824 } 01825 01826 // We've failed to copy the colour across, so set it to simple 'no colour' 01827 *ResultCol = DocColour(COLOUR_BLACK); 01828 }
|
|
Several things (Colour editor whenever the selection changes, generation of a new colour) need to know a 'useful' colour to display/copy. Rather than just showing the current default colour or something, they need to interactively update to show an appropriate colour from the selection and suchlike.
This is used to determine the colour definition for a colour to use when editing "local colours" in the colour editor. The exact colour returned will be NULL (in dire emergency, usually only occurs if there are no documents open), or will be chosen from this priority list of possible contenders: MonoOn (1) Colour of first selected fill-blob found (if !WantLineColour), (2) Fill-Colour of selection (if !WantLineColour), (3) current/default fill colour (if !WantLineColour), (4) line-Colour of selection (If WantLineColour), (5) current/default line colour (if WantLineColour), (6) COLOUR_BLACK MonoOff Notes: 'Colour of selection' is determined by using (if possible) the last object selected, or the frontmost selected object if this fails. If you are not interested in the ResultList return value, pass in NULL (use the default) for this parameter. Camelot will not return a 'no fill' default colour (conditions 3 and 6) but Webster does because the Webster colour editor wants to handle this situation. Definition at line 1202 of file colormgr.cpp. 01204 { 01205 ERROR3IF(ResultCol == NULL, "ColourManager::FindColourOfInterestToUser - ResultCol is NULL!"); 01206 01207 // Ensure safe return values 01208 *ResultCol = DocColour(COLOUR_BLACK); 01209 if (ResultList != NULL) 01210 *ResultList = NULL; 01211 01212 // If there are no documents available, then we can't find a colour - Return NULLs 01213 if (Document::GetSelected() == NULL) 01214 return; 01215 01216 // Ensure CurrentDoc == SelectedDoc 01217 Document *OldCurrentDoc = SetCurrentDoc(); 01218 01219 // Get the colour list. Just in case, we invalidate the cache (as this method is 01220 // called on document chnages and suchlike, so it is best to make sure we don't use 01221 // cached values for a no-longer-present document!) 01222 ColourList *ColList = ColourManager::GetColourList(TRUE); 01223 BOOL FoundUsefulColour = FALSE; 01224 01225 // First, check if there is a VISIBLE selected fill blob, and use the colour of 01226 // the first one that we find, if we are lucky enough to find one. 01227 if (!WantLineColour && AttrFillGeometry::CountSelectionControlPoints() > 0) 01228 { 01229 // Yep. There is at least 1 visible selected fill blob... 01230 AttrFillGeometry* Fill = AttrFillGeometry::FindFirstSelectedAttr(); 01231 while (Fill != NULL && !FoundUsefulColour) 01232 { 01233 if (Fill->GetSelectionCount() > 0) 01234 { 01235 // CGS .... 01236 01237 // DMc's multi stage fills (blobs) do not dynamically update the colour edit 01238 // dialog when they are clicked on. This has now been 01239 // fixed (by me!). Problem was to do with the fact that this function never 01240 // even considered them .... 01241 01242 FillRamp* pFillRamp = Fill->GetFillRamp (); 01243 01244 if (pFillRamp != NULL) 01245 { 01246 UINT32 NumberSelected = pFillRamp->CountSelBlobs (); 01247 01248 if (NumberSelected > 0) 01249 { 01250 INT32 SelectedIndex = pFillRamp->GetSelectedIndex (); 01251 ColRampItem* TheItem = (ColRampItem*) pFillRamp->GetValidIndexedItem (SelectedIndex); 01252 01253 if (TheItem != NULL) 01254 { 01255 FoundUsefulColour = TRUE; 01256 *ResultCol = TheItem->GetColour (); 01257 } 01258 } 01259 } 01260 01261 if (Fill->IsSelected(FILLCONTROL_STARTPOINT) && Fill->GetStartColour() != NULL) 01262 { 01263 // Use Fill Start Colour 01264 FoundUsefulColour = TRUE; 01265 *ResultCol = *(Fill->GetStartColour()); 01266 break; 01267 } 01268 01269 if (Fill->IsSelected(FILLCONTROL_ENDPOINT) && Fill->GetEndColour() != NULL) 01270 { 01271 // Use Fill End Colour 01272 FoundUsefulColour = TRUE; 01273 *ResultCol = *(Fill->GetEndColour()); 01274 break; 01275 } 01276 01277 if (Fill->IsSelected(FILLCONTROL_ENDPOINT2) && Fill->GetEndColour2() != NULL) 01278 { 01279 // Use Fill End Colour 01280 FoundUsefulColour = TRUE; 01281 *ResultCol = *(Fill->GetEndColour2()); 01282 break; 01283 } 01284 01285 if (Fill->IsSelected(FILLCONTROL_ENDPOINT3) && Fill->GetEndColour3() != NULL) 01286 { 01287 // Use Fill End Colour 01288 FoundUsefulColour = TRUE; 01289 *ResultCol = *(Fill->GetEndColour3()); 01290 break; 01291 } 01292 } 01293 01294 Fill = AttrFillGeometry::FindNextSelectedAttr(); 01295 } 01296 } 01297 01298 if (!FoundUsefulColour) 01299 { 01300 // Find the last node which was made selected (if any) 01301 // Scan back from this to find the nearest previous NodeAttribute which contains 01302 // colour(s), and make ResultColour ref the first IndexedColour which we find in this search. 01303 SelRange *Selection = GetApplication()->FindSelection(); 01304 01305 // If there are any selected nodes, then... 01306 if (Selection != NULL && Selection->Count() > 0) 01307 { 01308 Node *pNode = Selection->GetLastSelectedNode(); 01309 01310 // If the SelRange doesn't know what was last made selected, then see if anything 01311 // is selected, and if so, grab the last (topmost) selected object instead 01312 if (pNode == NULL) 01313 pNode = Selection->FindLast(); 01314 01315 // Now search through the attributes applied to this node, to see if we can 01316 // find an IndexedColour FILL (i.e. we ignore stroke colours for now) - we 01317 // will use the first one that we find 01318 NodeAttribute *pAttr = NULL; 01319 01320 if (!WantLineColour) 01321 { 01322 if (pNode != NULL) 01323 pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01324 01325 while (pAttr != NULL && !FoundUsefulColour) 01326 { 01327 // Scan each NodeAttribute in turn to see if any of them contain any colours 01328 DocColour *pColour; 01329 UINT32 Context = 0; 01330 01331 // Only check non-line-colour attributes 01332 if (!(IS_A(pAttr, AttrStrokeColour))) 01333 { 01334 do 01335 { 01336 // Get the next colour field (if any) from the attribute, and find the 01337 // IndexedColour (if any) to which it refers 01338 pColour = pAttr->EnumerateColourFields(Context++); 01339 if (pColour != NULL) 01340 { 01341 FoundUsefulColour = TRUE; 01342 *ResultCol = *pColour; 01343 } 01344 01345 } while (pColour != NULL && !FoundUsefulColour); 01346 } 01347 01348 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01349 } 01350 } 01351 else 01352 { 01353 // If we still haven't found a colour, try for a line/stroke colour instead 01354 if (pNode != NULL && !FoundUsefulColour) 01355 pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01356 01357 while (pAttr != NULL && !FoundUsefulColour) 01358 { 01359 // Scan each NodeAttribute in turn to see if any of them contain any colours 01360 DocColour *pColour; 01361 UINT32 Context = 0; 01362 01363 // Only check line-colour attributes 01364 if (IS_A(pAttr, AttrStrokeColour)) 01365 { 01366 do 01367 { 01368 // Get the next colour field (if any) from the attribute, and find the 01369 // IndexedColour (if any) to which it refers 01370 pColour = pAttr->EnumerateColourFields(Context++); 01371 if (pColour != NULL) 01372 { 01373 FoundUsefulColour = TRUE; 01374 *ResultCol = *pColour; 01375 } 01376 01377 } while (pColour != NULL && !FoundUsefulColour); 01378 } 01379 01380 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01381 } 01382 } 01383 01384 } 01385 } 01386 01387 if (!FoundUsefulColour) 01388 { 01389 // OK, then. let's see if there is a default fill colour, or failing that 01390 // (eg it could be 'no colour') a default line colour, which we can edit. 01391 AttributeManager &AttrMgr = Document::GetSelected()->GetAttributeMgr(); 01392 01393 DocColour LineCol; 01394 DocColour FillCol; 01395 01396 AttrMgr.GetCurrentLineAndFillColour(CC_RUNTIME_CLASS(NodeRenderableInk), 01397 &LineCol, &FillCol); 01398 01399 if (!WantLineColour) 01400 { 01401 // Webster wants the colour even if it is 'no fill' 01402 #ifndef WEBSTER 01403 if (!FillCol.IsTransparent()) 01404 #endif //WEBSTER 01405 { 01406 *ResultCol = FillCol; 01407 FoundUsefulColour = TRUE; 01408 } 01409 } 01410 else 01411 { 01412 #ifndef WEBSTER 01413 if (!LineCol.IsTransparent()) 01414 #endif //WEBSTER 01415 { 01416 *ResultCol = LineCol; 01417 FoundUsefulColour = TRUE; 01418 } 01419 } 01420 } 01421 01422 if (!FoundUsefulColour) 01423 { 01424 // Ok, we're rapidly approaching a moment of panic. Try the first non-deleted named 01425 // colour in the selected document's colour list. If nothing else, there should 01426 // always be a default Black that we can use 01427 01428 if (ColList != NULL) 01429 { 01430 IndexedColour *Ptr = (IndexedColour *) ColList->GetHead(); 01431 while (Ptr != NULL && !FoundUsefulColour) 01432 { 01433 if (Ptr->IsNamed() && !Ptr->IsDeleted()) 01434 { 01435 FoundUsefulColour = TRUE; 01436 ResultCol->MakeRefToIndexedColour(Ptr); 01437 } 01438 01439 Ptr = (IndexedColour *) ColList->GetNext(Ptr); 01440 } 01441 } 01442 } 01443 01444 // Fill in the return results 01445 if (ResultList != NULL) 01446 *ResultList = ColList; 01447 01448 // And restore the previous CurrentDocument state 01449 RestoreCurrentDoc(OldCurrentDoc); 01450 }
|
|
Several things (Colour editor whenever the selection changes, generation of a new colour) need to know a 'useful' colour to display/copy. Rather than just showing the current default colour or something, they need to interactively update to show an appropriate colour from the selection and suchlike.
The exact colour returned will be NULL (in dire emergency, usually only occurs if there are no documents open), or will be chosen from this priority list of possible contenders: MonoOn (1) Colour of first selected fill-blob found, (2) Fill-Colour of selection, (3) current/default fill colour, (4) line-Colour of selection, (5) current/default line colour, (6) the first active named colour in the document's colour list, (7) NULL MonoOff Notes: 'Colour of selection' is determined by using (if possible) the last object selected, or the frontmost selected object if this fails. If you are not interested in the ResultList return value, pass in NULL (use the default) for this parameter. In debug builds only, extra checks are made which can cause an ERROR3 if the colour found was not in the selected document's ColourList. Definition at line 932 of file colormgr.cpp. 00933 { 00934 ERROR3IF(ResultCol == NULL, "ColourManager::FindColourOfInterestToUser - ResultCol is NULL!"); 00935 00936 // Ensure safe return values 00937 *ResultCol = NULL; 00938 if (ResultList != NULL) 00939 *ResultList = NULL; 00940 00941 // If there are no documents available, then we can't find a colour - Return NULLs 00942 if (Document::GetSelected() == NULL) 00943 return; 00944 00945 // Ensure CurrentDoc == SelectedDoc 00946 Document *OldCurrentDoc = SetCurrentDoc(); 00947 00948 // Get the colour list. Just in case, we invalidate the cache (as this method is 00949 // called on document chnages and suchlike, so it is best to make sure we don't use 00950 // cached values for a no-longer-present document!) 00951 ColourList *ColList = ColourManager::GetColourList(TRUE); 00952 IndexedColour *UsefulColour = NULL; 00953 00954 // First, check if there is a VISIBLE selected fill blob, and use the colour of 00955 // the first one that we find, if we are lucky enough to find one. 00956 if (AttrFillGeometry::CountSelectionControlPoints() > 0) 00957 { 00958 // Yep. There is at least 1 visible selected fill blob... 00959 AttrFillGeometry* Fill = AttrFillGeometry::FindFirstSelectedAttr(); 00960 while (Fill != NULL && UsefulColour == NULL) 00961 { 00962 if (Fill->GetSelectionCount() > 0) 00963 { 00964 if (Fill->IsSelected(FILLCONTROL_STARTPOINT) && Fill->GetStartColour() != NULL) 00965 { 00966 // Use Fill Start Colour 00967 UsefulColour = Fill->GetStartColour()->FindParentIndexedColour(); 00968 break; 00969 } 00970 00971 if (Fill->IsSelected(FILLCONTROL_ENDPOINT) && Fill->GetEndColour() != NULL) 00972 { 00973 // Use Fill End Colour 00974 UsefulColour = Fill->GetEndColour()->FindParentIndexedColour(); 00975 break; 00976 } 00977 00978 if (Fill->IsSelected(FILLCONTROL_ENDPOINT2) && Fill->GetEndColour2() != NULL) 00979 { 00980 // Use Fill End Colour 00981 UsefulColour = Fill->GetEndColour2()->FindParentIndexedColour(); 00982 break; 00983 } 00984 00985 if (Fill->IsSelected(FILLCONTROL_ENDPOINT3) && Fill->GetEndColour3() != NULL) 00986 { 00987 // Use Fill End Colour 00988 UsefulColour = Fill->GetEndColour3()->FindParentIndexedColour(); 00989 break; 00990 } 00991 } 00992 00993 Fill = AttrFillGeometry::FindNextSelectedAttr(); 00994 } 00995 } 00996 00997 if (UsefulColour == NULL) 00998 { 00999 // Find the last node which was made selected (if any) 01000 // Scan back from this to find the nearest previous NodeAttribute which contains 01001 // colour(s), and make UsefulColour the first IndexedColour which we find in this search. 01002 SelRange *Selection = GetApplication()->FindSelection(); 01003 01004 if (Selection != NULL) 01005 { 01006 Node *pNode = Selection->GetLastSelectedNode(); 01007 // If the SelRange doesn't know what was last made selected, then see if anything 01008 // is selected, and if so, grab the last (topmost) selected object instead 01009 if (pNode == NULL) 01010 pNode = Selection->FindLast(); 01011 01012 // Now search through the attributes applied to this node, to see if we can 01013 // find an IndexedColour FILL (i.e. we ignore stroke colours for now) - we 01014 // will use the first one that we find 01015 NodeAttribute *pAttr = NULL; 01016 if (pNode != NULL) 01017 pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01018 01019 while (pAttr != NULL && UsefulColour == NULL) 01020 { 01021 // Scan each NodeAttribute in turn to see if any of them contain any colours 01022 DocColour *pColour; 01023 UINT32 Context = 0; 01024 01025 // Only check non-line-colour attributes 01026 if (!(IS_A(pAttr, AttrStrokeColour))) 01027 { 01028 do 01029 { 01030 // Get the next colour field (if any) from the attribute, and find the 01031 // IndexedColour (if any) to which it refers 01032 pColour = pAttr->EnumerateColourFields(Context++); 01033 if (pColour != NULL) 01034 UsefulColour = pColour->FindParentIndexedColour(); 01035 01036 } while (pColour != NULL && UsefulColour == NULL); 01037 } 01038 01039 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01040 } 01041 01042 01043 // If we still haven't found a colour, try for a line/stroke colour instead 01044 if (pNode != NULL && UsefulColour == NULL) 01045 pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01046 01047 while (pAttr != NULL && UsefulColour == NULL) 01048 { 01049 // Scan each NodeAttribute in turn to see if any of them contain any colours 01050 DocColour *pColour; 01051 UINT32 Context = 0; 01052 01053 // Only check line-colour attributes 01054 if (IS_A(pAttr, AttrStrokeColour)) 01055 { 01056 do 01057 { 01058 // Get the next colour field (if any) from the attribute, and find the 01059 // IndexedColour (if any) to which it refers 01060 pColour = pAttr->EnumerateColourFields(Context++); 01061 if (pColour != NULL) 01062 UsefulColour = pColour->FindParentIndexedColour(); 01063 01064 } while (pColour != NULL && UsefulColour == NULL); 01065 } 01066 01067 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01068 } 01069 01070 } 01071 } 01072 01073 if (UsefulColour == NULL) 01074 { 01075 // OK, then. let's see if there is a default fill colour, or failing that 01076 // (eg it could be 'no colour') a default line colour, which we can edit. 01077 AttributeManager &AttrMgr = Document::GetSelected()->GetAttributeMgr(); 01078 01079 DocColour LineCol; 01080 DocColour FillCol; 01081 01082 AttrMgr.GetCurrentLineAndFillColour(CC_RUNTIME_CLASS(NodeRenderableInk), 01083 &LineCol, &FillCol); 01084 01085 UsefulColour = FillCol.FindParentIndexedColour(); 01086 if (UsefulColour == NULL) 01087 UsefulColour = LineCol.FindParentIndexedColour(); 01088 } 01089 01090 if (UsefulColour == NULL) 01091 { 01092 // Ok, we're rapidly approaching a moment of panic. Try the first non-deleted named 01093 // colour in the selected document's colour list. If nothing else, there should 01094 // always be a default Black that we can use 01095 01096 if (ColList != NULL) 01097 { 01098 IndexedColour *Ptr = (IndexedColour *) ColList->GetHead(); 01099 while (Ptr != NULL && UsefulColour == NULL) 01100 { 01101 if (Ptr->IsNamed() && !Ptr->IsDeleted()) 01102 UsefulColour = Ptr; 01103 01104 Ptr = (IndexedColour *) ColList->GetNext(Ptr); 01105 } 01106 } 01107 } 01108 01109 // Sanity check. Should never ever ever be the case, ever. 01110 if (UsefulColour != NULL) 01111 ERROR3IF(UsefulColour->IsDeleted(), 01112 "ColourManager::FindColourOfInterestToUser - Colour found is DELETED!"); 01113 01114 // Fill in the return results 01115 *ResultCol = UsefulColour; 01116 if (UsefulColour != NULL && ResultList != NULL) 01117 *ResultList = ColList; 01118 01119 #ifdef _DEBUG 01120 // In debug builds, verify that the returned colour is in the list we 01121 // expect it to be in! 01122 01123 if (ColList != NULL && UsefulColour != NULL) 01124 { 01125 IndexedColour *Ptr = (IndexedColour *) ColList->GetHead(); 01126 while (Ptr != NULL && Ptr != UsefulColour) 01127 Ptr = (IndexedColour *) ColList->GetNext(Ptr); 01128 01129 if (Ptr == NULL) 01130 { 01131 Ptr = (IndexedColour *) ColList->GetUnnamedColours()->GetHead(); 01132 while (Ptr != NULL && Ptr != UsefulColour) 01133 Ptr = (IndexedColour *) ColList->GetUnnamedColours()->GetNext(Ptr); 01134 } 01135 01136 ERROR3IF(Ptr != UsefulColour, 01137 "ColourManager::FindColourOfInterestToUser" 01138 " - Colour found is not in the current colour list!"); 01139 } 01140 #endif 01141 01142 // And restore the previous CurrentDocument state 01143 RestoreCurrentDoc(OldCurrentDoc); 01144 }
|
|
Scans the document tree of the given scope document, and causes a redraw of all objects which are affected by any attributes which contain references to any of the colours in the given NULL-terminated list of colours. If none of the colours are in use in the document tree, nothing should result. (i.e. it force redraws any areas of the document containing any of the given colours).
Definition at line 261 of file colormgr.cpp. 00262 { 00263 #if !defined(EXCLUDE_FROM_RALPH) 00264 // Sanity check 00265 if (ScopeDoc == NULL) 00266 { 00267 ERROR3("Illegal NULL param"); 00268 return; 00269 } 00270 00271 OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_REDRAWCOLOURS); 00272 00273 if (OpDesc != NULL) 00274 { 00275 OpRedrawColoursInfo Info; 00276 Info.ScopeDoc = ScopeDoc; 00277 Info.Colours = Colours; 00278 00279 OpDesc->Invoke((OpParam *) &Info); 00280 } 00281 #endif 00282 }
|
|
Creates a new named IndexedColour. If possible, this colour is copied from the given SourceColour, but if this is not available, an attempt to find a useful colour to copy will be made - if this fails, a battleship grey will be created. i.e. apart from abject failure, this always creates a new colour.
NOTE that the user is prompted for a new name, and has the opportunity to cancel creation of the colour, in which case, NULL will be returned. You must therefore handle a NULL return *quietly*. Notes: This code is used by the ColourBar and ColourGallery "new colour" code to generate a new named colour.
Definition at line 1499 of file colormgr.cpp. 01501 { 01502 ERROR3IF(ParentList == NULL, "ColourManager::GenerateNamedColour - NULL ParentList!"); 01503 01504 IndexedColour *NewCol = NULL; 01505 01506 if (SourceColour != NULL) 01507 { 01508 // Copy the source colour 01509 NewCol = new IndexedColour(*SourceColour); 01510 01511 // If parent is named and not tint/linked colour, remember where we copied 01512 // it from so that we can give a useful default parent in the colour editor 01513 // if the user decides to make it a tint/linked colour later on. 01514 if (NewCol->IsNamed() && NewCol->FindLinkedParent() == NULL) 01515 NewCol->SetLinkedParent(SourceColour, NewCol->GetType()); 01516 } 01517 else 01518 { 01519 IndexedColour *UsefulColour; 01520 FindColourOfInterestToUser(&UsefulColour); 01521 01522 if (UsefulColour != NULL) 01523 { 01524 NewCol = new IndexedColour(*UsefulColour); 01525 01526 // If parent is named and not tint/linked colour, remember where we copied 01527 // it from so that we can give a useful default parent in the colour editor 01528 // if the user decides to make it a tint/linked colour later on. 01529 if (NewCol->IsNamed() && NewCol->FindLinkedParent() == NULL) 01530 NewCol->SetLinkedParent(UsefulColour, NewCol->GetType()); 01531 } 01532 else 01533 { 01534 // Create a mid-grey HSV colour for them to edit 01535 ColourHSVT Bob; 01536 Bob.Hue = Bob.Saturation = Bob.Transparent = 0; 01537 Bob.Value = FIXED24(0.5); 01538 01539 NewCol = new INDEXEDCOLOUR_HSVT(&Bob); 01540 } 01541 } 01542 01543 if (NewCol == NULL) // Serious memory failure! 01544 return(NULL); 01545 01546 // Set the colour's name (1 to make it named, and 2 so it is not 01547 // the same as the colour it was copied from) 01548 /* 01549 String_64 NewName; 01550 01551 if (NewCol->IsNamed()) 01552 { 01553 // Is named, so is a copy: Name it "New Colour (Copy of WXYZ)" 01554 String_64 OldName = *NewCol->GetName(); 01555 String_64 TruncOldName; // Truncate old name to 32 chars 01556 OldName.Left(&TruncOldName, 32); // and add it into the new name 01557 NewName.MakeMsg(_R(IDS_NEWCOLOUR_COPY), (TCHAR *)TruncOldName); 01558 } 01559 else 01560 NewName.MakeMsg(_R(IDS_NEWCOLOUR)); // No name, so make it named: "New colour" 01561 */ 01562 01563 #if !defined(EXCLUDE_FROM_RALPH) 01564 #ifndef STANDALONE 01565 // Ask for a new name for the colour. This also gives the user a chance 01566 // to back out of the deal without losing their deposit (though if they didn't 01567 // tick the small box in the small print, we'll continue sending them junk mail ;-) 01568 if (!NewColourDlg::InvokeDialog(ParentList, NewCol, NEWCOLOUR_MUSTBENAMED)) 01569 { 01570 delete NewCol; // Bummer. They cancelled their subscription 01571 return(NULL); 01572 } 01573 #endif 01574 #endif 01575 01576 // NewCol->SetName(NewName); 01577 01578 // Add the new colour (also ensuring that the colour has a unique name) 01579 ParentList->AddItem(NewCol); 01580 01581 // Create an undo record, but only if it is a colour style (named) 01582 IndexedColour *UnHideList[2]; 01583 UnHideList[0] = NewCol; 01584 UnHideList[1] = NULL; 01585 ColourManager::UnHideColours(ParentList, UnHideList); 01586 01587 return(NewCol); 01588 }
|
|
Creates a new named IndexedColour. If possible, this colour is copied from the given SourceColour, but if this is not available, an attempt to find a useful colour to copy will be made - if this fails, a battleship grey will be created. i.e. apart from abject failure, this always creates a new colour.
Notes: This code is used by the Colour Editor to generate a new unnamed colour when editing "local colours". Unnamed colours are auto-destructed when their usagecount is decremented to zero, so you don't generally need to clean up these colours. When copying a colour style as an unnamed colour, we force it to be 'normal' This is so that initial attempts to edit the colour of an object delink it from its parent, and allow the colour to be freely edited. When editing the local colour, this force won't occur, which allows the user to specifically make locals which are links/tints.
Definition at line 1641 of file colormgr.cpp. 01643 { 01644 if (ParentList == NULL) 01645 { 01646 ERROR3("ColourManager::GenerateNewUnnamedColour - NULL ParentList!"); 01647 return(NULL); 01648 } 01649 01650 IndexedColour *NewCol = NULL; 01651 01652 DocColour SourceColour(COLOUR_BLACK); 01653 if (BaseSourceColour == NULL) 01654 FindColourOfInterestToUser(&SourceColour); // No supplied colour, so find one 01655 else 01656 SourceColour = *BaseSourceColour; // Use the supplied colour 01657 01658 IndexedColour *SourceIxCol = SourceColour.FindParentIndexedColour(); 01659 if (SourceIxCol == NULL) 01660 { 01661 // Copy the definition of a DocColour 01662 ColourGeneric ColDef; 01663 SourceColour.GetSourceColour(&ColDef); 01664 01665 NewCol = new IndexedColour(SourceColour.GetColourModel(), &ColDef); 01666 } 01667 else 01668 { 01669 // Copy an IndexedColour 01670 NewCol = new IndexedColour(*SourceIxCol); 01671 01672 if (NewCol != NULL) 01673 { 01674 NewCol->SetUnnamed(); // Ensure the colour is unnamed 01675 01676 // When copying a colour style as an unnamed colour, we force it to be 'normal' 01677 // This is so that initial attempts to edit the colour of an object delink 01678 // it from its parent, and allow the colour to be freely edited. When editing 01679 // the local colour, this force won't occur, which allows the user to specifically 01680 // make locals which are links/tints. 01681 // NOTE that we make the source colour our parent, so that subsequent attempts 01682 // to edit this colour will choose a sensible parent. 01683 // if (SourceIxCol->IsNamed()) 01684 // { 01685 // We no longer do this (Jason - 18/10/95) 01686 // This was a fix to the fact that the user could not edit tints/linked colours in the "simple" 01687 // colour editor, and thus could get trapped in a very confusing uneditable state. 01688 // These days they have both the ability to edit all colour types in the simple mode, 01689 // and the extra status line and constraint-display stuff to make it more obvious why they 01690 // can't change stuff when they can't. 01691 // NewCol->SetLinkedParent(SourceIxCol, COLOURTYPE_NORMAL); 01692 // 01693 // } 01694 01695 // We have copied the Parent colour (hint) from the copied colour. 01696 // However, if this is a "normal" (unlinked) colour, we really want to set 01697 // the parent hint to be the colour we were copied from. 01698 // (But we can only use the source colour if it's named and "alive") 01699 if (NewCol->FindLinkedParent() == NULL && SourceIxCol->IsNamed() && !SourceIxCol->IsDeleted()) 01700 NewCol->SetLinkedParent(SourceIxCol, NewCol->GetType()); 01701 } 01702 } 01703 01704 // Check that the parent colour of our new one is a legal parent (named, not deleted, and exists 01705 // in the target document) 01706 if (NewCol != NULL) 01707 { 01708 IndexedColour *Parent = NewCol->FindLastLinkedParent(); 01709 if (Parent != NULL) 01710 { 01711 if (Parent->IsDeleted() || !Parent->IsNamed()) 01712 Parent = NULL; // Deleted or unnamed - forget it 01713 01714 if (Parent != NULL) 01715 { 01716 // Check that the parent colour is in the same colour list as the NewCol will be going 01717 IndexedColour *Ptr = ParentList->GetUndeletedHead(); 01718 while (Ptr != NULL) 01719 { 01720 if (Ptr == Parent) 01721 break; 01722 01723 Ptr = ParentList->GetUndeletedNext(Ptr); 01724 } 01725 01726 if (Ptr != Parent) 01727 Parent = NULL; 01728 } 01729 01730 // Nope - we haven't got a safe parent, so vape the parent field altogether 01731 if (Parent == NULL) 01732 { 01733 ERROR3("Warning: Had to correct colour with illegal parent pointer"); 01734 NewCol->SetLinkedParent(NULL, COLOURTYPE_NORMAL); 01735 } 01736 } 01737 01738 // Add the new colour (also ensuring that the colour has a unique name) 01739 ParentList->GetUnnamedColours()->AddTail(NewCol); 01740 } 01741 01742 return(NewCol); 01743 }
|
|
To easily find an appropriate colour context to use when converting colours. There are global contexts, but in order to supply special view-specific colour corrections etc, each document view actually has its own private set of contexts. Thus, you should call this function to determine the most appropriate context to use.
Definition at line 586 of file colormgr.cpp. 00587 { 00588 if (ScopeView != NULL) 00589 return(ScopeView->GetColourContext(Model)); 00590 00591 return(ColourContext::GetGlobalDefault(Model)); 00592 }
|
|
To easily find an appropriate colour context to use when converting colours. There are global contexts, but in order to supply special document-specific colour corrections etc, each document actually has its own private set of contexts. Thus, you should call this function to determine the most appropriate context to use.
Definition at line 552 of file colormgr.cpp. 00553 { 00554 if (ScopeDocument == NULL) 00555 return(ColourContext::GetGlobalDefault(Model)); 00556 00557 return(ScopeDocument->GetDefaultColourContexts()->Context[Model]); 00558 }
|
|
To obtain the ColourList of IndexedColours in the SelectedDocument (the colours which the user can use within the document; this is the set of colours displayed by the colour bar and edited by the ColourMgrDlg) Note that an ordered list is used so that multiple display orders can be used (e.g. for the ColourMgrDlg and ColourBar, etc).
The list is cached so this call is generally pretty efficient Definition at line 471 of file colormgr.cpp. 00472 { 00473 Document *ParentDoc = Document::GetSelected(); 00474 00475 if (ParentDoc != NULL) 00476 { 00477 if (InvalidateCache || ParentDoc != ScopeDocument) 00478 { 00479 CurrentColourList = ParentDoc->GetIndexedColours(); 00480 ScopeDocument = ParentDoc; 00481 } 00482 // else 00483 // Cache is up to date, so quit messing about 00484 } 00485 else 00486 { 00487 ScopeDocument = NULL; // ParentDocument is NULL - no colour list 00488 CurrentColourList = NULL; 00489 } 00490 00491 return(CurrentColourList); 00492 }
|
|
To obtain the ColourList of IndexedColours in the CurrentDocument.
Definition at line 517 of file colormgr.cpp. 00518 { 00519 Document *ParentDoc = Document::GetCurrent(); 00520 00521 if (ParentDoc != NULL) 00522 return(ParentDoc->GetIndexedColours()); 00523 00524 return(NULL); 00525 }
|
|
Determines the current line and fill colour attributes. These are the default ones, or if there is a selection, the attrs which are common to all selected objects. If there are many different attributes of the same type associated with the selection, NULL is returned. Notes: The ColourBar works exclusively on the SELECTED Doc. Change with care This function ensures that Current == Selected during its operation.
Definition at line 721 of file colormgr.cpp. 00723 { 00724 ENSURE(LineAttr != NULL && FillAttr != NULL, 00725 "ColourManager::GetCurrentLineAndFillAttrs - NULL pointers passed in!"); 00726 00727 *LineAttr = NULL; // Ensure safe exit if we fail 00728 *FillAttr = NULL; 00729 00730 // I don't think it is the colour bar's responsibility to check this, but 00731 // this is the only way that *I* can fix the problem of an ENSURE failure 00732 // on exit (we ask for info when no tools are current... I believe this is 00733 // because some slurphead has thrown away the tools BEFORE the document, 00734 // because the Document::GetSelected still does not return NULL in this case!) 00735 if (Tool::GetCurrent() == NULL) 00736 return(TRUE); 00737 00738 Document *SelectedDoc = Document::GetSelected(); 00739 if (SelectedDoc == NULL) 00740 return(TRUE); 00741 00742 // Save the current CurrentDoc, and set (CurrentDoc = SelectedDoc) 00743 Document *OldCurrentDoc = SetCurrentDoc(); 00744 00745 SelRange *Selection = Camelot.FindSelection(); 00746 ENSURE(Selection != NULL, "No Selection SelRange!?!"); 00747 00748 SelRange::CommonAttribResult result = 00749 Selection->FindCommonAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), 00750 (NodeAttribute **)LineAttr); 00751 if (result == SelRange::ATTR_MANY) 00752 *LineAttr = NULL; 00753 00754 result = Selection->FindCommonAttribute(CC_RUNTIME_CLASS(AttrFillGeometry), 00755 (NodeAttribute **)FillAttr); 00756 if (result == SelRange::ATTR_MANY) 00757 *FillAttr = NULL; 00758 00759 RestoreCurrentDoc(OldCurrentDoc); 00760 00761 return(result == SelRange::ATTR_NONE); 00762 }
|
|
Finds the current line and fill attributes, and dereferences them to find the current line and fill DocColours. These may be returned NULL if there are no current attributes (no document/many colours selected).
LineCol and/or FillCol may be passed in NULL if you are not interested in having these results returned to you. If EndGradFill is NULL and a grad fill is selected then FillColour will be filled in with the selected fill blob's colour (or NULL if there are zero or more than one selected blob). EndGradFill2 and EndGradFill3 will be filled in with NULL (if they are non NULL) If EndGradFill is non-NULL and a grad-fill is selected, instead of returning only the selected endpoint colour, it returns the start and end colours in FillCol (start) and EndGradFill (end). If the fill has more than two colours (ie GetEndColour2() != NULL) then both FillCol and EndGradFill will bet filled in with NULL (to indicate many). MULTIFILL: This system needs to be changed to support multistage fills.
Definition at line 814 of file colormgr.cpp. 00816 { 00817 if (LineCol != NULL) // Ensure return NULL if we fail 00818 *LineCol = NULL; 00819 00820 if (FillCol != NULL) 00821 *FillCol = NULL; 00822 00823 if (EndGradFill != NULL) 00824 *EndGradFill = NULL; 00825 00826 AttrStrokeColour *LineAttr = NULL; 00827 AttrFillGeometry *FillAttr = NULL; 00828 00829 BOOL result = GetCurrentLineAndFillAttrs(&LineAttr, &FillAttr); 00830 00831 if (LineAttr != NULL && LineCol != NULL) 00832 *LineCol = LineAttr->GetStartColour(); 00833 00834 if (FillAttr != NULL && FillCol != NULL) 00835 { 00836 // New bit added by will (3/11/94) to make colour bar show 00837 // the selected fill control point's colour. 00838 // Note this assumes there are only start and end colours, 00839 // and so will NOT work with multi-stage fills. 00840 00841 if (FillAttr->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrFlatColourFill)) 00842 { 00843 *FillCol = FillAttr->GetStartColour(); 00844 } 00845 else 00846 { 00847 if (EndGradFill == NULL) 00848 { 00849 // The caller wants the selected point's colour or NULL (already set) 00850 00851 if (FillAttr->GetSelectionCount() == 1) // If there is only 1 selected blob 00852 { 00853 // Get the colour of the selected blob 00854 00855 if (FillAttr->IsSelected(FILLCONTROL_STARTPOINT)) // Show Start Colour 00856 *FillCol = FillAttr->GetStartColour(); 00857 else if (FillAttr->IsSelected(FILLCONTROL_ENDPOINT)) // Show End Colour 00858 *FillCol = FillAttr->GetEndColour(); 00859 else if (FillAttr->IsSelected(FILLCONTROL_ENDPOINT2)) // Show End2 Colour 00860 *FillCol = FillAttr->GetEndColour2(); 00861 else if (FillAttr->IsSelected(FILLCONTROL_ENDPOINT3)) // Show End3 Colour 00862 *FillCol = FillAttr->GetEndColour3(); 00863 } 00864 } 00865 else 00866 { 00867 // User wants two colours 00868 00869 if (FillAttr->GetEndColour2() == NULL) // If the fill doesn't have a third colour 00870 { 00871 // We know FillCol is non-NULL 00872 *FillCol = FillAttr->GetStartColour(); 00873 00874 // We know EndGradFill is non-NULL 00875 *EndGradFill = FillAttr->GetEndColour(); 00876 } 00877 } 00878 } 00879 } 00880 00881 return(result); 00882 }
|
|
This 'deletes' colours by creating an undoable operation to hide them. It is assumed that the colours are not in use by the time you call this function - An ENSURE failure will occur if any are. After invoking the 'hide' operation, this function calls ColourListHasChanged.
Definition at line 2014 of file colormgr.cpp. 02016 { 02017 ERROR3IF(ColList == NULL || ColourArray == NULL, 02018 "ColourManager::HideColours cannot accept NULL parameters\n"); 02019 02020 HideColoursInfo HCInfo; 02021 02022 HCInfo.ParentList = ColList; 02023 HCInfo.Colours = ColourArray; 02024 HCInfo.ForceDelete = ForceDelete; 02025 HCInfo.HideThem = TRUE; 02026 02027 OpDescriptor* OpDesc = 02028 OpDescriptor::FindOpDescriptor( OPTOKEN_HIDECOLOURS ); 02029 02030 if (OpDesc != NULL) 02031 OpDesc->Invoke((OpParam *) &HCInfo); 02032 02033 return(TRUE); 02034 }
|
|
Initialises the entire colour system. This includes the colour manager, colour contexts, and colour dialogues, etc. Notes: Should only be called once ever. Called by Application::Init().
Reimplemented from SimpleCCObject. Definition at line 189 of file colormgr.cpp. 00190 { 00191 #if !defined(EXCLUDE_FROM_RALPH) 00192 // Init (register) all our operations 00193 #if !defined(EXCLUDE_FROM_XARALX) 00194 if (!::InitImagesettingOps()) 00195 return(FALSE); 00196 #endif 00197 00198 if (!OpHideColours::Init()) 00199 return(FALSE); 00200 00201 if (!OpColourChange::Init()) 00202 return(FALSE); 00203 00204 if (!OpRedrawColours::Init()) 00205 return(FALSE); 00206 00207 if (!OpMakeColourLocalToFrame::Init()) 00208 return(FALSE); 00209 #endif 00210 00211 // Init the global list of active colour contexts 00212 if (!ColourContextList::InitColourContexts()) 00213 return(FALSE); 00214 00215 return(TRUE); 00216 }
|
|
Process messages sent to the ColourManager Some messages (DocChanging) will cause new broadcasts indicating that the colour system has changed (new colour list has been paged in, etc).
Reimplemented from MessageHandler. Definition at line 303 of file colormgr.cpp. 00304 { 00305 if (MESSAGE_IS_A(Message, DocChangingMsg)) 00306 { 00307 DocChangingMsg *TheMsg = (DocChangingMsg *) Message; 00308 00309 switch ( TheMsg->State ) 00310 { 00311 case DocChangingMsg::SELCHANGED: 00312 if (TheMsg->pNewDoc == NULL) // No document selected any more 00313 { 00314 // Send PaletteChangingMsg - DESELECTED 00315 CurrentColourList = NULL; // No document present 00316 ScopeDocument = NULL; 00317 00318 BROADCAST_TO_ALL(ColourChangingMsg(ScopeDocument, CurrentColourList, NULL, 00319 ColourChangingMsg::LISTDESELECTED)); 00320 } 00321 else if (TheMsg->pOldDoc != TheMsg->pNewDoc) 00322 { 00323 // Send PaletteChangingMsg - PAGED 00324 CurrentColourList = NULL; // Cause re-caching of this info 00325 ScopeDocument = NULL; 00326 00327 GetColourList(TRUE); // Find the new colour list 00328 00329 BROADCAST_TO_ALL(ColourChangingMsg(ScopeDocument, CurrentColourList, NULL, 00330 ColourChangingMsg::LISTPAGED)); 00331 } 00332 break; 00333 00334 00335 case DocChangingMsg::ABOUTTODIE: 00336 // Pass this around as a ColourList killed message 00337 if (TheMsg->pChangingDoc != NULL) 00338 BROADCAST_TO_ALL(ColourChangingMsg(TheMsg->pChangingDoc, 00339 TheMsg->pChangingDoc->GetIndexedColours(), NULL, 00340 ColourChangingMsg::LISTDELETED)); 00341 00342 if (TheMsg->pChangingDoc == ScopeDocument) 00343 { 00344 // We can't keep a cached value around, as soon after this point the 00345 // colour list will cease to exist 00346 CurrentColourList = NULL; 00347 ScopeDocument = NULL; 00348 } 00349 break; 00350 default: 00351 break; 00352 } 00353 } 00354 else if (MESSAGE_IS_A(Message, ColourChangingMsg)) 00355 { 00356 ColourChangingMsg *TheMsg = (ColourChangingMsg *) Message; 00357 00358 switch ( TheMsg->State ) 00359 { 00360 case ColourChangingMsg::LISTUPDATED: 00361 // The list has changed- may involve a colour having been deleted. 00362 // We check if the attribute manager is using any colours which are 00363 // now deleted, and if so, set it to use safer ones! 00364 if (TheMsg->ScopeDoc == NULL || TheMsg->NewColourList == NULL) 00365 { 00366 ERROR3("ColChangingMsg::LISTUPDATED broadcast with NULL colour list"); 00367 } 00368 else 00369 TheMsg->ScopeDoc->GetAttributeMgr().UpdateForDeletedColours( 00370 TheMsg->NewColourList); 00371 break; 00372 00373 00374 case ColourChangingMsg::COLOURUPDATED: 00375 { 00376 // An IndexedColour has been edited. 00377 // We need to force an update on all colours Linked to this one, and 00378 // then redraw all DocViews on this document. 00379 00380 if (TheMsg->ScopeDoc != NULL && 00381 TheMsg->NewColourList != NULL && 00382 TheMsg->ChangedColour != NULL) 00383 { 00384 IndexedColour **AffectedColours = TheMsg->NewColourList-> 00385 CompileInheritanceArray(TheMsg->ChangedColour); 00386 00387 if (AffectedColours == NULL) 00388 { 00389 // Memory error means we can't get the array 00390 // Tell *all* linked colours in the list they may have changed 00391 List *TheList = TheMsg->NewColourList; 00392 00393 IndexedColour *Ptr = (IndexedColour *) (TheList->GetHead()); 00394 while (Ptr != NULL) 00395 { 00396 if (Ptr->FindLinkedParent() != NULL) // If is linked 00397 Ptr->LinkedAncestorHasChanged(); // Warn it of the change 00398 Ptr = (IndexedColour *) TheList->GetNext(Ptr); 00399 } 00400 00401 // And all unnamed colours too 00402 TheList = TheMsg->NewColourList->GetUnnamedColours(); 00403 00404 Ptr = (IndexedColour *) (TheList->GetHead()); 00405 while (Ptr != NULL) 00406 { 00407 if (Ptr->FindLinkedParent() != NULL) // If is linked 00408 Ptr->LinkedAncestorHasChanged(); // Warn it of the change 00409 Ptr = (IndexedColour *) TheList->GetNext(Ptr); 00410 } 00411 00412 // And force-redraw the entire document - all views 00413 CBitmapCache *pBC = Camelot.GetBitmapCache(); 00414 if( NULL != pBC ) 00415 pBC->DeInitialise(); // Brute force cache management! 00416 TheMsg->ScopeDoc->ForceRedraw(); 00417 } 00418 else 00419 { 00420 // Inform all the linked colours (except the first, which is the 00421 // actual colour which has changed) that they may have changed 00422 INT32 Index = 1; 00423 while (AffectedColours[Index] != NULL) 00424 { 00425 AffectedColours[Index]->LinkedAncestorHasChanged(); 00426 Index++; 00427 } 00428 00429 // And redraw all affected areas of the document 00430 ForceRedrawOfChangedColours(TheMsg->ScopeDoc, AffectedColours); 00431 } 00432 } 00433 } 00434 break; 00435 default: 00436 break; 00437 } 00438 } 00439 00440 return OK; 00441 }
|
|
To redraw all windows which depend upon the Selected View's colour context. i.e. The selected view, and also the colour editor, gallery, & line. (and maybe other windows in the future, e.g. object properties, grad fill editors, etc).
Notes: This should only be called when the selected view's RGB (screen) colour context is changed, which really shouldn't happen terribly often. Definition at line 616 of file colormgr.cpp. 00617 { 00618 View *SelView = DocView::GetSelected(); 00619 00620 if (SelView != NULL && SelView->IsKindOf(CC_RUNTIME_CLASS(DocView))) 00621 { 00622 CBitmapCache* pBC = Camelot.GetBitmapCache(); 00623 if( NULL != pBC ) 00624 pBC->DeInitialise(); // Brute force cache management 00625 00626 ((DocView *)SelView)->ForceRedraw(); 00627 } 00628 00629 BROADCAST_TO_ALL(ColourChangingMsg(NULL, NULL, NULL, 00630 ColourChangingMsg::SELVIEWCONTEXTCHANGE)); 00631 }
|
|
This un-'deletes' colours by creating an undoable operation to unhide them. This is used when creating a new colour to 'unhide' it (which has no immediate effect on the colour) - this creates an undo record that will hide the colour if the 'new' is undone.
Definition at line 2063 of file colormgr.cpp. 02064 { 02065 ERROR3IF(ColList == NULL || ColourArray == NULL, 02066 "ColourManager::UnHideColours cannot accept NULL parameters\n"); 02067 02068 HideColoursInfo HCInfo; 02069 02070 HCInfo.ParentList = ColList; 02071 HCInfo.Colours = ColourArray; 02072 HCInfo.ForceDelete = FALSE; 02073 HCInfo.HideThem = FALSE; 02074 02075 OpDescriptor* OpDesc = 02076 OpDescriptor::FindOpDescriptor( OPTOKEN_SHOWCOLOURS ); 02077 02078 if (OpDesc != NULL) 02079 OpDesc->Invoke((OpParam *) &HCInfo); 02080 02081 return(TRUE); 02082 }
|
|
Definition at line 264 of file colormgr.h. |
|
Definition at line 265 of file colormgr.h. |