home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-25 | 16.1 KB | 550 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Proxy.cpp
- // Release Version: $ ODF 1 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Container.hpp"
-
- #ifndef PROXY_H
- #include "Proxy.h"
- #endif
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWPXYITE_H
- #include "FWPxyIte.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWPRTITE_H
- #include "FWPrtIte.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWPXYFRM_H
- #include "FWPxyFrm.h"
- #endif
-
- #ifndef FWFCTCLP_H
- #include "FWFctClp.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWODGEOM_H
- #include "FWODGeom.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- #ifndef FWINK_H
- #include "FWInk.h"
- #endif
-
- #ifndef FWSTYLE_H
- #include "FWStyle.h"
- #endif
-
- #ifndef FWLINSHP_H
- #include "FWLinShp.h"
- #endif
-
- #ifndef SLSHATTR_H
- #include "SLShAttr.h"
- #endif
-
- // ----- Foundation Includes -----
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfcontainer
- #endif
-
- //========================================================================================
- // Globals
- //========================================================================================
-
- FW_CRectShape* CProxy::gWorkingHandle = NULL;
- unsigned long CProxy::gProxyCount = 0;
-
- //========================================================================================
- // CProxy
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CProxy::CProxy
- //----------------------------------------------------------------------------------------
-
- CProxy::CProxy(Environment* ev, const FW_CRect& bounds, CContainerPart* part) :
- FW_MProxy(ev, part, part->GetMainPresentation()),
- fContainerPart(part),
- fBounds(bounds),
- fSelected(false)
- {
- InitStatic();
- CProxy::gProxyCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::~CProxy
- //----------------------------------------------------------------------------------------
-
- CProxy::~CProxy()
- {
- CProxy::gProxyCount--;
- if (CProxy::gProxyCount == 0)
- delete CProxy::gWorkingHandle;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::InitStatic
- //----------------------------------------------------------------------------------------
-
- void CProxy::InitStatic()
- {
- if (gProxyCount == 0)
- {
- CProxy::gWorkingHandle = FW_NEW(FW_CRectShape, (FW_kZeroRect, FW_kFill));
- CProxy::gWorkingHandle->SetInk(FW_kInvertInk);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::FrameShapeRequested
- //----------------------------------------------------------------------------------------
-
- ODShape* CProxy::FrameShapeRequested(Environment* ev,
- FW_CEmbeddingFrame* embeddingFrame,
- ODFrame* odEmbeddedFrame,
- ODShape* requestedFrameShape)
- {
- // ----- get the bounding box of the asked frame shape
- FW_CRect frameRect = FW_GetShapeBoundingBox(ev, requestedFrameShape);
-
- fBounds.right = fBounds.left + frameRect.Width();
- fBounds.bottom = fBounds.top + frameRect.Height();
-
- // ----- Invalidate the old used Shape in case the embedded frame doesn't do it-----
- FW_CAcquiredODShape aqUsedShape = odEmbeddedFrame->AcquireUsedShape(ev, NULL);
- odEmbeddedFrame->Invalidate(ev, aqUsedShape, NULL);
-
- // ----- Don't forget to bump the refcount
- requestedFrameShape->Acquire(ev);
- return requestedFrameShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::UsedShapeChanged
- //----------------------------------------------------------------------------------------
-
- void CProxy::UsedShapeChanged(Environment* ev, FW_CEmbeddingFrame* embeddingFrame, ODFrame* odEmbeddedFrame)
- {
- FW_UNUSED(odEmbeddedFrame);
-
- // ----- Recalcul the clip -----
- FW_CAcquiredODShape changedShape = ::FW_NewODShape(ev, fBounds);
- FW_CFacetClipper facetClipper(ev, fContainerPart);
- facetClipper.Clip(ev, embeddingFrame, NULL /*changedShape*/);
-
- // ----- Invalidate
- embeddingFrame->Invalidate(ev, fBounds);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::GetHandleCenter
- //----------------------------------------------------------------------------------------
-
- void CProxy::GetHandleCenter(short whichHandle, FW_CPoint& center) const
- {
- const FW_Fixed fxHalf = FW_ODFixedToFixed(0x00008000);
- const FW_Fixed fxTwo = FW_IntToFixed(2);
- const FW_Fixed fxThree = FW_IntToFixed(3);
-
- switch (whichHandle)
- {
- case kInTopLeftCorner:
- center.x = fBounds.left - fxThree;
- center.y = fBounds.top - fxThree;
- break;
- case kInTopRightCorner:
- center.x = fBounds.right + fxTwo;
- center.y = fBounds.top - fxThree;
- break;
- case kInBottomLeftCorner:
- center.x = fBounds.left - fxThree;
- center.y = fBounds.bottom + fxTwo;
- break;
- case kInBottomRightCorner:
- center.x = fBounds.right + fxTwo;
- center.y = fBounds.bottom + fxTwo;
- break;
-
- case kInTopMiddle:
- center.x = fBounds.left + (fBounds.Width() * fxHalf);
- center.y = fBounds.top - fxThree;
- break;
- case kInLeftMiddle:
- center.x = fBounds.left - fxThree;
- center.y = fBounds.top + (fBounds.Height() * fxHalf);
- break;
- case kInBottomMiddle:
- center.x = fBounds.left + (fBounds.Width() * fxHalf);
- center.y = fBounds.bottom + fxTwo;
- break;
- case kInRightMiddle:
- center.x = fBounds.right + fxTwo;
- center.y = fBounds.top + (fBounds.Height() * fxHalf);
- break;
- }
- }
-
-
- //----------------------------------------------------------------------------------------
- // CProxy::ResizeProxy
- //----------------------------------------------------------------------------------------
-
- void CProxy::ResizeProxy(Environment* ev, const FW_CRect& srcRect, const FW_CRect& dstRect)
- {
- FW_CRect bounds(fBounds);
- bounds.Map(srcRect, dstRect);
- bounds.Sort();
-
- SetBounds(ev, bounds);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::OffsetProxy
- //----------------------------------------------------------------------------------------
-
- void CProxy::OffsetProxy(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
- {
- FW_CRect bounds(fBounds);
- bounds.Offset(xDelta, yDelta);
- SetBounds(ev, bounds);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::SelectProxy
- //----------------------------------------------------------------------------------------
- void CProxy::SelectProxy(Environment* ev, FW_Boolean state)
- {
- fSelected = state;
-
- // ----- Select all the embedded facet ----
- SetSelectState(ev, state);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::SubtractToWindowClip
- //----------------------------------------------------------------------------------------
- // ATTENTION: windowClip is in Window coordinates. tempShape is just a working shape. It is
- // used by CProxy so I don't have to allocate a shape every time.
-
- void CProxy::SubtractToWindowClip(Environment* ev,
- FW_CFacetClipper* facetClipper,
- ODFacet* containingFacet,
- ODShape* windowClip, ODShape* tempShape)
- {
- FW_UNUSED(tempShape);
-
- FW_CEmbeddedODFacetsIterator ite(ev, this, containingFacet, kODFrontToBack);
- for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
- {
- facetClipper->ClipOneEmbeddedFacet(ev, embeddedODFacet, windowClip);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::HitTest
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CProxy::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CPoint& where) const
- {
- FW_CRectShape rectShape(fBounds, FW_kFill);
- return rectShape.HitTest(gc, where, FW_kFixed0);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::CalcHandle
- //----------------------------------------------------------------------------------------
-
- void CProxy::CalcHandle(short whichHandle, FW_CRectShape* handle, const FW_CPoint& penSize) const
- {
- FW_CPoint pt;
- GetHandleCenter(whichHandle, pt);
-
- FW_Fixed fx = penSize.x + FW_ODFixedToFixed(0x00008000);
- FW_Fixed fy = penSize.y + FW_ODFixedToFixed(0x00008000);
- // const FW_Fixed fx25 = FW_DoubleToFixed(2.5);
- FW_CRect rect(pt.x - fx, pt.y - fy, pt.x + fx, pt.y + fy);
-
- handle->SetRectangle(rect);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::RenderSelectionFrame
- //----------------------------------------------------------------------------------------
-
- void CProxy::RenderSelectionFrame(FW_CGraphicContext& gc)
- {
- FW_CInk ink(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
- FW_CStyle style(FW_kFixed0, FW_kGrayPat);
-
- FW_CRect rect;
- GetHandleCenter(kInTopLeftCorner, rect[FW_kTopLeft]);
- GetHandleCenter(kInBottomRightCorner, rect[FW_kBotRight]);
- rect[FW_kBotRight] += FW_CPoint(FW_kFixedPos1, FW_kFixedPos1); // adjust for penSize
- FW_CRectShape::RenderRect(gc, rect, FW_kFrame, ink, style);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::RenderHandles
- //----------------------------------------------------------------------------------------
-
- void CProxy::RenderHandles(FW_CGraphicContext& gc)
- {
- // First draw the lines connecting the handles
- RenderSelectionFrame(gc);
-
- // Now draw the handles themselves
- FW_CPoint penSize = gc.DeviceToLogical(2, 2);
- for (short i=1; i<=kNumberOfHandles; i++)
- {
- CalcHandle(i, CProxy::gWorkingHandle, penSize);
- CProxy::gWorkingHandle->Render(gc);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::WhichHandle
- //----------------------------------------------------------------------------------------
-
- short CProxy::WhichHandle(FW_CGraphicContext& gc, const FW_CPoint& mouse) const
- {
- FW_CPoint penSize = gc.DeviceToLogical(4, 4);
- for (short i=1; i<=kNumberOfHandles; i++)
- {
- CalcHandle(i, CProxy::gWorkingHandle, penSize);
- if (CProxy::gWorkingHandle->HitTest(gc, mouse, FW_kFixed0))
- return i;
- }
-
- return 0;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::CreateProxyOutline
- //----------------------------------------------------------------------------------------
-
- ODShape* CProxy::CreateProxyOutline(Environment* ev)
- {
- // We don't acquire it because we return it
- ODShape* dragShape = ::FW_NewODShape(ev, fBounds);
-
- ::FW_OutlineODShape(ev, dragShape, FW_kFixed0);
-
- return dragShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::GetMappedRects
- //----------------------------------------------------------------------------------------
-
- void CProxy::GetMappedRects(short whichHandle, const FW_CPoint& mouseLoc, FW_CRect& srcRect, FW_CRect& dstRect)
- {
- dstRect = srcRect = fBounds;
-
- 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;
-
- case kInTopMiddle:
- dstRect.top = mouseLoc.y;
- break;
- case kInLeftMiddle:
- dstRect.left = mouseLoc.x;
- break;
- case kInBottomMiddle:
- dstRect.bottom = mouseLoc.y;
- break;
- case kInRightMiddle:
- dstRect.right = mouseLoc.x;
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::ResizeFeedback
- //----------------------------------------------------------------------------------------
-
- void CProxy::ResizeFeedback(FW_CGraphicContext& gc,
- const FW_CInk& ink,
- const FW_CStyle& style,
- short whichHandle,
- const FW_CPoint& mouseLoc)
- {
- FW_CRect srcRect, dstRect;
- GetMappedRects(whichHandle, mouseLoc, srcRect, dstRect);
- dstRect.Inset(FW_IntToFixed(-3) - FW_Half(style.GetPenSize()));
-
- dstRect.Sort();
-
- FW_CRectShape::RenderRect(gc,
- dstRect,
- FW_kFrame,
- ink,
- style);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::InSelectionRect
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CProxy::InSelectionRect(const FW_CRect& selectRect) const
- {
- FW_CRect temp(fBounds);
- temp.Intersection(selectRect);
-
- return fBounds == temp;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::GetUpdateBox
- //----------------------------------------------------------------------------------------
-
- void CProxy::GetUpdateBox(Environment* ev, ODShape* updateBox) const
- {
- FW_CRect bounds(fBounds);
- bounds.Inset(FW_IntToFixed(-6));
- updateBox->SetRectangle(ev, (ODRect*)&bounds);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::SetBounds
- //----------------------------------------------------------------------------------------
-
- void CProxy::SetBounds(Environment* ev, const FW_CRect& bounds)
- {
- fBounds = bounds;
-
- // ----- Resize/Move every embedded frame -----
- ChangeExternalTransforms(ev, fBounds.left, fBounds.top);
- ChangeFrameShapes(ev, fBounds.right - fBounds.left, fBounds.bottom - fBounds.top);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxy::Render
- //----------------------------------------------------------------------------------------
- // Because there can be multiple CProxy pointing on an embedded
- // frame, I only draw those belonging to this frame.
-
- void CProxy::Render(Environment *ev, ODFacet* facet, FW_CGraphicContext& gc)
- {
- // if the canvas is not dynamic (printing) I let OpenDoc draw embedded facets
- if (!facet->GetCanvas(ev)->IsDynamic(ev))
- return;
-
- FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
- FW_CAcquiredODShape aqTempClipShape(gc.AcquireClip()); // GetClip returns a copy in content coordinate
-
- // ----- Because we are calling the draw method of an embedded facet, we want
- // ----- to save our context. The embedded facet will be using the same grafport
- // ----- and may not be restoring it.
- FW_CSaveRestoreContext src(gc);
-
- FW_CEmbeddedODFacetsIterator ite(ev, this, facet, kODFrontToBack);
- for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
- {
- aqTempShape->CopyFrom(ev, aqTempClipShape);
-
- {
- FW_CAcquiredODTransform aqFrameTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
- aqTempShape->InverseTransform(ev, aqFrameTransform); // parent content (me) -> embedded frame
- }
-
- #ifdef FW_BUILD_WIN
- // [HLX] bug in windows? the invalidShape is expected to be in pixels instead of points
- aqTempShape->Outset(ev, ff(1)); // [HLX] Because of rounding errors
- FW_CGraphicDevice *device = gc.GetGraphicDevice();
- device->PointToPixel(ev, aqTempShape);
- #endif
-
- embeddedODFacet->Draw(ev, aqTempShape, NULL);
- embeddedODFacet->DrawChildren(ev, aqTempShape, NULL);
-
- {
- FW_CAcquiredODShape aqClipShape = embeddedODFacet->AcquireClipShape(ev, NULL);
- aqTempShape->CopyFrom(ev, aqClipShape);
- }
-
- {
- FW_CAcquiredODTransform aqExternalTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
- aqTempShape->Transform(ev, aqExternalTransform);
- }
-
- aqTempClipShape->Subtract(ev, aqTempShape);
- }
- }
-
-
-