Outlining, Dragging, and Pasting a Region (Visual J++)

Take the following steps to add code that lets you outline an area with a mouse, drag a copy of the selected area, and paste the copy into another part of the bitmap:

1. Start with the project that you created in Loading and Displaying an Image.

2. Add a second LEAD control, name it Lead2, and set its Visible property to False.

  1. 3.  Add the following private variables to your main form. In online help, you can use the Edit pull-down menu to copy the block of code.

private boolean m_bReadyToDrag = false;  // The state after marking the region but before dragging
private boolean m_bDragging = false;  // The state when the mouse is used for dragging the floater
private int m_nStartX = 0;  // Starting X position in screen twips
private int m_nStartY = 0;  // Starting Y position in screen twips
private int m_nFloaterX = 0;  // Floater X position in screen twips
private int m_nFloaterY = 0;  // Floater Y position in screen twips
private float m_fZoomFactorX = 0f;  // Used for translating positioning information
private float m_fZoomFactorY = 0f;  // Used for translating positioning information

4. image\btncmd.gif At the top of your main form, add two buttons and name them as follows:

Name

Text

SelRgnBtn

Select Region

PasteFloaterBtn

Paste Floater

5. Add the following code to the SelRgnBtn control's Click event. In online help, you can use the Edit pull-down menu to copy the block of code.

private void SelRgnBtn_click(Object source, Event e)
{
   LEAD1.setRgnMarkingMode( (short) LTOCXU.RgnMarkingModeConstants.RGNMARK_FREEHAND );
   MessageBox.show( "Draw a freehand region" );
}

6. Add the following code to the PasteFloaterBtn control's Click event:

private void PasteFloaterBtn_click(Object source, Event e)
{
   // Do nothing if there is no floater.
   if( LEAD1.getFloater() == 0 ) 
      return;

   // Get the floater into another bitmap
   LEAD2.setBitmap( LEAD1.getFloater() );

   // Get the floater's client coordinates into local variables.
   int nLCRgnX = (int) LEAD1.getFloaterDstLeft();
   int nLCRgnY = (int) LEAD1.getFloaterDstTop();
   int nLCRgnWidth = (int) LEAD1.getFloaterDstWidth();
   int nLCRgnHeight = (int) LEAD1.getFloaterDstHeight();

   // Delete the floater.
   LEAD1.setFloaterVisible( false );
   LEAD1.setFloater( 0 );

   // Translate the client coordinates to bitmap coordinates.
   int nLBRgnX = (int) ( ( ( nLCRgnX - LEAD1.getDstLeft() ) / m_fZoomFactorX ) + LEAD1.getSrcLeft() );
   int nLBRgnY = (int) ( ( ( nLCRgnY - LEAD1.getDstTop() ) / m_fZoomFactorY ) + LEAD1.getSrcTop() );
   int nLBRgnWidth = (int) ( nLCRgnWidth / m_fZoomFactorX );
   int nLBRgnHeight = (int) ( nLCRgnHeight / m_fZoomFactorY );

 

   // Reposition the region to use as a mask for the Combine method.
   LEAD1.OffsetRgn( nLBRgnX - LEAD1.getRgnLeft(), nLBRgnY - LEAD1.getRgnTop() );

   // Use the Combine method to paste the LEAD2 bitmap into the LEAD1 bitmap.
   int nMyOp = LTOCXU.CombineConstants.CB_OP_ADD | LTOCXU.CombineConstants.CB_DST_0;  // Operation flags for a simple paste.
   LEAD1.Combine( nLBRgnX, nLBRgnY, nLBRgnWidth, nLBRgnHeight, 
   LEAD2.getBitmap(), 0, 0, nMyOp );

   // Repaint the part of the client area that has changed.
   LEAD1.RepaintRect( nLCRgnX, nLCRgnY, nLCRgnWidth, nLCRgnHeight, false );

   // Free the region.
   LEAD1.FreeRgn();
}

7. In the LEAD1 control's MouseDown event, add the following code:

private void LEAD1_mouseDown(Object source, MouseEvent e)
{
   // Do nothing if we are drawing a region.
   if( LEAD1.getRgnMarkingMode() != LTOCXU.RgnMarkingModeConstants.RGNMARK_NONE ) 
      return;

   // Save the starting position, in case we need it.
   m_nStartY = e.y;
   m_nStartX = e.x;

   // If we are ready to drag the selection, get a floater.
   if( m_bReadyToDrag )
   {
      // Translate the current mouse coordinates.
      // These coordinates account for the zoom factor and offset.
      m_fZoomFactorX = LEAD1.getDstWidth() / LEAD1.getSrcWidth();
      m_fZoomFactorY = LEAD1.getDstHeight() / LEAD1.getSrcHeight();
      int nBitmapX = (int) ( ( e.x / m_fZoomFactorX ) - ( LEAD1.getDstLeft() / m_fZoomFactorX ) + LEAD1.getSrcLeft() );
      int nBitmapY = (int) ( ( e.y / m_fZoomFactorY ) - ( LEAD1.getDstTop() / m_fZoomFactorY ) +  LEAD1.getSrcTop() );

      // Continue to create the floater if the mouse is pointing to the region we marked.
      if( LEAD1.IsPtInRgn( nBitmapX, nBitmapY ) )
      {
         // Hide the region frame.
         LEAD1.setRgnFrameType( (short) LTOCXU.RgnFrameTypeConstants.RGNFRAME_NONE );

         // Create the floater bitmap, which will be the part of the main bitmap that is
         // in the region's bounding rectangle.
         LEAD1.setFloater( LEAD1.getBitmap() );

         // Translate the bitmap region coordinates to client area coordinates.
         int nNewY = (int) ( ( ( LEAD1.getRgnTop() - LEAD1.getSrcTop() ) * m_fZoomFactorY ) + LEAD1.getDstTop() );
         int nNewX = (int) ( ( ( LEAD1.getRgnLeft() - LEAD1.getSrcLeft() ) * m_fZoomFactorX ) + LEAD1.getDstLeft() );
         int nNewWidth = (int) ( LEAD1.getRgnWidth() * m_fZoomFactorX );
         int nNewHeight = (int) ( LEAD1.getRgnHeight() * m_fZoomFactorY );

         // Set the initial display position of the floater.
         LEAD1.SetFloaterDstRect( nNewX, nNewY, nNewWidth, nNewHeight );
         // Set form-level variables.
         m_nFloaterY = (int) LEAD1.getFloaterDstTop();
         m_nFloaterX = (int) LEAD1.getFloaterDstLeft();
         LEAD1.setFloaterVisible( true );
         m_bDragging = true;
         m_bReadyToDrag = false;
      }
   }
}

8. In the LEAD1 control's MouseMove event, add the following code.

private void LEAD1_mouseMove(Object source, MouseEvent e)
{
   // Do nothing if we are drawing a region.
   if( LEAD1.getRgnMarkingMode() != LTOCXU.RgnMarkingModeConstants.RGNMARK_NONE )
      return;

   // Reposition the floater if we are dragging it.
   if( m_bDragging && LEAD1.getFloater() != 0 )
      if( LEAD1.IsPtInFloater( e.x, e.y ) )
      {
         // Update the position variables.
         int nXDelta = e.x - m_nStartX;
         int nYDelta = e.y - m_nStartY;
         int nNewX = m_nFloaterX + nXDelta;
         int nNewY = m_nFloaterY + nYDelta;
         int nNewWidth = (int) LEAD1.getFloaterDstWidth();
         int nNewHeight = (int) LEAD1.getFloaterDstHeight();

         // Reposition the floater.
         LEAD1.SetFloaterDstRect( nNewX, nNewY, nNewWidth, nNewHeight );

         // Save the form-level position variables.
         m_nFloaterY = nNewY;
         m_nFloaterX = nNewX;
         m_nStartY = e.y;
         m_nStartX = e.x;
      }
}

9. In the LEAD1 control's MouseUp event, add the following code.

private void LEAD1_mouseUp(Object source, MouseEvent e)
{
   // If we were drawing a region, set up for the next operation.
   if( LEAD1.getRgnMarkingMode() != LTOCXU.RgnMarkingModeConstants.RGNMARK_NONE )
   {
      LEAD1.setRgnMarkingMode( (short) LTOCXU.RgnMarkingModeConstants.RGNMARK_NONE );
      LEAD1.setRgnFrameType( (short) LTOCXU.RgnFrameTypeConstants.RGNFRAME_STATIC );
      m_bReadyToDrag = true;
      MessageBox.show( "Now, drag the selection to another place." );
   }
}

10. Run your program to test it.