// $Revision: 1.4 $ // Copyright (c) 1994-1995 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_GRAPHICVIEW #include "GraphicView.h" #endif #ifndef TaligentSamples_POLYGONINTERACTOR #include "PolygonInteractor.h" #endif #ifndef Taligent_GRAFPORT #include #endif #ifndef Taligent_RGBCOLOR #include #endif #ifndef Taligent_ASSERTIONS #include #endif MCollectibleDefinitionsMacro(TGraphicView, kOriginalVersion); TGraphicView::TGraphicView() : TContentView(TGPoint(300, 50)), MMouseEventHandler(), fGraphic(NIL), fInteractor(NIL) { } TGraphicView::TGraphicView(const TGPoint& size, const TGPoint& location) : TContentView(size, location), MMouseEventHandler(), fGraphic(NIL), fInteractor(NIL) { } TGraphicView::~TGraphicView() { delete fGraphic; } void TGraphicView::HandleAfterConnectionToViewRoot() { RegisterSimpleTarget(*InternalGetEventReceiver()); } void TGraphicView::HandleBeforeDisconnectionFromViewRoot() { DeregisterSimpleTarget(*InternalGetEventReceiver()); } // Erase and then draw the graphic, if we have one. void TGraphicView::DrawContents(TGrafPort& port) const { static const TRGBColor white(1, 1, 1); static const TRGBColor black(0, 0, 0); static const TRGBColor blue(0, 0, 1); static const TFillAndFrameBundle eraseState(white, black, 2.0, TPen::kInsetFrame); static const TFillAndFrameBundle polyState(blue, black, 1.0, TPen::kInsetFrame); TGArea area; GetBounds(area); port.Draw(area, eraseState); if (fGraphic) { TLinkedBundlePort bundlePort(&port, &polyState); fGraphic->Draw(bundlePort); } } // When we get a mouse down, start the polygon interactor. It will keep control until // it is finished. It will change our graphic. bool TGraphicView::MouseDown(TMouseDownEvent& mouseDown) { mouseDown.StartInteractor(new TPolygonInteractor(this)); return true; } void TGraphicView::AdoptGraphic(MGraphic* graphic) { delete fGraphic; fGraphic = graphic; Invalidate(); } void TGraphicView::AddInteractor(TInteractor* interactor) { Assertion(interactor != NIL); if (fInteractor == NIL) { fInteractor = interactor; } } void TGraphicView::RemoveInteractor(const TInteractor& interactor) { if (fInteractor == &interactor) { fInteractor = NIL; } } // If we merely deactivated the interactor, it would still be around and would // intercept all the mouse events, but not dispatch them. This would effectively // disable our window. By calling SetDone, we ensure that when the next event // is passed the interactor: 1) it will just return false without dispatching // the event (as would be the case if we called Deactivate), and 2) the device // will delete it. Both conditions must be met for the device to dispatch the // event normally. // // We clean up the graphic ourselves. We could also have written protocol on // the interactor to do this. But by this time the view and interactor have // become so intertwined there is not so much point to it. void TGraphicView::HandleDeactivate() { if (fInteractor) { fInteractor->SetDone(true); AdoptGraphic(NIL); } } void TGraphicView::HandleAllocatedAreaChanged(const TGArea&) { InvalidateAll(); }