00001 // $Id: sgline.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 // sgline.cpp - Line SuperGallery classes - LineGallery and the LineAttrItem base class. 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" // global types 00104 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 00106 //#include "range.h" // selection & attributes - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "qualattr.h" 00108 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 00110 #include "ccdc.h" // render-into-dialogue support 00111 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "grnddib.h" 00113 00114 //#include "galres.h" // super-gallery support 00115 //#include "galstr.h" 00116 #include "sginit.h" 00117 #include "sgline.h" 00118 #include "sgline2.h" 00119 #include "sgmenu.h" 00120 #include "sglinepr.h" 00121 00122 #include "sgldrag.h" // dragging support 00123 #include "dragmgr.h" 00124 00125 #include "lattrops.h" // gadgets and resources 00126 //#include "justin.h" 00127 //#include "mario.h" // for _R(IDE_NOMORE_MEMORY) 00128 //#include "richard2.h" // for yet more strings 00129 00130 #ifdef VECTOR_STROKING 00131 #include "sgstroke.h" // Stroke attribute items 00132 #include "strkattr.h" // Stroke attributes 00133 #include "ppstroke.h" // PathProcessorStroke 00134 #include "ppairbsh.h" // PathProcessorStrokeAirbrush 00135 #include "ppvecstr.h" // PathProcessorStrokeVector 00136 #include "valfunc.h" // ValueFunctions 00137 #endif 00138 00139 #include "helpuser.h" 00140 //#include "xshelpid.h" 00141 //#include "helppath.h" 00142 00143 #include "brshcomp.h" // for the new style brushes 00144 #include "ppbrush.h" 00145 #include "brshattr.h" 00146 #include "sgbrush.h" 00147 #include "lineattr.h" 00148 //#include "rik.h" 00149 #include "brushmsg.h" 00150 #include "brshname.h" 00151 //#include "resdll.h" 00152 #include "fileutil.h" 00153 #include "brushop.h" 00154 00155 //#include "freehres.h" //_R(IDS_FEATURENOTIMPLEMENTED) 00156 //#include "resource.h" //_R(IDS_OK) 00157 00158 //#include "linegal.h" 00159 00160 // Version control. 00161 DECLARE_SOURCE("$Revision: 1282 $"); 00162 00163 // Implement the dynamic class bits... 00164 CC_IMPLEMENT_DYNCREATE(LineGallery, SuperGallery) 00165 CC_IMPLEMENT_DYNAMIC(LineAttrItem, SGDisplayItem) 00166 CC_IMPLEMENT_DYNCREATE(OpDisplayLineGallery, Operation); 00167 00168 // This line mustn't go before any CC_IMPLEMENT_... macros 00169 #define new CAM_DEBUG_NEW 00170 00171 00172 // This always points to the line gallery, or NULL if it doesn't exist. 00173 LineGallery* LineGallery::m_pTheGallery = NULL; 00174 00175 // These are the default scaling factors for the four stock sizes of arrowheads. 00176 double LineGallery::m_anArrowScales[4] = { 3.0, 8.0, 13.0, 18.0 }; 00177 00178 // initialise the array that holds the filenames of the default brush files 00179 String_256* LineGallery::m_pFileNameArray = NULL; 00180 UINT32 LineGallery::m_NumDefaultFiles = 0; 00181 00182 /******************************************************************************************** 00183 > LineAttrItem::LineAttrItem(const String& strDescription, 00184 LineAttritem::TextPosition eTextPos) 00185 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00186 Created: 27/3/95 00187 Inputs: strDescription text description of this item, eg "0.5 pt" 00188 eTextPos the default position for this item's text 00189 description 00190 Outputs: - 00191 Returns: - 00192 Purpose: Default constructor for a LineAttrItem. 00193 Errors: - 00194 SeeAlso: SGDisplayItem::SGDisplayItem 00195 ********************************************************************************************/ 00196 00197 LineAttrItem::LineAttrItem(const String& strDescription, LineAttrItem::TextPosition eTextPos) 00198 : m_strDescription(strDescription), 00199 m_eDefaultTextPosition(eTextPos), 00200 m_fIsCurrentAttrib(FALSE) 00201 { 00202 // Empty. 00203 } 00204 00205 00206 00207 /******************************************************************************************** 00208 > static BOOL LineAttrItem::UpdateCurrentAttribStatus() 00209 00210 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00211 Created: 17/4/95 00212 Inputs: - 00213 Outputs: - 00214 Returns: TRUE if no problems encountered, eg. out of memory. 00215 Purpose: Updates the "current attribute" status flag of every LineAttrItem 00216 within the line gallery, setting it to whether each item represents an 00217 attribute value applying to the current selection. 00218 Errors: Out of memory. 00219 SeeAlso: LineAttrItem::GetRuntimeClass; LineAttrItem::IsEqualValue 00220 ********************************************************************************************/ 00221 00222 BOOL LineAttrItem::UpdateCurrentAttribStatus() 00223 { 00224 // If the line gallery isn't running then we don't bother. 00225 if (!LineGallery::IsActive()) return TRUE; 00226 00227 // For each group in the line gallery, try to match the current attribute of the 00228 // selection with the group's items. 00229 SGDisplayRoot* pRoot = LineGallery::GetInstance()->GetDisplayTree(); 00230 if (pRoot == NULL) return FALSE; 00231 00232 for (LineAttrGroup* pGroup = (LineAttrGroup*) pRoot->GetChild(); 00233 pGroup != NULL; 00234 pGroup = (LineAttrGroup*) pGroup->GetNext()) 00235 { 00236 // Get a pointer to the first item within the group, if any. 00237 LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild(); 00238 if (pItem == NULL) continue; 00239 00240 // Get a pointer to the null-terminated array of pointers to run-time classes that 00241 // this type of item can represent. 00242 CCRuntimeClass** ppAttribClasses = pItem->GetAttribRuntimeClasses(); 00243 ERROR3IF(ppAttribClasses == NULL, 00244 "No attribute run-time classes in LineAttrItem::UpdateCurrentAttribStatus"); 00245 00246 // Count how many types of classes the item represents. Note the null statement. 00247 CCRuntimeClass** pprtc; 00248 for (pprtc = ppAttribClasses; *pprtc != NULL; pprtc++); 00249 INT32 nAttribClasses = pprtc - ppAttribClasses; 00250 00251 // Allocate an array of NodeAttribute pointers for each run-time class. 00252 typedef NodeAttribute* PATTRIBUTE; 00253 NodeAttribute** ppCommonAttribs = new PATTRIBUTE[nAttribClasses]; 00254 ERRORIF(ppCommonAttribs == NULL, _R(IDE_NOMORE_MEMORY), FALSE); 00255 00256 // For each run-time class that appears in *ppAttribClasses, try to find an 00257 // attribute of the same class that currently applies to the selection. 00258 for (INT32 i = 0; i < nAttribClasses; i++) 00259 { 00260 NodeAttribute* pattr = NULL; // sjk 00261 SelRange::CommonAttribResult eResult; 00262 00263 eResult = GetApplication()-> 00264 FindSelection()-> 00265 FindCommonAttribute(ppAttribClasses[i], &pattr); 00266 00267 // See if we found either a common attribute or the "default attribute". 00268 if (pattr != NULL) 00269 { 00270 // Check for nothing really brain-damaged happening. 00271 ERROR3IF(pattr->GetRuntimeClass() != ppAttribClasses[i], 00272 "Wrong kind of attribute in LineAttrItem::" 00273 "UpdateCurrentAttribStatus"); 00274 00275 // There is just one attribute applying, and we got it. 00276 ppCommonAttribs[i] = pattr; 00277 } 00278 else 00279 { 00280 // There are either many or none applying, so we aren't interested. 00281 ppCommonAttribs[i] = NULL; 00282 } 00283 } 00284 00285 // OK, so now we have an array of all the attributes this type of item is 00286 // interested in. Ask each item within the group to compare itself against 00287 // each attribute we have found, to see if it represents it or not. 00288 for (; pItem != NULL; pItem = (LineAttrItem*) pItem->GetNext()) 00289 { 00290 BOOL fOldState = pItem->m_fIsCurrentAttrib; 00291 pItem->m_fIsCurrentAttrib = pItem->IsEqualValueToAny(ppCommonAttribs); 00292 if (pItem->m_fIsCurrentAttrib != fOldState) pItem->ForceRedrawOfMyself(); 00293 } 00294 00295 // All done, we are finished with these kinds of attributes. 00296 delete[] ppCommonAttribs; 00297 } 00298 00299 // Everything went OK. 00300 return TRUE; 00301 } 00302 00303 00304 00305 /*********************************************************************************************** 00306 > virtual void LineAttrItem::CalculateMyRect(SGFormatInfo* pFormatInfo, 00307 SGMiscInfo* pMiscInfo) 00308 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00309 Created: 15/2/95 (base generated in sgbase.cpp) 00310 Inputs: pFormatInfo - The formatting info from which to calculate my position/size 00311 pMiscInfo - As usual, the useful misc info struct 00312 Outputs: member variable FormatRect - is returned filled in with the size/position of 00313 this LineAttrItem item's display area. This is dependent upon the current display 00314 mode and format state. 00315 FormatInfo will be updated as a result of the formatting operation 00316 Purpose: Shared code for LineAttrItem items to calculate where they will appear in the 00317 grand scheme of things 00318 Notes: LineAttrItems supply only one display mode ("full info") 00319 Scope: private (for use of LineAttrItem class only) 00320 ***********************************************************************************************/ 00321 00322 void LineAttrItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo) 00323 { 00324 // Find out the extent of this item, including a gap for formatting. 00325 MILLIPOINT xSize, ySize; 00326 GetSize(m_eDefaultTextPosition, &xSize, &ySize); 00327 if (xSize != SG_InfiniteWidth) 00328 xSize += GetHorzGap(); 00329 00330 ySize += GetVertGap(); 00331 00332 // Let the base class do what it needs to do with this. 00333 CalculateFormatRect(pFormatInfo, pMiscInfo, xSize, ySize); 00334 } 00335 00336 00337 00338 /******************************************************************************************** 00339 > void LineAttrItem::GetSize(LineAttrItem::TextPosition eTextPos, 00340 MILLIPOINT* pxSize, 00341 MILLIPOINT* pySize) const 00342 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00343 Created: 19/4/95 00344 Inputs: eTextPos where this item's text description should go 00345 Outputs: pxSize where to store the width of the item 00346 pySize where to store the height of the item 00347 Returns: - 00348 Purpose: Used to calculate how large this item is, in millipoints. 00349 Errors: - 00350 SeeAlso: LineAttrItem::CalculateMyRect 00351 ********************************************************************************************/ 00352 00353 void LineAttrItem::GetSize(LineAttrItem::TextPosition eTextPos, 00354 MILLIPOINT* pxSize, 00355 MILLIPOINT* pySize) const 00356 { 00357 // Make sure we can put the results somewhere. 00358 ERROR3IF(pxSize == NULL || pySize == NULL, "Null* passed in LineAttrItem::GetSize"); 00359 00360 // Get the basic size and add in a possible text size as well. 00361 *pxSize = GetWidth(); 00362 *pySize = GetHeight(); 00363 switch (eTextPos) 00364 { 00365 case LEFT: 00366 if (*pxSize != SG_InfiniteWidth) 00367 { 00368 *pxSize += (c_nHorzSizeOfText + c_nHorzGapAfterText); 00369 } 00370 break; 00371 00372 case BELOW: 00373 *pySize += (c_nVertSizeOfText + c_nVertGapAboveText); 00374 break; 00375 00376 case NO_LABEL: 00377 break; 00378 00379 default: 00380 ERROR3("Unexpected case in LineAttrItem::GetSize"); 00381 break; 00382 } 00383 } 00384 00385 00386 00387 /*********************************************************************************************** 00388 > virtual void LineAttrItem::HandleRedraw(SGRedrawInfo* pRedrawInfo, 00389 SGFormatInfo* pFormatInfo) 00390 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00391 Created: 15/2/95 (base generated in sgbase.cpp) 00392 Inputs: pRedrawInfo - The information on the kernel-rendered redraw area 00393 pFormatInfo - The formatting information structure 00394 00395 Member variable FormatRect should be set up (before calling this method) 00396 to be the rectangle in which to draw this item 00397 Purpose: LineAttrItem item redraw method - removed from the main HandleEvent 00398 method merely to make the code tidier. 00399 00400 Justin here: this version sets default attributes within the render region, 00401 such as foreground & background colour, and then calls the Render() function 00402 to do the actual drawing. 00403 Notes: VERY IMPORTANT: The rendering must be enclosed by calls to StartRendering 00404 and StopRendering, to ensure that rendering works properly (in the future 00405 we may change the redraw system to use a GRenderRegion for each individual 00406 item, rather than one global one for the window, for which these calls will 00407 be essential) 00408 Scope: protected 00409 ***********************************************************************************************/ 00410 00411 void LineAttrItem::HandleRedraw(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo) 00412 { 00413 // Remove the gap between the items, shrink by one pixel to ensure clean clipping, 00414 // and fix the bounds coincide with the position of pixels. 00415 DocRect drBounds(FormatRect); 00416 drBounds.Inflate(-(pMiscInfo->PixelSize + GetHorzGap() / 2), 00417 -(pMiscInfo->PixelSize + GetVertGap() / 2)); 00418 GridLockRect(pMiscInfo, &drBounds); 00419 00420 // Set the foreground and background colours according to whether this item is 00421 // selected or not. 00422 DocColour dcolForegnd, dcolBackgnd; 00423 if (Flags.Selected) 00424 { 00425 dcolForegnd = pRedrawInfo->SelForeground; 00426 dcolBackgnd = pRedrawInfo->SelBackground; 00427 } 00428 else 00429 { 00430 dcolForegnd = pRedrawInfo->Foreground; 00431 dcolBackgnd = pRedrawInfo->Background; 00432 } 00433 00434 // Set the attributes for drawing the formatted rectangle. 00435 RenderRegion* pRegion = pRedrawInfo->Renderer; 00436 pRegion->SetLineWidth(pMiscInfo->PixelSize); // line is one pixel wide 00437 pRegion->SetFillColour(dcolBackgnd); 00438 00439 // If we are drawing an item that is a "current attribute" then we want to draw it 00440 // with a "selected" line around it. Otherwise we draw it with effectively no line. 00441 if (m_fIsCurrentAttrib) 00442 { 00443 pRegion->SetLineColour(pRedrawInfo->SelBackground); 00444 } 00445 else 00446 { 00447 // Draw the line the same colour as the fill colour, so it's "invisible". 00448 pRegion->SetLineColour(dcolBackgnd); 00449 } 00450 00451 // Create a closed path that is filled with the fill colour and if necessary has 00452 // a visible outline. 00453 Path pth; 00454 pth.Initialise(); 00455 pth.IsFilled = TRUE; 00456 pth.IsStroked = m_fIsCurrentAttrib; // draw outline if "current attribute" 00457 00458 // "Draw" the bounding rectangle into the path. 00459 pth.InsertMoveTo(drBounds.lo); 00460 pth.InsertLineTo(DocCoord(drBounds.lo.x, drBounds.hi.y)); 00461 pth.InsertLineTo(drBounds.hi); 00462 pth.InsertLineTo(DocCoord(drBounds.hi.x, drBounds.lo.y)); 00463 pth.InsertLineTo(drBounds.lo); 00464 pth.CloseSubPath(); 00465 00466 // Draw the path. 00467 pRegion->DrawPath(&pth); 00468 00469 // Reset the rendering attributes back to the normal: standard gallery foreground 00470 // and background colours. 00471 pRegion->SetLineColour(dcolForegnd); 00472 pRegion->SetFixedSystemTextColours(&dcolForegnd, &dcolBackgnd); 00473 00474 // Shrink the rectangle by a pixel, to make sure it nicely fits within the bounds, 00475 // lock down, and let the derived class do the rest of the work as it pleases. 00476 drBounds.Inflate(-pMiscInfo->PixelSize, -pMiscInfo->PixelSize); 00477 GridLockRect(pMiscInfo, &drBounds); 00478 Render(pRegion, drBounds, m_eDefaultTextPosition); 00479 } 00480 00481 00482 00483 /******************************************************************************************** 00484 > void LineAttrItem::Render(RenderRegion* pRegion, 00485 const DocRect& drBounds, 00486 LineAttrItem::TextPosition eTextPos) const 00487 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00488 Created: 27/3/95 00489 Inputs: pRegion pointer to the RenderRegion to render into 00490 drBounds the bounding box to render within 00491 eTextPos whether and where to put the text description 00492 Outputs: - 00493 Returns: - 00494 Purpose: Called by the HandleRedraw function. Can be overridden by derived classes. 00495 This base class version draws the text describing this item within the 00496 text bounding box, and a line within the line bounding box. 00497 Errors: - 00498 SeeAlso: LineAttrItem::HandleRedraw 00499 ********************************************************************************************/ 00500 00501 void LineAttrItem::Render(RenderRegion* pRegion, const DocRect& drBounds, 00502 LineAttrItem::TextPosition eTextPos) const 00503 { 00504 // Make a copy of the given bounding box rectangle so that we can adjust it later 00505 // if we render some text within it. 00506 DocRect drLineBounds(drBounds); 00507 00508 // Next, render the text description of this item, if necessary. 00509 if (eTextPos != NO_LABEL) 00510 { 00511 // We must adjust the bounding box of the line to account for the text rendered 00512 // into it. Items display their text on the left of the rendered attribute. 00513 DocRect drTextBounds(drLineBounds); 00514 switch (eTextPos) 00515 { 00516 case BELOW: 00517 { 00518 // Divide the bounds horizontally, text below. 00519 drTextBounds.hi.y = drTextBounds.lo.y + c_nVertSizeOfText; 00520 drLineBounds.lo.y = drTextBounds.hi.y + c_nVertGapAboveText; 00521 00522 // Centre the text bounds. As there is no "GetTextExtent" function for 00523 // "system text" we have the obligatory bodge . . . 00524 // MILLIPOINT nTextLen = (GetDescription().Length() + 1) * c_nAveCharWidth; 00525 DocRect TextBounds; 00526 String_256 Desc = GetDescription(); 00527 pRegion->GetFixedSystemTextSize(&Desc, &TextBounds); 00528 MILLIPOINT nTextLen = TextBounds.Width() / 2; 00529 MILLIPOINT xMid = (drTextBounds.lo.x + drTextBounds.hi.x) / 2; 00530 drTextBounds.lo.x = xMid - nTextLen; 00531 drTextBounds.hi.x = xMid + nTextLen; 00532 break; 00533 } 00534 00535 case LEFT: 00536 // Divide the bounds vertically, text to the left. 00537 drTextBounds.hi.x = drTextBounds.lo.x + c_nHorzSizeOfText; 00538 drLineBounds.lo.x = drTextBounds.hi.x + c_nHorzGapAfterText; 00539 break; 00540 00541 default: 00542 ERROR3("Unexpected case in LineAttrItem::Render"); 00543 return; 00544 } 00545 00546 // Draw the text description of this item. Note that the foreground and 00547 // background colours have already been set by the caller. 00548 pRegion->DrawFixedSystemText((String*) &GetDescription(), drTextBounds); 00549 } 00550 00551 // Set the default line width for lines rendered within the gallery and let a 00552 // derived class set some specialised rendering attributes for its item. Then draw 00553 // the line, by default through the centre of the given bounding box. A derived 00554 // class may very occasionally need to override this as well (eg. to render join-types). 00555 pRegion->SaveContext(); 00556 pRegion->SetLineWidth(c_nDefaultLineWidth); 00557 SetAttributes(pRegion); 00558 DrawItem(pRegion, drLineBounds); 00559 pRegion->RestoreContext(); 00560 } 00561 00562 00563 00564 /******************************************************************************************** 00565 > virtual void LineAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const 00566 00567 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00568 Created: 29/3/95 00569 Inputs: pRegion pointer to the RenderRegion to draw into 00570 drBounds reference to the bounding box rectangle to draw within 00571 Outputs: - 00572 Returns: - 00573 Purpose: Draws this item within the bouding box. This default implementation draws 00574 a single line through the centre of the box, fine for almost all derived 00575 classes. You can override this to do something else (cf. the join-types 00576 attribute item, that must draw two lines that meet). 00577 Errors: - 00578 SeeAlso: LineAttrItem::Render 00579 ********************************************************************************************/ 00580 00581 void LineAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const 00582 { 00583 // Calculate the mid-point of the vertical sides of the bounding box. 00584 INT32 yMid = (drBounds.lo.y + drBounds.hi.y) / 2; 00585 00586 // Draw a line at this height from the left to the right edge. 00587 Path pthLinePath; 00588 if (pthLinePath.Initialise()) 00589 { 00590 pthLinePath.InsertMoveTo(DocCoord(drBounds.lo.x, yMid)); 00591 pthLinePath.InsertLineTo(DocCoord(drBounds.hi.x, yMid)); 00592 pthLinePath.IsFilled = FALSE; 00593 pthLinePath.IsStroked = TRUE; 00594 pRegion->DrawPath(&pthLinePath); 00595 } 00596 } 00597 00598 00599 00600 /******************************************************************************************** 00601 > virtual MILLIPOINT LineAttrItem::GetWidth() const 00602 00603 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00604 Created: 19/4/95 00605 Inputs: - 00606 Outputs: - 00607 Returns: The width of this item, in millipoints. 00608 Purpose: Called by the formatting code. 00609 Errors: - 00610 SeeAlso: LineAttrItem::GetSize; LineAttrItem::CalculateMyRect 00611 ********************************************************************************************/ 00612 00613 MILLIPOINT LineAttrItem::GetWidth() const 00614 { 00615 return c_nHorzSizeOfItem; 00616 } 00617 00618 00619 00620 /******************************************************************************************** 00621 > virtual MILLIPOINT LineAttrItem::GetHeight() const 00622 00623 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00624 Created: 19/4/95 00625 Inputs: - 00626 Outputs: - 00627 Returns: The height of this item, in millipoints. 00628 Purpose: Called by the formatting code. 00629 Errors: - 00630 SeeAlso: LineAttrItem::GetSize; LineAttrItem::CalculateMyRect 00631 ********************************************************************************************/ 00632 00633 MILLIPOINT LineAttrItem::GetHeight() const 00634 { 00635 return c_nVertSizeOfItem; 00636 } 00637 00638 00639 00640 /******************************************************************************************** 00641 > virtual MILLIPOINT LineAttrItem::GetHorzGap() const 00642 00643 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00644 Created: 17/4/95 00645 Inputs: - 00646 Outputs: - 00647 Returns: The horizontal gap between this item and another item of the same type, in 00648 millipoints. 00649 Purpose: Called by the formatting code. This base-class version returns a default 00650 value, derived classes may override it to make items closer or further 00651 apart. 00652 Errors: - 00653 SeeAlso: - 00654 ********************************************************************************************/ 00655 00656 MILLIPOINT LineAttrItem::GetHorzGap() const 00657 { 00658 return c_nHorzGapBetweenItems; 00659 } 00660 00661 00662 00663 /******************************************************************************************** 00664 > virtual MILLIPOINT LineAttrItem::GetVertGap() const 00665 00666 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00667 Created: 17/4/95 00668 Inputs: - 00669 Outputs: - 00670 Returns: The vertical gap between this item and another item of the same type, in 00671 millipoints. 00672 Purpose: Called by the formatting code. This base-class version returns a default 00673 value, derived classes may override it to make items closer or further 00674 apart. 00675 Errors: - 00676 SeeAlso: - 00677 ********************************************************************************************/ 00678 00679 MILLIPOINT LineAttrItem::GetVertGap() const 00680 { 00681 return c_nVertGapBetweenItems; 00682 } 00683 00684 00685 00686 /*********************************************************************************************** 00687 > virtual BOOL LineAttrItem::HandleEvent(SGEventType EventType, 00688 void* EventInfo, 00689 SGMiscInfo* pMiscInfo) 00690 00691 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00692 Created: 15/2/95 (base generated in sgbase.cpp) 00693 Inputs: EventType - An enumerated value describing what type of event is to be processed 00694 EventInfo - A structure describing the event (may be NULL). The exact thing 00695 pointed at by this pointer depends upon the event type: 00696 MonoOn 00697 Event Thing EventInfo points at 00698 SGEVENT_FORMAT (SGFormatInfo *) 00699 SGEVENT_REDRAW (SGRedrawInfo *) 00700 SGEVENT_MOUSECLICK (SGMouseInfo *) 00701 MonoOff 00702 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this 00703 information - they provide useful error/type checking, and hide the cast 00704 00705 MiscInfo - always provided. Contains a few useful bits of info that may be 00706 needed for all event types. 00707 Outputs: FormatInfo is updated as appropriate 00708 Returns: TRUE if the event was handled successfully 00709 FALSE if it was not 00710 Purpose: Handles a SuperGallery DisplayTree event 00711 Notes: This overrides the pure virtual SGDisplayNode::HandleEvent method. 00712 A node need not handle a specific event - if it does not handle it, it 00713 should return FALSE. 00714 Redraw and Formatting handlers should never return TRUE, as this will 00715 prevent the event from continuing through the tree. 00716 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order 00717 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't. 00718 SeeAlso: SGDisplayNode::HandleEvent 00719 ***********************************************************************************************/ 00720 00721 BOOL LineAttrItem::HandleEvent(SGEventType EventType, void* EventInfo, SGMiscInfo *MiscInfo) 00722 { 00723 switch (EventType) 00724 { 00725 case SGEVENT_FORMAT: 00726 { 00727 SGFormatInfo* FormatInfo = GetFormatInfo(EventType, EventInfo); 00728 CalculateMyRect(FormatInfo, MiscInfo); // Cache our FormatRect for later use 00729 } 00730 break; 00731 00732 00733 case SGEVENT_REDRAW: 00734 { 00735 // Rely on FormatRect being cached from above 00736 SGRedrawInfo* RedrawInfo = GetRedrawInfo(EventType, EventInfo); 00737 00738 // only redraw if we intersect the clip rect 00739 if (IMustRedraw(RedrawInfo)) 00740 { 00741 // Now render the item. 00742 StartRendering(RedrawInfo, MiscInfo); 00743 RedrawInfo->Renderer->SaveContext(); 00744 HandleRedraw(RedrawInfo, MiscInfo); 00745 RedrawInfo->Renderer->RestoreContext(); 00746 StopRendering(RedrawInfo, MiscInfo); 00747 } 00748 } 00749 break; // exit and return FALSE to pass the redraw event on 00750 00751 00752 case SGEVENT_MOUSECLICK: 00753 { 00754 SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo); 00755 00756 if (FormatRect.ContainsCoord(Mouse->Position)) 00757 { 00758 //OK temporary dodge (see, not a bodge) to stop people doing things with brushes in the 00759 //line gallery before we get them working! 00760 // LineAttrItem* pItem = this; 00761 00762 { 00763 // If the colour is in the selected document, then it is safe to 00764 // do a colour drag - for now, it will only allow drags for the 00765 // selected doc. 00766 // Otherwise, the normal click action takes place. 00767 // If the drag fails (turns into a click) then the normal click action 00768 // takes place, passed on by the GalleryColourDragInfo::OnClick handler 00769 // SGDisplayGroup *Parent = (SGDisplayGroup *) GetParent(); 00770 00771 if (Mouse->DoubleClick) // || Parent->GetParentDocument() != Document::GetSelected()) 00772 DefaultClickHandler(Mouse, MiscInfo); 00773 else 00774 { 00775 DefaultPreDragHandler(Mouse, MiscInfo); 00776 00777 GalleryLineDragInfo* pInfo; 00778 pInfo = new GalleryLineDragInfo(this, Mouse, MiscInfo, Mouse->MenuClick); 00779 if (pInfo != NULL) DragManagerOp::StartDrag(pInfo, GetListWindow()); 00780 } 00781 } 00782 00783 return(TRUE); // Claim this event - nobody else can own this click 00784 } 00785 } 00786 break; 00787 00788 default: 00789 // Pass unknown events on to the base class 00790 return(SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo)); 00791 } 00792 00793 // Default return value: We do not claim this event, so it will be passed on to others 00794 return FALSE; 00795 } 00796 00797 00798 00799 /*********************************************************************************************** 00800 > virtual void LineAttrItem::DragWasReallyAClick(SGMouseInfo* pMouse, 00801 SGMiscInfo* pMiscInfo) 00802 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00803 Created: 10/4/95 00804 Inputs: Mouse - The mouse info passed to the original click handler 00805 MiscInfo - The misc info passed to the original click handler 00806 Purpose: Handles a mouse click event. This is a callback function - drags of 00807 line attributes from the gallery will call this function back if the drag 00808 turns out to just be a click. 00809 SeeAlso: LineAttrItem::HandleEvent; GalleryLineDragInfo::OnClick 00810 ***********************************************************************************************/ 00811 00812 void LineAttrItem::DragWasReallyAClick(SGMouseInfo* pMouse, SGMiscInfo* pMiscInfo) 00813 { 00814 // Just get default selection action to be applied for this click. 00815 DefaultClickHandler(pMouse, pMiscInfo); 00816 } 00817 00818 00819 00820 /******************************************************************************************** 00821 > virtual BOOL LineAttrItem::DefaultClickHandler(SGMouseInfo* pMouse, 00822 SGMiscInfo* pMiscInfo) 00823 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00824 Created: 7/4/95 00825 Inputs: (see base-class implementation in SGDisplayItem) 00826 Outputs: - 00827 Returns: (see base-class implementation in SGDisplayItem) 00828 Purpose: Overrides the default behaviour when items in the line gallery are 00829 clicked on, so that it is possible to simple-click and select items 00830 in different groups without clearing the selection. 00831 Errors: - 00832 SeeAlso: SGDisplayItem::DefaultClickHandler 00833 ********************************************************************************************/ 00834 00835 BOOL LineAttrItem::DefaultClickHandler(SGMouseInfo* pMouse, SGMiscInfo* pMiscInfo) 00836 { 00837 // Get some objects. 00838 SuperGallery* pParent = GetParentGallery(); 00839 SGDisplayGroup* pGroup = (SGDisplayGroup*) GetParent(); 00840 ERROR3IF(pGroup == NULL, "No parent group in LineAttrItem::DefaultClickHandler?"); 00841 00842 // If there is any other item within the group already selected then 00843 // deselect it. We start searching from the first child of this group. 00844 for (LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild(); 00845 pItem != NULL; 00846 pItem = (LineAttrItem*) pItem->GetNext()) 00847 { 00848 if (pItem != this) pItem->SetSelected(FALSE); 00849 } 00850 00851 // If Adjust, toggle my selection state 00852 // If Select, set myself selected, and ensure all other items deselected 00853 // NB. NOTE THAT "ADJUST" IS REALLY WHAT EVERY ONE ELSE CALLS "CONSTRAIN"!! 00854 // (Well, actually, it's what Windows uses for altering a selection... it's not my 00855 // fault that the rest of Camelot flies in the face of windows conventions... and 00856 // as galleries are really "super" windows list boxes, they have to use windows 00857 // conventions. Note also that pMouse->Adjust is not necessarily fixed to any key 00858 // but happens under Windows to be attached to ctrl or the right button) 00859 SetSelected((pMouse->Adjust && !pMouse->DoubleClick) ? !Flags.Selected : TRUE); 00860 00861 // OK, now we have guaranteed that an item is selected on a double click we can run 00862 // an Apply action. 00863 if (pMouse->DoubleClick) 00864 { 00865 // Apply the attributes. 00866 if (pParent->ApplyAction(pMouse->Adjust ? SGACTION_APPLYADJUST : SGACTION_APPLY) && 00867 pMouse->Adjust) 00868 { 00869 // Adjust/Ctrl double click of an item. This applies the item and then 00870 // auto closes the gallery (just like RISC OS and Win95) 00871 // Auto-close only occurs, however, if the item says it's OK, as arrowheads 00872 // use the ctrl-double click to apply in a special way, so shouldn't autoclose. 00873 00874 if (ShouldCloseOnDoubleClick()) 00875 { 00876 pParent->SetVisibility(FALSE); 00877 00878 DialogBarOp::SetSystemStateChanged(); // Ensure toolbar button pops out again 00879 } 00880 } 00881 00882 return TRUE; 00883 } 00884 00885 // Update the pParent to know that we are the new multi-selection anchor 00886 // (The anchor only changes when single items are (de)selected) 00887 pParent->SetLastSelectedNode((Flags.Selected) ? this : NULL); 00888 00889 // Finally, inform the parent gallery that the selection has changed, so it can 00890 // shade/unshade buttons as appropriate, etc 00891 pParent->SelectionHasChanged(); 00892 return TRUE; 00893 } 00894 00895 00896 00897 /******************************************************************************************** 00898 > const String& LineAttrItem::GetDescription() const 00899 00900 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00901 Created: 28/3/95 00902 Inputs: - 00903 Outputs: - 00904 Returns: A reference to a string that describes what this item represents. 00905 Purpose: Describes this item, basically. 00906 Errors: - 00907 SeeAlso: LineAttrItem::LineAttrItem 00908 ********************************************************************************************/ 00909 00910 const String& LineAttrItem::GetDescription() const 00911 { 00912 return m_strDescription; 00913 } 00914 00915 /******************************************************************************************** 00916 > void LineAttrItem::SetDescription(StringBase *pNewDescription) 00917 00918 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 00919 Created: 06/03/97 00920 Inputs: pNewDescription - New description of the item 00921 Purpose: Changes the item's text in the gallery 00922 ********************************************************************************************/ 00923 00924 void LineAttrItem::SetDescription(StringBase *pNewDescription) 00925 { 00926 if(pNewDescription != NULL) 00927 { 00928 m_strDescription = *pNewDescription; 00929 } 00930 } 00931 00932 00933 00934 /******************************************************************************************** 00935 > void LineAttrItem::SetTextPosition(LineAttrItem::TextPosition eNewTextPos) 00936 00937 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00938 Created: 29/3/95 00939 Inputs: eNewTextPos the new position of the text description 00940 Outputs: - 00941 Returns: - 00942 Purpose: Tells SGDisplayLineAttrItems whether to display themselves with a label 00943 describing themselves, or not. 00944 Errors: - 00945 SeeAlso: - 00946 ********************************************************************************************/ 00947 00948 void LineAttrItem::SetTextPosition(LineAttrItem::TextPosition eNewTextPos) 00949 { 00950 m_eDefaultTextPosition = eNewTextPos; 00951 } 00952 00953 00954 00955 /******************************************************************************************** 00956 > virtual BOOL LineAttrItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult) 00957 00958 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00959 Created: 13/6/95 00960 Inputs: dcMousePos (not used) 00961 Outputs: pResult where to put the text 00962 Returns: TRUE 00963 Purpose: Sets the given string to the text description of this line item. 00964 ********************************************************************************************/ 00965 00966 BOOL LineAttrItem::GetStatusLineHelp(DocCoord*, String_256* pResult) 00967 { 00968 // Check for rubbish. 00969 ERROR3IF(pResult == NULL, "Null String_256* passed to LineAttrItem::GetStatusLineHelp"); 00970 00971 // Build up the status-line text. This is composed of the item's text description, 00972 // followed by the text of the item's group title, without the last pluralising 's'. 00973 String_256 str; 00974 if (IsSelected()) 00975 str = String_256(_R(IDS_LINEGAL_SEL_CTRLCLICK)); 00976 else 00977 str = String_256(_R(IDS_LINEGAL_SEL_CLICK)); 00978 00979 str += GetDescription(); 00980 str += String_8(_R(IDS_SGLINE_STAT_SPACE_SEP)); // " " 00981 str += ((LineAttrGroup*) GetParent())->GetTitle(); 00982 str.Left(pResult, str.Length() - 1); 00983 00984 String_256 strAttr(_R(IDS_LINEGAL_ATTR)); 00985 *pResult += strAttr; 00986 00987 // if (IsSelected()) // removing this test fixes bug #4684 (hee hee!!) 00988 { 00989 String_256 strDbl(_R(IDS_LINEGAL_SEL_DBLCLK)); 00990 *pResult += strDbl; 00991 } 00992 00993 // Success! 00994 return TRUE; 00995 } 00996 00997 00998 00999 /******************************************************************************************** 01000 01001 > virtual BOOL LineAttrItem::ShouldCloseOnDoubleClick(void) 01002 01003 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01004 Created: 12/12/95 01005 01006 Returns: TRUE 01007 01008 Purpose: When an item is ctrl-double-clicked, the default action is to apply the 01009 item and close the gallery (for convenience). However, arrowheads do 01010 a special action for ctrl-double-click (they apply to the other end 01011 of the line) so they do not want auto-close to occur. 01012 01013 This function returns TRUE (auto-close) by default, and is overridden 01014 to return FALSE by derived classes which wish to stop the auto-close action. 01015 01016 SeeAlso: LineArrowItem::ShouldCloseOnDoubleClick 01017 01018 ********************************************************************************************/ 01019 01020 BOOL LineAttrItem::ShouldCloseOnDoubleClick(void) 01021 { 01022 return(TRUE); 01023 } 01024 01025 01026 01027 /******************************************************************************************** 01028 > virtual void LineAttrItem::ItemSelected() 01029 01030 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01031 Created: 20/1/2000 01032 Inputs: pNewAttr - the attribute that we are about to apply 01033 Outputs: - 01034 Returns: TRUE if we want the line gallery to go ahead and apply the attribute, 01035 FALSE if we applied it ourselves. 01036 Purpose: utility fn called when the item is selected. If your item needs to do anything 01037 just prior to it becoming selected then override this function. 01038 Errors: - 01039 SeeAlso: BrushAttrItem::ItemSelected 01040 ********************************************************************************************/ 01041 01042 BOOL LineAttrItem::ItemSelected(NodeAttribute* pNewAttr) 01043 { 01044 return TRUE; 01045 } 01046 01047 01048 /******************************************************************************************** 01049 > LineAttrGroup::LineAttrGroup(const String_64& strTitle, SuperGallery* pGal) 01050 01051 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01052 Created: 28/3/95 01053 Inputs: strTitle the title string to display within the group heading 01054 pGal pointer to the owning super-gallery object 01055 Outputs: - 01056 Returns: - 01057 Purpose: Contructs a LineAttrGroup, representing a section heading within 01058 the line-attributes super-gallery. 01059 Errors: - 01060 SeeAlso: SGDisplayGroup::SGDisplayGroup 01061 ********************************************************************************************/ 01062 01063 LineAttrGroup::LineAttrGroup(const String_64& strTitle, SuperGallery* pGal) 01064 : SGDisplayGroup(pGal, NULL, NULL) 01065 { 01066 // Set the title (in the base class). 01067 TitleText = strTitle; 01068 } 01069 01070 01071 01072 /******************************************************************************************** 01073 > const String_64& LineAttrGroup::GetTitle() const 01074 01075 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01076 Created: 13/6/95 01077 Returns: A reference to the string containing this group's title. 01078 Purpose: Gets this group's title (the text displayed next to the folder icon). 01079 SeeAlso: LineAttrItem::GetStatusLineHelp 01080 ********************************************************************************************/ 01081 01082 const String_64& LineAttrGroup::GetTitle() const 01083 { 01084 return TitleText; 01085 } 01086 01087 01088 01089 /******************************************************************************************** 01090 > static BOOL LineGallery::Init() 01091 01092 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01093 Created: 28/3/95 01094 Inputs: - 01095 Outputs: - 01096 Returns: TRUE if gallery initialisation is successful. 01097 Purpose: Called when the program starts, loading .INI file settings. 01098 Errors: - 01099 SeeAlso: - 01100 ********************************************************************************************/ 01101 01102 BOOL LineGallery::Init() 01103 { 01104 return Camelot.DeclareSection(TEXT("Displays"), 20) 01105 && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale1"), 01106 &m_anArrowScales[0], 0.1, 50.0) 01107 && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale2"), 01108 &m_anArrowScales[1], 0.1, 50.0) 01109 && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale3"), 01110 &m_anArrowScales[2], 0.1, 50.0) 01111 && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale4"), 01112 &m_anArrowScales[3], 0.1, 50.0) 01113 && PrepareBrushFolders(); 01114 } 01115 01116 01117 01118 /******************************************************************************************** 01119 > static LineGallery* LineGallery::GetInstance() 01120 01121 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01122 Created: 17/4/95 01123 Inputs: - 01124 Outputs: - 01125 Returns: A pointer to the program's line gallery if it exists, or NULL. 01126 Purpose: Public access function to the line gallery. 01127 Errors: - 01128 SeeAlso: - 01129 ********************************************************************************************/ 01130 01131 LineGallery* LineGallery::GetInstance() 01132 { 01133 return m_pTheGallery; 01134 } 01135 01136 01137 01138 /******************************************************************************************** 01139 > static BOOL LineGallery::IsActive() 01140 01141 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01142 Created: 17/4/95 01143 Inputs: - 01144 Outputs: - 01145 Returns: TRUE if the line gallery is currently visible on-screen, FALSE otherwise. 01146 Purpose: Used by the message-handlers of gadgets within the line gallery to 01147 determine if they should update themselves or not. 01148 Errors: - 01149 SeeAlso: - 01150 ********************************************************************************************/ 01151 01152 BOOL LineGallery::IsActive() 01153 { 01154 return m_pTheGallery != NULL && m_pTheGallery->IsVisible(); 01155 } 01156 01157 01158 01159 /******************************************************************************************** 01160 > LineGallery::LineGallery() 01161 01162 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01163 Created: 15/2/95 (base generated in sgbase.cpp) 01164 Purpose: LineGallery default constructor. Sets a global instance pointer to 01165 this object. 01166 ********************************************************************************************/ 01167 01168 LineGallery::LineGallery() 01169 { 01170 // Remember a pointer to the global instance of this gallery. 01171 ERROR3IF(m_pTheGallery != NULL, "Gallery already exists in LineGallery::LineGallery?"); 01172 m_pTheGallery = this; 01173 01174 DlgResID=_R(IDD_LINESGALLERY); 01175 01176 // set to the normal default 01177 m_PreviousLineWidth = 500; 01178 } 01179 01180 01181 01182 /******************************************************************************************** 01183 > virtual LineGallery::~LineGallery() 01184 01185 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01186 Created: 17/4/95 01187 Inputs: - 01188 Outputs: - 01189 Returns: - 01190 Purpose: Destroys a line gallery, resetting the global instance pointer to NULL. 01191 Errors: - 01192 SeeAlso: - 01193 ********************************************************************************************/ 01194 01195 LineGallery::~LineGallery() 01196 { 01197 // Make sure nothing is seriously screwed-up. 01198 ERROR3IF(m_pTheGallery == NULL, "No gallery in LineGallery::~LineGallery?"); 01199 m_pTheGallery