Jump to content

MouseManager.java

From EDM2
Revision as of 01:25, 1 January 2018 by Ak120 (talk | contribs)
package macrolanguage;
import java.awt.*;
import java.awt.event.*;
import macrolanguage.FreeFormEdit;
import macrolanguage.NotAContainerException;

/**
 * This class is a part of FreeFormEdit torn out to allow a more dynamic
 * design, rather than concentrating all the events into one class I removed
 * all the mouse events to a separate class.
**/
class MouseManager implements MouseListener, MouseMotionListener
{
  /**
   * The constructor needs a pointer to its FreeFormEdit owner
   * so it will be able to respond to it's events with callback
   * for methods.
  **/
  MouseManager(FreeFormEdit client)
  {
    this.client = client;
  }

  /**
   * Places the component comp on the next click on the free form
   * edit surface.
  **/
  public void placeComponentOnNextClick(Component comp)
  {
    componentToPlace = comp;
  }

  /**
   * This method is a part of the MouseMotionListener interface and is
   * called whenever a mouse is dragged.
   * This method abstracts the dragging and dropping of components
   * on the free form surface.
  **/
  public void mouseDragged(java.awt.event.MouseEvent ev)
  {
    // Get the position of the event.
    Point pos = ev.getPoint();

    // Get the source component of the event.
    Component c = (Component)ev.getSource();

    // Is the event generated by our owning FreeFormEdit instance?
    if(c != client)
    { // If not:
      // If the positions are negative then fix them into
      // positive absolute positions.
      if(pos.x < 0)
      {
        pos.x = c.getLocation().x + pos.x;
        if(pos.y >= 0)
        {
          c.setLocation(pos.x,
                        calculateParentContainerXY(c, client, pos.x, pos.y).y);
        }
        else
        {
          pos.y = c.getLocation().y + pos.y;
          c.setLocation(calculateParentContainerXY(c, client, pos.x, pos.y).x,
                        pos.y);
        }
        return;
      }
      else
        if(pos.y < 0)
        {
          pos.y = c.getLocation().y + pos.y;
          c.setLocation(pos.x,pos.y);
          return;
        }

      // Set the location to pos which is the absolute position
      // for the component.
      c.setLocation(calculateParentContainerXY(c, client, pos.x, pos.y));
    }
  }

  /**
   * Required by the MouseMotionListener interface.
  **/
  public void mouseMoved(java.awt.event.MouseEvent ev)
  {
  }

  /**
   * Required by the MouseListener interface.
   * When a mouse is clicked that could mean 2 things:
   * 1. Selection of a component on the surface.
   * 2. Dropping a new component onto the surface.
  **/
  public void mouseClicked(java.awt.event.MouseEvent ev)
  {
    // If we are in the midst of placeing a new component onto
    // the free edit surface.
    if(componentToPlace != null)
    {
      try
      {
        // Set the mouse cursor to the original cursor.
        client.setCursor(Cursor.getDefaultCursor());

        // Add the new component to the correct location.
        client.add(componentToPlace, ev.getPoint().x, ev.getPoint().y);

        // Set the size of the component to the default size for all the
        // components.
        componentToPlace.setSize(20,20);

        // Set the new component to be the selected component.
        client.setSelection(componentToPlace);

        // Mark the fact that the component was placed.
        componentToPlace = null;
        return;
      }
      catch(NotAContainerException e)
      {
        System.out.println("Not a container. A component can only be placed in a container.");
      }
    }

    // Set the selected component to be the component which
    // generated the mouse click event.
    client.setSelection((Component)ev.getSource());
  }

  /**
   * Required by the MouseListener interface.
  **/
  public void mousePressed(java.awt.event.MouseEvent ev)
  {
  }

  /**
   * Required by the MouseListener interface.
   * The drop operation when dragging is implemented here.
   **/
  public void mouseReleased(java.awt.event.MouseEvent ev)
  {
    Component c = (Component)ev.getSource();
    if(c != client)
      c.setLocation(calculateParentContainerXY(c, client,
                                               ev.getPoint().x,
                                               ev.getPoint().y));
  }

  /**
   * Required by the MouseMotionListener interface.
  **/
  public void mouseEntered(java.awt.event.MouseEvent ev)
  {
  }

  /**
   * Required by the MouseMotionListener interface.
  **/
  public void mouseExited(java.awt.event.MouseEvent ev)
  {
  }

  /**
   * This method receives a component ,a container and an x,y coordinate.
   * When a mouse event is received we get a relative x,y coordinate to the
   * owning component and not the container, if we need an absolute position
   * relative to the owning container we need to use this method.
   **/
  private Point calculateParentContainerXY(Component relativeComponent,
                                           Container owningContainer,
                                           int x, int y)
  {
    // If this is the owner component then return these coordinates.
    if(relativeComponent == owningContainer)
      return(new Point(x, y));
    Component c = relativeComponent.getParent();
    return(calculateParentContainerXY(c, owningContainer,
                                      relativeComponent.getLocation().x + x,
                                      relativeComponent.getLocation().y + y));
  }

  private Component componentToPlace = null; // the new Component we
                                             // will drop on the surface.
  private FreeFormEdit client;               // the owning FreeFormEdit.
}