// **************************************************************************** // // Function Name: RSingleSelection::GetRotateHandle( ) // // Description: Retrieves a vector rect representing the rotation handle. // // Returns: Nothing // // Exceptions: Nothing // // **************************************************************************** // void RSingleSelection::GetRotateHandle( RRealVectorRect& rotateHandleRect ) const { // Get the bounding rect YSelectionBoundingRect boundingRect; GetSelectionBoundingRect( boundingRect ); RRealPoint centerPoint = boundingRect.GetCenterPoint( ); R2dTransform transform( boundingRect.GetTransform( ) ); transform.PostTranslate( centerPoint.m_x-boundingRect.m_TopLeft.m_x, centerPoint.m_y-boundingRect.m_TopLeft.m_y ); // Break the transform into its components YAngle angle; YRealDimension xScale; YRealDimension yScale; transform.Decompose( angle, xScale, yScale ); // Figure out where to end the line RRealPoint lineEndPoint = GetRotateHandleCenterPoint( ); YRealDimension distance = centerPoint.Distance( lineEndPoint ); if ( xScale < 0 ) xScale = -xScale; rotateHandleRect.Set( RRealSize(distance/xScale,1), transform ); // Convert to device units RRealSize handleSize( kRotateHandleHitSize/2, kRotateHandleHitSize/2 ); ::DeviceUnitsToLogicalUnits( handleSize, *m_pView ); rotateHandleRect.Inflate( handleSize ); }
// **************************************************************************** // // Function Name: RSingleSelection::DrawRotateHandle( ) // // Description: Draws the rotation line and handle // // Returns: Nothing // // Exceptions: Memory // // **************************************************************************** // void RSingleSelection::DrawRotateHandle( RDrawingSurface& drawingSurface, const R2dTransform& transform, const RIntRect& ) const { // Get the bounding rect YSelectionBoundingRect boundingRect; GetSelectionBoundingRect( boundingRect ); // Get the center point; this will be one end point of the rotate handle line RRealPoint centerPoint = boundingRect.GetCenterPoint( ); // Get the other end point RRealPoint lineEndPoint = GetRotateHandleCenterPoint( ); // Draw the line drawingSurface.MoveTo( centerPoint, transform ); drawingSurface.LineTo( lineEndPoint, transform ); // Now draw the rotate handle // Convert to device units ::LogicalUnitsToDeviceUnits( lineEndPoint, *m_pView ); // Now build the rotate handle, using this point as the middle of the left side RRealRect rotateHandleRect; rotateHandleRect.m_Left = lineEndPoint.m_x - ( kRotateHandleRenderSize / 2 ); rotateHandleRect.m_Top = lineEndPoint.m_y - ( kRotateHandleRenderSize / 2 ); rotateHandleRect.m_Right = lineEndPoint.m_x + ( kRotateHandleRenderSize / 2 ) + 1; rotateHandleRect.m_Bottom = lineEndPoint.m_y + ( kRotateHandleRenderSize / 2 ) + 1; ::DeviceUnitsToLogicalUnits( rotateHandleRect, *m_pView ); // Now draw the rotate handle rotateHandleRect *= transform; drawingSurface.FillRectangle( rotateHandleRect ); }
// **************************************************************************** // // Function Name: RRotateSelectionTracker::BeginTracking( ) // // Description: Called when tracking begins; ie. when the mouse button goes // down. // // Returns: Nothing // // Exceptions: None // // **************************************************************************** // void RRotateSelectionTracker::BeginTracking( const RRealPoint& mousePoint, YModifierKey modifierKeys ) { // Remove the selection m_pSelection->Remove( FALSE ); // Get the controlling object RSingleSelection* pHitObject = m_pSelection->GetHitSingleSelection( mousePoint ); TpsAssert( pHitObject, "No hit object!" ); // Save the original handle point m_TrackingOriginalHandlePoint = pHitObject->GetRotateHandleCenterPoint( ); // Get its bounding rect YSelectionBoundingRect objectBoundingRect; pHitObject->GetObjectBoundingRect( objectBoundingRect ); // Save away the initial rotation angle of the controlling object. We might // need it to do constraining RRealSize delta = m_TrackingOriginalHandlePoint - objectBoundingRect.GetCenterPoint( ); m_ControllingObjectInitialAngle = ::atan2( -delta.m_dy, delta.m_dx ); // Get the center of the selection and use it as the center of rotation YSelectionBoundingRect boundingRect; m_pSelection->GetSelectionBoundingRect( boundingRect ); m_TrackingRotationCenter = boundingRect.GetCenterPoint( ); // Compute the initial angle delta = m_TrackingOriginalHandlePoint - m_TrackingRotationCenter; m_TrackingInitialRotationAngle = ::atan2( delta.m_dy, delta.m_dx ); // If the appropriate modifiey key is down, constrain the rotation m_fConstrainRotation = static_cast<BOOLEAN>( modifierKeys & kRotateConstrainModifier ); // Call the base class RSelectionTracker::BeginTracking( mousePoint, modifierKeys ); }
// **************************************************************************** // // Function Name: RSingleSelection::GetRotateHandleCenterPoint( ) // // Description: Retrieves the center point of the rotate handle // // Returns: See above // // Exceptions: Nothing // // **************************************************************************** // RRealPoint RSingleSelection::GetRotateHandleCenterPoint( ) const { // Get the bounding rect and center point YSelectionBoundingRect boundingRect; GetSelectionBoundingRect( boundingRect ); RRealPoint centerPoint = boundingRect.GetCenterPoint( ); // We are going to use ratios of similar triangles to calculate the position of the rotate handle YRealDimension deltaX = boundingRect.m_BottomRight.m_x - boundingRect.m_BottomLeft.m_x; YRealDimension deltaY = boundingRect.m_BottomRight.m_y - boundingRect.m_BottomLeft.m_y; YRealDimension deltaXPrime = deltaX * ( 0.5 + kRotateHandleLineLengthRatio ); YRealDimension deltaYPrime = deltaY * ( 0.5 + kRotateHandleLineLengthRatio ); return RRealPoint( centerPoint.m_x + deltaXPrime, centerPoint.m_y + deltaYPrime ); }
// **************************************************************************** // // Function Name: RSingleSelection::GetResizeSelectionHandle( ) // // Description: Retrieves a vector rect representing requested resize handle. // // Returns: Nothing // // Exceptions: Memory // // **************************************************************************** // void RSingleSelection::GetResizeSelectionHandle( RRealRect& rHandle, const R2dTransform& transform, EHitLocation eHit, BOOLEAN fRender ) const { RRealPoint point; YSelectionBoundingRect boundingRect; RIntSize outsetSize = (fRender)? RRealSize( kCornerResizeHandleRenderSize, kCornerResizeHandleRenderSize ) : RRealSize( kResizeHandleHitSize, kResizeHandleHitSize ); // Get the bounding rectangle GetSelectionBoundingRect( boundingRect ); // Get the proper point to transform switch ( eHit ) { case kLeftResizeHandle: ::midpoint( point, boundingRect.m_TopLeft, boundingRect.m_BottomLeft ); outsetSize.m_dx = Max( kEdgeResizeHandleRenderSize, YIntDimension(outsetSize.m_dx/2) ); break; case kTopResizeHandle: ::midpoint( point, boundingRect.m_TopLeft, boundingRect.m_TopRight ); outsetSize.m_dy = Max( kEdgeResizeHandleRenderSize, YIntDimension(outsetSize.m_dy/2) ); break; case kRightResizeHandle: ::midpoint( point, boundingRect.m_TopRight, boundingRect.m_BottomRight ); outsetSize.m_dx = Max( kEdgeResizeHandleRenderSize, YIntDimension(outsetSize.m_dx/2) ); break; case kBottomResizeHandle: ::midpoint( point, boundingRect.m_BottomLeft, boundingRect.m_BottomRight ); outsetSize.m_dy = Max( kEdgeResizeHandleRenderSize, YIntDimension(outsetSize.m_dy/2) ); break; case kTopLeftResizeHandle: point = boundingRect.m_TopLeft; break; case kTopRightResizeHandle: point = boundingRect.m_TopRight; break; case kBottomLeftResizeHandle: point = boundingRect.m_BottomLeft; break; case kBottomRightResizeHandle: point = boundingRect.m_BottomRight; break; default : TpsAssertAlways( "Asking for the selection handle of invalid type" ); point = boundingRect.GetCenterPoint(); } RIntSize halfOutset( outsetSize.m_dx/2, outsetSize.m_dy/2); ::LogicalUnitsToDeviceUnits( point, *m_pView ); rHandle.m_Left = point.m_x - halfOutset.m_dx; rHandle.m_Top = point.m_y - halfOutset.m_dy; rHandle.m_Right = point.m_x + outsetSize.m_dx - halfOutset.m_dx; rHandle.m_Bottom = point.m_y + outsetSize.m_dy - halfOutset.m_dy; ::DeviceUnitsToLogicalUnits( rHandle, *m_pView ); rHandle *= transform; }