home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-16 | 18.9 KB | 641 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Frame.cpp
- // Release Version: $ ODF 1 $
- //
- // Author: Henri Lamiraux
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Bitmap.hpp"
-
- #ifndef FRAME_H
- #include "Frame.h"
- #endif
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- #ifndef CONTENT_H
- #include "Content.h"
- #endif
-
- #ifndef SELECT_H
- #include "Select.h"
- #endif
-
- #ifndef RBBRBAND_H
- #include "RbbrBand.h"
- #endif
-
- #ifndef DEFINES_K
- #include "Defines.k"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWCLPCMD_H
- #include "FWClpCmd.h"
- #endif
-
- #ifndef FWDRCMD_H
- #include "FWDrCmd.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWPRTITE_H
- #include "FWPrtIte.h"
- #endif
-
- #ifndef FWGROWBX_H
- #include "FWGrowBx.h"
- #endif
-
- #ifndef FWSCLBAR_H
- #include "FWSclBar.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWIDLE_H
- #include "FWIdle.h"
- #endif
-
- #ifndef FWCONTXT_H
- #include "FWContxt.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWODGEOM_H
- #include "FWODGeom.h"
- #endif
-
- #ifndef FWBMPSHP_H
- #include "FWBmpShp.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- #ifndef SLMixOS_H
- #include "SLMixOS.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_ODDragItemIterator_xh
- #include <DgItmIt.xh>
- #endif
-
- //========================================================================================
- // Runtime Informations
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfbitmap
- #endif
-
- //========================================================================================
- // class CBitmapFrame
- //========================================================================================
-
- FW_DEFINE_AUTO(CBitmapFrame)
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::CBitmapFrame
- //----------------------------------------------------------------------------------------
- // CBitmapFrame constructor
-
- CBitmapFrame::CBitmapFrame(Environment* ev, ODFrame* odFrame, FW_CPresentation* presentation, CBitmapPart* bitmapPart, CBitmapContent* content) :
- FW_CFrame(ev, odFrame, presentation, bitmapPart),
- FW_MDroppableFrame(ev, this),
- FW_MDraggableFrame(ev, this),
- fBitmapContent(content),
- fChoosenSize(cFitToFrame),
- fSelection((CBitmapSelection*)presentation->GetSelection(ev)),
- fIdler(NULL)
- {
- if (IsRoot(ev))
- fChoosenSize = cRealSize;
-
- // ----- Save my current frame rect -----
- fFrameRect = this->GetBounds(ev);
-
- fIdler = FW_NEW(FW_CIdler, (this, 15));
-
- // ----- I want to be able to drop even in thumbnail mode -----
- ChangeDroppableState(ev, FW_kFrameDroppable | FW_kThumbnailDroppable);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::~CBitmapFrame
- //----------------------------------------------------------------------------------------
- // CBitmapFrame destructor
-
- CBitmapFrame::~CBitmapFrame()
- {
- FW_START_DESTRUCTOR
-
- delete fIdler;
- fIdler = NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::DoAdjustMenus
- //----------------------------------------------------------------------------------------
- // ODF Method
-
- FW_Boolean CBitmapFrame::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
- {
- if (hasMenuFocus)
- {
- // ----- OpenDoc Items -----
- FW_Boolean hasRightProperty = HasPropertyOnClipboard(ev, kODPropContents, GetPart(ev)->GetPartKind(ev));
-
- #ifdef FW_BUILD_MAC
- // ----- On the Mac I allow Paste for both my kind and PICT. On Window I only allow Paste for my kind
- if (!hasRightProperty)
- hasRightProperty = hasRightProperty || HasPropertyOnClipboard(ev, kODPropContents, FW_CPart::gMacPICTDataType);
- #endif
-
- menuBar->EnableCommand(ev, kODCommandSelectAll, TRUE); // Allow Select All
- menuBar->EnableCommand(ev, kODCommandClear, FALSE); // Don't allow Clear
- menuBar->EnableCommand(ev, kODCommandCut, FALSE); // Don't allow cut
- menuBar->EnableCommand(ev, kODCommandCopy, !fSelection->IsEmpty(ev)); // Allow copy only if my selection is not empty
- menuBar->EnableCommand(ev, kODCommandPaste, hasRightProperty); // Allow Paste if right property on the clipboard
- menuBar->EnableCommand(ev, kODCommandPasteAs, FALSE); // Don't allow Past As for now
-
- // ----- My Items -----
- ODCommandID choosenSize = GetChoosenSize();
-
- menuBar->EnableAndCheckCommand(ev, cHalfSize, TRUE, fChoosenSize == cHalfSize);
- menuBar->EnableAndCheckCommand(ev, cRealSize, TRUE, fChoosenSize == cRealSize);
- menuBar->EnableAndCheckCommand(ev, cDoubleSize, TRUE, fChoosenSize == cDoubleSize);
- menuBar->EnableAndCheckCommand(ev, cFitToFrame, TRUE, fChoosenSize == cFitToFrame);
- menuBar->EnableCommand(ev, cRequestFrame, !IsRoot(ev));
- menuBar->EnableCommand(ev, cRemoveFrame, IsRequestedFrame(ev));
- }
-
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::DoMenu
- //----------------------------------------------------------------------------------------
- // ODF method
-
- FW_Boolean CBitmapFrame::DoMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
- {
- FW_Boolean result = TRUE;
- ODCommandID commandID = theMenuEvent.GetCommandID(ev);
-
- FW_CPresentation* myPresentation = GetPresentation(ev);
-
- switch (commandID)
- {
- case cHalfSize:
- case cRealSize:
- case cDoubleSize:
- case cFitToFrame:
- if (commandID != fChoosenSize)
- {
- fChoosenSize = commandID;
- AdjustFrameSize(ev);
- }
- break;
-
- case cRequestFrame:
- {
- FW_CAcquiredODShape aqShape = FW_CopyAndRelease(ev, AcquireFrameShape(ev));
- ODID sequence = myPresentation->RequestSiblingFrame(ev, this, aqShape, GetViewType(ev), FALSE);
- if (sequence != kODNULLID)
- myPresentation->Invalidate(ev, NULL, sequence); // invalidate all frames of this sequence
- }
- break;
-
- case cRemoveFrame:
- myPresentation->RemoveSiblingFrame(ev, this);
- break;
-
- default:
- result = FALSE;
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::DoIdle
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CBitmapFrame::DoIdle(Environment* ev, const FW_CNullEvent& theNullEvent)
- {
- FW_UNUSED(theNullEvent);
- if (fSelection != NULL && !fSelection->IsEmpty(ev))
- fSelection->MoveAnts(ev, this);
-
- return TRUE;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::AdjustFrameSize
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::AdjustFrameSize(Environment* ev)
- {
- if (IsRoot(ev))
- UpdateUsedAndActiveShapes(ev);
- else
- {
- FW_CRect usedRect;
- CalcUsedRect(ev, usedRect);
- usedRect.Place(FW_kZeroPoint);
-
- FW_CAcquiredODShape aqAskedFrameShape = ::FW_NewODShape(ev, usedRect);
- FW_CAcquiredODShape aqFrameShape = AcquireFrameShape(ev);
-
- if (aqAskedFrameShape->IsSameAs(ev, aqFrameShape))
- UpdateUsedAndActiveShapes(ev);
- else
- this->RequestFrameShape(ev, aqAskedFrameShape);
- }
-
- this->Invalidate(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::FocusStateChanged
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::FocusStateChanged(Environment* ev, ODTypeToken focus, FW_Boolean newState, ODFrame* newOwner)
- {
- FW_CFrame::FocusStateChanged(ev, focus, newState, newOwner);
-
- if (focus == FW_CPart::gSelectionFocusToken)
- {
- if (!fSelection->IsEmpty(ev))
- fSelection->DrawAnts(ev, this);
-
- fIdler->RegisterIdle(ev, newState);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::FrameShapeChanged
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::FrameShapeChanged(Environment* ev)
- {
- FW_CFrame::FrameShapeChanged(ev);
-
- Invalidate(ev); // redraw the whole frame
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::BuildThumbnail
- //----------------------------------------------------------------------------------------
- // I just render the bitmap. I want to use the full 64*64
-
- void CBitmapFrame::BuildThumbnail(Environment* ev, FW_CGraphicContext& gc, FW_CRect& usedRect)
- {
- FW_CBitmap bitmap = fBitmapContent->GetBitmap(ev);
- FW_CBitmapShape::RenderBitmap(gc, bitmap, usedRect);
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::NewClipboardCommand
- //----------------------------------------------------------------------------------------
-
- FW_CClipboardCommand* CBitmapFrame::NewClipboardCommand(Environment* ev, ODCommandID commandID)
- {
- return FW_NEW(FW_CClipboardCommand, (ev,
- commandID,
- this,
- FW_kCantUndo));
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::AdjustUsedShape
- //----------------------------------------------------------------------------------------
- // This Bitmap sample may draw in an area smaller than the frame shape. We let OpenDoc
- // know what shape is actually used so that containers of Bitmap can draw outside.
- // suggestedUsedShape is equal to the frame shape on entry.
-
- ODShape* CBitmapFrame::AdjustUsedShape(Environment* ev, ODShape* suggestedUsedShape)
- {
- // [LSD] OpenDoc bug or feature? Do not make the used shape smaller than the frame
- // shape in the case of root frames! Otherwise, since the active shape will be set
- // to the used shape by default, mouse events won't be processed outside this shape.
-
- if (!IsRoot(ev))
- {
- FW_CRect usedShapeRect;
- CalcUsedRect(ev, usedShapeRect);
-
- FW_CRect frameRect = GetBounds(ev);
- usedShapeRect.Intersection(frameRect);
-
- ODRect odUsedShapeRect = usedShapeRect;
- suggestedUsedShape->SetRectangle(ev, &odUsedShapeRect);
-
- // Must acquire it because I am reusing the shape passed as parameter
- suggestedUsedShape->Acquire(ev);
- return suggestedUsedShape;
- }
- else
- return NULL; // use the frame shape for root frames
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::AdjustActiveShape
- //----------------------------------------------------------------------------------------
- // AdjustActiveShape must also be implemented whenever AdjustUsedShape is, otherwise
- // OpenDoc will use the frame shape by default, and we want the used shape to the default
- // active shape.
-
- ODShape* CBitmapFrame::AdjustActiveShape(Environment* ev, ODFacet* facet, ODShape* suggestedActiveShape)
- {
- // Root frames should not use a smaller active shape. See comments in AdjustUsedShape
-
- if (!IsRoot(ev))
- {
- // suggestedActiveShape is a copy of the used shape (in FW_CFrame::UpdateActiveShape)
- // We tell OpenDoc that we're going to use it.
- suggestedActiveShape->Acquire(ev);
- return suggestedActiveShape;
- }
- else
- return NULL; // use the frame shape for root frames
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::AdjustZoomedWindowSize
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::AdjustZoomedWindowSize(Environment *ev, FW_CPoint& proposedSize)
- {
- FW_CRect usedShapeRect;
- CalcUsedRect(ev, usedShapeRect);
-
- proposedSize.Set(usedShapeRect.Width() + FW_IntToFixed(10), usedShapeRect.Height() + FW_IntToFixed(10));
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::GetZoomRatio
- //----------------------------------------------------------------------------------------
-
- FW_CPoint CBitmapFrame::GetZoomRatio(Environment* ev) const
- {
- FW_CBitmap bitmap = fBitmapContent->GetBitmap(ev);
- FW_CRect bounds;
- bitmap.GetBitmapBounds(bounds);
-
- FW_CRect usedRect;
- CalcUsedRect(ev, usedRect);
-
- FW_CPoint ratio(
- (usedRect.right - usedRect.left) / bounds.right,
- (usedRect.bottom - usedRect.top) / bounds.bottom);
-
- return ratio;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::Draw
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::Draw(Environment* ev, ODFacet* odFacet, ODShape* invalidShape)
- {
- FW_CViewContext vc(ev, this, odFacet, invalidShape);
-
- // ------ [HLX] Will be moved to an adorner
- if (IsTopFrame(ev))
- {
- FW_CRect invalidRect;
- vc.GetClipRect(invalidRect);
-
- #ifdef FW_BUILD_MAC
- FW_CInk ink(FW_kRGBWhite,
- FW_kRGBWhite,
- FW_kErase);
- #else
- FW_CInk ink(FW_CColor(::GetSysColor(COLOR_WINDOWTEXT), 0),
- FW_CColor(::GetSysColor(COLOR_APPWORKSPACE), 0),
- FW_kErase);
- #endif
- FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, ink);
- }
-
- FW_CRect usedRect;
- CalcUsedRect(ev, usedRect);
-
- // ----- Use the static rendering method -----
- FW_CBitmapShape::RenderBitmap(vc, fBitmapContent->GetBitmap(ev), usedRect);
-
- // ----- Draw the ants if there is a selection -----
- if (HasSelectionFocus(ev) && !fSelection->IsEmpty(ev))
- {
- fSelection->DoDrawAnts(ev, vc, this);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::CalcUsedRect
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::CalcUsedRect(Environment* ev, FW_CRect& newUsedRect) const
- {
- ODCommandID choosenSize = GetChoosenSize();
-
- FW_CRect frameRect = GetBounds(ev);
- frameRect.Place(FW_kZeroPoint);
-
- if (choosenSize == cFitToFrame)
- {
- newUsedRect = frameRect;
- }
- else
- {
- fBitmapContent->GetBitmap(ev).GetBitmapBounds(newUsedRect); // return in 72 dpi
-
- if (choosenSize == cHalfSize)
- {
- newUsedRect.right = FW_Half(newUsedRect.right);
- newUsedRect.bottom = FW_Half(newUsedRect.bottom);
- }
- else if (choosenSize == cDoubleSize)
- {
- newUsedRect.right = FW_MultipliedByInt(newUsedRect.right, 2);
- newUsedRect.bottom = FW_MultipliedByInt(newUsedRect.bottom, 2);
- }
-
- newUsedRect.PlaceInCenter(frameRect);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::DoMouseDown
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CBitmapFrame::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
- {
- if (fSelection->IsMouseInDraggableItem(ev, this, theMouseEvent, FALSE))
- {
- if (!Drag(ev, theMouseEvent))
- fSelection->CloseSelection(ev);
- }
- else
- {
- fSelection->CloseSelection(ev);
-
- FW_CRect usedRect;
- CalcUsedRect(ev, usedRect);
-
- FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
- FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, theMouseEvent.GetFacet(ev)->GetFrame(ev));
- frame->GetContentView(ev)->FrameToViewContent(ev, where);
-
- if (usedRect.Contains(where))
- {
- // ----- start a track -----
- CRectRubberBand rubberBand(ev, this, theMouseEvent.GetFacet(ev), usedRect, GetZoomRatio(ev));
-
- if (rubberBand.Track(ev, theMouseEvent))
- {
- FW_CRect rect;
- rubberBand.GetRect(rect);
-
- // ----- Apply the zoom ratio ----
- fSelection->SetSelectRect(GetZoomRatio(ev), usedRect, rect);
- fSelection->DrawAnts(ev, this);
- }
- }
- else
- FW_Beep();
- }
-
- return TRUE;
- }
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::CanAcceptDrop
- //----------------------------------------------------------------------------------------
-
- ODDragResult CBitmapFrame::CanAcceptDrop(Environment* ev, ODDragItemIterator* dragInfo)
- {
- ODDragResult result = FW_MDroppableFrame::CanAcceptDrop(ev, dragInfo);
-
- // ----- Test also for a PICT -----
- if (!result)
- {
- for (ODStorageUnit *dragSU = dragInfo->First(ev); dragSU; dragSU = dragInfo->Next(ev))
- if (dragSU->Exists(ev, kODPropContents, FW_CPart::gMacPICTDataType, 0)) // 'PICT' in Scrap
- return TRUE;
- else if (dragSU->Exists(ev, kODPropContents, FW_CPart::gMacPICTFileType, 0)) // PICT file
- return TRUE;
- }
-
- return result;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::CreateSubViews
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::CreateSubViews(Environment* ev)
- {
- // ----- Create a GrowBox only for root frames
- // (see Form or Container samples for declaring the grow-box in resources)
-
- if (IsRoot(ev))
- {
- FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
-
- FW_CRect frameRect = this->GetBounds(ev);
- frameRect.bottom -= sbSize.y;
- frameRect.right -= sbSize.x;
-
- FW_CGrowBox* growBox = new FW_CGrowBox(ev, this, 0, frameRect[FW_kBotRight]);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::ExternalizeFrame
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::ExternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
- {
- FW_CFrame::ExternalizeFrame(ev, storageUnitView);
-
- FW_PStorageUnitSink suSink(ev, storageUnitView);
- FW_CWritableStream stream(suSink);
- stream << fChoosenSize;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::InternalizeFrame
- //----------------------------------------------------------------------------------------
-
- void CBitmapFrame::InternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
- {
- FW_CFrame::InternalizeFrame(ev, storageUnitView);
-
- FW_PStorageUnitSink suSink(ev, storageUnitView);
- // FW_PBufferedSink sink(ev, suSink);
- FW_CReadableStream stream(suSink);
- stream >> fChoosenSize;
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::NewDragCommand
- //----------------------------------------------------------------------------------------
-
- FW_CDragCommand* CBitmapFrame::NewDragCommand(Environment *ev,
- FW_CFrame* theFrame,
- const FW_CMouseEvent& theMouseEvent)
- {
- FW_UNUSED(theMouseEvent);
-
- return FW_NEW(FW_CDragCommand, (ev, theFrame, FW_kCantUndo));
- }
-
- //----------------------------------------------------------------------------------------
- // CBitmapFrame::NewDropCommand
- //----------------------------------------------------------------------------------------
-
- FW_CDropCommand* CBitmapFrame::NewDropCommand(Environment *ev,
- FW_CFrame* frame,
- ODDragItemIterator* dropInfo,
- ODFacet* facet,
- const FW_CPoint& dropPoint)
- {
-
- return FW_NEW(FW_CDropCommand, (ev, frame, dropInfo, facet, dropPoint, FW_kCantUndo));
- }
-