SGDisplayNode Class Reference

This DisplayTree node type is used by the SuperGallery This is a virtual class from which all nodes in the DisplayTree are derived. More...

#include <sgtree.h>

Inheritance diagram for SGDisplayNode:

CCObject SimpleCCObject SGDisplayGroup SGDisplayItem SGDisplayRoot LineAttrGroup SGDisplayColourGroup SGFontsGroup SGLayerGroup SGLibGroup SGNameGroup SGNameGroup LineAttrItem SGDisplayColour SGDisplayDATATYPE SGDisplayKernelBitmap SGDisplayLayer SGDisplayPreviewFonts SGLibDisplayItem SGNameItem SGNameItem SGDisplayRootScroll List of all members.

Public Member Functions

 SGDisplayNode ()
 SGDisplayNode constructor.
 ~SGDisplayNode ()
 SGDisplayNode destructor.
SGDisplayNodeGetParent () const
 Finds the parent of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.
virtual SGDisplayNodeGetChild () const
 Finds the child of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.
SGDisplayNodeGetNext () const
 Finds the next (right) sibling of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.
SGDisplayNodeGetPrevious () const
 Finds the previous (left) sibling of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.
virtual SuperGalleryGetParentGallery () const
 Recursively scans up the tree asking each parent node in turn for the parent gallery. It is expected that a node (eg SGDisplayRoot or SGDisplayGroup) will be found somewhere on this path which will know who our parent gallery is. (If not, there is a serious tree problem!).
virtual void AddItem (SGDisplayNode *NodeToInsert, SGSortKey *SortInfo=NULL)
 Inserts the given node/subtree into this subtree. If SortInfo == NULL or NodeToInsert is not an SGDisplayItem, it is added as the last child of this node. Otherwise, it is inserted into the subtree of SGDisplayItems at the point 'specified' by SortInfo (By asking each DisplayItem in turn to compare itself to the one being added, until one is found which is considered "greater than" this one according to the sort mode).
virtual void InsertAfter (SGDisplayNode *NodeToInsert)
 Inserts the given node into the DisplayTree as the next (right) sibling of this node.
virtual void InsertBefore (SGDisplayNode *NodeToInsert)
 Inserts the given node into the DisplayTree as the previous (left) sibling of this node.
virtual void MoveAfter (SGDisplayNode *NodeToInsert)
 MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted.
virtual void MoveBefore (SGDisplayNode *NodeToInsert)
 MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted.
virtual void RemoveFromTree (void)
 De-links this node/subtree from the DisplayTree. This DOES NOT DELETE the node, just unlinks it in preparation for being deleted.
virtual void DestroySubtree (BOOL IncludingThisNode=TRUE)
 DESTROYS the subtree starting at (and including, if IncludingThisNode is TRUE) this node. This does a depth-first recursive scan of the subtree, delinking each item, and then CALLING EACH ITEMS DESTRUCTOR.
virtual SGDisplayGroupFindSubtree (SuperGallery *ParentGal, Document *ParentDoc, Library *ParentLib)
 Searches this node and its subtree for any SGDisplayGroup nodes which have parent pointers which exactly match the input parameters. This is used to find the subtree for a given document or library.
virtual BOOL SetFoldedState (BOOL NewState, BOOL ForceRedraw=TRUE)
 Folds or unfolds a display node.
BOOL IsSelected (void)
 Returns TRUE if this item is selected, FALSE if it is not.
virtual void SetSelected (BOOL IsSelected=TRUE)
 Sets the selection state of a SuperGallery Display Item tree node. Note that this does not cause a redraw of the gallery list box or anything. After setting the state(s) of item(s) you must therefore redraw them.
virtual INT32 CompareTo (SGDisplayNode *Other, INT32 SortKey)
 Compares this node to the 'other' node, to determine their relative positions in the display tree. Returns a value which usually indicates that the other node should be inserted before (-1, or 0) or after (+1) this item.
virtual void GetNameText (String_256 *Result)
 To determine a name string for this node. Generally, this is used for a simple mechanism which searches for display items whose names match given search parameters in some way. It is also used in libraries to provide default redraw methods.
virtual void GetFullInfoText (String_256 *Result)
 To determine a full-info string for this node. Generally, this is used for a simple mechanism which searches for display items whose info matches given search parameters in some way. It is also used in libraries to provide default redraw methods.
virtual void GetKeyWords (String_256 *Result)
 To determine the keywords for this node. Generally, this is used for a simple searching mechanism.
virtual BOOL GetBubbleHelp (DocCoord *MousePos, String_256 *Result)
 Called by the parent gallery when bubble help is needed. The parent gallery will do a hit test to determine which node contains the pointer, and will then ask that node to supply bubble/status-line help.
virtual BOOL GetStatusLineHelp (DocCoord *MousePos, String_256 *Result)
 Called by the parent gallery when status line help is needed. The parent gallery will do a hit test to determine which node contains the pointer, and will then ask that node to supply bubble/status-line help.
virtual void StartRendering (SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo)
 MUST be called by all derived node types when they are about to start rendering. This allows us to do things like using GRenderRegions to small bitmaps (a region for each item rather than one region for the whole window) and other fabby things.
virtual void StopRendering (SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo)
 MUST be called by all derived node types when they have finished rendering. This allows us to do things like using GRenderRegions to small bitmaps (a region for each item rather than one region for the whole window) and other fabby things.
SGFormatInfoGetFormatInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
SGRedrawInfoGetRedrawInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
SGMouseInfoGetMouseInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
DragMessageGetDragInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
SGClaimPointInfoGetClaimPointInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
ThumbMessageGetThumbMsgInfo (SGEventType EventType, void *EventInfo)
 Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).
virtual BOOL HandleEvent (SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
 Handles a generic display tree event. Events of interest trigger specific actions.
virtual void DragWasReallyAClick (SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
 Handles a mouse click event. This is a callback function - drags of items from galleries will call this function back if the drag turns out to just be a click.
virtual void GetFormatRect (DocRect *LayoutRect)
 Determines where this item wants to redraw itself within the logical window DocCoord coordinates. If this is not a visible node type, or if someone neglected to cache the value in overridden methods, returns (0,0,0,0).
virtual void ForceRedrawOfMyself (BOOL bEraseBkg=TRUE)
 Uses the cached FormatRect to force-redraw the appropriate part of the SuperGallery display window to cause myself (only) to be redrawn.
virtual void ForceRedrawOfMyselfAndChildren (void)
 Uses the cached FormatRect to force-redraw the appropriate part of the SuperGallery display window to cause myself to be redrawn - derived classes may override this to also redraw their children (SGDisplayNode).
virtual void SelectItems (BOOL SelectThem, BOOL Exclusive=FALSE, Document *ParentDocument=NULL, Library *ParentLibrary=NULL)
 To select/deselect groups of display items in this Gallery display. All items whose state changes will force redraw themselves.
virtual void SelectGroups (BOOL SelectThem, BOOL Exclusive, Document *ParentDocument, Library *ParentLibrary)
 To select/deselect sets of display groups in this Gallery display. All groups whose state changes will force redraw themselves.
virtual void SelectRangeGroups (SGDisplayGroup *PrimeNode, SGDisplayGroup *AnchorNode)
 Selects the PrimeNode, and if possible, all sibling items between it and the Anchor node. If Anchor == NULL or is not found, only PrimeNode is selected. Does not deselect any items - you should call SelectItems first to clear the seln.
virtual void SelectRangeItems (SGDisplayItem *PrimeNode, SGDisplayItem *AnchorNode)
 Selects the PrimeNode, and if possible, all sibling items between it and the Anchor node. If Anchor == NULL or is not found, only PrimeNode is selected. Does not deselect any items - you should call SelectItems first to clear the seln.
SGDisplayNodeDoBGRedrawPass (SGMiscInfo *MiscInfo)
 Applies a background rendering pass to the display tree. This will scan the tree from this node onwards looking for a node to background render.
virtual BOOL DefaultPreDragHandler (SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
 Provides part 1 of the default selection model for clicks on gallery display nodes. Should be called by all derived gallery DisplayItems to handle clicks upon them, when multiple-selection support is desired.
virtual BOOL DefaultClickHandler (SGMouseInfo *Mouse, SGMiscInfo *MiscInfo, BOOL AfterDrag=FALSE, BOOL AdjustDoubleClick=TRUE)
 Provides the default selection model for clicks on gallery display nodes. Should be called by all derived gallery DisplayItems to handle clicks upon them, when multiple-selection support is desired.

Public Attributes

SGDisplayFlags Flags

Protected Member Functions

virtual void SetChild (SGDisplayNode *NewChild)
 Sets the child of this DisplayTree Node.
virtual void InsertInternal (SGDisplayNode *NodeToInsert, SGDisplayNode *PrevNode, SGDisplayNode *NextNode)
 Inserts the given node/subtree into this subtree, between PrevNode and NextNode. One of these two nodes may be NULL if you are trying to insert at the head/tail of a sibling list.
virtual BOOL GiveEventToMyChildren (SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
 Causes the entire subtree below this node to check their formatting, and handle the given event. Once a node returns TRUE from its HandleEvent method, the event will NOT be passed on.
virtual void NewLine (SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
 Resets the formatting info structure to default values for the start of the next 'line'.
virtual void CalculateFormatRect (SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo, INT32 ItemWidth, INT32 ItemHeight)
 Given current formatting information, generates the rectangle within which this node and its subtree should be redrawn.
BOOL IMustRedraw (SGRedrawInfo *RedrawInfo)
 To determine if a given item needs to be redrawn. This is done by determining if its bounding rectangle ('FormatRect') overlaps the bounding rectangle of the area to be redrawn as specified by RedrawInfo->Bounds.
INT32 DevicePixels (SGMiscInfo *MiscInfo, INT32 NumPixels)
 Because we work in millipoints, it is difficult to get the right values for 'thin' lines (1-device pixel thick) or thin gaps (e.g. 1 or 2 pixels) This function uses the FormatInfo to determine the size, in millipoints, of device pixels, and multiplies this by the input parameter, to give the size in millipoints of that many device pixels.
void DrawPlinth (SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo, DialogColourInfo *RedrawColours, DocRect *ButtonRect, BOOL Indented=FALSE, UINT32 GlyphResourceID=0)
 Draws a plinth (2 white lines and 2 dark grey lines) around the inside edge of the given rectangle, in order to give a Windows 95 like button plinth. It can include a button glyph bitmap. It's static so anybody can call it if they so desire.
void DrawSelectionOutline (SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo, DocRect *BoundsRect, INT32 Width=0)
 Draws a black 2-pixel-thick frame-rectangle just inside the given Rect. This is the normal selection-rectangle outline which should go outside an icon or thumbnail when an item is selected.
void DrawBitmap (RenderRegion *Renderer, DocRect *BoundsRect, UINT32 ResID)
 Draws the given bitmap to screen in the given DocRect of the supergallery display list. (Used to be necessary before RR:DrawBitmap came along).
CWindowID GetListWindow (void)
 Returns the window id of the list box window of the parent gallery.
virtual void RegisterForBGRedraw (void)
 Called by derived classes to register themselves for background redraw.
virtual BOOL DoBGRedraw (SGMiscInfo *MiscInfo)
 Forces an immediate redraw of a given node, if it is pending for background redraw.
virtual void DeregisterForBGRedraw (void)
 Ensures that this node is not pending background redraw (resets it) This is called in response to SGEVENT_BGFLUSH, when flushing BG redraws.
virtual BOOL ShouldIDrawForeground (BOOL ForceForeground=FALSE)
 Call this method in derived class redraw methods. Your code should go like this: MonoOn if (ShouldIDrawForeground(ByGollyIveGotAThumbnailCachedAlready) DrawTheItemFully(); else DrawAGreyBox(); MonoOff.

Static Protected Member Functions

static INT32 GridLock (SGMiscInfo *MiscInfo, INT32 Coordinate)
 In order to avoid rounding errors in the mapping between millipoints and output device pixels from causing coordinates to alias to different pixels when in different positions, all SuperGallery display coordinates must be snapped onto a grid of pixel-positions. This function does this snapping.
static void GridLockRect (SGMiscInfo *MiscInfo, DocRect *Rect)
 Given a rectangle and the normal FormatInfo, this ensures that all points of the rectangle are snapped onto a grid of the destination device pixels. This ensures that aliasing effects, due to rounding errors when mapping to the output pixel coordinates, do not occur.

Protected Attributes

DocRect FormatRect

Static Protected Attributes

static SGDisplayNodeCurrentBGRenderNode = NULL
static BOOL BGRenderClaimed = FALSE
static BOOL BkgEraseMode = TRUE

Private Attributes

SGDisplayNodeParent
SGDisplayNodeNext
SGDisplayNodePrevious

Detailed Description

This DisplayTree node type is used by the SuperGallery This is a virtual class from which all nodes in the DisplayTree are derived.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Before using DisplayTrees, or deriving classes from this one, please read Docs.doc, which has a section on how these nodes function.

See also:
SuperGallery; SGDisplayGroup; SGDisplayList

Definition at line 595 of file sgtree.h.


Constructor & Destructor Documentation

SGDisplayNode::SGDisplayNode  ) 
 

SGDisplayNode constructor.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
See also:
SuperGallery; SGDisplayGroup; SGDisplayItem

Definition at line 162 of file sgtree.cpp.

00163 {
00164     Parent = Next = Previous = NULL;
00165 
00166     Flags.Invisible = Flags.ReadOnly = Flags.Modified = FALSE;
00167     Flags.CanSelect = Flags.Selected = FALSE;
00168     Flags.Folded = Flags.RedrawPending = FALSE;
00169     Flags.Virtualised = FALSE;
00170 
00171     Flags.HandleEventCount = 0;
00172 
00173     Flags.Reserved = 0;
00174 
00175     FormatRect = DocRect(0,0,0,0);
00176 }

SGDisplayNode::~SGDisplayNode  ) 
 

SGDisplayNode destructor.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
See also:
SuperGallery; SGDisplayGroup; SGDisplayItem

Definition at line 191 of file sgtree.cpp.

00192 {
00193     ERROR3IF(Flags.HandleEventCount > 0, "AWOOGA! SGDisplayNode deleted while in its own HandleEvent method - Alert Jason!");
00194     ERROR3IF(Flags.HandleEventCount != 0, "Deleted SGDisplayNode had a corrupted HandleEventCount");
00195 
00196     if (Parent != NULL || GetChild() != NULL || Next != NULL || Previous != NULL)
00197     {
00198         ERROR3("Destructing SGDisplayNode which is still linked into a tree! I'll try to delink it first\n");
00199         RemoveFromTree();
00200     }
00201 }


Member Function Documentation

void SGDisplayNode::AddItem SGDisplayNode NodeToInsert,
SGSortKey SortInfo = NULL
[virtual]
 

Inserts the given node/subtree into this subtree. If SortInfo == NULL or NodeToInsert is not an SGDisplayItem, it is added as the last child of this node. Otherwise, it is inserted into the subtree of SGDisplayItems at the point 'specified' by SortInfo (By asking each DisplayItem in turn to compare itself to the one being added, until one is found which is considered "greater than" this one according to the sort mode).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
NodeToInsert - the node/subtree to be inserted [INPUTS] SortInfo - NULL, or an array of MaxSGSortKeys sort key structures which describe how the item should be inserted. [NOTE that this parameter is only used for insertion of SGDisplayItem and derived classes]
Returns:
Errors: ERROR3s will be reported in debug builds for NULL NodeToInsert, or if NodeToInsert is linked into another tree (has non-null parent/next/previous pointers). It is perfectly legal for it to have a child subtree, though.
See also:
SuperGallery; SGDisplayNode::InsertAfter; SGDisplayNode::InsertBefore

Reimplemented in SGDisplayItem.

Definition at line 377 of file sgtree.cpp.

00378 {
00379     if (NodeToInsert == NULL)
00380     {
00381         ERROR3("Attempt to add a NULL node to a tree was ignored");
00382         return;
00383     }
00384 
00385     // The node cannot have parent, next, prev, but can have children
00386     ERROR3IF(NodeToInsert->Parent != NULL ||
00387              NodeToInsert->Next != NULL   || NodeToInsert->Previous != NULL,
00388              "Illegal attempt to link an already-linked node into a tree");
00389 
00390     if (GetChild() == NULL) // We have no children, so there is only one place for this node!
00391     {
00392         SetChild(NodeToInsert);                     // Add it as our first child and return
00393         NodeToInsert->Parent = this;
00394 
00395         // Because we have recreated part of the tree, we must inform the gallery that the
00396         // cached format is incorrect and needs to be recalculated.
00397         SuperGallery *ParentGallery = GetParentGallery();
00398         if (ParentGallery != NULL)
00399             ParentGallery->InvalidateCachedFormat();
00400         return;
00401     }
00402 
00403     SGDisplayNode *Ptr  = GetChild();
00404     SGDisplayNode *Last = NULL;
00405 
00406     if (SortInfo == NULL || SortInfo[0].SortKey == 0 ||
00407             !NodeToInsert->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem)) ||
00408             !IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup)))
00409     {
00410         // There is no requested sort mode, or it is sort-by-none, or the node being inserted
00411         // is not a DisplayItem, or I am not a DisplayGroup, so I just add the item to the end
00412         // of my child list
00413 
00414         while (Ptr != NULL)     // Find the end of the sibling list
00415         {
00416             Last = Ptr;
00417             Ptr  = Ptr->Next;
00418         }
00419 
00420         // This ENSURE should never occur, as we checked for no-children above
00421         ERROR3IF(Last == NULL, "Something screwy has happened in SGDisplayNode:AddItem!");
00422         InsertInternal(NodeToInsert, Last, NULL);   // Insert it as the last child
00423     }
00424     else
00425     {
00426         // While searching givvus a parent! (bodge so libraries can sort whilst adding)
00427         NodeToInsert->Parent = this;
00428 
00429         // We can add with sorting, so add the item at an appropriate position based upon
00430         // the provided sort mode
00431         INT32 Result;
00432         while (Ptr != NULL)     // Search the sibling list for the first appropriate insertion point
00433         {
00434             Last = Ptr;
00435 
00436             // Compare using sort key 1
00437             Result = Ptr->CompareTo(NodeToInsert, SortInfo[0].SortKey);
00438             if (SortInfo[0].Reversed)
00439                 Result = -Result;
00440 
00441             // If they are equal, and we have multi-key sort, use key 2
00442             if (Result == 0 && SortInfo[1].SortKey != 0)
00443             {
00444                 Result = Ptr->CompareTo(NodeToInsert, SortInfo[1].SortKey);
00445                 if (SortInfo[1].Reversed)
00446                     Result = -Result;
00447             }
00448         
00449             // We have compared - if the current item is "greater" than the one being
00450             // inserted, then we can stop and insert it before that item
00451             if (Result > 0)
00452                 break;
00453 
00454             Ptr = Ptr->Next;
00455         }
00456 
00457         // Delink the parent since it shouldn't really be connected yet
00458         NodeToInsert->Parent = NULL;
00459         
00460         if (Ptr == NULL)
00461         {
00462             // We must have run off the end of the list - insert at the end
00463             ERROR3IF(Last == NULL, "Something screwy has happened in SGDisplayNode:AddItem!");
00464             InsertInternal(NodeToInsert, Last, NULL);
00465         }
00466         else
00467         {
00468             // We found an item to insert before, so insert before it
00469             InsertInternal(NodeToInsert, Ptr->GetPrevious(), Ptr);
00470         }
00471     }
00472 }

void SGDisplayNode::CalculateFormatRect SGFormatInfo FormatInfo,
SGMiscInfo MiscInfo,
INT32  ItemWidth,
INT32  ItemHeight
[protected, virtual]
 

Given current formatting information, generates the rectangle within which this node and its subtree should be redrawn.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/10/94
Parameters:
FormatInfo - A structure containing all relevant information for items to [INPUTS] calculate their formatted positions in the display list. NOTE this is also an output! (As passed into HandleEvent for SGEVENT_FORMAT events)
MiscInfo - Miscellaneous information needed for formatting; as passed into all HandleEvent calls

ItemWidth - The width of this item in millipoints, or 0 if this item is 'infinite' width (fills the entire line). If there is not enough space left on this line for the item, a new line is started.

ItemHeight - The height of this item in millipoints. Sibling items are currently expected to have equal heights; although line formatting will cope with different heights, redraw may miss strips below items for the time being.

Parameters:
FormatInfo - updated as appropriate [OUTPUTS] Member variable FormatRect now contains the format rectangle
Returns:
TRUE if the resulting rectangle overlaps RedrawInfo->Bounds (i.e. if the node would need to redraw itself if handling a redraw request) else FALSE if the node need not be redrawn
Notes: This relies upon the cached formatting information in this node being correct - this function can only be called once per node during a pass through the tree... the second call would give a different result.

If you do not use this function to do all the formatting work for you, then you must remember to either updaet the 'FormatRect' member variable, or override the 'GetFormatRect' member function to supply this information to the caller properly.

See also:
SGDisplayNode::HandleEvent; SGDisplayRoot::HandleEvent; SGDisplayGroup::HandleEvent; SGDisplayItem::HandleEvent

Definition at line 1050 of file sgtree.cpp.

01052 {
01053     ERROR3IF(FormatInfo == NULL || MiscInfo == NULL,
01054              "NULL parameter(s) passed to SGDisplayNode::CalculateFormatRect");
01055 
01056     if (Previous == NULL                        ||  // Is first child node, so go to a new line
01057         FormatInfo->AvailableWidth <= 0         ||  // No room left at all on this line
01058         FormatInfo->AvailableWidth < ItemWidth  ||  // Not enough room on the line for this item
01059         ItemWidth == 0)                             // This item is infinitely wide
01060     {
01061             NewLine(FormatInfo, MiscInfo);
01062     }
01063 
01064     // If items do not fill the entire width, add a 2-pixel gap at the right edge, so that
01065     // adjacent items have a small gap between them. (see below)
01066     if (ItemWidth != 0)
01067         ItemWidth += MiscInfo->PixelSize * 2;
01068 
01069     ItemWidth  = GridLock(MiscInfo, ItemWidth);
01070     ItemHeight = GridLock(MiscInfo, ItemHeight);
01071 
01072     // We must now have enough room for this item across the current line, so plonk it in!
01073     // Update the height of the current line
01074     if (FormatInfo->LineHeight < ItemHeight)
01075     {
01076         // if (LineHeight != 0) AWOOGA! Line height has increased! Must go back and fill in
01077         // the background colour below the previous items on this line, to ensure the entire
01078         // line is fully redrawn.
01079 
01080         ERROR3IF(FormatInfo->LineHeight != 0,
01081             "Sibling Display Item heights are not equal! Jason must upgrade the redraw code");
01082 
01083         FormatInfo->LineHeight = ItemHeight;
01084     }
01085 
01086     // Generate the position rectangle. Note that this may be wider than MaxWidth - it is the
01087     // actual rectangle the item has (so scaling into the returned rect will always work,
01088     // even if part of the rectangle is clipped out of view). However, if the item was
01089     // requested as infinite width, it is returned as MaxWidth.
01090     INT32 ActualWidth = (ItemWidth == 0) ? FormatInfo->AvailableWidth : ItemWidth;
01091 
01092     // Ensure it is clipped within the available window space
01093     if (ActualWidth > FormatInfo->AvailableWidth)
01094         ActualWidth = FormatInfo->AvailableWidth;
01095     
01096     DocRect OldFormatRect(FormatRect);
01097     FormatRect.lo.x = MiscInfo->MaxWidth - FormatInfo->AvailableWidth;
01098     FormatRect.hi.x = FormatRect.lo.x + ActualWidth;
01099     FormatRect.lo.y = FormatInfo->LinePos - FormatInfo->LineHeight;
01100     FormatRect.hi.y = FormatInfo->LinePos;
01101 
01102     // If items do not fill the entire width, add a 2-pixel gap at the right edge, so that
01103     // adjacent items have a small gap between them. (see above)
01104     if (ActualWidth < FormatInfo->AvailableWidth)
01105         FormatRect.hi.x -= MiscInfo->PixelSize * 2;
01106 
01107     GridLockRect(MiscInfo, &FormatRect);    // And ensure it is locked onto the grid
01108 
01109     // If this node is no longer in the same position as it was last time we formatted,
01110     // then accumulate its Y bounds into the 'InvalidBounds' rect, to allow the gallery
01111     // to redraw only those regions of the list which are invalid
01112     if (FormatInfo->AccumulateBounds)
01113     {
01114         if (OldFormatRect != FormatRect)
01115         {
01116             FormatInfo->LastInvalidNode = this;     // We are the last node found to have invalid bounds
01117 
01118             if (FormatInfo->InvalidBounds.hi.y > 0) // If we haven't found an invalid item before
01119                 FormatInfo->InvalidBounds.hi.y = FormatRect.hi.y;
01120 
01121             if (FormatInfo->InvalidBounds.lo.y > FormatRect.lo.y)
01122                 FormatInfo->InvalidBounds.lo.y = FormatRect.lo.y;
01123         }
01124         else
01125         {
01126             if (FormatInfo->LastInvalidNode != NULL)
01127             {
01128                 // The immediately previous node had invalid bounds. If we lie below the current
01129                 // invalid bounds, then we extend them to touch the top of us, to include any gap
01130                 // between them and us.
01131 
01132                 ERROR3IF(FormatInfo->InvalidBounds.hi.y > 0,
01133                             "Gallery display formatting error - LastInvalidNode should be NULL "
01134                             "if there haven't been any invalid nodes yet");
01135 
01136                 if (FormatInfo->InvalidBounds.lo.y > FormatRect.hi.y)
01137                     FormatInfo->InvalidBounds.lo.y = FormatRect.hi.y;
01138 
01139                 FormatInfo->LastInvalidNode = NULL;     // Reset LastInvalid node so that the next node doesn't extend!
01140             }
01141         }
01142     }
01143 
01144 //  if (Flags.Invisible)
01145 //  {
01146 //      FormatRect.hi.x = FormatRect.lo.x;
01147 //      FormatRect.hi.y = FormatRect.lo.y;
01148 //  }
01149 
01150     // Update the free width on the end of this line. Note that this may now be 0 or -ve,
01151     // but this will be sorted out on the next call to this method, in the clauses above.
01152 //  if (!Flags.Invisible)
01153 //  {
01154         FormatInfo->AvailableWidth -= ActualWidth;
01155         GridLock(MiscInfo, FormatInfo->AvailableWidth);
01156 //  }
01157 }

INT32 SGDisplayNode::CompareTo SGDisplayNode Other,
INT32  SortKey
[virtual]
 

Compares this node to the 'other' node, to determine their relative positions in the display tree. Returns a value which usually indicates that the other node should be inserted before (-1, or 0) or after (+1) this item.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/10/94
Parameters:
Other - the node to compare this node to [INPUTS] SortKey - An integer identifying how to compare the items 0 = No sorting (always returns 0) 1 = Sort-by-name Other values will return 0, unless the derived class overrides this method in order to provide other sort modes.
Returns:
negative (I am lesser), 0 (we are equal), or positive (I am greater)
See also:
SGDisplayNode::AddItem

Reimplemented in SGNameItem, SGDisplayColour, SGDisplayLibColour, SGLibDisplayItem, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 1799 of file sgtree.cpp.

01800 {
01801     ERROR3IF(Other == NULL, "Illegal NULL parameter");
01802 
01803     switch (SortKey)
01804     {
01805         case SGSORTKEY_BYNAME:
01806             {
01807                 String_256 MyName;
01808                 String_256 ItsName;
01809 
01810                 GetNameText(&MyName);
01811                 Other->GetNameText(&ItsName);
01812 
01813                 return(MyName.CompareTo(ItsName));
01814             }
01815             break;
01816     }
01817 
01818     // No sorting (SGSORTKEY_NONE - 0), or 
01819     return(0);
01820 }

BOOL SGDisplayNode::DefaultClickHandler SGMouseInfo Mouse,
SGMiscInfo MiscInfo,
BOOL  AfterDrag = FALSE,
BOOL  AdjustDoubleClick = TRUE
[virtual]
 

Provides the default selection model for clicks on gallery display nodes. Should be called by all derived gallery DisplayItems to handle clicks upon them, when multiple-selection support is desired.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/2/94
Parameters:
Mouse - Information on the mouse state for this click [INPUTS] MiscInfo - the normal info as passed to event handlers
AfterDrag - TRUE if this is being called when a drag turns into a click, and you called DefaultPreDragHandler before the drag started

AdjustDoubleClick - TRUE to do normal adjust-double-click handling (which closes the gallery after applying the item) FALSE to not close the gallery (used by the colour gallery to stop the gallery closing when applying with adjust as it applies line colour, so overrides the default behaviour)

Returns:
TRUE if the click caused any action to be taken (selection state to change) FALSE if the click was ignored for whatever reason
See also:
SuperGallery; SGDisplayNode::InsertAfter; SGDisplayNode::InsertBefore

Reimplemented in SGDisplayItem.

Definition at line 2712 of file sgtree.cpp.

02714 {
02715     TRACEUSER( "Matt", _T("SGDisplyaNode::DefaultClickHandler called\n"));
02716     SuperGallery *ParentGallery = GetParentGallery();
02717 
02718     if (!AfterDrag)
02719     {
02720         // This was not called after having previously called DefaultPreDragHandler, 
02721         // so we have to do both halves of the processing. If PreDrag deals with it,
02722         // we don't need to do anything further.
02723         if (DefaultPreDragHandler(Mouse, MiscInfo))
02724             return(TRUE);
02725     }
02726 
02727     if (Mouse->DoubleClick && !Flags.Invisible)
02728     {
02729         // On double-click, this item becomes the only selected item, and
02730         // it is applied (if that action is supported by the parent gallery)
02731 
02732         ParentGallery->SelectItems(FALSE);  // Deselect everything else
02733         ParentGallery->SelectGroups(FALSE); // Deselect all groups
02734 
02735         // Repaint the list box now. This is because if there is a large
02736         // distance between the old selection and the new one, we get a huge
02737         // redraw cliprect, so get a (slow) complete redraw, instead of two
02738         // small redraws. It is thus better to break the redraw into 2 steps
02739         // so that we are more likely to get 2 fast redraws than one slow one.
02740         ParentGallery->PaintListNow();
02741     
02742         // And select myself, and do an immediate redraw
02743         SetSelected(TRUE);
02744         ParentGallery->PaintListNow();
02745 
02746         // Update the ParentGallery to know that we are the new multi-selection anchor
02747         ParentGallery->SetLastSelectedNode(this);
02748 
02749         // And inform the parent gallery that the selection may have changed
02750         ParentGallery->SelectionHasChanged();
02751     
02752         if (Mouse->Adjust)
02753         {
02754             BOOL ActionApplied = ParentGallery->ApplyAction(SGACTION_APPLYADJUST);
02755             if (!ActionApplied)
02756                 ActionApplied = ParentGallery->ApplyAction(SGACTION_APPLY);
02757 
02758             if (ActionApplied && AdjustDoubleClick)
02759             {
02760                 // Adjust/Ctrl double click of an item. This applies the item and then
02761                 // auto closes the gallery (just like RISC OS and Win95)
02762                 ParentGallery->SetVisibility(FALSE);
02763 
02764                 DialogBarOp::SetSystemStateChanged();   // Ensure toolbar button pops out again
02765             }
02766         }
02767 PORTNOTE("galleries", "Disabled clipart gallery")
02768 #ifndef EXCLUDE_FROM_XARALX
02769         else if (ParentGallery->IsKindOf(CC_RUNTIME_CLASS(LibFillsSGallery)))
02770                          LibClipartSGallery::ImportClipart(TRUE, (LibraryGallery*) ParentGallery);
02771 #endif
02772         else
02773             ParentGallery->ApplyAction(SGACTION_APPLY);
02774 
02775         return(TRUE);
02776     }
02777 
02778     // If this was an adjust click, it should toggle the selection state
02779     if (Mouse->Adjust)
02780     {
02781         BOOL AreWeSelected = IsSelected();
02782 
02783         // Mutual exclusion stuff... If we're a group, deselect all items, etc...
02784         if(this->IS_KIND_OF(SGDisplayGroup))
02785             ParentGallery->SelectItems(FALSE);
02786         else if(this->IS_KIND_OF(SGDisplayItem))
02787             ParentGallery->SelectGroups(FALSE);
02788         else
02789             ERROR3("What are we if we're not a group or an item ?");                
02790 
02791         // Invert my selection state, and do an immediate redraw
02792         SetSelected(!AreWeSelected);
02793         ParentGallery->PaintListNow();
02794 
02795         // Update the ParentGallery to know that we are the new multi-selection anchor
02796         ParentGallery->SetLastSelectedNode(this);
02797 
02798         // And inform the parent gallery that the selection may have changed
02799         ParentGallery->SelectionHasChanged();
02800 
02801         return(TRUE);
02802     }
02803     return(FALSE);
02804 }

BOOL SGDisplayNode::DefaultPreDragHandler SGMouseInfo Mouse,
SGMiscInfo MiscInfo
[virtual]
 

Provides part 1 of the default selection model for clicks on gallery display nodes. Should be called by all derived gallery DisplayItems to handle clicks upon them, when multiple-selection support is desired.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/4/95
Parameters:
Mouse - Information on the mouse state for this click [INPUTS] MiscInfo - the normal info as passed to event handlers
Returns:
TRUE if the click caused any action to be taken (selection state to change) FALSE if the click was ignored for whatever reason
You should call this method immediately prior to starting a drag as a result of a click event. Note that it is paired with DefaultClickHandler (which should be called when the drag you start turns out to be a click, if you want multiple-selection capability).

See the SGDisplayColour (kernel.cpp) for an example of use

See also:
SGDisplayItem::DefaultClickHandler; SGDisplayColour::HandleEvent

Reimplemented in SGDisplayGroup, and SGDisplayItem.

Definition at line 2573 of file sgtree.cpp.

02574 {
02575     if (Mouse->Adjust)      // Drags cannot be started with adjust
02576         return(FALSE);
02577 
02578     SuperGallery *ParentGallery = GetParentGallery();
02579 
02580     if (Mouse->Extend)
02581     {
02582         BOOL Handled = TRUE;
02583 
02584         // This was a click to extend the selection to the clicked item
02585 #if FALSE
02586 /* I was led to believe that this was how shift-select worked, but it isn't (thank God)
02587    so I have removed this case again - Jason
02588 
02589         if (IsSelected())
02590         {
02591             // If this item is selected, then shift-clicking it acts to leave it
02592             // selected, and deselect every other item.
02593             
02594             ParentGallery->SelectItems(FALSE);  // Deselect everything else
02595             ParentGallery->SelectGroups(FALSE); // Deselect all groups
02596 
02597             // Repaint the list box now. This is because if there is a large
02598             // distance between the old selection and the new one, we get a huge
02599             // redraw cliprect, so get a (slow) complete redraw, instead of two
02600             // small redraws. It is thus better to break the redraw into 2 steps
02601             // so that we are more likely to get 2 fast redraws than one slow one.
02602             ParentGallery->PaintListNow();
02603         
02604             // And select myself, with immediate redraw
02605             SetSelected(TRUE);
02606             ParentGallery->PaintListNow();
02607 
02608             // Update the ParentGallery to know that we are the new multi-selection anchor
02609             ParentGallery->SetLastSelectedNode(this);
02610 
02611             // And inform the parent gallery that the selection may have changed
02612             ParentGallery->SelectionHasChanged();
02613 
02614             return(TRUE);
02615         }
02616         else
02617 */
02618 #endif
02619         {
02620             if (ParentGallery->GetSelectedItemCount() == 0 && ParentGallery->GetSelectedGroupCount() == 0)
02621                 Handled = FALSE;    // No selection - treat extend-click as a normal click
02622             else
02623             {
02624                 ParentGallery->SelectItems(FALSE);  // Deselect all items
02625                 ParentGallery->SelectGroups(FALSE); // Deselect all groups
02626 
02627                 ParentGallery->SelectRange(this, ParentGallery->GetLastSelectedNode());
02628             }
02629         }
02630 
02631         if (Handled)
02632             return(TRUE);
02633     }
02634     
02635     
02636     if (!Flags.Selected)
02637     {
02638         if (!Mouse->Adjust)
02639         {
02640             // If it's not an adjust-click, deselect all other items and groups
02641             ParentGallery->SelectItems(FALSE);
02642             ParentGallery->SelectGroups(FALSE);
02643 
02644             // Repaint the list box now. This is because if there is a large
02645             // distance between the old selection and the new one, we get a huge
02646             // redraw cliprect, so get a (slow) complete redraw, instead of two
02647             // small redraws. It is thus better to break the redraw into 2 steps
02648             // so that we are more likely to get 2 fast redraws than one slow one.
02649             ParentGallery->PaintListNow();
02650         }
02651         else
02652         {
02653             // Mutual exclusion stuff... If we're a group, deselect all items, etc...
02654             if(this->IS_KIND_OF(SGDisplayGroup))
02655                 ParentGallery->SelectItems(FALSE);
02656             else if(this->IS_KIND_OF(SGDisplayItem))
02657                 ParentGallery->SelectGroups(FALSE);
02658             else
02659                 ERROR3("What are we if we're not a group or an item ?");                
02660         }
02661     
02662         // And select myself, and do an immediate redraw
02663         SetSelected(TRUE);
02664         ParentGallery->PaintListNow();
02665 
02666         // Update the ParentGallery to know that we are the new multi-selection anchor
02667         ParentGallery->SetLastSelectedNode(this);
02668 
02669         // And inform the parent gallery that the selection may have changed
02670         ParentGallery->SelectionHasChanged();
02671 
02672         return(TRUE);
02673     }
02674 
02675     return(FALSE);
02676 }

void SGDisplayNode::DeregisterForBGRedraw void   )  [protected, virtual]
 

Ensures that this node is not pending background redraw (resets it) This is called in response to SGEVENT_BGFLUSH, when flushing BG redraws.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/4/95
DO NOT call this method directly - see ShouldIDrawForeground()

Notes: DO NOT TOUCH the Flags.RedrawPending member variable directly!

See also:
SGDisplayNode::RegisterForBGRedraw; SGDisplayNode::ShouldIDrawForeground

Definition at line 1627 of file sgtree.cpp.

01628 {
01629     if (Flags.RedrawPending /*&& !Flags.Invisible*/)
01630     {
01631         SuperGallery *ParentGallery = GetParentGallery();
01632 
01633         if (ParentGallery != NULL)
01634             ParentGallery->DecrementPendingRedraws();
01635 
01636         Flags.RedrawPending = FALSE;        // And finally, turn off pending flag
01637     }
01638 }

void SGDisplayNode::DestroySubtree BOOL  IncludingThisNode = TRUE  )  [virtual]
 

DESTROYS the subtree starting at (and including, if IncludingThisNode is TRUE) this node. This does a depth-first recursive scan of the subtree, delinking each item, and then CALLING EACH ITEMS DESTRUCTOR.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/10/94
Parameters:
IncludingThisNode - TRUE (The default) to delete this node (the root of [INPUTS] the subtree) as well as all its children. FALSE to delete its children only (This leaves this node untouched, but vapes all child nodes)
Notes: If you destroy at the root node, the entire tree is destroyed. The root node will be deleted, but note that the reference(s) to the root node (e.g. in the parent SuperGallery) will NOT be de-linked, so be *very* careful!

However, if the root node is a derived SGDisplayRoot node, it will refuse to delete itself in this case,

Returns:
Errors: May be generated by the RemoveFromTree and destructor calls if the subtree is in some way corrupt - see these calls for details.
An ERROR3 may be caused by the destructor if you are trying to delete a tree item from within that item's event handler!

See also:
SuperGallery; SGDisplayNode::RemoveFromTree; SGDisplayNode::~SGDisplayNode

Reimplemented in SGDisplayRoot.

Definition at line 754 of file sgtree.cpp.

00755 {
00756     while (GetChild() != NULL)          // Recurse depth-first down the subtree, destroying it
00757         GetChild()->DestroySubtree();   // Destroy child. Child now points at the next child
00758 
00759     if (IncludingThisNode)          // If this node is included in the destruction...
00760     {
00761         RemoveFromTree();           // Delink ourself from the tree
00762         delete this;                // and invoke our own destructor
00763     }
00764 }

INT32 SGDisplayNode::DevicePixels SGMiscInfo MiscInfo,
INT32  NumPixels
[inline, protected]
 

Because we work in millipoints, it is difficult to get the right values for 'thin' lines (1-device pixel thick) or thin gaps (e.g. 1 or 2 pixels) This function uses the FormatInfo to determine the size, in millipoints, of device pixels, and multiplies this by the input parameter, to give the size in millipoints of that many device pixels.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/94
Parameters:
MiscInfo - A structure containing information relevant to gridlocking. [INPUTS] This is passed into all HandleEvent calls.
NumPixels - the number of 'pixels' you want

See also:
SGDisplayNode::GridLock; SGDisplayNode::GridLockRect

Definition at line 952 of file sgtree.h.

00953 {
00954     return(NumPixels * MiscInfo->PixelSize);
00955 }

BOOL SGDisplayNode::DoBGRedraw SGMiscInfo MiscInfo  )  [protected, virtual]
 

Forces an immediate redraw of a given node, if it is pending for background redraw.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/4/95
Parameters:
MiscInfo - the usual [INPUTS]
Returns:
TRUE to claim the redraw event, FALSE to not claim it
This is used by the base-class system to render items waiting for BG redraw, but can also be used by derived classes to force a given item to be visible immediately. e.g. This might be done if your item is clicked while waiting to be redrawn.

DO NOT call this method directly - see ShouldIDrawForeground()

Notes: DO NOT TOUCH the Flags.RedrawPending member variable directly!

See also:
SGDisplayNode::RegisterForBGRedraw; SGDisplayNode::ShouldIDrawForeground

Definition at line 1512 of file sgtree.cpp.

01513 {
01514     BGRenderClaimed = FALSE;            
01515 
01516     if (Flags.RedrawPending /*&& !Flags.Invisible*/)
01517     {
01518         SuperGallery *ParentGallery = GetParentGallery();
01519 
01520         if (ParentGallery != NULL)
01521         {
01522             // Interlock the redraw with the drag manager to make sure the screen isn't
01523             // screwed up by us redrawing over a solid drag
01524             DocRect KernelRect(FormatRect);
01525             BOOL NeedInterlock = ParentGallery->ConvertFromVirtualCoords(MiscInfo, &KernelRect);
01526 
01527             if (NeedInterlock)
01528             {
01529                 DragManagerOp::RedrawStarting(ParentGallery->WindowID,
01530                                             ParentGallery->GetListGadgetID(),
01531                                             &KernelRect);
01532             }
01533 
01534             CurrentBGRenderNode = this;
01535             ForceRedrawOfMyself();              // Invalidate myself
01536             ParentGallery->PaintListNow();      // And immediately redraw
01537             CurrentBGRenderNode = NULL;
01538 
01539             if (NeedInterlock)
01540                 DragManagerOp::RedrawFinished();
01541 
01542         }
01543     }
01544 
01545     return(BGRenderClaimed);
01546 }

SGDisplayNode * SGDisplayNode::DoBGRedrawPass SGMiscInfo MiscInfo  ) 
 

Applies a background rendering pass to the display tree. This will scan the tree from this node onwards looking for a node to background render.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/5/95
Parameters:
MiscInfo - The usual gallery MiscInfo struct [INPUTS]
Returns:
NULL, or a pointer to the last rendered node.
Once a node has been background rendered, this method will return the node which was rendered - SuperGalleries store this in LastBackgroundNode, and will call this method again, using that pointer as a point to start scanning from.

This makes scanning for background rendering nodes generally very much more efficient than searching the entire tree each time, as usually bg render nodes occur in sequential runs in the tree.

Notes: The SGDisplayNode RemoveFromTree method ensures that the parent gallery does not use this pointer after the node is deleted, by calling SuperGallery::SetLastBackgroundNode(NULL) if necessary - if the system is changed, make sure that it is updated to ensure that the pointer is not called upon after the item it references has been deleted.

ONLY LEAF NODES are guaranteed to background render with this scheme

See also:
SGDisplayNode::RegisterForBGRedraw; SGDisplayNode::ShouldIDrawForeground; SuperGallery::SetLastBackgroundNode; SGDisplayNode::RemoveFromTree

Definition at line 1677 of file sgtree.cpp.

01678 {
01679     // If I'm not a leaf node, scan down the tree until the first leaf child is found
01680     if (GetChild() != NULL)
01681         return(GetChild()->DoBGRedrawPass(MiscInfo));
01682 
01683     // This is a bit nasty... The trouble is, if a group is virtualised, GetChild() will
01684     // return NULL and we won't go any further. In such situations we now execute this
01685     // bit of code here which will pass the rendering onto the next group...
01686     if (this->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup)))
01687     {
01688         if(GetNext() != NULL)
01689             return(GetNext()->DoBGRedrawPass(MiscInfo));
01690     }
01691 
01692     // Search (including ourself in the search) for the next node which needs to render
01693     // If we find one, we render it and return immediately, returning the pointer to that
01694     // node as the place to start the next BG rendering pass.
01695     SGDisplayNode *Ptr = this;
01696     while (Ptr != NULL)
01697     {
01698         if (Ptr->DoBGRedraw(MiscInfo))
01699             return(Ptr);
01700 
01701         Ptr = Ptr->GetNext();
01702     }
01703 
01704     // We failed to find a sibling that needs to redraw, so go skip on to the next group
01705     // To save the stack, we search until we find a likely candidate (a group with kids)
01706     Ptr = Parent;
01707     while (Ptr != NULL)
01708     {
01709         // Go on to the next sibling of our parent
01710         Ptr = Ptr->GetNext();
01711 
01712         if (Ptr != NULL && (Ptr->Flags.RedrawPending || Ptr->GetChild() != NULL))
01713             return(Ptr->DoBGRedrawPass(MiscInfo));
01714     }
01715 
01716     // We didn't find anything to draw. On the next pass, we'll start from the root of
01717     // the tree again (we pass back NULL, and the SuperGallery starts from scratch)
01718     return(NULL);
01719 }

void SGDisplayNode::DragWasReallyAClick SGMouseInfo MouseInfo,
SGMiscInfo MiscInfo
[virtual]
 

Handles a mouse click event. This is a callback function - drags of items from galleries will call this function back if the drag turns out to just be a click.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/3/95
Parameters:
MouseInfo - The mouse info passed to the original click handler [INPUTS] MiscInfo - The misc info passed to the original click handler
Notes: The base class method takes no action whatsoever. Derived classes should override this method to do something useful.

For a description of how to use this, see the documentation, or take a look at other galleries for example code.

Documentation: docs.doc

See also:
SGDisplayNode::HandleEvent; SGDisplayNode::DefaultDragHandler

Reimplemented in SGNameItem, SGDisplayKernelBitmap, SGDisplayColour, SGLibDisplayItem, LineAttrItem, SGDisplayGroup, and SGDisplayPreviewFonts.

Definition at line 1306 of file sgtree.cpp.

01307 {
01308     // The base class does nothing
01309 }

void SGDisplayNode::DrawBitmap RenderRegion Renderer,
DocRect BoundsRect,
UINT32  ResID
[protected]
 

Draws the given bitmap to screen in the given DocRect of the supergallery display list. (Used to be necessary before RR:DrawBitmap came along).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/2/95
Parameters:
Renderer - The render region to render with [INPUTS] BoundsRect - The rectangle to draw the bitmap into ResID - A non-zero bitmap-resource identifier (the bitmap to draw)
See also:
RenderRegion::DrawBitmap

Definition at line 2479 of file sgtree.cpp.

02480 {
02481     ERROR3IF(Renderer == NULL || BoundsRect == NULL || ResID == 0,
02482             "SGDisplayNode::DrawBitmap - NULL Parameter(s) are illegal");
02483 
02484 //  if (!Flags.Invisible)
02485 //  {
02486         Renderer->DrawBitmap(BoundsRect->lo, ResID);
02487 //  }
02488 }

void SGDisplayNode::DrawPlinth SGRedrawInfo RedrawInfo,
SGMiscInfo MiscInfo,
DialogColourInfo RedrawColours,
DocRect ButtonRect,
BOOL  Indented = FALSE,
UINT32  GlyphResourceID = 0
[protected]
 

Draws a plinth (2 white lines and 2 dark grey lines) around the inside edge of the given rectangle, in order to give a Windows 95 like button plinth. It can include a button glyph bitmap. It's static so anybody can call it if they so desire.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/1/95
Parameters:
RedrawInfo - The redraw info, as normal with all this redraw stuff [INPUTS] MiscInfo - The MiscInfo, as normal for a SG Event RedrawColours - The object what knows about them thar plotting colours ButtonRect - The rectangle inside which to draw the plinth Indented - TRUE for indented button, FALSE for raised button GlyphResourceID - 0 (for no glyph, in which case the plinth 'face' is flat- filled with the appropriate colour), else the resource ID of a bitmap to be drawn in the center of the plinth/button.
Notes: It would be advantageous if the provided button rectangle is aligned to the device pixel grid if you want its appearance to be correct

The area within the plinth is filled with colour, so all pixels within the given rectangle are guaranteed to be painted - i.e. you do not need to clear the background region before calling this routine (indeed you should not, if you wish to avoid flicker)

Definition at line 2311 of file sgtree.cpp.

02315 {
02316     ERROR3IF(RedrawInfo == NULL || RedrawColours == NULL || ButtonRect == NULL,
02317             "SGDisplayNode::DrawPlinth - NULL parameters aer illegal");
02318 //  if (!Flags.Invisible)
02319 //  {
02320         RenderRegion *pRender = RedrawInfo->Renderer;
02321         pRender->SaveContext();
02322     
02323         pRender->SetLineWidth(0);
02324     
02325         // Fill inside the plinth with Button Face grey
02326         DocRect InsideRect(*ButtonRect);
02327         InsideRect.Inflate(-MiscInfo->PixelSize);
02328 
02329         // Fill inside the plinth with button-face (grey), and optionally with the glyph bitmap
02330         // (We always fill behind the bitmap first in case the bitmap isn't big enough to
02331         // fill the entire area)
02332         DocColour trans(COLOUR_TRANS);
02333         pRender->SetLineColour(trans);
02334         pRender->SetFillColour(RedrawColours->ButtonFace());
02335         pRender->DrawRect(&InsideRect);
02336 
02337         if (GlyphResourceID != 0)
02338         {
02339             // Quick v1.5 release bodge to center the up & down scroll arrow glyphs in the plinth
02340             if (GlyphResourceID == _R(IDB_GALLERY_SCROLLUP) || GlyphResourceID == _R(IDB_GALLERY_SCROLLDOWN))
02341             {
02342                 DocRect CenterRect(InsideRect);
02343                 CenterRect.Inflate(((7*MiscInfo->PixelSize) - CenterRect.Width())/2);   // Shrink to 7 pixels, centered
02344                 DrawBitmap(pRender, &CenterRect, GlyphResourceID);
02345             }
02346             else
02347                 DrawBitmap(pRender, &InsideRect, GlyphResourceID);
02348         }
02349 
02350         // Draw the plinth border
02351         DocColour LineCol;
02352 
02353         if (Indented)
02354             LineCol = RedrawColours->ButtonShadow();
02355         else
02356             LineCol = RedrawColours->ButtonHighlight();
02357 
02358         pRender->SetFillColour(LineCol);
02359 
02360         DocRect TempRect(*ButtonRect);                  // Left
02361         TempRect.hi.x = TempRect.lo.x + MiscInfo->PixelSize;
02362         pRender->DrawRect(&TempRect);
02363 
02364         TempRect = *ButtonRect;                         // Top
02365         TempRect.lo.y = TempRect.hi.y - MiscInfo->PixelSize;
02366         pRender->DrawRect(&TempRect);
02367 
02368         if (Indented)
02369             LineCol = RedrawColours->ButtonHighlight();
02370         else
02371             LineCol = RedrawColours->ButtonShadow();
02372     
02373         pRender->SetFillColour(LineCol);
02374         TempRect = *ButtonRect;                         // Right
02375         TempRect.lo.x = TempRect.hi.x - MiscInfo->PixelSize;
02376         pRender->DrawRect(&TempRect);
02377     
02378         TempRect = *ButtonRect;                         // Bottom
02379         TempRect.hi.y = TempRect.lo.y + MiscInfo->PixelSize;
02380         pRender->DrawRect(&TempRect);
02381     
02382         pRender->RestoreContext();
02383 //  }
02384 }

void SGDisplayNode::DrawSelectionOutline SGRedrawInfo RedrawInfo,
SGMiscInfo MiscInfo,
DocRect BoundsRect,
INT32  Width = 0
[protected]
 

Draws a black 2-pixel-thick frame-rectangle just inside the given Rect. This is the normal selection-rectangle outline which should go outside an icon or thumbnail when an item is selected.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/3/95
Parameters:
RedrawInfo - The info passed in to HandleEvent for redraws [INPUTS] MiscInfo - Standard miscinfo struct BoundsRect - The rectangle to draw the border into Width - 0 for a default (2-pixel-wide) border, else the width of the lines, in pixels. The outside of the frame will always touch the edge of the given rectangle, so essentially, this is used as a 'defalate' value to find the inside edge of the lines.
Notes: If you wish to draw inside the rectangle, use TheRect.Inflate(DevicePixels(MiscInfo, 2));

This draws 4 filled rectangles around the border of the rectangle. The area inside the rectangle is left unpainted - this will reduce flicker on large items as compared to blatting a single rectangle behind the icon/thumbnail.

Definition at line 2418 of file sgtree.cpp.

02420 {
02421     ERROR3IF(RedrawInfo == NULL || MiscInfo == NULL || BoundsRect == NULL,
02422             "SGDisplayNode::DrawSelectionOutline - NULL parameters aer illegal");
02423 
02424 //  if (!Flags.Invisible)
02425 //  {
02426         RenderRegion *pRender = RedrawInfo->Renderer;   
02427 
02428         if (Width == 0)         // Default value of zero means a 2-pixel border
02429             Width = DevicePixels(MiscInfo, 2);
02430 
02431         pRender->SaveContext();
02432     
02433         pRender->SetLineWidth(0);
02434         DocColour trans(COLOUR_TRANS);
02435         pRender->SetLineColour(trans);
02436         DocColour black(COLOUR_BLACK);
02437         pRender->SetFillColour(black);
02438 
02439         DocRect TempRect(*BoundsRect);                  // Left
02440         TempRect.hi.x = TempRect.lo.x + Width;
02441         pRender->DrawRect(&TempRect);
02442 
02443         TempRect = *BoundsRect;                         // Top
02444         TempRect.lo.y = TempRect.hi.y - Width;
02445         pRender->DrawRect(&TempRect);
02446 
02447         TempRect = *BoundsRect;                         // Right
02448         TempRect.lo.x = TempRect.hi.x - Width;
02449         pRender->DrawRect(&TempRect);
02450 
02451         TempRect = *BoundsRect;                         // Bottom
02452         TempRect.hi.y = TempRect.lo.y + Width;
02453         pRender->DrawRect(&TempRect);
02454 
02455         pRender->RestoreContext();
02456 //  }
02457 }

SGDisplayGroup * SGDisplayNode::FindSubtree SuperGallery ParentGal,
Document ParentDoc,
Library ParentLib
[virtual]
 

Searches this node and its subtree for any SGDisplayGroup nodes which have parent pointers which exactly match the input parameters. This is used to find the subtree for a given document or library.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/10/94
Parameters:
ParentGal - The parent gallery of the node to find [INPUTS] ParentDoc - The parent document of the node to find ParentLib - The parent library of the node to find
Returns:
NULL, or the found node
See also:
SGDisplayGroup::SGDisplayGroup

Definition at line 1745 of file sgtree.cpp.

01747 {
01748     SGDisplayNode  *Ptr = GetChild();
01749     SGDisplayGroup *Result;
01750 
01751     while (Ptr != NULL)
01752     {
01753         if (Ptr->IsKindOf(CC_RUNTIME_CLASS(SGDisplayGroup)))    // Search immediate children
01754         {
01755             Result = (SGDisplayGroup *) Ptr;
01756             if (Result->GetParentGallery()  == ParentGal &&
01757                 Result->GetParentDocument() == ParentDoc &&
01758                 Result->GetParentLibrary()  == ParentLib)
01759                 return(Result);
01760         }
01761 
01762                                                                 // Recurse down subtrees
01763         Result = Ptr->FindSubtree(ParentGal, ParentDoc, ParentLib);
01764         if (Result != NULL)
01765             return(Result);
01766 
01767         Ptr = Ptr->GetNext();                                   // No luck - try the next child
01768     }
01769 
01770     return(NULL);
01771 }

void SGDisplayNode::ForceRedrawOfMyself BOOL  bEraseBkg = TRUE  )  [virtual]
 

Uses the cached FormatRect to force-redraw the appropriate part of the SuperGallery display window to cause myself (only) to be redrawn.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Notes: Before redrawing, this scans up the tree to see if any parent is Folded. If this is the case, it returns without doing anything, as this item must therefore be hidden in the fold. By default, the background is erased. If bEraseBkg is FALSE, the backgound will not be altered before redrawing. (Adrian 10/05/97)

See also:
SuperGallery::ForceRedrawOfArea

Definition at line 1397 of file sgtree.cpp.

01398 {
01399 //  if (!Flags.Invisible)
01400 //  {
01401         SuperGallery *ParentGallery = GetParentGallery();
01402         if (ParentGallery != NULL)
01403         {
01404             // Before redrawing, search up the tree for any nodes which are folded - if there
01405             // are any, then I cannot be visible, so should not redraw!
01406 
01407             SGDisplayNode *Ptr = GetParent();
01408             while (Ptr != NULL)
01409             {
01410                 if (Ptr->Flags.Folded)
01411                     return;
01412 
01413                 Ptr = Ptr->GetParent();
01414             }
01415 
01416             // Not hidden in a fold, so redraw my rectangle and set the redraw mode
01417             BkgEraseMode = bEraseBkg ? TRUE : FALSE;
01418             ParentGallery->ForceRedrawOfArea(&FormatRect);
01419         }
01420 //  }
01421 }

void SGDisplayNode::ForceRedrawOfMyselfAndChildren void   )  [virtual]
 

Uses the cached FormatRect to force-redraw the appropriate part of the SuperGallery display window to cause myself to be redrawn - derived classes may override this to also redraw their children (SGDisplayNode).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95

Reimplemented in SGDisplayGroup.

Definition at line 1438 of file sgtree.cpp.

01439 {
01440 //  if (!Flags.Invisible)
01441 //  {
01442         ForceRedrawOfMyself();
01443 //  }
01444 }

BOOL SGDisplayNode::GetBubbleHelp DocCoord MousePos,
String_256 Result
[virtual]
 

Called by the parent gallery when bubble help is needed. The parent gallery will do a hit test to determine which node contains the pointer, and will then ask that node to supply bubble/status-line help.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/4/95
Parameters:
MousePos - The current mouse position. This will generally be expected [INPUTS] to lie inside this item's FormatRect. With it, this item can provide help on specific areas of an item.
On exit, if the return value is TRUE, the string pointed at by Result [OUTPUTS] will contain a bubble help string for this item
Returns:
TRUE if it filled in the string, FALSE if it did not
Notes: The base class returns FALSE (i.e. provides no help) If you can provide help, then override the base class method to do so.

See also:
SGDisplayNode::GetStatusLineHelp

Reimplemented in SGNameItem, SGDisplayColour, SGLibDisplayItem, SGLibGroup, SGNameItem, SGFontsGroup, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 1949 of file sgtree.cpp.

01950 {
01951     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01952     return(FALSE);
01953 }

SGDisplayNode * SGDisplayNode::GetChild void   )  const [virtual]
 

Finds the child of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94 (Made virtual on 13/5/95)
Returns:
A pointer to the first child of this SGDisplayNode object, or NULL
Notes: This base-class method returns NULL - base nodes and items do not have children (to reduce memory usage). SGDisplayRoot and SGDisplayGroup override this method to provide child pointers.

See also:
SGDisplayNode::SetChild; SuperGallery; SGDisplayNode::GetParent; SGDisplayNode::GetNext; SGDisplayNode::GetPrevious

Reimplemented in SGDisplayRoot, and SGDisplayGroup.

Definition at line 226 of file sgtree.cpp.

00227 {
00228     return NULL;
00229 }

SGClaimPointInfo * SGDisplayNode::GetClaimPointInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 1078 of file sgtree.h.

01079 {
01080     ERROR3IF(EventType != SGEVENT_CLAIMPOINT, "ClaimPointInfo not available for this event type!");
01081     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
01082     return((SGClaimPointInfo *) EventInfo);
01083 }

DragMessage * SGDisplayNode::GetDragInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/2/95
Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 1052 of file sgtree.h.

01053 {
01054     ERROR3IF(EventType != SGEVENT_DRAGSTARTED, "DragInfo not available for this event type!");
01055     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
01056     return((DragMessage *) EventInfo);
01057 }

SGFormatInfo * SGDisplayNode::GetFormatInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/1/95
Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 976 of file sgtree.h.

00977 {
00978     ERROR3IF(EventType != SGEVENT_FORMAT, "FormatInfo not available for this event type!");
00979     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
00980     return((SGFormatInfo *) EventInfo);
00981 }

void SGDisplayNode::GetFormatRect DocRect ResultFormatRect  )  [virtual]
 

Determines where this item wants to redraw itself within the logical window DocCoord coordinates. If this is not a visible node type, or if someone neglected to cache the value in overridden methods, returns (0,0,0,0).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/1/95
Parameters:
FormatRect - Returned containing the format rectangle where this item last [OUTPUTS] positioned itself - make sure a formatting event has gone around before calling this method, so that you get a meaningful result

Definition at line 1330 of file sgtree.cpp.

01331 {
01332     if (ResultFormatRect != NULL)
01333         *ResultFormatRect = FormatRect;
01334 }

void SGDisplayNode::GetFullInfoText String_256 Result  )  [virtual]
 

To determine a full-info string for this node. Generally, this is used for a simple mechanism which searches for display items whose info matches given search parameters in some way. It is also used in libraries to provide default redraw methods.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/3/95
Parameters:
On exit, the string pointed at by Result will contain either a blank [OUTPUTS] string, or the full-information text associated with this item (if any) (NOTE that the FullInfo string does NOT include the name!)
Notes: The base class returns a blank string

If you can provide a better full-info string, then override the base class method to do so.

See also:
SGDisplayNode::GetNameText

Reimplemented in SGDisplayKernelBitmap, SGDisplayColour, SGLibDisplayItem, SGDisplayPreviewFonts, SGTTFItem, SGATMItem, and SGLibFontItem.

Definition at line 1882 of file sgtree.cpp.

01883 {
01884     ERROR3IF(Result == NULL, "Illegal NULL param");
01885     if(Result == NULL) return;
01886 
01887     *Result = TEXT("");
01888 }

void SGDisplayNode::GetKeyWords String_256 Result  )  [virtual]
 

To determine the keywords for this node. Generally, this is used for a simple searching mechanism.

Author:
Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/3/95
Parameters:
On exit, the string pointed at by Result will contain either a blank [OUTPUTS] string, or a list of | seperated keywords associated with the item
Notes: The base class returns a blank string. If you can provide a better name string, then override the base class method to do so.

See also:
SGDisplayNode::GetFullInfoText

Reimplemented in SGLibDisplayItem, and SGDisplayPreviewFonts.

Definition at line 1912 of file sgtree.cpp.

01913 {
01914     ERROR3IF(Result == NULL, "Illegal NULL param");
01915     if(Result == NULL) return;
01916 
01917     *Result = TEXT("");
01918 }

CWindowID SGDisplayNode::GetListWindow void   )  [protected]
 

Returns the window id of the list box window of the parent gallery.

Author:
Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/05/2006
See also:
-

Definition at line 2820 of file sgtree.cpp.

02821 {
02822     return(DialogManager::GetGadget(GetParentGallery()->GetReadWriteWindowID(), GetParentGallery()->GetListGadgetID()));
02823 }

SGMouseInfo * SGDisplayNode::GetMouseInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/1/95
Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 1026 of file sgtree.h.

01027 {
01028     ERROR3IF(EventType != SGEVENT_MOUSECLICK, "MouseInfo not available for this event type!");
01029     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
01030     return((SGMouseInfo *) EventInfo);
01031 }

void SGDisplayNode::GetNameText String_256 Result  )  [virtual]
 

To determine a name string for this node. Generally, this is used for a simple mechanism which searches for display items whose names match given search parameters in some way. It is also used in libraries to provide default redraw methods.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/3/95
Parameters:
On exit, the string pointed at by Result will contain either a blank [OUTPUTS] string, or the name text associated with this item (if any)
Notes: The base class returns a blank string. If you can provide a better name string, then override the base class method to do so.

See also:
SGDisplayNode::GetFullInfoText

Reimplemented in SGNameItem, SGDisplayDATATYPE, SGDisplayKernelBitmap, SGDisplayColour, SGDisplayLibColour, SGLibDisplayItem, LineAttrItem, SGNameItem, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 1847 of file sgtree.cpp.

01848 {
01849     ERROR3IF(Result == NULL, "Illegal NULL param");
01850     if(Result == NULL) return;
01851 
01852     *Result = TEXT("");
01853 }

SGDisplayNode * SGDisplayNode::GetNext void   )  const [inline]
 

Finds the next (right) sibling of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Returns:
A pointer to the resquested SGDisplayNode object, or NULL
See also:
SuperGallery; SGDisplayNode::GetParent; SGDisplayNode::GetChild; SGDisplayNode::GetPrevious

Definition at line 872 of file sgtree.h.

00873 {
00874     return Next;
00875 }

SGDisplayNode * SGDisplayNode::GetParent  )  const [inline]
 

Finds the parent of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Returns:
A pointer to the resquested SGDisplayNode object, or NULL
See also:
SuperGallery; SGDisplayNode::GetChild; SGDisplayNode::GetNext; SGDisplayNode::GetPrevious

Definition at line 849 of file sgtree.h.

00850 {
00851     return Parent;
00852 }

SuperGallery * SGDisplayNode::GetParentGallery void   )  const [virtual]
 

Recursively scans up the tree asking each parent node in turn for the parent gallery. It is expected that a node (eg SGDisplayRoot or SGDisplayGroup) will be found somewhere on this path which will know who our parent gallery is. (If not, there is a serious tree problem!).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Returns:
NULL if a cataclysmic event occurs Otherwise,a pointer to the SuperGallery that 'owns' the tree this node is in
Nodes which directly know their parent gallery must override this method to ensure that they return the correct result instead of asking their parent!

See also:
SGDisplayRoot::GetParentGallery; SGDisplayGroup::GetParentGallery

Reimplemented in SGDisplayRoot, and SGDisplayGroup.

Definition at line 790 of file sgtree.cpp.

00791 {
00792     if (GetParent() != NULL) return GetParent()->GetParentGallery();
00793 
00794     return NULL;
00795 }

SGDisplayNode * SGDisplayNode::GetPrevious  )  const [inline]
 

Finds the previous (left) sibling of this DisplayTree Node. Returns NULL if you have reached the boundary of the tree.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Returns:
A pointer to the resquested SGDisplayNode object, or NULL
See also:
SuperGallery; SGDisplayNode::GetParent; SGDisplayNode::GetChild; SGDisplayNode::GetNext;

Definition at line 895 of file sgtree.h.

00896 {
00897     return Previous;
00898 }

SGRedrawInfo * SGDisplayNode::GetRedrawInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/1/95
Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 1001 of file sgtree.h.

01002 {
01003     ERROR3IF(EventType != SGEVENT_REDRAW, "RedrawInfo not available for this event type!");
01004     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
01005     return((SGRedrawInfo *) EventInfo);
01006 }

BOOL SGDisplayNode::GetStatusLineHelp DocCoord MousePos,
String_256 Result
[virtual]
 

Called by the parent gallery when status line help is needed. The parent gallery will do a hit test to determine which node contains the pointer, and will then ask that node to supply bubble/status-line help.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/4/95
Parameters:
MousePos - The current mouse position. This will generally be expected [INPUTS] to lie inside this item's FormatRect. With it, this item can provide help on specific areas of an item.
On exit, if the return value is TRUE, the string pointed at by Result [OUTPUTS] will contain a status line help string for this item
Returns:
TRUE if it filled in the string, FALSE if it did not
Notes: The base class returns FALSE (i.e. provides no help) If you can provide help, then override the base class method to do so.

See also:
SGDisplayNode::GetBubbleHelp

Reimplemented in SGNameItem, SGDisplayKernelBitmap, SGDisplayColour, SGLibDisplayItem, SGLibGroup, LineAttrItem, SGNameItem, SGFontsGroup, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 1984 of file sgtree.cpp.

01985 {
01986     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01987     return(FALSE);
01988 }

ThumbMessage * SGDisplayNode::GetThumbMsgInfo SGEventType  EventType,
void *  EventInfo
[inline]
 

Extracts certain event information from the event information passed in to a SGDisplayNode::HandleEvent() method. Not only gets the info for you, but checks the validity (ERROR3's if you've asked for the wrong type of information for the current event type, and if the information is NULL).

Parameters:
EventType - The type of the current event [INPUTS] EventInfo - TheEventInfo for the current event

Definition at line 1104 of file sgtree.h.

01105 {
01106     ERROR3IF(EventType != SGEVENT_THUMBMSG, "ThumbMsg info not available for this event type!");
01107     ERROR3IF(EventInfo == NULL, "EventInfo for this event was NULL!");
01108     return((ThumbMessage *) EventInfo);
01109 }

BOOL SGDisplayNode::GiveEventToMyChildren SGEventType  EventType,
void *  EventInfo,
SGMiscInfo MiscInfo
[protected, virtual]
 

Causes the entire subtree below this node to check their formatting, and handle the given event. Once a node returns TRUE from its HandleEvent method, the event will NOT be passed on.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
EventType - An enumerated value describing what type of event is to be processed [INPUTS]
EventInfo - A structure describing the event (may be NULL). The exact thing pointed at by this pointer depends upon the event type:

MonoOn Event Thing EventInfo points at SGEVENT_FORMAT (SGFormatInfo *) SGEVENT_REDRAW (SGRedrawInfo *) SGEVENT_MOUSECLICK (SGMouseInfo *) MonoOff

Use the SGDisplayNode::Get[Format]Info() inlines to retrieve this information for you (it does helpful ERROR3 checking for you)

MiscInfo - A structure containing any other relevant information. This will always be non-NULL, and contain valid information.

Parameters:
FormatInfo is updated as appropriate [OUTPUTS]
Returns:
TRUE if the event was handled successfully FALSE if it was not
Notes: This is used by derived classes to save them the work of having to scan the tree in their own event code - each node just redraws itself, and then passes the event along by calling this function.

If this node is folded, then it is treated as having no children (as they do not appear in the displayed list.

The traversal loops in this code can handle any nodes being deleted around them, except for the "current node". However, in debug builds the "current node" should refuse to be deleted while it is handling an event. The traversal loops increment the "HandleEventCount" during calls to all the node HandleEvent methods in order to be able to detect this situation (It's done here to save doing it in all derived HandleEvent methods).

See also:
SGDisplayNode::HandleEvent; SGDisplayRoot::HandleEvent; SGDisplayGroup::HandleEvent; SGDisplayItem::HandleEvent

Definition at line 855 of file sgtree.cpp.

00857 {
00858     BOOL Handled = FALSE;
00859     SGDisplayNode *Ptr = GetChild();
00860 //  SGDisplayNode *NextPtr = NULL;
00861 
00862     if (EventType == SGEVENT_FORMAT)
00863     {
00864         // We're formatting, so update FormatInfo as we go
00865         SGFormatInfo *FormatInfo = GetFormatInfo(EventType, EventInfo);
00866 
00867         NewLine(FormatInfo, MiscInfo);      // When going down the tree, go to a new line
00868 
00869         if (Flags.Folded || Ptr == NULL)    // If folded, or no children, return
00870             return(FALSE);
00871 
00872         if (!Flags.Invisible)
00873             FormatInfo->IndentLevel++;      // Increment the indent level
00874 
00875         while (Ptr != NULL && !Handled)
00876         {
00877             // Call each child's handler in turn. We can cope with any child being deleted except
00878             // for the current one. To detect this, we increment HandleEventCOunt across the
00879             // call, which will trigger ERROR3's in the destructor if we attempt suicide!
00880             Ptr->Flags.HandleEventCount++;
00881             ERROR3IF(Ptr->Flags.HandleEventCount > 100,
00882                         "Rampant recursion or node corruption in GiveEventToMyChildren");
00883             if (Ptr->HandleEvent(EventType, EventInfo, MiscInfo))
00884                 Handled = TRUE;
00885             Ptr->Flags.HandleEventCount--;
00886 
00887             Ptr = Ptr->Next;
00888         }
00889 
00890         if (!Flags.Invisible)
00891             FormatInfo->IndentLevel--;      // Restore the indent level
00892 
00893         NewLine(FormatInfo, MiscInfo);      // When ascending back up the tree, go to a new line
00894 
00895         FormatInfo->LineHeight = UpTreeGap;
00896         NewLine(FormatInfo, MiscInfo);      // ... and add a small gap
00897     }
00898     else
00899     {
00900         if (Ptr == NULL)        // We have no children, so return
00901             return(FALSE);
00902 
00903         if (EventType != SGEVENT_BGFLUSH && Flags.Folded)
00904         {
00905             // If folded, return (but not if this is a FLUSH, which MUST go to ALL)
00906             return(FALSE);
00907         }
00908 
00909         while (Ptr != NULL && !Handled)
00910         {
00911             // Call each child's handler in turn. We can cope with any child being deleted except
00912             // for the current one. To detect this, we increment HandleEventCOunt across the
00913             // call, which will trigger ERROR3's in the destructor if we attempt suicide!
00914             Ptr->Flags.HandleEventCount++;
00915             ERROR3IF(Ptr->Flags.HandleEventCount > 100,
00916                         "Rampant recursion or node corruption in GiveEventToMyChildren");
00917             if (Ptr->HandleEvent(EventType, EventInfo, MiscInfo))
00918                 Handled = TRUE;
00919             Ptr->Flags.HandleEventCount--;
00920 
00921             Ptr = Ptr->Next;
00922         }
00923     }
00924 
00925     return(Handled);
00926 }

INT32 SGDisplayNode::GridLock SGMiscInfo MiscInfo,
INT32  Coordinate
[inline, static, protected]
 

In order to avoid rounding errors in the mapping between millipoints and output device pixels from causing coordinates to alias to different pixels when in different positions, all SuperGallery display coordinates must be snapped onto a grid of pixel-positions. This function does this snapping.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/94
Parameters:
MiscInfo - A structure containing information relevant to gridlocking. [INPUTS] This is passed into all HandleEvent calls.
Coordinate - the coord to be snapped onto the pixel grid

See also:
SGDisplayNode::GridLockRect; SGDisplayNode::DevicePixels

Definition at line 923 of file sgtree.h.

00924 {
00925     return(Coordinate - (Coordinate % MiscInfo->PixelSize));
00926 }

void SGDisplayNode::GridLockRect SGMiscInfo MiscInfo,
DocRect Rect
[static, protected]
 

Given a rectangle and the normal FormatInfo, this ensures that all points of the rectangle are snapped onto a grid of the destination device pixels. This ensures that aliasing effects, due to rounding errors when mapping to the output pixel coordinates, do not occur.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/94
Parameters:
FormatInfo - A structure containing all relevant information for items to [INPUTS] calculate their formatted positions in the display list. NOTE this is also an output!
Rect - A rectangle which needs to be locked to the pixel grid

Parameters:
FormatInfo - updated as appropriate [OUTPUTS] Rect - modified as necessary to lock its points to the pixel grid
See also:
SGDisplayNode::GridLock; SGDisplayNode::DevicePixels

Definition at line 991 of file sgtree.cpp.

00992 {
00993     Rect->lo.x = GridLock(MiscInfo, Rect->lo.x);
00994     Rect->lo.y = GridLock(MiscInfo, Rect->lo.y);
00995     Rect->hi.x = GridLock(MiscInfo, Rect->hi.x);
00996     Rect->hi.y = GridLock(MiscInfo, Rect->hi.y);
00997 }

BOOL SGDisplayNode::HandleEvent SGEventType  EventType,
void *  EventInfo,
SGMiscInfo MiscInfo
[virtual]
 

Handles a generic display tree event. Events of interest trigger specific actions.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/4/95 (was pure virtual before then)
Parameters:
EventType - Indicates the event type to be handled (see SGEventType) [INPUTS]
EventInfo - NULL, or points at a structure containing useful info for processing this specific event. (See SGEventInfo)

MiscInfo - Always supplied. Points at an SGMiscInfo struct which contains miscellanous useful information.

Generally overridden to provide redraw, mouse click, etc functionality. Overridden methos should call the base class for any event types which are unknown or which they do not specifically want to handle.

For a description of how to use this, see the documentation, or take a look at other SGDisplay* types and galleries for example code.

The base class doesn't do much, but does handle background redraw, and will pass all unhandled events on to its children (if any)

Documentation: docs.doc

Reimplemented in SGNameItem, SGDisplayDATATYPE, SGDisplayKernelBitmap, SGDisplayColour, SGDisplayLibColour, SGDisplayFrame, SGFrameGroup, SGDisplayLayer, SGLayerGroup, SGClipartItem, SGFillsItem, SGLibDisplayItem, SGLibGroup, LineAttrItem, SGNameItem, SGDisplayRoot, SGDisplayRootScroll, SGDisplayGroup, SGDisplayItem, SGFontsGroup, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 1253 of file sgtree.cpp.

01254 {
01255     switch(EventType)
01256     {
01257 // Now handled by recursive DoBGRedrawPass method
01258 //      case SGEVENT_BGREDRAW:
01259 //          // Redraw in the background if necessary. This will return TRUE if it claims
01260 //          // the event (the first one that successfully background renders will claim
01261 //          // the event)
01262 //          if (DoBGRedraw(MiscInfo))
01263 //              return(TRUE);
01264 //          break;
01265 
01266         case SGEVENT_BGFLUSH:
01267             DeregisterForBGRedraw();
01268             break;              // And drop through to flush all children
01269         default:
01270             break;
01271     }
01272 
01273     // And pass all events on to my children
01274     return(GiveEventToMyChildren(EventType, EventInfo, MiscInfo));
01275 }

BOOL SGDisplayNode::IMustRedraw SGRedrawInfo RedrawInfo  )  [protected]
 

To determine if a given item needs to be redrawn. This is done by determining if its bounding rectangle ('FormatRect') overlaps the bounding rectangle of the area to be redrawn as specified by RedrawInfo->Bounds.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/10/94
Parameters:
RedrawInfo - The redraw information indicating the redraw Bounds [INPUTS]
Returns:
TRUE if this item should redraw itself. FALSE if it need not bother
Notes: Obviously, if FormatRect has not been correctly calculated/cached, this method will give spurious results!

See also:
SGDisplayNode::CalculateFormatRect

Definition at line 1361 of file sgtree.cpp.

01362 {
01363     // No redraw info?!
01364     if (RedrawInfo == NULL)
01365         return(TRUE);
01366 
01367     // Determine if the rect overlaps RedrawInfo->Bounds, returning TRUE if it does
01368     return (FormatRect.lo.y <= RedrawInfo->Bounds.hi.y &&
01369             FormatRect.hi.y >= RedrawInfo->Bounds.lo.y &&
01370             FormatRect.lo.x <= RedrawInfo->Bounds.hi.x &&
01371             FormatRect.hi.x >= RedrawInfo->Bounds.lo.x);
01372 }

void SGDisplayNode::InsertAfter SGDisplayNode NodeToInsert  )  [virtual]
 

Inserts the given node into the DisplayTree as the next (right) sibling of this node.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
NodeToInsert - the node to, ... erm... insert. [INPUTS]
Notes: The derived SGDisplayRoot node overrides this with a call to AddItem()

Returns:
Errors: ERROR3 and quiet exit if NodeToInsert == NULL
See also:
SuperGallery; SGDisplayNode::InsertBefore; SGDisplayNode::AddItem

Reimplemented in SGDisplayRoot.

Definition at line 496 of file sgtree.cpp.

00497 {
00498     // Set the parent to modified to signify that one of it's children has been
00499     SGDisplayNode *Parent = GetParent();
00500     if(Parent != NULL)
00501         Parent->Flags.Modified = TRUE;
00502 
00503     InsertInternal(NodeToInsert, this, Next);
00504 }

void SGDisplayNode::InsertBefore SGDisplayNode NodeToInsert  )  [virtual]
 

Inserts the given node into the DisplayTree as the previous (left) sibling of this node.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
NodeToInsert - the node to, ... erm... insert. [INPUTS]
Notes: The derived SGDisplayRoot node overrides this with a call to AddItem()

Returns:
Errors: ERROR3 and quiet exit if NodeToInsert == NULL
See also:
SuperGallery; SGDisplayNode::InsertAfter; SGDisplayNode::AddItem

Reimplemented in SGDisplayRoot.

Definition at line 528 of file sgtree.cpp.

00529 {
00530     // Set the parent to modified to signify that one of it's children has been
00531     SGDisplayNode *Parent = GetParent();
00532     if(Parent != NULL)
00533         Parent->Flags.Modified = TRUE;
00534 
00535     InsertInternal(NodeToInsert, Previous, this);
00536 }

void SGDisplayNode::InsertInternal SGDisplayNode NodeToInsert,
SGDisplayNode PrevNode,
SGDisplayNode NextNode
[protected, virtual]
 

Inserts the given node/subtree into this subtree, between PrevNode and NextNode. One of these two nodes may be NULL if you are trying to insert at the head/tail of a sibling list.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
NodeToInsert - the node to insert [INPUTS] PrevNode - NULL, or the node to insert after NextNode - NULL, or the node to insert before
Returns:
Errors: ERROR3s will be reported in debug builds for NULL NodeToInsert, or if NodeToInsert is linked into another tree (has non-null parent/next/previous pointers). It is perfectly legal for it to have a child subtree, though.
Errors will also occur if BOTH Next/PrevNode are NULL, or if PrevNode is not currently the Previous Node of NextNode. (i.e. you must insert between two valid adjacent nodes, or at the head/tail of the sibling list)

See also:
SuperGallery; SGDisplayNode::AddItem; SGDisplayNode::InsertAfter; SGDisplayNode::InsertBefore

Definition at line 289 of file sgtree.cpp.

00291 {
00292     if (NodeToInsert == NULL)
00293     {
00294         ERROR3("Attempt to insert a NULL node into a tree was ignored");
00295         return;
00296     }
00297 
00298     // The node cannot be inserted after/before *itself*!
00299     ERROR3IF(NodeToInsert == PrevNode || NodeToInsert == NextNode,
00300             "Illegal attempt to link a node before/after ITSELF!");
00301 
00302     // The node cannot have parent, next, prev, but can have children
00303     ERROR3IF(NodeToInsert->Parent != NULL ||
00304              NodeToInsert->Next != NULL   || NodeToInsert->Previous != NULL,
00305              "Illegal attempt to link an already-linked node into a tree");
00306 
00307     ERROR3IF(PrevNode == NULL && NextNode == NULL,
00308              "SGDisplayNode::InsertInternal - can't insert between TWO NULL nodes!");
00309 
00310     ERROR3IF((PrevNode != NULL && PrevNode->Next != NextNode) ||
00311              (NextNode != NULL && NextNode->Previous != PrevNode),
00312              "SGDisplayNode::InsertInternal - Prev/Next nodes are not adjacent!");
00313 
00314     NodeToInsert->Previous = PrevNode;
00315     if (PrevNode != NULL)
00316     {
00317         // Linking in the middle of the sibling list
00318         PrevNode->Next = NodeToInsert;
00319         NodeToInsert->Parent = PrevNode->Parent;
00320     }
00321     else
00322     {
00323         // Must be trying to insert at the head of the sibling list, so becomes 1st child
00324         if (NextNode != NULL)
00325         {
00326             ERROR3IF(NextNode->Parent->GetChild() != NextNode,
00327                         "Attempt to Insert node as first child has gone awry!");
00328         
00329             NextNode->Parent->SetChild(NodeToInsert);
00330         }
00331     }
00332 
00333     NodeToInsert->Next = NextNode;
00334     if (NextNode != NULL)
00335     {
00336         NextNode->Previous = NodeToInsert;
00337         NodeToInsert->Parent = NextNode->Parent;
00338     }
00339 
00340     // Because we have recreated part of the tree, we must inform the gallery that the
00341     // cached format is incorrect and needs to be recalculated.
00342     SuperGallery *ParentGallery = GetParentGallery();
00343     if (ParentGallery != NULL)
00344         ParentGallery->InvalidateCachedFormat();
00345 }

BOOL SGDisplayNode::IsSelected void   )  [inline]
 

Returns TRUE if this item is selected, FALSE if it is not.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/94
See also:
SGDisplayItem::SetSelected

Definition at line 1126 of file sgtree.h.

01127 {
01128     return(Flags.Selected);
01129 }

void SGDisplayNode::MoveAfter SGDisplayNode NodeToMove  )  [virtual]
 

MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/3/95
Parameters:
NodeToMove - the node to move [INPUTS]
Notes: This base class method simply delinks the item and relinks it elsewhere in the display tree. However, derived classes will override this method so that moving display items can have a further effect of also rearranging the displayed "real" items. Before/After moving the real item, the derived class can then call this baseclass method to complete the action.

Take care when moving items between groups (e.g. if an item is "moved" from one docuemnt to another, it could be a bad thing, so be very careful in derived classes to take appropriate action)

Any attempt to move an item after *itself* is queitly ignored

Returns:
Errors: ERROR3 and quiet exit if NodeToMove == NULL
See also:
SuperGallery; SGDisplayNode::InsertAfter; SGDisplayNode::AddItem

Reimplemented in SGDisplayKernelBitmap, SGDisplayColour, SGDisplayLayer, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 571 of file sgtree.cpp.

00572 {
00573     ERROR3IF(NodeToMove == NULL, "Illegal NULL param");
00574 
00575     if (NodeToMove == this)
00576         return;
00577 
00578     NodeToMove->RemoveFromTree();
00579     InsertAfter(NodeToMove);
00580 }

void SGDisplayNode::MoveBefore SGDisplayNode NodeToMove  )  [virtual]
 

MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/3/95
Parameters:
NodeToMove - the node to move [INPUTS]
Notes: This base class method simply delinks the item and relinks it elsewhere in the display tree. However, derived classes will override this method so that moving display items can have a further effect of also rearranging the displayed "real" items. Before/After moving the real item, the derived class can then call this baseclass method to complete the action.

Take care when moving items between groups (e.g. if an item is "moved" from one docuemnt to another, it could be a bad thing, so be very careful in derived classes to take appropriate action)

Any attempt to move an item before *itself* is queitly ignored

Returns:
Errors: ERROR3 and quiet exit if NodeToMove == NULL
See also:
SuperGallery; SGDisplayNode::InsertBefore; SGDisplayNode::AddItem

Reimplemented in SGDisplayKernelBitmap, SGDisplayColour, SGDisplayLayer, SGDisplayPreviewFonts, and SGLibFontItem.

Definition at line 615 of file sgtree.cpp.

00616 {
00617     ERROR3IF(NodeToMove == NULL, "Illegal NULL param");
00618 
00619     if (NodeToMove == this)
00620         return;
00621 
00622     NodeToMove->RemoveFromTree();
00623     InsertBefore(NodeToMove);
00624 }

void SGDisplayNode::NewLine SGFormatInfo FormatInfo,
SGMiscInfo MiscInfo
[protected, virtual]
 

Resets the formatting info structure to default values for the start of the next 'line'.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/10/94
Parameters:
FormatInfo - A structure containing all relevant information for items to [INPUTS] calculate their formatted positions in the display list
FormatInfo is updated as appropriate [OUTPUTS]
See also:
SGDisplayNode::HandleEvent; SGDisplayRoot::HandleEvent; SGDisplayGroup::HandleEvent; SGDisplayItem::HandleEvent

Definition at line 950 of file sgtree.cpp.

00951 {
00952     if (FormatInfo->LineHeight > 0)
00953     {
00954         FormatInfo->LineHeight = GridLock(MiscInfo, FormatInfo->LineHeight) +
00955                                     GridLock(MiscInfo, InterLineGap);
00956         FormatInfo->LinePos -= FormatInfo->LineHeight;
00957     }
00958     
00959     FormatInfo->LineHeight = 0;
00960     FormatInfo->AvailableWidth = MiscInfo->MaxWidth - (FormatInfo->IndentLevel * IndentWidth);
00961     FormatInfo->AvailableWidth = GridLock(MiscInfo, FormatInfo->AvailableWidth);
00962 }

void SGDisplayNode::RegisterForBGRedraw void   )  [protected, virtual]
 

Called by derived classes to register themselves for background redraw.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/4/95
Must be called every time you want a background redraw to occur. May be called multiple times before the redraw occurs (it ignores repeated calls)

DO NOT call this method directly - see ShouldIDrawForeground()

Notes: DO NOT TOUCH the Flags.RedrawPending member variable directly!

See also:
SGDisplayNode::DoBGRedraw; SGDisplayNode::ShouldIDrawForeground

Definition at line 1469 of file sgtree.cpp.

01470 {
01471     if (!Flags.RedrawPending)
01472     {
01473         SuperGallery *ParentGallery = GetParentGallery();
01474 
01475         if (ParentGallery != NULL)
01476         {
01477             Flags.RedrawPending = TRUE;
01478             ParentGallery->IncrementPendingRedraws();
01479         }
01480     }
01481 }

void SGDisplayNode::RemoveFromTree void   )  [virtual]
 

De-links this node/subtree from the DisplayTree. This DOES NOT DELETE the node, just unlinks it in preparation for being deleted.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Notes: This does NOT delink children of this node from this node. To do that, you must call RemoveFromTree from each child node in turn. To delete a subtree you are better off calling DestroySubtree

Returns:
Errors: ERROR3s will be reported in debug builds if certain corrupted tree structures are detected, indicating tree generation/maintenance code has gone wrong
See also:
SuperGallery; SGDisplayNode::InsertAfter; SGDisplayNode::InsertBefore; SGDisplayNode::AddItem; SGDisplayNode::DestroySubtree

Reimplemented in SGDisplayRoot, and SGDisplayItem.

Definition at line 652 of file sgtree.cpp.

00653 {
00654     // Because we have changed part of the tree, we must inform the gallery that the
00655     // cached format is incorrect and needs to be recalculated. We must also make sure
00656     // that this item is not pending a background redraw.
00657     SuperGallery *ParentGallery = GetParentGallery();
00658     if (ParentGallery != NULL)
00659     {
00660         // Ensure that the ParentGallery doesn't dereference this pointer on the next background
00661         // rendering pass (if we happen to be removed just after redrawing in the BG)
00662         if (this == ParentGallery->GetLastBackgroundNode())
00663             ParentGallery->SetLastBackgroundNode(NULL);
00664 
00665         if (Flags.RedrawPending)
00666             ParentGallery->DecrementPendingRedraws();
00667 
00668         ParentGallery->InvalidateCachedFormat();
00669     }
00670 
00671     Flags.RedrawPending = FALSE;        // We are NOT pending a redraw!
00672 
00673     if (Next == NULL)
00674     {
00675         // If the next sibling ptr is NULL, then we are at the end of a group or the list
00676         // so we 'touch' the previous node (or parent) FormatRect so that the next reformat
00677         // realises that a change has occurred around here and redraws where we were.
00678         SGDisplayNode *ToTouch = Previous;
00679         if (ToTouch == NULL)
00680             ToTouch = Parent;
00681 
00682         if (ToTouch != NULL)
00683             ToTouch->FormatRect.MakeEmpty();
00684     }
00685 
00686     // Delink our Parent from ourself
00687     if (Parent != NULL)
00688     {
00689         if (Parent->GetChild() == this)     // If we are first child, make Next child the first
00690         {
00691             // I must be the first child, so should not have a Previous node
00692             ERROR3IF(Previous != NULL, "Tree linking failure detected in SGDisplayNode::RemoveFromTree");
00693             Parent->SetChild(Next);
00694         }
00695         else
00696         {
00697             // I am not the parent's first child, so I must have a Previous node
00698             ERROR3IF(Previous == NULL, "Tree linking failure detected in SGDisplayNode::RemoveFromTree");
00699         }
00700     }
00701 
00702 
00703     // Delink our Previous/Next siblings (if any) from ourself
00704     if (Previous != NULL)
00705         Previous->Next = Next;
00706 
00707     if (Next != NULL)
00708         Next->Previous = Previous;
00709 
00710 
00711     // And finally, destroy our own backward links to parent, next, previous.
00712     // Done last to avoid 'losing' pointers before we have finished using them for delinking!
00713     Parent   = NULL;
00714     Previous = NULL;
00715     Next     = NULL;
00716 }

void SGDisplayNode::SelectGroups BOOL  SelectThem,
BOOL  Exclusive,
Document ParentDocument,
Library ParentLibrary
[virtual]
 

To select/deselect sets of display groups in this Gallery display. All groups whose state changes will force redraw themselves.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/5/95
Parameters:
SelectThem - TRUE to select the given groups, FALSE to deselect them [INPUTS]
Exclusive - TRUE to apply this action to all groups *outside* the given range, FALSE to apply it to all groups *inside* the range.

Document - NULL, or the document which defines the range of groups to affect

Library - NULL, or the library which defines the range of groups to affect

If selecting, all items in the tree will be deselected

Do not call this method - use the SuperGallery version

Notes: To select all groups in a range, and deselect all groups outside the range, you need to use 2 calls to this method.

To select/deselect all groups in the display, pass FALSE, NULL, NULL to the last 3 parameters. (If Doc/Lib are both NULL, 'Exclusive' has no effect)

See also:
SuperGallery::SelectGroups; SGDisplayGroup::SelectGroups

Reimplemented in SGDisplayGroup.

Definition at line 2086 of file sgtree.cpp.

02088 {
02089     // First, if selecting, then we need to ensure that all base-class nodes are deselected.
02090     // The group class overrides this behaviour to correctly select groups.
02091     if (SelectThem && !Flags.Invisible && Flags.CanSelect)
02092         SetSelected(FALSE);
02093 
02094     // Now, pass the selection request on to my children
02095     SGDisplayNode *Ptr = GetChild();
02096     while (Ptr != NULL)
02097     {
02098         Ptr->SelectGroups(SelectThem, Exclusive, ParentDocument, ParentLibrary);
02099         Ptr = Ptr->GetNext();
02100     }
02101 }

void SGDisplayNode::SelectItems BOOL  SelectThem,
BOOL  Exclusive = FALSE,
Document ParentDocument = NULL,
Library ParentLibrary = NULL
[virtual]
 

To select/deselect groups of display items in this Gallery display. All items whose state changes will force redraw themselves.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/95
Parameters:
SelectThem - TRUE to select the given items, FALSE to deselect them [INPUTS]
Exclusive - TRUE to apply this action to all items *outside* the given range, FALSE to apply it to all items *inside* the range.

Document - NULL, or the document which defines the range of items to affect

Library - NULL, or the library which defines the range of items to affect

If selecting items, all groups will be deselected

Do not call this method - use the SuperGallery version

Notes: To select all items in a range, and deselect all items outside the range, you need to use 2 calls to this method.

To select/deselect all items in the display, pass FALSE, NULL, NULL to the last 3 parameters. (If Doc/Lib are both NULL, 'Exclusive' has no effect)

This base-class method does a simple thing: If this node is selectable (not invisible) then it sets its own selection state according to the 'SelectThem' flag, and then passes the request on to its children. Any node type which understands how to cope with the last 3 parameters MUST override this method to provide the appropriate handling. (This default handling suffices, however, for root and leaf nodes)

See also:
SuperGallery::SelectItems; SGDisplayGroup::SelectItems

Reimplemented in SGDisplayGroup.

Definition at line 2033 of file sgtree.cpp.

02035 {
02036     // First, if I'm a selectable node, {de}select myself as appropriate to the request
02037     if (!Flags.Invisible && Flags.CanSelect)
02038         SetSelected(SelectThem);
02039 
02040     // Now, pass the selection request on to my children
02041     SGDisplayNode *Ptr = GetChild();
02042 
02043     while (Ptr != NULL)
02044     {
02045         Ptr->SelectItems(SelectThem, Exclusive, ParentDocument, ParentLibrary);
02046         Ptr = Ptr->GetNext();
02047     }
02048 }

void SGDisplayNode::SelectRangeGroups SGDisplayGroup PrimeNode,
SGDisplayGroup AnchorNode
[virtual]
 

Selects the PrimeNode, and if possible, all sibling items between it and the Anchor node. If Anchor == NULL or is not found, only PrimeNode is selected. Does not deselect any items - you should call SelectItems first to clear the seln.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/2/95
Parameters:
PrimeNode - The group which MUST be selected. May NOT be NULL. [INPUTS]
AnchorNode - The other group, specifying a range of sibling groups to be selected. May be NULL, in which case only PrimeNode is selected

Definition at line 2122 of file sgtree.cpp.

02123 {
02124     ERROR3IF(PrimeNode == NULL, "SGDisplayNode::SelectRangeGroup - PrimeNode must be non-NULL");
02125 
02126     BOOL AnchorIsHere = FALSE;
02127     SGDisplayGroup *First = PrimeNode;
02128 
02129     SuperGallery *ParentGallery = GetParentGallery();
02130     ERROR3IF(ParentGallery == NULL, "NULL Parent gallery?!");
02131 
02132     if (AnchorNode != NULL)
02133     {
02134         SGDisplayNode *Ptr = PrimeNode->GetParent();
02135         ERROR3IF(Ptr == NULL, "SGDisplayNode::SelectRangeGroup - Tree linkage corrupt, or PrimeNode is the root!");     
02136 
02137         // Find which of the two nodes comes first  
02138         Ptr = Ptr->GetChild();
02139         while (Ptr != NULL && Ptr != PrimeNode)
02140         {
02141             if (Ptr == AnchorNode)
02142             {
02143                 First = (SGDisplayGroup *)AnchorNode;       // Ooops - the Anchor node occurs first!
02144                 AnchorIsHere = TRUE;    // And remember we've found the Anchor
02145                 break;
02146             }
02147             
02148             Ptr = Ptr->GetNext();
02149         }
02150 
02151         // Continue scanning until we can be sure that the Anchor Node is in the sibling list
02152         while (Ptr != NULL && !AnchorIsHere)
02153         {
02154             AnchorIsHere = (Ptr == AnchorNode);
02155             Ptr = Ptr->GetNext();
02156         }
02157     }
02158 
02159     if (!AnchorIsHere)      // Only one item in the range!
02160     {
02161         PrimeNode->SetSelected(TRUE);
02162         PrimeNode->ForceRedrawOfMyself();
02163 
02164         // And inform the parent gallery of the selection change
02165         ParentGallery->SetLastSelectedNode(PrimeNode);
02166         ParentGallery->SelectionHasChanged();
02167         return;
02168     }
02169 
02170     // We have a valid range. Scan from First to Last, selecting everything in our path
02171     SGDisplayGroup *Last = (First == PrimeNode) ? AnchorNode : PrimeNode;
02172     while (First != NULL && First != Last)
02173     {
02174         First->SetSelected(TRUE);
02175         First->ForceRedrawOfMyself();
02176         
02177         First = (SGDisplayGroup *) First->GetNext();
02178     }
02179 
02180     // And set the last one
02181     Last->SetSelected(TRUE);
02182     Last->ForceRedrawOfMyself();
02183 
02184     // And inform the parent gallery of the selection change
02185     ParentGallery->SetLastSelectedNode(Last);
02186     ParentGallery->SelectionHasChanged();
02187 }

void SGDisplayNode::SelectRangeItems SGDisplayItem PrimeNode,
SGDisplayItem AnchorNode
[virtual]
 

Selects the PrimeNode, and if possible, all sibling items between it and the Anchor node. If Anchor == NULL or is not found, only PrimeNode is selected. Does not deselect any items - you should call SelectItems first to clear the seln.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/2/95
Parameters:
PrimeNode - The item which MUST be selected. May NOT be NULL. [INPUTS]
AnchorNode - The other item, specifying a range of sibling items to be selected. May be NULL, in which case only PrimeNode is selected

Definition at line 2208 of file sgtree.cpp.

02209 {
02210     ERROR3IF(PrimeNode == NULL, "SGDisplayItem::SelectRangeItem - PrimeNode must be non-NULL");
02211 
02212     BOOL AnchorIsHere = FALSE;
02213     SGDisplayItem *First = PrimeNode;
02214 
02215     SuperGallery *ParentGallery = GetParentGallery();
02216     ERROR3IF(ParentGallery == NULL, "NULL Parent gallery?!");
02217 
02218     if (AnchorNode != NULL)
02219     {
02220         SGDisplayNode *Ptr = PrimeNode->GetParent();
02221         ERROR3IF(Ptr == NULL, "SGDisplayItem::SelectRangeItem - Tree linkage corrupt, or PrimeNode is the root!");      
02222 
02223         // Find which of the two nodes comes first  
02224         Ptr = Ptr->GetChild();
02225         while (Ptr != NULL && Ptr != PrimeNode)
02226         {
02227             if (Ptr == AnchorNode)
02228             {
02229                 First = (SGDisplayItem *)AnchorNode;        // Ooops - the Anchor node occurs first!
02230                 AnchorIsHere = TRUE;    // And remember we've found the Anchor
02231                 break;
02232             }
02233             
02234             Ptr = Ptr->GetNext();
02235         }
02236 
02237         // Continue scanning until we can be sure that the Anchor Node is in the sibling list
02238         while (Ptr != NULL && !AnchorIsHere)
02239         {
02240             AnchorIsHere = (Ptr == AnchorNode);
02241             Ptr = Ptr->GetNext();
02242         }
02243     }
02244 
02245     if (!AnchorIsHere)      // Only one item in the range!
02246     {
02247         PrimeNode->SetSelected(TRUE);
02248         PrimeNode->ForceRedrawOfMyself();
02249 
02250         // And inform the parent gallery of the selection change
02251         ParentGallery->SetLastSelectedNode(PrimeNode);
02252         ParentGallery->SelectionHasChanged();
02253         return;
02254     }
02255 
02256     // We have a valid range. Scan from First to Last, selecting everything in our path
02257     SGDisplayItem *Last = (First == PrimeNode) ? AnchorNode : PrimeNode;
02258     while (First != NULL && First != Last)
02259     {
02260         First->SetSelected(TRUE);
02261         First->ForceRedrawOfMyself();
02262         
02263         First = (SGDisplayItem *) First->GetNext();
02264     }
02265 
02266     // And set the last one
02267     Last->SetSelected(TRUE);
02268     Last->ForceRedrawOfMyself();
02269 
02270     // And inform the parent gallery of the selection change
02271     ParentGallery->SetLastSelectedNode(Last);
02272     ParentGallery->SelectionHasChanged();
02273 }

void SGDisplayNode::SetChild SGDisplayNode NewChild  )  [protected, virtual]
 

Sets the child of this DisplayTree Node.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
A pointer to the new first-child of this SGDisplayNode object [INPUTS]
Notes: This base-class method gives an ERROR3 - base nodes and items do not have children (to reduce memory usage). SGDisplayRoot and SGDisplayGroup override this method to provide child pointers.

See also:
SuperGallery; SGDisplayNode::GetParent; SGDisplayNode::GetNext; SGDisplayNode::GetPrevious

Reimplemented in SGDisplayRoot, and SGDisplayGroup.

Definition at line 253 of file sgtree.cpp.

00254 {
00255     ERROR3("This is a childless SGDisplayNode - You cannot set it's child!");
00256 }

BOOL SGDisplayNode::SetFoldedState BOOL  NewState,
BOOL  ForceRedraw = TRUE
[virtual]
 

Folds or unfolds a display node.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/4/95
Parameters:
NewState - TRUE to fold, FALSE to unfold [INPUTS]
Returns:
TRUE if the new state is different from the old state (if anything has changed)
Notes: This base-class implementation gives an ERROR3 - use folding only on groups

Reimplemented in SGDisplayGroup.

Definition at line 1178 of file sgtree.cpp.

01179 {
01180     ERROR3("Folding can only be applied to groups!");
01181     return(FALSE);
01182 }

void SGDisplayNode::SetSelected BOOL  IsSelected = TRUE  )  [virtual]
 

Sets the selection state of a SuperGallery Display Item tree node. Note that this does not cause a redraw of the gallery list box or anything. After setting the state(s) of item(s) you must therefore redraw them.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/94
Parameters:
IsSelected - TRUE to select, FALSE to deselect this item [INPUTS]
Notes: An ENSURE will be generated by any node which cannot be selected. (Derived classes wishing to allow selection state changes should set Flags.CanSelect)

See also:
SGDisplayItem::SetSelected; SGDisplayNode::IsSelected

Definition at line 1207 of file sgtree.cpp.

01208 {
01209     ERROR3IF(!Flags.CanSelect, "Base class SGDisplayNode::SetSelected called! I'm not a selectable ITEM!");
01210 
01211     if (Flags.CanSelect && Flags.Selected != (UINT32)IsSelected)
01212     {
01213         Flags.Selected = (UINT32) IsSelected;
01214         ForceRedrawOfMyself();
01215     }
01216 }

BOOL SGDisplayNode::ShouldIDrawForeground BOOL  ForceForeground = FALSE  )  [protected, virtual]
 

Call this method in derived class redraw methods. Your code should go like this: MonoOn if (ShouldIDrawForeground(ByGollyIveGotAThumbnailCachedAlready) DrawTheItemFully(); else DrawAGreyBox(); MonoOff.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/5/95
Parameters:
ForceForeground - TRUE if you want to force foreground redrawing (e.g. if you [INPUTS] know your thumbnail is cached you are better off just drawing it immediately), or FALSE to allow the operation to be backgrounded.
Returns:
TRUE if you should draw in the foreground (i.e. draw the item to completion), FALSE if you should draw the background stuff (i.e. draw a grey box instead of a thumbnail) - if FALSE, you'll be called back to complete the redraw later.
This system is full automatic, and is all you have to do to get BG redraw to work. Note that foreground redraw will be expected when (a) ForceForeground is TRUE, (b) the item is selected, or (c) we are doing the second BG redraw pass. Background redraw will generally be used in all other circumstances.

See also:
SGDisplayNode::RegisterForBGRedraw

Reimplemented in SGLibDisplayItem.

Definition at line 1583 of file sgtree.cpp.

01584 {
01585     BOOL FG = FALSE;
01586 
01587     if (ForceForeground || Flags.Selected)
01588         FG = TRUE;
01589     else
01590     {
01591         if (CurrentBGRenderNode == this)
01592             FG = TRUE;
01593     }
01594 
01595     // And make sure our current idea of the state is up to date
01596     if (FG)
01597     {
01598         DeregisterForBGRedraw();
01599         BGRenderClaimed = TRUE;     // Flag the fact that someone has FG rendered
01600     }
01601     else
01602         RegisterForBGRedraw();
01603 
01604     return(FG);
01605 }

void SGDisplayNode::StartRendering SGRedrawInfo RedrawInfo,
SGMiscInfo MiscInfo
[virtual]
 

MUST be called by all derived node types when they are about to start rendering. This allows us to do things like using GRenderRegions to small bitmaps (a region for each item rather than one region for the whole window) and other fabby things.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/2/95
Parameters:
RedrawInfo - The RedrawInfo passed to your HandleEvent function [INPUTS] for SGEVENT_REDRAWs MiscInfo - The MiscInfo passed in to your HandleEvent function
See also:
SGDisplayNode::StopRendering

Definition at line 2512 of file sgtree.cpp.

02513 {
02514     // Does nothing, for now
02515 }

void SGDisplayNode::StopRendering SGRedrawInfo RedrawInfo,
SGMiscInfo MiscInfo
[virtual]
 

MUST be called by all derived node types when they have finished rendering. This allows us to do things like using GRenderRegions to small bitmaps (a region for each item rather than one region for the whole window) and other fabby things.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/2/95
Parameters:
RedrawInfo - The RedrawInfo passed to your HandleEvent function [INPUTS] for SGEVENT_REDRAWs MiscInfo - The MiscInfo passed in to your HandleEvent function
See also:
SGDisplayNode::StopRendering

Definition at line 2539 of file sgtree.cpp.

02540 {
02541     // Does nothing, for now
02542 }


Member Data Documentation

BOOL SGDisplayNode::BGRenderClaimed = FALSE [static, protected]
 

Definition at line 794 of file sgtree.h.

BOOL SGDisplayNode::BkgEraseMode = TRUE [static, protected]
 

Definition at line 823 of file sgtree.h.

SGDisplayNode * SGDisplayNode::CurrentBGRenderNode = NULL [static, protected]
 

Definition at line 793 of file sgtree.h.

SGDisplayFlags SGDisplayNode::Flags
 

Reimplemented in SGDisplayLibColour.

Definition at line 812 of file sgtree.h.

DocRect SGDisplayNode::FormatRect [protected]
 

Definition at line 822 of file sgtree.h.

SGDisplayNode* SGDisplayNode::Next [private]
 

Definition at line 817 of file sgtree.h.

SGDisplayNode* SGDisplayNode::Parent [private]
 

Definition at line 816 of file sgtree.h.

SGDisplayNode* SGDisplayNode::Previous [private]
 

Definition at line 818 of file sgtree.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:01:03 2007 for Camelot by  doxygen 1.4.4