Package ketUI

Source Code of ketUI.MouseEventHandler

/*
* Copyright (C) 2011  Alasdair C. Hamilton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package ketUI;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

import geom.*;
import ket.display.box.Box;
import ketUI.panel.KetPanel;
import ketUI.responder.Responder;


import ket.*;
import ket.math.*;
import ketUI.modes.*;
import ket.math.EquationList;


public class MouseEventHandler implements MouseListener, MouseMotionListener {

  // TODO: Untested for false values: switch selection back on.
  public static final boolean MOUSE_MOTION = true;

  // External connections.
  final Document document;

  // Internal state.
  Position initialPosition; // click for click-drag-release
  Position currentPosition; // movement location.

  final MouseLoop mouseLoop;

  /**
   * In some contexts, a click on the window by the user only seeks to
   * clear a button menu and so should otherwise be ignored.
   */
  boolean hold;


  public MouseEventHandler(Document document) {
    this.document = document;
    mouseLoop = new MouseLoop(document);
    initialPosition = null;
    currentPosition = null;
    hold = false;
  }

  @Override
  public void mouseClicked(MouseEvent e) {
    mouseLoop.clear(); //?
  }

  @Override
  public void mouseEntered(MouseEvent e) {
    // This is the only time an event is thrown that provides
    // access to the destination component and mouse position.
    // Record it for later.
    setDestination(e.getComponent(), new Position(e.getX(), e.getY()));
  }

  @Override
  public void mouseExited(MouseEvent e) {
    // Do nothing
  }

  @Override
  public void mousePressed(MouseEvent e) {
    // TODO: Move this somewhere more specific, e.g. add another callback to responder.respondToClick().
    //-? boolean left = MouseButton.getMouseButton(e)==MouseButton.LEFT;
    boolean normalMode = document.getModes().getDocumentState()==DocumentState.NORMAL;
    if (/*-? left && */ normalMode) {
      Position p = new Position(e.getX(), e.getY());
      Argument a = getKetPanel().findDeepestArgument(p);
      if (a!=null) {
        document.getCursor().setCurrent(a);
      }
    }
    // Ingore previous destinations to which equations have
    // been dragged.
    setDestination(null, null);

    // Start a new selection loop.
    mouseLoop.clear();

    // TODO: Coordinate selection with chord events.
    setInitialPosition(e.getX(), e.getY());
    // Select the current equation location.

    getKetPanel().updateDragIcon(initialPosition);
    getKetPanel().updateAndRepaint();
  }

  private MathCollection getMathCollection() {
    return document.getMathCollection();
  }

  private KetPanel getKetPanel() {
    return document.getKetPanel();
  }

  /**
   * If the mouse has been draggend (from this docuemnt) to another
   * window, copy the selection and add it as a new equation in the
   * (other) desination document.
   */
  private boolean dragToAnotherDocument(Component component, MouseButton mouseButton, Position p) { // Drag to another document.
    KetPanel toPanel = getLastDestination();
    if (toPanel==null || toPanel==component) {
      // Edit within the current ket panel...
      // Clear (not needed, but just being careful).
      setDestination(null, null); // i.e. clear
      return false;
    } else  if (mouseButton!=MouseButton.LEFT) {
      // TODO: Extend.
      return true; // Done [nothing].
    }
    Document toDocument = toPanel.getDocument();
    Selection toSelection = toDocument.getSelection();
    // Copy argument or equation accross (non-destructively).
    Position to = getLastPosition();
    Equation toEquation = toPanel.pointToEquation(to);
    if (toEquation!=null) {
      toSelection.setCurrent(toEquation.getRoot());
    }
    // Clone and add as a new equation below the selection.
    Equation equationCopy = getSelection().getCurrent().getEquation().cloneEquation(); // Include the entire equation: root and label etc.?
    toSelection.appendEquation(equationCopy);
    setDestination(null, null); // i.e. clear

    getKetPanel().updateAndRepaint();
    toPanel.updateAndRepaint();
    getMathCollection().updateUndoStack();
    toDocument.getMathCollection().updateUndoStack();
    return true;
  }

  public void setHold(boolean hold) {
    Ket.out.println("Hold: " + hold);
    this.hold = hold;
  }

  public boolean getHold() {
    return hold;
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    if (hold) {
      // Limited to a single click.
      hold = false;
      return;
    }
    getKetPanel().requestFocusInWindow();
    //- getKetPanel().setDragLocation(null); // Clear the potential drag image.
    getKetPanel().clearDragIcon();
    Position p = new Position(e.getX(), e.getY());
    boolean done = dragToAnotherDocument(e.getComponent(), MouseButton.getMouseButton(e), p);
    if (done) return;
    // TODO: The current approach to click and drag does not work:- fix it.
    // Note: Don't confuse this with other, working click-and-drag stuff.
    //- Box.displayBorders = false;
    boolean userClicked = p.equals(initialPosition);
    MouseButton mouseButton = MouseButton.getMouseButton(e);
    Responder responder = getModes().getResponder();
    if (userClicked) {
      boolean singleClick = e.getClickCount()==1;
      responder.respondToMouseClick(mouseButton, singleClick, p);
    } else {
      responder.respondToMouseDrag(mouseButton, initialPosition, p);
    }
    getKetPanel().updateForAnimatedDisplay();         // <---------------- animate.
    getKetPanel().updateAndRepaint();
    getMathCollection().updateUndoStack();
  }

  public Position getInitialPosition() {
    return initialPosition;
  }

  public Position getCurrentPosition() {
    return currentPosition;
  }

  /**
   * Record the initial mouse-click position.
   */
  private void setInitialPosition(double initialX, double initialY) {
    this.initialPosition = new Position(initialX, initialY);
  }

  /**
   * Record the initial mouse-click position.
   */
  private void setCurrentPosition(double initialX, double initialY) {
    this.currentPosition = new Position(initialX, initialY);
  }

  private Modes getModes() {
    return document.getModes();
  }

  /**
   * Return the current selection model which is stored within
   * mathCollection.
   */
  private Selection getSelection() {
    return getMathCollection().getSelection();
  }
 

  ///////////////////////////////////
  // MOUSE MOTION LISTENER METHODS //
  ///////////////////////////////////

  /**
   * Invoked when a mouse button is pressed on a component and then dragged.
   */
  @Override
  public void mouseDragged(MouseEvent e) {
    mouseLoop.clear();
    //- document.getKetPanel().repaint();
    //- Modes mode = document.getModes();
    boolean left = SwingUtilities.isLeftMouseButton(e); // HACK: e.getButton() is 0 rather than BUTTON1 | BUTTON2.
    if (left) {
      KetPanel ketPanel = document.getKetPanel();
      Position p = new Position(e.getX(), e.getY());
      ketPanel.setDragLocation(p);
    }
  }

  /**
   * Invoked when the mouse cursor has been moved onto a component but no
   * buttons have been pushed.
   */
  @Override
  public void mouseMoved(MouseEvent e) {
    KetPanel ketPanel = document.getKetPanel();
    Modes mode = document.getModes();
    Responder responder = mode.getResponder();
    setCurrentPosition(e.getX(), e.getY());

    // Border what the mouse is currently over.
    boolean normalMode = document.getModes().getDocumentState()==DocumentState.NORMAL;
    if (normalMode) {
      Position p = new Position(e.getX(), e.getY());
      Box deepest = ketPanel.findDeepestBox(p);
      ketPanel.markBorder(deepest);
      ketPanel.repaint();
    } else {
      if (responder==mode.getMouseResponder()) {
        mouseLoop.clear();
      } else if (mode.getDocumentState().isTracked() || responder==mode.getNormalResponder()) {
        mouseLoop.append(e.getX(), e.getY());
      }
    }
    if (ketPanel.isPerspectiveDisplayMode()) { // Move this somewhere more appropriate?
      ketPanel.repaint();
    }
  }

  public MouseLoop getMouseLoop() {
    return mouseLoop;
  }

  public Position getLastPosition() {
    DocumentManager dm = getDocumentManager();
    if (dm==null) return null;
    return dm.getLastPosition();
  }

  public KetPanel getLastDestination() {
    DocumentManager dm = getDocumentManager();
    if (dm==null) return null;
    return dm.getLastDestination();
  }

  public void setDestination(Component destination, Position p) {
    DocumentManager dm = getDocumentManager();
    if (dm==null) return;
    dm.setDestination(destination, p);
  }

  private DocumentManager getDocumentManager() {
    return document.getDocumentManager();
  }


}
TOP

Related Classes of ketUI.MouseEventHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.