package org.geogebra.desktop.cas.view;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.geogebra.common.kernel.geos.GeoCasCell;
import org.geogebra.common.util.debug.Log;
import org.geogebra.desktop.main.AppD;
/**
* Handles mouse and key events in row headers of the CAS table
*
*/
public class RowHeaderListener extends MouseAdapter
implements KeyListener, ListSelectionListener, MouseMotionListener {
private final CASTableD table;
private final JList rowHeader;
private int mousePressedRow;
private boolean rightClick;
private AppD app;
/**
* @param table
* CAS table
* @param rowHeader
* row headers
*/
public RowHeaderListener(CASTableD table, JList rowHeader, AppD app) {
this.table = table;
this.rowHeader = rowHeader;
this.app = app;
}
@Override
public void mousePressed(MouseEvent e) {
rightClick = AppD.isRightClick(e);
table.stopEditing();
mousePressedRow = rowHeader.locationToIndex(e.getPoint());
table.setClickedRow(mousePressedRow);
rowHeader.requestFocus();
}
@Override
public void mouseDragged(MouseEvent e) {
e.consume();
// update selection
int mouseDraggedRow = rowHeader.locationToIndex(e.getPoint());
// make sure mouse pressed is initialized, this may not be the case
// after closing the popup menu
if (mousePressedRow < 0) {
table.stopEditing();
mousePressedRow = mouseDraggedRow;
}
if (AppD.isControlDown(e)) {
rowHeader.addSelectionInterval(mousePressedRow, mouseDraggedRow);
} else {
rowHeader.setSelectionInterval(mousePressedRow, mouseDraggedRow);
}
}
@Override
public void mouseReleased(MouseEvent e) {
e.consume();
// handle marble click
int releasedRow = table.rowAtPoint(e.getPoint());
try {
RowHeaderRenderer rhr = (RowHeaderRenderer) rowHeader
.getCellRenderer().getListCellRendererComponent(rowHeader,
(releasedRow + 1) + "", releasedRow, false, false);
boolean marbleVisible = rhr.getComponent(1).isVisible();
if (releasedRow == mousePressedRow && marbleVisible
&& !rightClick) {
int totalHeight = 0;
for (int i = 0; i < releasedRow; i++) {
totalHeight += table.getRowHeight(i);
}
// not using the renderer to get the marble top because
// sometimes it gives wrong? values
// see Ticket #3439, comments 8, 12
int marbleTop = table.getRowHeight(releasedRow) / 2 + 4;
if (e.getY() > marbleTop + totalHeight - 4
&& e.getY() < marbleTop + totalHeight
+ app.getScaledIconSize()) {
GeoCasCell clickedCell = table
.getGeoCasCell(table.rowAtPoint(e.getPoint()));
if (table.isEditing()) {
table.stopEditing();
}
clickedCell.toggleTwinGeoEuclidianVisible();
}
}
} catch (IndexOutOfBoundsException ex) {
// this can come, if one clicked on an empty header
Log.warn("No cas cell " + releasedRow);
}
mousePressedRow = -1;
// handle right click
if (rightClick) {
if (!rowHeader.isSelectedIndex(releasedRow)) {
rowHeader.setSelectedIndex(releasedRow);
}
if (rowHeader.getSelectedIndices().length > 0) {
RowHeaderPopupMenuD popupMenu = new RowHeaderPopupMenuD(
rowHeader, table);
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
}
@Override
public void mouseClicked(MouseEvent e) {
// not needed, we handle mouse events in mouseReleased
}
@Override
public void mouseMoved(MouseEvent e) {
e.consume();
}
@Override
public void keyPressed(KeyEvent e) {
boolean undoNeeded = false;
switch (e.getKeyCode()) {
default:
// do nothing
break;
case KeyEvent.VK_DELETE:
case KeyEvent.VK_BACK_SPACE:
int[] selRows = rowHeader.getSelectedIndices();
undoNeeded = table.getCASView().deleteCasCells(selRows);
if (selRows != null && selRows.length > 0) {
int row = selRows[0];
rowHeader.setSelectedIndex(row);
}
break;
}
if (undoNeeded) {
// store undo info
table.getApplication().storeUndoInfo();
}
}
@Override
public void keyReleased(KeyEvent e) {
// not needed, we handle key events in keyPressed
}
@Override
public void keyTyped(KeyEvent e) {
// not needed, we handle key events in keyPressed
}
@Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
int minIndex = lsm.getMinSelectionIndex();
int maxIndex = lsm.getMaxSelectionIndex();
if (minIndex == maxIndex) {
table.startEditingRow(minIndex);
}
}
}