A common example involves rotating and scaling a graphic. When the end user rotates a graphic, a selection graphic of some kind rotates with the graphic. If the end user selects another graphic and then returns to select the original graphic, the selection graphic is oriented as it was when the graphic was last selected. That is, each graphic maintains its own axis of orientation. Scaling transformations generally work with respect to this axis of orientation.
When graphics maintain their own axis or orientation, rotate, scale, and translate operations must not change the points of the graphic. To keep from changing the points, the following must be implemented in your code:
Concrete canvas graphics implement the virtual functions shown in Figure 29.
You implement the concrete canvas graphics functions in any MCanvasGraphic concrete classes. The code to do this is straightforward.
HandleDraw
The HandleDraw function draws the untransformed geometry into the provided drawing port. The attribute bundle and transformation matrix have already been applied to the drawing port that is passed into HandleDraw. The MGraphic::Draw function is implemented in terms of HandleDraw.
virtual void HandleDraw( TGrafPort& ) const = 0;
virtual TGRect HandleGetBounds() const = 0;
Boolean
TMyCanvasGraphic::HandleHit( const TGPoint& p ) const
{
if( fMyGeometry ) { TGRect rect ( p, p ); rect.Inset( TGPoint( -2., -2. ); return fMyGeometry->Intersects( rect ); } else return FALSE; }
virtual TCanvasInteractor* HandleCreateInteractor( MCanvasSelection* adoptTarget, MToolHandler*, const TGPoint& hit ) const;
virtual MCanvasGraphic* HandleCreateFeedbacker();