// $Revision: 1.20 $ //======================================================================= // File: CanvasGraphicFunnels.h // // Description: // // Modification History: // // rtw 12/15/93 new file // // Copyright (C) 1994 Taligent, Inc. All rights reserved. // All rights reserved. //======================================================================== #ifndef Taligent_GRAFEDIT #include "GrafEdit.h" #endif #ifndef Taligent_GRAFEDITUTILITIES #include "GrafEditUtilities.h" #endif #ifndef Taligent_CANVASGRAPHICMANIPULATION #include "CanvasGraphicManipulation.h" #endif #ifndef Taligent_CANVASCONVENIENCEFILTERS #include "CanvasConvenienceFilters.h" #endif #ifndef Taligent_GRAFEDITTRACE #include "GrafEditTrace.h" #endif // ******************************************************************************** // class TCanvasGraphicFilter // // description Wraps a canvas graphic read iterator and can reverse direction // of iteration and filter out undesired graphics. Passed into // TCanvas::EnumnerateGraphics. // // use A client of TCanvas::EnunerateGraphics will create a filter // to describe the desired direction of enumeration and to filter // undesired graphics. For example, in drawing the client may // create and pass a filter for enumeration from back to front // of only those graphics in a given invalidation rect. // // subclassing Subclass to create concrete filters to process canvas // graphics. Typically, you will subclass from either // TCanvasFrontToBackFilter or TCanvasBackToFrontFilter. // // related classes See also TCanvas::EnumerateGraphics and TCanvasGraphicFunnel. // // ******************************************************************************** TCanvasGraphicFilter::TCanvasGraphicFilter () : fIterator (NIL) { PVMARK("TCanvasGraphicFilter::TCanvasGraphicFilter"); #ifdef DEBUG ::qprintf ("TCanvasGraphicFilter::TCanvasGraphicFilter\n"); #endif } TCanvasGraphicFilter::~TCanvasGraphicFilter () { PVMARK("TCanvasGraphicFilter::~TCanvasGraphicFilter"); #ifdef DEBUG ::qprintf ("TCanvasGraphicFilter::~TCanvasGraphicFilter\n"); #endif } void TCanvasGraphicFilter::SetIterator (TCanvasGraphicReadIterator* theIterator) { PVMARK("TCanvasGraphicFilter::SetIterator"); #ifdef DEBUG ::qprintf ("TCanvasGraphicFilter::SetIterator\n"); #endif fIterator = theIterator; } TCanvasGraphicReadIterator* TCanvasGraphicFilter::GetIterator () { PVMARK("TCanvasGraphicFilter::GetIterator"); #ifdef DEBUG ::qprintf ("TCanvasGraphicFilter::GetIterator\n"); #endif return fIterator; } // ******************************************************************************** // class TCanvasSelectionFilter // // description TCanvasGraphicFilter subclass that is used by filters wishing // to deal with selections. For instance, the TCanvasTopSelectionDrawingFilter // and the TCanvasTopSelectionHitDetectionFilter subclass from this // class. The main functionality provided by this level of abstraction // are the two virtual CreateFeedbacker methods. // // ******************************************************************************** TCanvasSelectionFilter::TCanvasSelectionFilter (TSRTFeedbacker* feedbacker) : TCanvasGraphicFilter(), fCanvasFeedbacker(feedbacker) { PVMARK("TCanvasSelectionFilter::TCanvasSelectionFilter"); #ifdef DEBUG ::qprintf ("TCanvasSelectionFilter::TCanvasSelectionFilter\n"); #endif if (!fCanvasFeedbacker) fCanvasFeedbacker = new TSRTBoxFeedbacker(); // note that this feedbacker is not valid until TSRTFeedbacker::SetGraphic is called on it } TCanvasSelectionFilter::~TCanvasSelectionFilter () { PVMARK("TCanvasSelectionFilter::~TCanvasSelectionFilter"); #ifdef DEBUG ::qprintf ("TCanvasSelectionFilter::~TCanvasSelectionFilter\n"); #endif if (fCanvasFeedbacker) delete fCanvasFeedbacker; } void TCanvasSelectionFilter::SetCanvasFeedbacker (const TSRTFeedbacker& feedbacker) { PVMARK("TCanvasSelectionFilter::SetCanvasFeedbacker"); #ifdef DEBUG ::qprintf ("TCanvasSelectionFilter::SetCanvasFeedbacker\n"); #endif if (fCanvasFeedbacker) delete fCanvasFeedbacker; fCanvasFeedbacker = ::Copy(feedbacker); } MCanvasGraphic* TCanvasSelectionFilter::GetCanvasFeedbacker (const MCanvasGraphic& usedForSizeOfFeedbacker) { PVMARK("TCanvasSelectionFilter::GetCanvasFeedbacker"); #ifdef DEBUG ::qprintf ("TCanvasSelectionFilter::GetCanvasFeedbacker\n"); #endif // This provides a main "standard" feedbacker that most of your graphics can utilize. This // feedbacker is provided by your particular filter subclasses or someone else who has called // SetCanvasFeedbacker (or set the feedbacker via the proper constructor). If there is no feedbacker // the first time this is used, it defaults to using a TSRTBoxFeedbacker, which is only created the one time. if (fCanvasFeedbacker) fCanvasFeedbacker->SetGraphic(&usedForSizeOfFeedbacker); else fCanvasFeedbacker = new TSRTBoxFeedbacker(usedForSizeOfFeedbacker); return fCanvasFeedbacker; } MCanvasGraphic* TCanvasSelectionFilter::GetGraphicFeedbacker (const MCanvasGraphic& aGraphic) { PVMARK("TCanvasSelectionFilter::GetGraphicFeedbacker"); #ifdef DEBUG ::qprintf ("TCanvasSelectionFilter::GetGraphicFeedbacker\n"); #endif return aGraphic.GetFeedbacker(); } // ******************************************************************************** // class TCanvasBackToFrontFilter // // description A canvas graphic filter for enumeration from back to front. // Will be used and/or subclassed for enumeration in painting. // // ******************************************************************************** TCanvasBackToFrontFilter::TCanvasBackToFrontFilter () { PVMARK("TCanvasBackToFrontFilter::TCanvasBackToFrontFilter"); #ifdef DEBUG ::qprintf ("TCanvasBackToFrontFilter::TCanvasBackToFrontFilter\n"); #endif } TCanvasBackToFrontFilter::~TCanvasBackToFrontFilter () { PVMARK("TCanvasBackToFrontFilter::~TCanvasBackToFrontFilter"); #ifdef DEBUG ::qprintf ("TCanvasBackToFrontFilter::~TCanvasBackToFrontFilter\n"); #endif } const MCanvasGraphic* TCanvasBackToFrontFilter::First () { PVMARK("TCanvasBackToFrontFilter::First"); #ifdef DEBUG ::qprintf ("TCanvasBackToFrontFilter::First\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); return i ? i->Last() : NIL; } const MCanvasGraphic* TCanvasBackToFrontFilter::Next () { PVMARK("TCanvasBackToFrontFilter::Next"); #ifdef DEBUG ::qprintf ("TCanvasBackToFrontFilter::Next\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); return i ? i->Previous() : NIL; } // ******************************************************************************** // class TCanvasFrontToBackFilter // // description A canvas graphic filter for enumeration from front to back. // Will be used and/or subclassed for enumeration in hit detection. // // ******************************************************************************** TCanvasFrontToBackFilter::TCanvasFrontToBackFilter () { PVMARK("TCanvasFrontToBackFilter::TCanvasFrontToBackFilter"); #ifdef DEBUG ::qprintf ("TCanvasFrontToBackFilter::TCanvasFrontToBackFilter\n"); #endif } TCanvasFrontToBackFilter::~TCanvasFrontToBackFilter () { PVMARK("TCanvasFrontToBackFilter::~TCanvasFrontToBackFilter"); #ifdef DEBUG ::qprintf ("TCanvasFrontToBackFilter::~TCanvasFrontToBackFilter\n"); #endif } const MCanvasGraphic* TCanvasFrontToBackFilter::First () { PVMARK("TCanvasFrontToBackFilter::First"); #ifdef DEBUG ::qprintf ("TCanvasFrontToBackFilter::First\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); return i ? i->First() : NIL; } const MCanvasGraphic* TCanvasFrontToBackFilter::Next () { PVMARK("TCanvasFrontToBackFilter::Next"); #ifdef DEBUG ::qprintf ("TCanvasFrontToBackFilter::Next\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); return i ? i->Next() : NIL; } // ******************************************************************************** // class TCanvasTopSelectionDrawingFilter // // description This is the flavor of how it will work, but filters are // still being implemented to support chaining. // // ******************************************************************************** TCanvasTopSelectionDrawingFilter::TCanvasTopSelectionDrawingFilter (const MCanvasSelection* selection) : TCanvasSelectionFilter(), fSelection (selection), fSelectionPass (false), fCurrentFeedbacker (NIL) { PVMARK("TCanvasTopSelectionDrawingFilter::TCanvasTopSelectionDrawingFilter"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionDrawingFilter::TCanvasTopSelectionDrawingFilter\n"); #endif } TCanvasTopSelectionDrawingFilter::~TCanvasTopSelectionDrawingFilter () { PVMARK("TCanvasTopSelectionDrawingFilter::~TCanvasTopSelectionDrawingFilter"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionDrawingFilter::~TCanvasTopSelectionDrawingFilter\n"); #endif } const MCanvasGraphic* TCanvasTopSelectionDrawingFilter::First () { PVMARK("TCanvasTopSelectionDrawingFilter::First"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionDrawingFilter::First\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); const MCanvasGraphic* first = NIL; if ( i ) first = i->Last (); return first; } const MCanvasGraphic* TCanvasTopSelectionDrawingFilter::Next () { PVMARK("TCanvasTopSelectionDrawingFilter::Next"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionDrawingFilter::Next\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); const MCanvasGraphic* next = NIL; if ( i ) { next = i->Previous (); if ( next == NIL && !fSelectionPass && fSelection != NIL) { fSelectionPass = true; next = i->Last (); } if ( fSelectionPass ) { while (next != NIL && !fSelection->IsGraphicSelected(*next)) next = i->Previous (); if ( next != NIL ) { fCurrentFeedbacker = GetGraphicFeedbacker (*next); if (!fCurrentFeedbacker) fCurrentFeedbacker = GetCanvasFeedbacker (*next); next = fCurrentFeedbacker; } } } return next; } // ******************************************************************************** // class TCanvasTopSelectionHitDetectionFilter // // description This is the flavor of how it will work, but filters are // still being implemented to support chaining. // // ******************************************************************************** TCanvasTopSelectionHitDetectionFilter::TCanvasTopSelectionHitDetectionFilter (const MCanvasSelection* selection) : TCanvasSelectionFilter(), fSelection (selection), fSelectionPass (false), fCurrentFeedbacker (NIL) { PVMARK("TCanvasTopSelectionHitDetectionFilter::TCanvasTopSelectionHitDetectionFilter"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionHitDetectionFilter::TCanvasTopSelectionHitDetectionFilter\n"); #endif } TCanvasTopSelectionHitDetectionFilter::~TCanvasTopSelectionHitDetectionFilter () { PVMARK("TCanvasTopSelectionHitDetectionFilter::~TCanvasTopSelectionHitDetectionFilter"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionHitDetectionFilter::~TCanvasTopSelectionHitDetectionFilter\n"); #endif } const MCanvasGraphic* TCanvasTopSelectionHitDetectionFilter::First () { PVMARK("TCanvasTopSelectionHitDetectionFilter::First"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionHitDetectionFilter::First\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); const MCanvasGraphic* first = NIL; if ( i ) { first = i->First (); if ( first != NIL && fSelection != NIL ) { fSelectionPass = true; if ( fSelection->IsGraphicSelected(*first) ) { fCurrentFeedbacker = GetGraphicFeedbacker (*first); if (!fCurrentFeedbacker) fCurrentFeedbacker = GetCanvasFeedbacker (*first); first = fCurrentFeedbacker; } else first = Next (); } } return first; } const MCanvasGraphic* TCanvasTopSelectionHitDetectionFilter::Next () { PVMARK("TCanvasTopSelectionHitDetectionFilter::Next"); #ifdef DEBUG ::qprintf ("TCanvasTopSelectionHitDetectionFilter::Next\n"); #endif TCanvasGraphicReadIterator *i = GetIterator (); const MCanvasGraphic* next = NIL; if ( i ) { next = i->Next (); if ( fSelectionPass ) { while (next != NIL && !fSelection->IsGraphicSelected(*next)) next = i->Next (); if ( next != NIL ) { fCurrentFeedbacker = GetGraphicFeedbacker (*next); if (!fCurrentFeedbacker) fCurrentFeedbacker = GetCanvasFeedbacker (*next); next = fCurrentFeedbacker; } else { fSelectionPass = false; next = i->First (); } } } return next; }