home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-16 | 20.5 KB | 711 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Select.cpp
- // Release Version: $ ODF 1 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Container.hpp"
-
- #ifndef SELECT_H
- #include "Select.h"
- #endif
-
- #ifndef CONTENT_H
- #include "Content.h"
- #endif
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- #ifndef FRAME_H
- #include "Frame.h"
- #endif
-
- #ifndef PROXY_H
- #include "Proxy.h"
- #endif
-
- #ifndef COMMANDS_H
- #include "Commands.h"
- #endif
-
- #ifndef TRACKER_H
- #include "Tracker.h"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWCONTXT_H
- #include "FWContxt.h"
- #endif
-
- #ifndef FWFCTCLP_H
- #include "FWFctClp.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef SLMixOS_H
- #include "SLMixOS.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfcontainer
- #endif
-
- //========================================================================================
- // class CContainerSelection
- //========================================================================================
-
- FW_DEFINE_AUTO(CContainerSelection)
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CContainerSelection
- //----------------------------------------------------------------------------------------
-
- CContainerSelection::CContainerSelection(Environment* ev, CContainerPart* part):
- FW_CSelection(ev, false, false), // no linking allowed
- fContainerPart(part),
- fUpdateShape(NULL),
- fCount(0),
- fSelectionContent(NULL),
- fWorkingHandle(FW_kZeroRect, FW_kFill),
- fDraggedContent(NULL)
- {
- fSelectionContent = FW_NEW(CSelectionContent, (ev, part, this));
- fWorkingHandle.SetInk(FW_kInvertInk);
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::~CContainerSelection
- //----------------------------------------------------------------------------------------
-
- CContainerSelection::~CContainerSelection()
- {
- FW_START_DESTRUCTOR
- if (fUpdateShape)
- {
- FW_SOMEnvironment ev;
- fUpdateShape->Release(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::GetSelectedContent
- //----------------------------------------------------------------------------------------
-
- FW_CContent* CContainerSelection::GetSelectedContent(Environment* ev)
- {
- return fSelectionContent;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::WhichHandle
- //----------------------------------------------------------------------------------------
-
- CProxy* CContainerSelection::WhichHandle(Environment* ev, FW_CGraphicContext& gc, const FW_CPoint& mouse, short& whichHandle) const
- {
- whichHandle = 0;
-
- if (fCount != 0)
- {
- CContentProxyIterator ite(fSelectionContent);
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- whichHandle = proxy->WhichHandle(gc, mouse);
- if (whichHandle != 0)
- return proxy;
- }
- }
-
- return NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::RenderSelectionHandles
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::RenderSelectionHandles(Environment* ev, FW_CGraphicContext& gc)
- {
- CContentProxyIterator ite(fSelectionContent);
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- proxy->RenderHandles(gc);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::RenderAllHandles
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::RenderAllHandles(Environment* ev, FW_CFrame* frame)
- {
- if (fCount != 0)
- {
- FW_CFrameFacetIterator ite(ev, frame);
- for (ODFacet* facet = (ODFacet*)ite.First(ev); ite.IsNotComplete(ev); facet = (ODFacet*)ite.Next(ev))
- {
- FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
- RenderSelectionHandles(ev, vc);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::RenderHandles
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::RenderHandles(Environment* ev, CProxy* proxy)
- {
- FW_CPresentationFrameIterator ite(ev, GetPresentation(ev));
- for (FW_CFrame* frame = ite.First(ev); ite.IsNotComplete(ev); frame = ite.Next(ev))
- {
- if (frame->HasSelectionFocus(ev))
- {
- FW_CFrameFacetIterator i(ev, frame);
- for (ODFacet* facet = i.First(ev); i.IsNotComplete(ev); facet = i.Next(ev))
- {
- FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
- proxy->RenderHandles(vc);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CloseSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::CloseSelection(Environment* ev)
- {
- CProxy* proxy;
- while ((proxy = fSelectionContent->GetFirstProxy()) != NULL)
- {
- DoRemove(ev, proxy);
- RenderHandles(ev, proxy); // turn off
- }
-
- CalcCache(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::AddToSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::AddToSelection(Environment* ev, CProxy* theProxy, FW_Boolean renderHandles)
- {
- if (theProxy != NULL)
- {
- DoAdd(ev, theProxy);
- if (renderHandles)
- RenderHandles(ev, theProxy); // Turn on
- }
-
- CalcCache(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::RemoveFromSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::RemoveFromSelection(Environment* ev, CProxy* proxy, FW_Boolean renderHandles)
- {
- if (proxy != NULL)
- {
- DoRemove(ev, proxy);
- if (renderHandles)
- RenderHandles(ev, proxy); // Turn Off
- }
-
- CalcCache(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::DoAdd
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::DoAdd(Environment* ev, CProxy* proxy)
- {
- fSelectionContent->AddProxy(ev, proxy);
- this->ProxyAdded(ev, proxy);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::ProxyAdded
- //----------------------------------------------------------------------------------------
- void CContainerSelection::ProxyAdded(Environment* ev, CProxy* proxy)
- {
- proxy->SelectProxy(ev, true);
- fCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::DoRemove
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::DoRemove(Environment* ev, CProxy* proxy)
- {
- fSelectionContent->RemoveProxy(ev, proxy);
- proxy->SelectProxy(ev, false);
- fCount--;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::ClearSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::ClearSelection(Environment* ev)
- {
- CProxy* proxy;
- while ((proxy = fSelectionContent->GetFirstProxy()) != NULL)
- {
- DoRemove(ev, proxy); // Remove from selection list
- fContainerPart->DetachProxy(ev, proxy); // Remove from part
- }
-
- FW_CFacetClipper facetClipper(ev, fContainerPart);
- facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);
- GetPresentation(ev)->Invalidate(ev, fUpdateShape);
-
- CalcCache(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::SelectAll
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::SelectAll(Environment* ev)
- {
- FW_CFrame* activeFrame = fContainerPart->GetLastActiveFrame(ev);
-
- RenderAllHandles(ev, activeFrame);
-
- CContentProxyIterator ite(fContainerPart->GetPartContent());
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- if (!proxy->IsSelected())
- DoAdd(ev, proxy);
- }
-
- RenderAllHandles(ev, activeFrame);
-
- CalcCache(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::IsEmpty
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CContainerSelection::IsEmpty(Environment* ev) const
- {
- return fCount == 0;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CenterSelection
- //----------------------------------------------------------------------------------------
-
- FW_CPoint CContainerSelection::CenterSelection(Environment* ev, FW_CFrame* scopeFrame)
- {
- FW_ASSERT(scopeFrame);
-
- CalcCache(ev);
-
- FW_CRect bounds = scopeFrame->GetContentView(ev)->GetBoundsInContent(ev);
- FW_CRect box(fDragRect);
- box.PlaceInCenter(bounds);
-
- FW_CPoint result(box.left - fDragRect.left, box.top - fDragRect.top);
- OffsetSelection(ev, result.x, result.y);
-
- FW_CFacetClipper facetClipper(ev, fContainerPart);
- facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);
- GetPresentation(ev)->Invalidate(ev, fUpdateShape);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::Resize
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CContainerSelection::Resize(Environment* ev, const FW_CMouseEvent& theMouseEvent)
- {
- if (fClickedHandle == 0)
- return FALSE;
-
- if (!this->IsOKtoEdit(ev)) // can't resize read only part
- {
- FW_Beep();
- return TRUE;
- }
-
- if (!theMouseEvent.WaitUntilMouseMoved(ev))
- return TRUE;
-
- ODFacet* facet = theMouseEvent.GetFacet(ev);
- FW_CFrame* frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
-
- CProxy* anchorProxy = GetAnchorProxy();
-
- FW_CInk resizeInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
- FW_CStyle resizeStyle(FW_kFixed0, FW_kGrayPat);
-
- CResizeTracker resizeTracker(ev, frame->GetContentView(ev), facet, anchorProxy, fClickedHandle, resizeInk, resizeStyle);
- if (resizeTracker.Track(ev, theMouseEvent))
- {
- GetPresentation(ev)->Invalidate(ev, fUpdateShape);
-
- FW_CPoint lastLocation;
- resizeTracker.GetLastLocation(lastLocation);
- FW_CRect srcRect, dstRect;
- anchorProxy->GetMappedRects(fClickedHandle, lastLocation, srcRect, dstRect);
-
- CResizeCommand* cmd = FW_NEW(CResizeCommand,
- (ev, fContainerPart, frame, this,
- srcRect, dstRect));
- cmd->Execute(ev);
- }
- else
- {
- FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
-
- FW_CPoint penSize = vc.DeviceToLogical(2, 2);
- anchorProxy->CalcHandle(fClickedHandle, &fWorkingHandle, penSize);
- fWorkingHandle.Render(vc); // redraw the handle
- }
-
- return TRUE;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CalcCache
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::CalcCache(Environment* ev)
- {
- fDragRect.Clear();
-
- if (fUpdateShape == NULL)
- fUpdateShape = ::FW_NewODShape(ev);
-
- if (fCount == 0)
- return;
-
- FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
- FW_CRect tempRect;
-
- FW_Boolean first = TRUE;
- CContentProxyIterator ite(fSelectionContent);
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- tempRect = proxy->GetBounds(ev);
- proxy->GetUpdateBox(ev, aqTempShape);
- if (first)
- {
- fDragRect = tempRect;
- fUpdateShape->CopyFrom(ev, aqTempShape);
- }
- else
- {
- fDragRect |= tempRect;
- fUpdateShape->Union(ev, aqTempShape);
- }
-
- first = FALSE;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CreateSelectionShape
- //----------------------------------------------------------------------------------------
-
- ODShape* CContainerSelection::CreateSelectionShape(Environment* ev, ODFacet* facet, FW_CFrame* frame) const
- {
- FW_UNUSED(frame);
- FW_UNUSED(facet);
-
- ODShape* shape = ::FW_NewODShape(ev, fDragRect);
- return shape;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::CreateSelectionOutline
- //----------------------------------------------------------------------------------------
-
- ODShape* CContainerSelection::CreateSelectionOutline(Environment* ev, ODFacet* facet, FW_CFrame* frame) const
- {
- FW_ASSERT(GetAnchorProxy());
- ODShape* outline = GetAnchorProxy()->CreateProxyOutline(ev);
-
- if (fCount > 1)
- {
- FW_CAcquiredODShape shapeOutline = FW_CSelection::CreateSelectionOutline(ev, facet, frame);
- outline->Union(ev, shapeOutline);
- }
-
- return outline;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::OffsetSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::OffsetSelection(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
- {
- FW_CAcquiredODShape aqUnionShape(fUpdateShape->Copy(ev));
-
- CContentProxyIterator ite(fSelectionContent);
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- proxy->OffsetProxy(ev, xDelta, yDelta);
- }
-
- CalcCache(ev);
-
- aqUnionShape->Union(ev, fUpdateShape);
-
- FW_CFacetClipper facetClipper(ev, fContainerPart);
- facetClipper.Clip(ev, GetPresentation(ev), aqUnionShape);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::SelectWithRectangle
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::SelectWithRectangle(Environment* ev, const FW_CMouseEvent& theMouseEvent)
- {
- FW_CStyle trackStyle(FW_kFixed0, FW_kAntPat);
- FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
- CTrackRect rectShape(trackInk, trackStyle); // Create a rect shape on the stack
-
- ODFacet* facet = theMouseEvent.GetFacet(ev);
- FW_CFrame* frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
-
- CSelectTracker tracker(ev, frame->GetContentView(ev), facet, &rectShape);
- if (tracker.Track(ev, theMouseEvent))
- {
- FW_Boolean isShift = theMouseEvent.IsExtendModifier(ev);
- FW_CRect selectRect;
- rectShape.GetRectBounds(selectRect);
-
- CContentProxyIterator ite(fContainerPart->GetPartContent());
- for (CProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
- {
- if (proxy->InSelectionRect(selectRect))
- {
- if (proxy->IsSelected())
- {
- if (isShift)
- {
- DoRemove(ev, proxy);
- RenderHandles(ev, proxy); // Turn Off
- }
- }
- else
- {
- DoAdd(ev, proxy);
- RenderHandles(ev, proxy); // Turn on
- }
- }
- else if (proxy->IsSelected() && !isShift)
- {
- DoRemove(ev, proxy);
- RenderHandles(ev, proxy); // Turn Off
- }
- }
- CalcCache(ev);
- }
- else
- {
- if (!theMouseEvent.IsExtendModifier(ev))
- CloseSelection(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::SelectionChanged
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::SelectionChanged(Environment* ev)
- {
- //--- Notify frames ---
- GetPresentation(ev)->ContentUpdated(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::IsMouseInDraggableItem
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CContainerSelection::IsMouseInDraggableItem(Environment* ev,
- FW_CFrame* frame,
- const FW_CMouseEvent& theMouseEvent,
- FW_Boolean inBackground)
- {
- fClickedHandle = 0;
- fAnchorProxy = NULL;
-
- FW_CViewContext vc(ev, frame->GetContentView(ev), theMouseEvent.GetFacet(ev));
-
- // ----- Look first for a handle -----
- FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
- frame->GetContentView(ev)->FrameToViewContent(ev, where);
-
- CProxy* clickedProxy = WhichHandle(ev, vc, where, fClickedHandle);
- if (clickedProxy != NULL)
- {
- fAnchorProxy = clickedProxy;
- return FALSE; // if in a handle we won't drag
- }
-
- // ----- then look for a selected proxy -----
- CProxy* proxy = fContainerPart->WhichProxy(ev, vc, where, TRUE);
-
- if (proxy != NULL && proxy->IsSelected())
- {
- fAnchorProxy = proxy;
- return TRUE;
- }
-
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::UpdateSelectionOnMouseDown
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::UpdateSelectionOnMouseDown(Environment* ev,
- const FW_CMouseEvent& mouseEvent,
- ODFacet* embeddedFacet,
- FW_Boolean inEmbeddedFrameBorder,
- FW_Boolean inBackground)
- {
- if (inEmbeddedFrameBorder)
- {
- fClickedHandle = 0;
- fAnchorProxy = NULL;
-
- CProxy* theProxy = (CProxy*)fContainerPart->GetProxy(ev, embeddedFacet->GetFrame(ev));
- FW_ASSERT(theProxy);
-
- if (!theProxy->IsSelected())
- AddToSelection(ev, theProxy, TRUE);
-
- fAnchorProxy = theProxy;
- }
- else
- {
- ODFacet* facet = mouseEvent.GetFacet(ev);
- FW_CFrame* frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
- FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
- FW_CPoint where = mouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
- frame->GetContentView(ev)->FrameToViewContent(ev, where);
-
- CProxy* clickedProxy = fContainerPart->WhichProxy(ev, vc, where, FALSE);
- if (clickedProxy)
- {
- if (mouseEvent.IsExtendModifier(ev))
- {
- if (clickedProxy->IsSelected())
- {
- RemoveFromSelection(ev, clickedProxy, !inBackground);
- if (clickedProxy == fAnchorProxy)
- fAnchorProxy = NULL;
- }
- else
- {
- AddToSelection(ev, clickedProxy, !inBackground);
- fAnchorProxy = clickedProxy;
- }
- }
- else if (!clickedProxy->IsSelected())
- {
- fAnchorProxy = clickedProxy;
- CloseSelection(ev);
- AddToSelection(ev, clickedProxy, !inBackground);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::DeleteSelection
- //----------------------------------------------------------------------------------------
-
- void CContainerSelection::DeleteSelection(Environment* ev)
- {
- CProxy* proxy;
- while ((proxy = fSelectionContent->GetFirstProxy()) != NULL)
- {
- DoRemove(ev, proxy); // Remove from selection
- fContainerPart->DeleteProxy(ev, proxy); // delete the proxy
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::IsOKtoEdit
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CContainerSelection::IsOKtoEdit(Environment* ev)
- {
- // Check for a read-only part
- if (fContainerPart->IsReadOnly(ev))
- return false;
-
- return true;
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::SelectContent
- //----------------------------------------------------------------------------------------
- void CContainerSelection::SelectContent(Environment* ev, CBaseContent* content)
- {
- this->CloseSelection(ev);
-
- CContentProxyIterator it(content);
- for (CProxy* proxy = it.First(); it.IsNotComplete(); proxy = it.Next())
- {
- this->AddToSelection(ev, proxy, TRUE);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CContainerSelection::GetSelectionContent
- //----------------------------------------------------------------------------------------
-
- CBaseContent* CContainerSelection::GetSelectionContent(Environment* ev)
- {
- return fSelectionContent;
- }
-