home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-16 | 20.7 KB | 676 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: GroupShp.cpp
- // Release Version: $ ODF 1 $
- //
- // Author: Mary Boetcher
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "ODFDraw.hpp"
-
- #ifndef GROUPSHP_H
- #include "GroupShp.h"
- #endif
-
- #ifndef DRAWPART_H
- #include "DrawPart.h"
- #endif
-
- #ifndef DRAWCLIP_H
- #include "DrawClip.h"
- #endif
-
- #ifndef UTILS_H
- #include "Utils.h"
- #endif
-
- #ifndef CONTENT_H
- #include "Content.h"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWODGEOM_H
- #include "FWODGeom.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfdrawshapes
- #endif
-
- FW_DEFINE_CLASS_M1(CGroupShape, CBaseShape)
-
- const FW_ClassTypeConstant LGroupShape = FW_TYPE_CONSTANT('s','h','g','p');
- FW_REGISTER_ARCHIVABLE_CLASS(LGroupShape, CGroupShape, CGroupShape::Read, 0, 0, CBaseShape::Write)
-
- FW_DEFINE_AUTO(CGroupShape)
- FW_DEFINE_AUTO(CAllShapeIterator)
-
- //========================================================================================
- // class CGroupShape
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CGroupShape constructors
- //----------------------------------------------------------------------------------------
- CGroupShape::CGroupShape()
- : CBaseShape(4, kGroupShape, kFrameOnly),
- fShapeList(NULL)
- {
- fShapeList = FW_NEW(CShapeCollection, ());
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- CGroupShape::CGroupShape(CShapeCollection* shapeList)
- : CBaseShape(4, kGroupShape, kFrameOnly)
- {
- fShapeList = FW_NEW(CShapeCollection, ());
- CShapeCollectionIterator it(shapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- fShapeList->AddLast(shape);
- }
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- CGroupShape::CGroupShape(FW_CReadableStream& archive)
- : CBaseShape(archive)
- {
- fShapeList = FW_NEW(CShapeCollection, ());
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape destructor
- //----------------------------------------------------------------------------------------
- CGroupShape::~CGroupShape()
- {
- FW_START_DESTRUCTOR
-
- this->EmptyShapes(true); // delete shapes
- delete fShapeList;
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::EmptyShapes
- //----------------------------------------------------------------------------------------
- void CGroupShape::EmptyShapes(FW_Boolean deleteShapes)
- {
- if (fShapeList)
- {
- CBaseShape* shape;
- while ((shape = fShapeList->First()) != NULL)
- {
- fShapeList->Remove(shape);
- if (deleteShapes)
- {
- FW_SOMEnvironment ev;
- shape->Deleted(ev);
- delete shape;
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::Read
- //----------------------------------------------------------------------------------------
- void* CGroupShape::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
- {
- FW_UNUSED(type);
- CGroupShape* groupShape = FW_NEW(CGroupShape, (stream));
-
- // Read shapes from the stream and add them to the group
- unsigned long count;
- stream >> count;
- for (short i = 0; i<count; i++)
- {
- CBaseShape* theShape = NULL;
- FW_READ_DYNAMIC_OBJECT(stream, &theShape, CBaseShape);
- FW_ASSERT(theShape);
-
- // ----- Add the shape to the group -----
- groupShape->AddShape(theShape);
- }
-
- return groupShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::Flatten
- //----------------------------------------------------------------------------------------
- void CGroupShape::Flatten(FW_CWritableStream& archive)
- {
- CBaseShape::Flatten(archive);
-
- unsigned long count = fShapeList->Count();
- archive << count;
-
- // Write group shapes to the archive
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- FW_WRITE_DYNAMIC_OBJECT(archive, shape, CBaseShape);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::CreateShapeOutline
- //----------------------------------------------------------------------------------------
- ODShape* CGroupShape::CreateShapeOutline(Environment* ev)
- {
- FW_CRect bounds = GetRectGeometry();
-
- // We don't acquire it because we return it
- ODShape* outline = ::FW_NewODShape(ev, bounds);
-
- ::FW_OutlineODShape(ev, outline, GetPenSize());
-
- return outline;
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::GetClipRegion
- //----------------------------------------------------------------------------------------
- void CGroupShape::GetClipRegion(Environment* ev, ODShape* clipRegion)
- {
- if (fShapeList->Count() == 0) return;
-
- ODShape* updateShape = ::FW_NewODShape(ev);
-
- FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
- FW_Boolean first = TRUE;
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->GetUpdateBox(ev, aqTempShape);
- if (first)
- {
- updateShape->CopyFrom(ev, aqTempShape);
- }
- else
- {
- updateShape->Union(ev, aqTempShape);
- }
-
- first = FALSE;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::GetHandleCenter
- //----------------------------------------------------------------------------------------
- void CGroupShape::GetHandleCenter(short whichHandle, FW_CPoint& center) const
- {
- FW_CRect bounds = GetRectGeometry();
-
- switch (whichHandle)
- {
- case kInTopLeftCorner:
- center.x = bounds.left;
- center.y = bounds.top;
- break;
- case kInTopRightCorner:
- center.x = bounds.right;
- center.y = bounds.top;
- break;
- case kInBottomLeftCorner:
- center.x = bounds.left;
- center.y = bounds.bottom;
- break;
- case kInBottomRightCorner:
- center.x = bounds.right;
- center.y = bounds.bottom;
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::GetMapRects
- //----------------------------------------------------------------------------------------
- void CGroupShape::GetMapRects(short whichHandle, const FW_CPoint& mouseLoc,
- FW_CRect& srcRect, FW_CRect& dstRect)
- {
- srcRect = GetRectGeometry();
- dstRect = srcRect;
-
- switch (whichHandle)
- {
- case kInTopLeftCorner:
- dstRect.left = mouseLoc.x;
- dstRect.top = mouseLoc.y;
- break;
- case kInTopRightCorner:
- dstRect.right = mouseLoc.x;
- dstRect.top = mouseLoc.y;
- break;
- case kInBottomLeftCorner:
- dstRect.left = mouseLoc.x;
- dstRect.bottom = mouseLoc.y;
- break;
- case kInBottomRightCorner:
- dstRect.right = mouseLoc.x;
- dstRect.bottom = mouseLoc.y;
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::GetRectGeometry
- //----------------------------------------------------------------------------------------
-
- FW_CRect CGroupShape::GetRectGeometry() const
- {
- // Calculate the boundary rectangle for our shapes
- FW_CRect rect = FW_kZeroRect;
- if (fShapeList->Count() != 0)
- {
- FW_Boolean first = true;
- FW_CRect tempRect;
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->GetDragRect(tempRect);
- if (first)
- rect = tempRect;
- else
- rect |= tempRect;
- first = false;
- }
- }
- return rect;
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::HitTest
- //----------------------------------------------------------------------------------------
- FW_Boolean CGroupShape::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CMouseEvent& theMouseEvent) const
- {
- // Perform HitTest on each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- if (shape->HitTest(ev, gc, theMouseEvent))
- return true;
- }
-
- return false;
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::MapShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::MapShape(Environment* ev, CDrawPart* part, const FW_CRect& srcRect, const FW_CRect& dstRect)
- {
- // Map each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->MapShape(ev, part, srcRect, dstRect);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::OffsetShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::OffsetShape(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
- {
- ClearCache();
-
- // Offset each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->OffsetShape(ev, xDelta, yDelta);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::RenderShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::RenderShape(Environment* ev, ODFacet* facet, FW_CGraphicContext& gc)
- {
- // Render each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->RenderShape(ev, facet, gc);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ResizeFeedback
- //----------------------------------------------------------------------------------------
- void CGroupShape::ResizeFeedback(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style,
- short whichHandle, const FW_CPoint& mouseLoc)
- {
- FW_CRect srcRect, dstRect;
- GetMapRects(whichHandle, mouseLoc, srcRect, dstRect);
- dstRect.Sort();
- OutlineShape(gc, ink, style, dstRect);
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::SetShapeGeometry
- //----------------------------------------------------------------------------------------
- void CGroupShape::SetShapeGeometry(const FW_CPoint& anchorPoint, const FW_CPoint& currentPoint)
- {
- FW_CRect rect = GetRectGeometry();
-
- if (anchorPoint.x < currentPoint.x)
- {
- rect.left = anchorPoint.x;
- rect.right = currentPoint.x;
- }
- else
- {
- rect.left = currentPoint.x;
- rect.right = anchorPoint.x;
- }
-
- if (anchorPoint.y < currentPoint.y)
- {
- rect.top = anchorPoint.y;
- rect.bottom = currentPoint.y;
- }
- else
- {
- rect.top = currentPoint.y;
- rect.bottom = anchorPoint.y;
- }
-
- /* How to change group shape's geometry? */
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::OutlineShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::OutlineShape(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, const FW_CRect& rect)
- {
- FW_CRect bounds(rect);
- AdjustRectForPenSize(bounds, style.GetPenSize());
- FW_CRectShape::RenderRect(gc,
- bounds,
- FW_kFrame,
- ink, style);
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::Removed
- //----------------------------------------------------------------------------------------
- void CGroupShape::Removed(Environment* ev)
- {
- CBaseShape::Removed(ev);
-
- // Call Removed on each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->Removed(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::SelectShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::SelectShape(Environment* ev, FW_Boolean state)
- {
- CBaseShape::SelectShape(ev, state);
-
- // ----- Select all the shapes in this group ----
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->SelectShape(ev, state);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::SubtractToWindowClip
- //----------------------------------------------------------------------------------------
- void CGroupShape::SubtractToWindowClip(Environment* ev,
- CDrawFacetClipper* facetClipper,
- ODFacet* containingFacet,
- ODShape* windowClip, ODShape* tempShape)
- {
- // Call SubtractToWindowClip on each shape in this group
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->SubtractToWindowClip(ev, facetClipper, containingFacet, windowClip, tempShape);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::AddShape
- //----------------------------------------------------------------------------------------
- void CGroupShape::AddShape(CBaseShape* shape)
- {
- fShapeList->AddLast(shape);
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::CountShapes
- //----------------------------------------------------------------------------------------
- unsigned long CGroupShape::CountShapes() const
- {
- return fShapeList->Count();
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::GetFirstShape
- //----------------------------------------------------------------------------------------
- CBaseShape* CGroupShape::GetFirstShape() const
- {
- return fShapeList->First();
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::RemoveShapes
- //----------------------------------------------------------------------------------------
- void CGroupShape::RemoveShapes()
- {
- this->EmptyShapes(false);
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::Remove1Shape
- //----------------------------------------------------------------------------------------
- void CGroupShape::Remove1Shape(CBaseShape* shape)
- {
- fShapeList->Remove(shape);
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangeFillColor
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangeFillColor(Environment* ev, CDrawPart* part, const FW_CColor& color)
- {
- CBaseShape::ChangeFillColor(ev, part, color);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangeFillColor(ev, part, color);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangeFrameColor
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangeFrameColor(Environment* ev, CDrawPart* part, const FW_CColor& color)
- {
- CBaseShape::ChangeFrameColor(ev, part, color);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangeFrameColor(ev, part, color);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangeFillPattern
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangeFillPattern(Environment* ev, CDrawPart* part, const FW_CPattern& pattern)
- {
- CBaseShape::ChangeFillPattern(ev, part, pattern);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangeFillPattern(ev, part, pattern);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangeFramePattern
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangeFramePattern(Environment* ev, CDrawPart* part, const FW_CPattern& pattern)
- {
- CBaseShape::ChangeFramePattern(ev, part, pattern);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangeFramePattern(ev, part, pattern);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangePenSize
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangePenSize(Environment* ev, CDrawPart* part, FW_Fixed newPenSize)
- {
- CBaseShape::ChangePenSize(ev, part, newPenSize);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangePenSize(ev, part, newPenSize);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::ChangeRenderVerb
- //----------------------------------------------------------------------------------------
- void CGroupShape::ChangeRenderVerb(Environment* ev, CDrawPart* part, unsigned short renderVerb)
- {
- CBaseShape::ChangeRenderVerb(ev, part, renderVerb);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->ChangeRenderVerb(ev, part, renderVerb);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CGroupShape::SetSubscribeLink
- //----------------------------------------------------------------------------------------
-
- void CGroupShape::SetSubscribeLink(Environment* ev, CDrawSubscribeLink* subscribeLink)
- {
- CBaseShape::SetSubscribeLink(ev, subscribeLink);
-
- CShapeCollectionIterator it(fShapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- shape->SetSubscribeLink(ev, subscribeLink);
- }
- }
-
- //========================================================================================
- // class CAllShapeIterator
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- CAllShapeIterator::CAllShapeIterator(CShapeCollection* shapeList)
- : fIter(NULL),
- fTempList(NULL)
- {
- fTempList = FW_NEW(CShapeCollection, ());
- PrivFlattenList(shapeList);
- fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- CAllShapeIterator::CAllShapeIterator(CDrawContent* content)
- : fIter(NULL),
- fTempList(NULL)
- {
- fTempList = FW_NEW(CShapeCollection, ());
- PrivFlattenList(content->fShapeList);
- fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- CAllShapeIterator::~CAllShapeIterator()
- {
- FW_START_DESTRUCTOR
- delete fTempList;
- delete fIter;
- }
-
- //----------------------------------------------------------------------------------------
- CBaseShape* CAllShapeIterator::First()
- {
- return fIter->First();
- }
-
- //----------------------------------------------------------------------------------------
- CBaseShape* CAllShapeIterator::Next()
- {
- return fIter->Next();
- }
-
- //----------------------------------------------------------------------------------------
- FW_Boolean CAllShapeIterator::IsNotComplete()
- {
- return fIter->IsNotComplete();
- }
-
- //----------------------------------------------------------------------------------------
- void CAllShapeIterator::PrivFlattenList(CShapeCollection* shapeList)
- {
- CShapeCollectionIterator it(shapeList);
- for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
- {
- if (shape->GetShapeType() == kGroupShape)
- PrivFlattenList(((CGroupShape*)shape)->GetShapeList());
- else
- fTempList->AddLast(shape);
- }
- }
-
- //----------------------------------------------------------------------------------------
- unsigned long CAllShapeIterator::CountShapes()
- {
- return fTempList->Count();
- }
-