/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
* Corporate:
* Astrium SAS
* Individual:
* Claude Cazenave
*
* $Id: SceneGraphEditor.java,v 1.12 2005/09/02 11:57:30 ogor Exp $
*
* Changes
* -------
* 3-Feb-2004 : Creation date (CC);
*
*/
package syn3d.ui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.tree.TreePath;
import syn3d.base.ActiveNode;
import syn3d.base.PluginManager;
/**
* Class description ...
*
* @author Claude CAZENAVE
*
*/
public class SceneGraphEditor implements ActionListener, MouseListener {
protected SceneGraphTree sceneTree;
protected PluginManager pluginManager;
public SceneGraphEditor(SceneGraphTree sTree, PluginManager pm){
sceneTree=sTree;
pluginManager = pm;
sceneTree.addMouseListener(this);
sceneTree.registerKeyboardAction(
this,
"delete_node",
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0),
JComponent.WHEN_FOCUSED
);
sceneTree.registerKeyboardAction(
this,
"delete_node",
KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,0),
JComponent.WHEN_FOCUSED
);
}
/** Adds all expanded path under the given tree path to the arraylist, recusrively */
protected void recursiveExpandedPathFinder(TreePath current, ArrayList expPaths) {
if (!sceneTree.isExpanded(current)) return;
expPaths.add(current);
ActiveNode node = (ActiveNode)current.getLastPathComponent();
for (Iterator it = node.getChildren().iterator(); it.hasNext();) {
recursiveExpandedPathFinder(current.pathByAddingChild((ActiveNode)it.next()),expPaths);
}
}
// Menu item dedicated to temporarily store the node reference for doing an action
protected class ActionMenuItem extends JMenuItem {
public ActiveNode node;
public Object action;
public ActionMenuItem(ActiveNode node, Object action) {
super(action.toString());
this.node = node;
this.action = action;
addActionListener(SceneGraphEditor.this);
}
}
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof ActionMenuItem) {
ActionMenuItem a = (ActionMenuItem)e.getSource();
a.node.doAction(a.action);
}
String cmd = e.getActionCommand();
if (cmd.equals("delete_node")) {
Object o = sceneTree.getLastSelectedPathComponent();
if (o==null) return;
if (!(o instanceof ActiveNode)) return;
ActiveNode node = (ActiveNode)o;
node.remove();
return;
}
// Use the following to do something special when the user selects a ChildMenu item
// The tree already listens to add events, so there is nothing to do here
// if (e.getActionCommand().equals("childCreated")) {}
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
public void mouseClicked(MouseEvent e) {
if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) == MouseEvent.BUTTON3_MASK) {
Object dest = null;
TreePath path = sceneTree.getPathForLocation(e.getX(), e.getY());
if (path != null) sceneTree.setSelectionPath(path);
if (sceneTree.getSelectionPath() != null) {
dest = sceneTree.getSelectionPath().getLastPathComponent();
}
if (dest==null) dest = ((SceneGraphModel)sceneTree.getModel()).getRoot();
if (!(dest instanceof ActiveNode)) return;
ActiveNode node = (ActiveNode)dest;
JPopupMenu menu = pluginManager.getChildMenu(node, this);
List actions = node.getActions();
if ((menu==null) && ((actions==null) || (actions.size()==0)))
return; // this component does not have any declared potential children, and no actions
// If there are actions, but no children, new menu
if (menu==null) menu = new JPopupMenu();
// Otherwise, add separator if needed
else if ((actions!=null) && (actions.size()>0)) menu.add(new JPopupMenu.Separator(), 0);
// Now add actions on top of menu, keeping order
if (actions!=null)
for (int i=actions.size()-1; i>=0; --i) {
Object a = actions.get(i);
if (a!=null) menu.add(new ActionMenuItem(node, a), 0);
}
// Finally popup the result
menu.show((JComponent)e.getSource(), e.getX(), e.getY());
} else if (e.getClickCount()==2 && (e.getModifiers()&MouseEvent.BUTTON1_MASK)==MouseEvent.BUTTON1_MASK){
Object dest = null;
TreePath path = sceneTree.getPathForLocation(e.getX(), e.getY());
if (path != null) sceneTree.setSelectionPath(path);
if (sceneTree.getSelectionPath() != null) {
dest = sceneTree.getSelectionPath().getLastPathComponent();
}
if (dest==null) dest = ((SceneGraphModel)sceneTree.getModel()).getRoot();
if (!(dest instanceof ActiveNode)) return;
ActiveNode node = (ActiveNode)dest;
pluginManager.showProperties(node, this);
}
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
public void mouseEntered(MouseEvent e) {
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
public void mouseExited(MouseEvent e) {
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
*/
public void mousePressed(MouseEvent e) {
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
public void mouseReleased(MouseEvent e) {
}
}