00001 // $Id: sgbrush.cpp 1732 2006-09-03 14:08:16Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // Line Gallery interface for Brush Attributes - implementation 00100 00101 #include "camtypes.h" 00102 #include "sgbrush.h" 00103 #include "sgline.h" 00104 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 #include "brshcomp.h" 00106 #include "qualattr.h" 00107 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "paths.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "dlgcol.h" 00110 #include "lineattr.h" 00111 #include "ppbrush.h" 00112 //#include "msg.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "brushmsg.h" 00114 #include "ndoptmz.h" 00115 //#include "rik.h" 00116 00117 CC_IMPLEMENT_DYNAMIC(BrushAttrItem, LineAttrItem); 00118 00119 #define new CAM_DEBUG_NEW 00120 00121 /******************************************************************************************** 00122 00123 > BrushAttrItem::BrushAttrItem(BrushAttrAttrValue *pBrush, const String &strDescription) 00124 00125 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00126 Created: 3/3/97 00127 Inputs: pBrush - a pointer to an attribute to be used for this 00128 brush item. This now belongs to the BrushAttrItem, 00129 so you must not delete it 00130 strDescription - a text description of this user-interface item 00131 Outputs: - 00132 Returns: - 00133 Purpose: Constructs a user-interface item representing a stroke type 00134 00135 ********************************************************************************************/ 00136 00137 BrushAttrItem::BrushAttrItem(BrushAttrValue *pBrush, const String &strDescription) 00138 : LineAttrItem(strDescription, BELOW) 00139 { 00140 ERROR3IF(pBrush == NULL, "Illegal NULL param"); 00141 m_pBrushAttrVal = pBrush; 00142 } 00143 00144 00145 00146 /******************************************************************************************** 00147 00148 > BrushAttrItem::~BrushAttrItem() 00149 00150 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00151 Created: 3/3/97 00152 00153 Purpose: Destructor 00154 00155 ********************************************************************************************/ 00156 00157 BrushAttrItem::~BrushAttrItem() 00158 { 00159 if (m_pBrushAttrVal != NULL) 00160 { 00161 m_pBrushAttrVal->FlushCache(); 00162 m_pBrushAttrVal->SetPathProcessor(NULL); 00163 delete m_pBrushAttrVal; 00164 } 00165 } 00166 00167 00168 /******************************************************************************************** 00169 00170 > virtual void BrushAttrItem::SetAttributes(RenderRegion* pRegion) const 00171 00172 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00173 Created: 3/3/97 00174 00175 Inputs: pRegion - the render-region to draw into 00176 00177 Purpose: Sets the brush attributes in the given render-region to render this 00178 item correctly. 00179 00180 ********************************************************************************************/ 00181 00182 void BrushAttrItem::SetAttributes(RenderRegion* pRegion) const 00183 { 00184 // code has been moved into DrawItem, as we need to know the bounding box 00185 // before we can make the scaling adjustment 00186 00187 00188 // Set a line width 00189 //pRegion->SetLineWidth(1000); 00190 00191 // Set the line width (this overrides the "default" line width set by the caller). 00192 //m_pBrushAttrVal->Render(pRegion, FALSE); 00193 } 00194 00195 00196 00197 /******************************************************************************************** 00198 00199 > virtual NodeAttribute *BrushAttrItem::CreateNewAttribute(BOOL) const 00200 00201 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00202 Created: 3/3/97 00203 00204 Returns: A pointer to a NodeAttribute-derivative that this user-interface item 00205 represents, ie. a line-width attribute that can be passed to the 00206 attribute manager. 00207 00208 Purpose: Create a NodeAttribute representing the attribute this item applies 00209 00210 ********************************************************************************************/ 00211 00212 NodeAttribute *BrushAttrItem::CreateNewAttribute(BOOL) const 00213 { 00214 // because we may have changed some of the attribute data to render the brush objects 00215 // in the line gallery we really want to make sure the new path processor takes all 00216 // its data from the original brush definition. 00217 // This is a bit long winded but safer than just taking the local data 00218 AttrBrushType* pAttrBrushType = (AttrBrushType*)m_pBrushAttrVal->MakeNode(); 00219 if (pAttrBrushType == NULL) 00220 { 00221 ERROR3("Failed to make node"); 00222 return NULL; 00223 } 00224 BrushAttrValue* pNewBrushAttrVal = (BrushAttrValue*)pAttrBrushType->GetAttributeValue(); 00225 if (pNewBrushAttrVal == NULL) 00226 { 00227 ERROR3("No BrushAttrVal"); 00228 return NULL; 00229 } 00230 00231 // now get the brush definition 00232 BrushDefinition* pBrush = m_pBrushAttrVal->GetBrushDefinition(); 00233 if (pBrush == NULL) 00234 { 00235 // not an error 00236 return pAttrBrushType; 00237 } 00238 00239 PathProcessorBrush* pPathProc = pNewBrushAttrVal->GetPathProcessor(); 00240 if (pPathProc == NULL) 00241 { 00242 // not actually an error, as this could be a default 'normal line' brush 00243 return pAttrBrushType; 00244 } 00245 00246 00247 // copy the data to the new processor 00248 pBrush->CopyDataToProcessor(pPathProc); 00249 00250 // tell the processor which attribute value it belongs to 00251 pPathProc->SetParentAttribute(pAttrBrushType); 00252 00253 00254 return pAttrBrushType; 00255 } 00256 00257 00258 /******************************************************************************************** 00259 00260 > virtual BOOL BrushAttrItem::IsEqualValueToAny(NodeAttribute** ppOtherAttribs) const 00261 00262 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00263 Created: 7/1/2000 00264 Inputs: pOtherAttrib - the attribute value to compare this item to 00265 Outputs: - 00266 Returns: TRUE if this item represents the same attribute value as the given 00267 attribute. 00268 Purpose: Used when searching for display items representing the selection's current 00269 attributes. 00270 00271 ********************************************************************************************/ 00272 00273 BOOL BrushAttrItem::IsEqualValueToAny(NodeAttribute** ppOtherAttribs) const 00274 { 00275 if (*ppOtherAttribs == NULL) // When multiple attribs are selected, this will be NULL 00276 return(FALSE); 00277 00278 AttrBrushType* pAttr = (AttrBrushType *) *ppOtherAttribs; 00279 ERROR3IF(!pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrBrushType)), 00280 "BrushAttrItem::IsEqualValueToAny - unexpected object type"); 00281 00282 if (pAttr != NULL) 00283 { 00284 BrushAttrValue *pOther = (BrushAttrValue *) pAttr->GetAttributeValue(); 00285 //return((*m_pBrushAttrVal) == (*pOther)); 00286 00287 // to simplify - just check to see if they have the same brush handle 00288 BrushHandle Other = pOther->GetBrushHandle(); 00289 BrushHandle This = m_pBrushAttrVal->GetBrushHandle(); 00290 return (Other == This); 00291 } 00292 00293 return(FALSE); 00294 } 00295 00296 00297 /******************************************************************************************** 00298 00299 > virtual BrushDefinition *BrushTypeItem::GetBrushDefinition() 00300 00301 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00302 Created: 7/1/2000 00303 00304 Returns: The BrushDefinition for this item 00305 Purpose: Get the BrushDefinition for this item 00306 00307 ********************************************************************************************/ 00308 00309 BrushDefinition *BrushAttrItem::GetBrushDefinition() 00310 { 00311 BrushHandle Handle = GetBrushHandle(); 00312 if(Handle != BrushHandle(-1)) 00313 { 00314 // get the brush component 00315 Document* pDoc = Document::GetCurrent(); 00316 ERROR2IF(pDoc == NULL, NULL, "Wheres the document?"); 00317 BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent)); 00318 ERROR2IF(pBrushComp == NULL, NULL, "No brush component"); 00319 return pBrushComp->FindBrushDefinition(Handle); 00320 } 00321 00322 return NULL; 00323 } 00324 00325 /******************************************************************************************** 00326 00327 > virtual BrushHandle BrushTypeItem::GetBrushHandle() 00328 00329 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00330 Created: 7/1/2000 00331 00332 Returns: The BrushHandle for this item, or BrushHandle_NoBrush if strife 00333 Purpose: Get the BrushHandle for this item 00334 00335 ********************************************************************************************/ 00336 00337 BrushHandle BrushAttrItem::GetBrushHandle() 00338 { 00339 BrushAttrValue *pAttrValue = GetBrushAttrValue(); 00340 if(pAttrValue != NULL) 00341 { 00342 PathProcessorBrush *pProcessor = pAttrValue->GetPathProcessor(); 00343 if (pProcessor != NULL && pProcessor->IsKindOf(CC_RUNTIME_CLASS(PathProcessorBrush))) 00344 { 00345 BrushHandle Handle = ((PathProcessorBrush *)pProcessor)->GetBrushDefinitionHandle(); 00346 return Handle; 00347 } 00348 } 00349 00350 return BrushHandle_NoBrush; 00351 } 00352 00353 00354 /******************************************************************************************** 00355 00356 > virtual void BrushAttrItem::RenderItem(RenderRegion *pRender, DocRect *pDocRect) 00357 00358 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00359 Created: 9/1/2000 00360 00361 Inputs: pRender - RenderRegion to render into 00362 pDocRect - Rectangle to render 00363 00364 Purpose: Renders a representation of the stroke into the given renderregion. This 00365 is used by the line properties dialog since all the stuff needed seems to 00366 be private... 00367 00368 ********************************************************************************************/ 00369 00370 void BrushAttrItem::RenderItem(RenderRegion *pRender, DocRect *pDocRect, INT32 Width) 00371 { 00372 if(pRender == NULL || pDocRect == NULL) 00373 { 00374 ERROR3("BrushAttrItem::RenderItem given null params"); 00375 return; 00376 } 00377 00378 pRender->SaveContext(); 00379 00380 // Make sure we're anti-aliasing 00381 Quality AntiAliasQuality(Quality::QualityMax); 00382 QualityAttribute AntiAliasQualityAttr(AntiAliasQuality); 00383 pRender->SetQuality(&AntiAliasQualityAttr,FALSE); 00384 00385 // Render the background rectangle 00386 DialogColourInfo RedrawColours; 00387 pRender->SetLineColour(RedrawColours.DialogBack()); 00388 pRender->SetFillColour(RedrawColours.DialogBack()); 00389 pRender->DrawRect(pDocRect); 00390 00391 // Draw the Saturation vs. Value square 00392 Path SquarePath; 00393 LinearFillAttribute ValueGradFill; 00394 LinearTranspFillAttribute TransFill; 00395 00396 ValueGradFill.Colour = DocColour(255L, 0L, 0L); 00397 ValueGradFill.EndColour = DocColour(255L, 255L, 255L); 00398 00399 DocCoord ThePoint(pDocRect->lo.x, pDocRect->hi.y); 00400 ValueGradFill.SetStartPoint(&ThePoint); 00401 ThePoint = DocCoord(pDocRect->hi.x, pDocRect->hi.y); 00402 ValueGradFill.SetEndPoint(&ThePoint); 00403 ValueGradFill.SetEndPoint2(NULL); 00404 00405 pRender->SetFillGeometry(&ValueGradFill, FALSE); // Set Grad-filled 00406 00407 00408 pRender->SetLineColour(RedrawColours.TextFore()); 00409 00410 SetAttributes(pRender); 00411 pRender->SetLineWidth((INT32)((double)Width * 0.8)); 00412 DrawItem(pRender, *pDocRect); 00413 00414 pRender->RestoreContext(); 00415 } 00416 00417 00418 00419 /******************************************************************************************** 00420 00421 > virtual void BrushAttrItem::UpdateGalleryItem() 00422 00423 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00424 Created: 9/1/2000 00425 00426 Purpose: Updates the gallery item's cached data to represent any changes this 00427 Stoke might have had done to it. Also redraw the gallery if necessary. 00428 00429 ********************************************************************************************/ 00430 00431 void BrushAttrItem::UpdateGalleryItem() 00432 { 00433 BrushDefinition *pBrush = GetBrushDefinition(); 00434 if(pBrush != NULL) 00435 { 00436 // first try and allocate a new PPB 00437 PathProcessorBrush* pNewPPB = new PathProcessorBrush; 00438 if (pNewPPB == NULL) 00439 return; 00440 // give it the latest data 00441 pBrush->CopyDataToProcessor(pNewPPB); 00442 00443 // tell it what handle to use 00444 pNewPPB->SetBrushDefinition(m_pBrushAttrVal->GetBrushHandle()); 00445 //ask our attr to delete its path processor 00446 m_pBrushAttrVal->SetPathProcessor(pNewPPB); 00447 00448 // set the new name 00449 SetDescription(pBrush->GetLineName()); 00450 } 00451 00452 ForceRedrawOfMyself(); 00453 } 00454 00455 /******************************************************************************************** 00456 00457 > virtual CCRuntimeClass** BrushAttrItem::GetAttribRuntimeClasses() const 00458 00459 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00460 Created: 3/3/97 00461 Inputs: - 00462 Outputs: - 00463 Returns: The run-time class of the line attribute this type of display item 00464 represents. 00465 Purpose: Used when searching for display items representing the selection's current 00466 attributes. 00467 00468 ********************************************************************************************/ 00469 00470 CCRuntimeClass** BrushAttrItem::GetAttribRuntimeClasses() const 00471 { 00472 static CCRuntimeClass* aprtc[] = 00473 { 00474 CC_RUNTIME_CLASS(AttrBrushType), 00475 NULL 00476 }; 00477 00478 return aprtc; 00479 } 00480 00481 00482 00483 /******************************************************************************************** 00484 > virtual void BrushAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const 00485 00486 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00487 Created: 10/1/2000 00488 Inputs: pRegion pointer to the RenderRegion to draw into 00489 drBounds reference to the bounding box rectangle to draw within 00490 Outputs: - 00491 Returns: - 00492 Purpose: Draws this item within the bounding box. The aim is to work out what scaling we 00493 need in order to fit the brush into the FormatRect. Therefore we draw a line 00494 through the bounding box, get its bounding box with the brush applied and work out 00495 the scaling that will fit this into the formatrect. 00496 Errors: - 00497 SeeAlso: LineAttrItem::Render 00498 ********************************************************************************************/ 00499 00500 void BrushAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const 00501 { 00502 if (m_pBrushAttrVal == NULL) 00503 { 00504 ERROR3("Wheres the AttrVal gone?"); 00505 return; 00506 } 00507 00508 // Calculate the mid-point of the vertical sides of the bounding box. 00509 INT32 yMid = ((drBounds.lo.y + drBounds.hi.y) / 2) - (drBounds.Height() / 3); 00510 00511 // Draw a line at this height from the left to the right edge. 00512 Path pthLinePath; 00513 if (pthLinePath.Initialise()) 00514 { 00515 pthLinePath.InsertMoveTo(DocCoord(drBounds.lo.x, yMid)); 00516 pthLinePath.InsertLineTo(DocCoord(drBounds.hi.x, yMid)); 00517 pthLinePath.IsFilled = FALSE; 00518 pthLinePath.IsStroked = TRUE; 00519 00520 // Get the brush definition and the local path processor 00521 BrushDefinition* pBrushDef = m_pBrushAttrVal->GetBrushDefinition(); 00522 if (pBrushDef != NULL) 00523 { 00524 PathProcessorBrush* pPathProc = m_pBrushAttrVal->GetPathProcessor(); 00525 if (pPathProc == NULL) 00526 { 00527 ERROR3("No brush definition"); 00528 return; 00529 } 00530 MILLIPOINT LineWidth = 18000; 00531 00532 pPathProc->ScaleToValue(LineWidth); 00533 pRegion->SetLineWidth(LineWidth); 00534 00535 // render the attribute, i.e. push the path processor 00536 m_pBrushAttrVal->Render(pRegion, FALSE); 00537 // draw the line 00538 pRegion->DrawPath(&pthLinePath); 00539 } 00540 else // no actual brush - just draw the line 00541 pRegion->DrawPath(&pthLinePath); 00542 } 00543 else 00544 ERROR3("Failed to initialise path"); 00545 00546 } 00547 00548 00549 /******************************************************************************************** 00550 00551 > virtual void BrushAttrItem::ItemSelected() 00552 00553 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00554 Created: 9/1/2000 00555 Inputs; pNewAttr - the attribute node created from this BrushAttrItem 00556 Outputs: - 00557 Returns: FALSE, if all went well and we applied the attributes here ok 00558 Purpose: Sets the default line width to be that of the brush, or the previous line 00559 width if the brush doesn't have one. Also broadcasts a message saying that 00560 it has been selected, for the benefit of the freehand tool. 00561 ********************************************************************************************/ 00562 00563 BOOL BrushAttrItem::ItemSelected(NodeAttribute* pAttrBrush) 00564 { 00565 if (m_pBrushAttrVal == NULL) 00566 { 00567 ERROR3("BrushAttrValue is NULL"); 00568 return TRUE; 00569 } 00570 00571 // if we are setting a 'no brush' brush we must restore its line width to the last 00572 // line width set that had 'no brush' 00573 BOOL bSettingNoBrush = (m_pBrushAttrVal->GetBrushHandle() == BrushHandle_NoBrush); 00574 00575 // if there is something in the selection then we do not want to change 00576 // the line width, as they may be different. the only exception to this is 00577 // if we are setting the default 'no brush' 00578 SelRange* pSel = GetApplication()->FindSelection(); 00579 if (pSel == NULL) 00580 return TRUE; 00581 if (pSel->FindFirst() != NULL) 00582 { 00583 if (!bSettingNoBrush) 00584 return TRUE; 00585 } 00586 00587 MILLIPOINT OldLineWidth = 500; // initialise to default 00588 00589 // first make sure the line gallery has its previous line width member set 00590 LineGallery* pLineGal = LineGallery::GetInstance(); 00591 if (pLineGal == NULL) 00592 return TRUE; 00593 else 00594 { 00595 // get the last line width in case we need it 00596 OldLineWidth = pLineGal->GetPreviousLineWidth(); 00597 00598 // if we are going from a 'no brush' to a brush then we need to store the line 00599 // width of the 'no brush' 00600 if ((GetCurrentDefaultBrushHandle() == BrushHandle_NoBrush) && (!bSettingNoBrush)) 00601 pLineGal->SetPreviousLineWidth(); 00602 } 00603 00604 // get the line width from the attribute 00605 MILLIPOINT LineWidth = m_pBrushAttrVal->GetDefaultLineWidth(TRUE); 00606 00607 // if we receive < 0 from GetDefaultLineWidth it means that we have no 00608 // ink objects associated with this brush. In this instance it means we 00609 // are probably selecting the 'simple line' brush and should set the old line 00610 // width 00611 if (LineWidth <= 0) 00612 { 00613 if (OldLineWidth < 0) 00614 { 00615 ERROR3("negative line width"); 00616 return TRUE; 00617 } 00618 else 00619 LineWidth = OldLineWidth; 00620 } 00621 00622 // quick hack until the problems in attrmgr.cpp with applying non-text attributes in the 00623 // text tool are sorted out 00624 if (Tool::GetCurrentID() == TOOLID_TEXT) 00625 return FALSE; 00626 00627 // make a new line width node 00628 NodeAttribute* pNewAttr = new AttrLineWidth; 00629 if (pNewAttr == NULL) 00630 { 00631 ERROR3("Failed to allocate new line width"); 00632 return TRUE; 00633 } 00634 ((AttrLineWidth*)pNewAttr)->Value.LineWidth = LineWidth; 00635 00636 // in order to apply the attributes together we need to make a list 00637 List AttribsList; 00638 NodeAttributePtrItem* pBrushAttrPtr = new NodeAttributePtrItem; 00639 if (pBrushAttrPtr == NULL) 00640 { 00641 delete pNewAttr; 00642 return TRUE; 00643 } 00644 pBrushAttrPtr->NodeAttribPtr = pAttrBrush; 00645 00646 AttribsList.AddHead(pBrushAttrPtr); 00647 00648 NodeAttributePtrItem* pLineWidthPtr = new NodeAttributePtrItem; 00649 if (pLineWidthPtr == NULL) 00650 { 00651 pBrushAttrPtr->NodeAttribPtr = NULL; 00652 return TRUE; 00653 } 00654 pLineWidthPtr->NodeAttribPtr = pNewAttr; 00655 00656 AttribsList.AddHead(pLineWidthPtr); 00657 00658 AttributeManager::AttributesSelected(AttribsList, _R(IDS_APPLYBRUSH_UNDO)); 00659 00660 00661 // We don't need the list of attrs anymore 00662 NodeAttributePtrItem* pAttrItem = (NodeAttributePtrItem*)AttribsList.GetHead(); 00663 while (pAttrItem) 00664 { 00665 delete (pAttrItem->NodeAttribPtr); 00666 pAttrItem->NodeAttribPtr = NULL; 00667 pAttrItem = (NodeAttributePtrItem*)AttribsList.GetNext(pAttrItem); 00668 } 00669 AttribsList.DeleteAll(); // tidyup 00670 00671 BrushHandle NewHandle = GetBrushHandle(); 00672 BROADCAST_TO_ALL(BrushMsg(NewHandle)); 00673 return FALSE; 00674 } 00675 //AttributeManager::AttributeSelected(pNewAttr); 00676 /* 00677 // turn off the warning if it isn't already 00678 BOOL ResetAttrMgrFlag = AttributeManager::AskBeforeSettingCurrentAttr; 00679 if (ResetAttrMgrFlag) 00680 AttributeManager::AskBeforeSettingCurrentAttr = FALSE; 00681 00682 00683 00684 // turn it back on if we need to 00685 if (ResetAttrMgrFlag) 00686 AttributeManager::AskBeforeSettingCurrentAttr = TRUE; 00687 */ 00688 // tell the world we have changed brushes 00689 00690 00691 00692 00693 00694 00695 /******************************************************************************************** 00696 00697 > void BrushAttrItem::GetCurrentDefaultBrushHandle() 00698 00699 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00700 Created: 10/10/99 00701 Returns: the handle of the current defalt brush attribute 00702 Purpose: as above 00703 00704 ********************************************************************************************/ 00705 00706 BrushHandle BrushAttrItem::GetCurrentDefaultBrushHandle() 00707 { 00708 Document* pDoc = Document::GetCurrent(); 00709 if (pDoc == NULL) 00710 { 00711 ERROR3("No document"); 00712 return BrushHandle_NoBrush; 00713 } 00714 00715 AttributeManager* pAttrMgr = &(pDoc->GetAttributeMgr()); 00716 if (pAttrMgr == NULL) 00717 { 00718 ERROR3("No attribute manager"); 00719 return BrushHandle_NoBrush; 00720 } 00721 00722 AttrBrushType* pAttr = (AttrBrushType*)(pAttrMgr->GetCurrentAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), CC_RUNTIME_CLASS(AttrBrushType))); 00723 00724 if (pAttr == NULL) 00725 { 00726 ERROR3("No current brush attribute"); 00727 return BrushHandle_NoBrush; 00728 } 00729 return pAttr->GetBrushHandle(); 00730 00731 }