21 package net.squiz.matrix.inspector;
23 import net.squiz.matrix.core.*;
24 import net.squiz.matrix.matrixtree.*;
25 import net.squiz.matrix.ui.*;
29 import java.io.IOException;
32 import java.awt.dnd.*;
33 import java.awt.datatransfer.*;
34 import java.awt.event.*;
35 import java.awt.image.*;
36 import java.awt.geom.*;
39 import javax.swing.event.*;
40 import javax.swing.table.*;
41 import javax.swing.tree.*;
42 import javax.swing.plaf.*;
51 implements MouseListener,
53 NodeDoubleClickedListener,
55 InitialisationListener,
60 private java.util.List filters =
new Vector();
61 private MatrixTree tree;
62 private InspectorNavigator navigator;
63 private TreePath currentPath;
65 private SelectionTool selTool;
69 private DragSource dragSource = null;
71 private int lastRowOver = -1;
72 private static final int AUTOSCROLL_MARGIN = 12;
74 private static final int CUE_LEFT = 0;
75 private static final int CUE_RIGHT = 1;
77 protected BufferedImage dblBuffer = null;
91 addMouseListener(
this);
97 tree.getModel().addTreeModelListener(getInspectorTreeModelListener());
101 navigator =
new InspectorNavigator(
this);
102 selTool =
new SelectionTool((JTable)
this);
105 menuHandler = getMenuHandler();
107 addMouseListener(selTool);
108 addMouseListener(menuHandler);
109 addMouseMotionListener(selTool);
111 dragSource = DragSource.getDefaultDragSource();
113 DragGestureRecognizer dgr =
114 dragSource.createDefaultDragGestureRecognizer(
116 DnDConstants.ACTION_COPY_OR_MOVE,
120 dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK);
121 DropTarget dropTarget =
new DropTarget(
this, dropHandler);
123 AssetManager.addInitialisationListener(
this);
125 setUI(
new MatrixTableUI());
152 setAutoscrolls(
false);
174 public void autoscroll(Point pt) {
175 int row = rowAtPoint(pt);
176 Rectangle bounds = getBounds();
178 if (pt.y + bounds.y <= AUTOSCROLL_MARGIN) {
182 if (row < getRowCount() - 1) ++row;
184 scrollRectToVisible(getCellRect(row, 0,
true));
187 public Insets getAutoscrollInsets() {
188 Rectangle outer = getBounds();
189 Rectangle inner = getParent().getBounds();
190 return new Insets( inner.y - outer.y + AUTOSCROLL_MARGIN,
191 inner.x - outer.x + AUTOSCROLL_MARGIN,
192 outer.height - inner.height - inner.y + outer.y + AUTOSCROLL_MARGIN,
193 outer.width - inner.width - inner.x + outer.x + AUTOSCROLL_MARGIN);
222 int row = getSelectedRow();
223 int col = getSelectedColumn();
225 if (isCellSelected(row,col)) {
240 int rowIndexStart = getSelectedRow();
241 int rowIndexEnd = getSelectionModel().getMaxSelectionIndex();
242 int colIndexStart = getSelectedColumn();
243 int colIndexEnd = getColumnModel().getSelectionModel().getMaxSelectionIndex();
248 ArrayList nodes =
new ArrayList();
250 for (
int row = 0; row <= getRowCount(); row++) {
251 for (
int col = 0; col <= getColumnCount(); col++) {
252 if (isCellSelected(row, col)) {
269 for (
int i = 0; i < positions.length; i++){
270 if (positions[i].getRow() < topMost.
getRow())
271 topMost = positions[i];
284 for (
int i = 0; i < positions.length; i++){
285 if (positions[i].getRow() > bottomMost.
getRow())
286 bottomMost = positions[i];
299 for (
int i = 0; i < positions.length; i++){
300 if (positions[i].getColumn() < leftMost.
getColumn())
301 leftMost = positions[i];
314 for (
int i = 0; i < positions.length; i++){
315 if (positions[i].getColumn() > rightMost.
getColumn())
316 rightMost = positions[i];
329 TreePath[] paths =
new TreePath[nodes.length];
331 for (
int i = 0; i < nodes.length; i++) {
333 paths[i] = tree.getPathToRoot(node);
338 public TreePath getSelectionPath() {
341 return tree.getPathToRoot(node);
357 int topX = (int) getCellRect(leftMost.
getRow(),leftMost.
getColumn(),
true).getX();
358 int topY = (int) getCellRect(topMost.
getRow(),topMost.
getColumn(),
true).getY();
360 int bottomX = (int) getCellRect(rightMost.
getRow(),rightMost.
getColumn(),
true).getX();
361 bottomX += (int) getCellRect(rightMost.
getRow(),rightMost.
getColumn(),
true).getWidth();
363 int bottomY = (int) getCellRect(bottomMost.
getRow(),bottomMost.
getColumn(),
true).getY();
364 bottomY += (int) getCellRect(bottomMost.
getRow(),bottomMost.
getColumn(),
true).getHeight();
366 return new Rectangle(topX, topY, bottomX - topX, bottomY - topY);
375 for (
int i = getColumnCount() - 1; i >= 0; i--) {
376 if (getValueAt(getRowCount() - 1, i) != null)
389 Enumeration children = parent.children();
390 int childCount = parent.getChildCount();
392 columns = Math.round(getWidth() / 70);
402 int allowedNodes = 0;
404 boolean rowAdded =
false;
406 while (children.hasMoreElements()) {
423 if (!rowAdded && i > 0)
435 if (Math.round(getWidth()) / 70 == columns)
438 columns = Math.round(getWidth()) / 70;
440 DefaultTableModel oldModel = (DefaultTableModel) getModel();
447 for (
int b = 0; b < oldModel.getRowCount(); b++) {
448 for (
int c = 0; c < oldModel.getColumnCount(); c++) {
458 boolean rowAdded =
false;
459 for (
int j = 0; j < nodes.length; j++) {
474 if (!rowAdded && i > 0)
523 if (GUIUtilities.isRightMouseButton(evt))
526 if (evt.getClickCount() != 2)
529 if (getSelectedColumn() == -1)
534 if (node.
getAsset().getNumKids() == 0)
542 if (!node.
getAsset().childrenLoaded()) {
543 MatrixStatusBar.setStatus(
"Loading children...");
544 MatrixSwingWorker worker =
new MatrixSwingWorker() {
545 public Object construct() {
547 AssetManager.refreshAsset(node,
"");
548 }
catch (IOException ioe) {
549 ioe.printStackTrace();
551 MatrixStatusBar.setStatusAndClear(
"Success!", 1000);
552 TreePath path = tree.getPathToRoot(node);
554 navigator.setBackPath(path);
560 TreePath path = tree.getPathToRoot(node);
562 navigator.setBackPath(path);
616 Object[] listeners = listenerList.getListenerList();
621 for (
int i = listeners.length - 2; i >= 0; i -= 2) {
625 evt =
new TransferEvent(
this, dragIndex, dropIndex, node, dropParent);
641 navigator.setBackPath(e.getClickedPath());
642 currentPath = e.getClickedPath();
656 tree.fireCreateLink(NewLinkEvent.LINK_TYPE_MOVE,
new MatrixTreeNode [] { evt.
getNode() }, evt.getDropParent(), evt.getDropIndex());
667 currentPath = tree.getPathToRoot(e.getRootNode());
668 navigator.setCurrentPath(currentPath);
669 populateInspector(currentPath);
681 int row = rowAtPoint(point);
682 int col = columnAtPoint(point);
683 TableCellRenderer renderer = getCellRenderer(row,col);
684 JLabel label = (JLabel) renderer.getTableCellRendererComponent(
this,getValueAt(row,col),
true,
true,row,col);
689 Dimension dim = label.getPreferredSize();
691 Rectangle cellRect = getCellRect(row,col,
true);
694 int iconX = (int)( ( cellRect.getWidth() - label.getIcon().getIconWidth() ) / 2 + cellRect.getX() );
695 int iconY = (int)( ( cellRect.getHeight() - dim.getHeight() ) / 2 + cellRect.getY() );
697 Rectangle iconRect =
new Rectangle(iconX, iconY, label.getIcon().getIconWidth(), label.getIcon().getIconHeight());
699 if (iconRect.contains(point))
708 if (dim.getWidth() > cellRect.getWidth())
709 textWidth = (
int) cellRect.getWidth();
711 textWidth = (int) dim.getWidth();
716 textHeight = (int)( dim.getHeight() - label.getIcon().getIconHeight() + label.getIconTextGap() );
718 int textX = (int)( ( cellRect.getWidth() - textWidth ) / 2 + cellRect.getX() );
719 int textY = (int)( iconRect.getY() + iconRect.getHeight() - label.getIconTextGap() );
721 Rectangle textRect =
new Rectangle(textX, textY, textWidth, textHeight);
723 if (textRect.contains(point))
737 Graphics2D g2 = (Graphics2D) g;
740 if (dblBuffer == null) {
743 g2.drawImage(dblBuffer, null, 0, 0);
744 super.paintComponent(g);
746 if (selTool.isDragging())
747 selTool.paintSelectionTool(g2);
748 else if (dropHandler.isDropping()) {
749 dropHandler.paintDropImage(g2);
750 dropHandler.paintCueLine(g2);
765 Iterator filterIterator = filters.iterator();
766 while (filterIterator.hasNext()) {
768 if (!filter.allowsNode(node))
792 protected MenuHandler getMenuHandler() {
793 return new MenuHandler();
796 protected InspectorTreeModelListener getInspectorTreeModelListener() {
797 return new InspectorTreeModelListener();
809 Component c = getComponentForPosition(position);
813 Rectangle bounds = getCellRect(position.
getRow(), position.
getColumn(),
true);
815 c.setSize(bounds.width, bounds.height);
817 BufferedImage image =
new BufferedImage(
820 BufferedImage.TYPE_INT_ARGB_PRE
823 Graphics2D g2d = (Graphics2D) image.createGraphics();
824 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.9f));
840 Rectangle bounds = getSelectionBounds(positions);
842 BufferedImage image =
new BufferedImage((
int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
844 Graphics2D g2d = (Graphics2D) image.createGraphics();
847 int heightOffset = 0;
850 NodePosition leftMost = getLeftMostSelection(positions);
855 if (topMost.
getRow() != 0)
856 heightOffset = topMost.
getRow() * ((int) getCellRect(topMost.
getRow(), topMost.
getColumn(),
true).getHeight());
858 for (
int i = 0; i < positions.length; i++) {
859 if (getValueAt(positions[i].getRow(), positions[i].
getColumn()) != null) {
860 Image nodeImage = getGhostedNode(positions[i]);
861 Rectangle nodeBounds = getCellRect( positions[i].getRow(), positions[i].getColumn(),
true );
862 g2d.drawImage(nodeImage, nodeBounds.x - widthOffset, nodeBounds.y - heightOffset, null);
981 if ( (pos == null) || (!mouseInsideCellComponent(dge.getDragOrigin())) ) {
986 dragPaths = getSelectionPaths();
988 if (dragNode != null) {
989 MatrixTreeTransferable transferable =
new MatrixTreeTransferable(dragPaths);
991 BufferedImage dragImage = (BufferedImage) getDragImageForPosition(getSelectionNodes());
995 Point topLeft =
new Point(getSelectionBounds(getSelectionNodes()).getLocation());
996 Point origin = dge.getDragOrigin();
997 dragOffset.setLocation(origin.getX() - topLeft.getX(), origin.getY() - topLeft.getY());
1000 new Cursor(Cursor.DEFAULT_CURSOR),
1007 DragImageExchange.setDragImage(dragImage, dragOffset);
1021 protected Point initMousePt;
1022 protected Point lastMousePt;
1023 protected BufferedImage dragImage;
1024 protected Point mouseOffset =
new Point(5,5);
1025 private boolean isDropping =
false;
1034 dragImage = DragImageExchange.getDragImage();
1035 mouseOffset = DragImageExchange.getMouseOffset();
1065 if (lastMousePt != null && lastMousePt.equals(dtde.getLocation()))
1067 if (initMousePt == null) {
1068 initMousePt = dtde.getLocation();
1069 SwingUtilities.convertPointFromScreen(initMousePt,
InspectorGadget.this);
1071 lastMousePt = dtde.getLocation();
1081 public void drop(DropTargetDropEvent dtde) {
1083 Transferable transfer = dtde.getTransferable();
1084 java.util.List paths = null;
1086 paths = (java.util.List) transfer.getTransferData(
1087 MatrixTreeTransferable.TREE_NODE_FLAVOUR);
1088 }
catch (UnsupportedFlavorException ufe) {
1089 ufe.printStackTrace();
1090 }
catch (IOException ioe) {
1091 ioe.printStackTrace();
1094 Point dropLocation = dtde.getLocation();
1096 int mouseX = (int) dtde.getLocation().getX();
1098 int dropRow = rowAtPoint(dropLocation);
1099 int dropCol = columnAtPoint(dropLocation);
1102 dropRow = getRowCount() - 1;
1104 Rectangle cellBounds = getCellRect(dropRow, dropCol,
true);
1106 if (mouseX > (cellBounds.x + cellBounds.width / 2))
1107 if (dropCol < getColumnCount() - 1)
1110 int dropIndex = ( dropRow * getColumnCount() ) + dropCol;
1112 if (getValueAt(dropRow,dropCol) == null) {
1115 dropIndex = ( dropRow * getColumnCount() ) + dropCol;
1130 for (
int i = 0; i < paths.size(); i++) {
1132 int dragIndex = node.getParent().getIndex(node);
1135 fireTransfer(dragIndex, dropIndex, node, dropParent);
1144 DragImageExchange.completeExchange();
1167 int x = lastMousePt.x - mouseOffset.x;
1168 int y = lastMousePt.y - mouseOffset.y;
1181 int row = rowAtPoint(lastMousePt);
1182 int col = columnAtPoint(lastMousePt);
1189 row = getRowCount() - 1;
1191 if (getValueAt(row,col) == null) {
1197 Rectangle cellBounds = getCellRect(row, col,
true);
1198 Rectangle bounds = getBounds();
1200 int mouseX = (int) lastMousePt.getX();
1201 int mouseY = (int) lastMousePt.getY();
1205 if (mouseX < (cellBounds.x + cellBounds.width / 2))
1206 leftRight = CUE_LEFT;
1208 leftRight = CUE_RIGHT;
1210 int x = 0, y = 0, height = 0;
1212 x = leftRight == CUE_LEFT ? cellBounds.x : cellBounds.x + cellBounds.width;
1214 height = cellBounds.height;
1216 g2d.setColor(UIManager.getColor(
"CueLine.stroke"));
1218 g2d.setStroke(
new BasicStroke(1));
1219 g2d.drawLine(x, y, x, y + height);
1220 g2d.drawLine(x - 2, y, x + 2, y);
1221 g2d.drawLine(x - 2, y + height, x + 2, y + height);
1226 public void mouseClicked(MouseEvent evt) {
1227 if (!GUIUtilities.isRightMouseButton(evt))
1229 JPopupMenu menu = null;
1236 int currentRow = rowAtPoint(evt.getPoint());
1237 int currentColumn = columnAtPoint(evt.getPoint());
1239 if (currentRow == -1 || currentColumn == -1)
1242 changeSelection(currentRow, currentColumn,
false,
false);
1243 TreePath[] selectedPaths = getSelectionPaths();
1245 menu = (selectedPaths.length == 1)
1246 ? getMenuForSingleSelection()
1247 : getMenuForMultipleSelection();
1253 protected JPopupMenu getMenuForVoidSpace() {
1254 return MatrixMenus.getPopupAddMenu(null);
1256 protected JPopupMenu getMenuForSingleSelection() {
1257 return MatrixMenus.getPopupScreenMenu((
MatrixTreeNode) getSelectionPath().getLastPathComponent());
1259 protected JPopupMenu getMenuForMultipleSelection() {
1262 protected JMenuItem[] getAncillaryMenuItems() {
1269 public void treeNodesChanged(TreeModelEvent e) {
1270 populateInspector(currentPath);
1273 public void treeNodesInserted(TreeModelEvent e) {
1274 populateInspector(currentPath);
1277 public void treeNodesRemoved(TreeModelEvent e) {
1278 populateInspector(currentPath);
1281 public void treeStructureChanged(TreeModelEvent e) {}
1294 class MatrixTableUI
extends javax.swing.plaf.basic.BasicTableUI {
1301 protected MouseInputListener createMouseInputListener() {
1302 return new MatrixMouseHandler();
1312 implements MouseMotionListener {
1314 boolean isDragging =
false;
1349 int mouseX = evt.getX();
1350 int mouseY = evt.getY();
1352 if ((rowAtPoint(evt.getPoint()) == -1)
1353 && !GUIUtilities.isRightMouseButton(evt))
1355 else if (!mouseInsideCellComponent(evt.getPoint()))
1358 super.mouseReleased(evt);