sgline.cpp

Go to the documentation of this file.
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