/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2011 Neil C Smith. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 only, as * published by the Free Software Foundation. * * This code 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 * version 3 for more details. * * You should have received a copy of the GNU General Public License version 3 * along with this work; if not, see http://www.gnu.org/licenses/ * * * Please visit http://neilcsmith.net if you need additional information or * have any questions. */ package net.neilcsmith.praxis.live.pxr.gui; import java.awt.Component; import java.awt.event.ActionEvent; import java.beans.PropertyVetoException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToggleButton; import javax.swing.KeyStroke; import javax.swing.OverlayLayout; import javax.swing.SwingUtilities; import net.neilcsmith.praxis.live.model.ContainerProxy; import net.neilcsmith.praxis.live.model.RootProxy; import net.neilcsmith.praxis.live.pxr.api.PaletteUtils; import net.neilcsmith.praxis.live.pxr.api.RootEditor; import static net.neilcsmith.praxis.live.pxr.gui.LayoutAction.Type.*; import org.openide.actions.DeleteAction; import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerUtils; import org.openide.nodes.Node; import org.openide.util.Lookup; import org.openide.util.Utilities; import org.openide.util.actions.Presenter; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; import org.openide.util.lookup.Lookups; import org.openide.util.lookup.ProxyLookup; /** * * @author Neil C Smith <http://neilcsmith.net> */ public class GuiEditor extends RootEditor { private RootProxy root; private JComponent editorComponent; private JLayeredPane layeredPane; private EditLayer editLayer; private ExplorerManager em; private Lookup lookup; private EditAction editAction; // private LayoutAction[] layoutActions; private Action[] actions; private InstanceContent content; GuiEditor(RootProxy root) { this.root = root; em = new ExplorerManager(); em.setRootContext(root.getNodeDelegate()); // init components layeredPane = new JLayeredPane(); layeredPane.setLayout(new OverlayLayout(layeredPane)); layeredPane.setFocusable(true); editorComponent = new JScrollPane(layeredPane); initActions(layeredPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT), layeredPane.getActionMap()); content = new InstanceContent(); lookup = new ProxyLookup( ExplorerUtils.createLookup(em, layeredPane.getActionMap()), Lookups.fixed(PaletteUtils.getPalette("gui")), new AbstractLookup(content)); } private void initActions(InputMap inputMap, ActionMap actionMap) { actions = new Action[13]; editAction = new EditAction(); actions[0] = editAction; actions[1] = null; actions[2] = new LayoutAction(MoveLeft); actions[3] = new LayoutAction(MoveUp); actions[4] = new LayoutAction(MoveDown); actions[5] = new LayoutAction(MoveRight); actions[6] = null; actions[7] = new LayoutAction(IncreaseSpanX); actions[8] = new LayoutAction(DecreaseSpanX); actions[9] = new LayoutAction(IncreaseSpanY); actions[10] = new LayoutAction(DecreaseSpanY); actions[11] = null; actions[12] = DeleteAction.get(DeleteAction.class); inputMap.put(Utilities.stringToKey("D-e"), "edit"); actionMap.put("edit", editAction); inputMap.put(KeyStroke.getKeyStroke("LEFT"), "move-left"); actionMap.put("move-left", actions[2]); inputMap.put(KeyStroke.getKeyStroke("UP"), "move-up"); actionMap.put("move-up", actions[3]); inputMap.put(KeyStroke.getKeyStroke("DOWN"), "move-down"); actionMap.put("move-down", actions[4]); inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "move-right"); actionMap.put("move-right", actions[5]); inputMap.put(KeyStroke.getKeyStroke("shift RIGHT"), "increase-span-x"); actionMap.put("increase-span-x", actions[7]); inputMap.put(KeyStroke.getKeyStroke("shift LEFT"), "decrease-span-x"); actionMap.put("decrease-span-x", actions[8]); inputMap.put(KeyStroke.getKeyStroke("shift DOWN"), "increase-span-y"); actionMap.put("increase-span-y", actions[9]); inputMap.put(KeyStroke.getKeyStroke("shift UP"), "decrease-span-y"); actionMap.put("decrease-span-y", actions[10]); actionMap.put(DeleteAction.get(DeleteAction.class).getActionMapKey(), ExplorerUtils.actionDelete(em, true)); } @Override public JComponent getEditorComponent() { return editorComponent; } @Override public Lookup getLookup() { return lookup; } @Override public Action[] getActions() { return actions.clone(); } RootProxy getRoot() { return root; } void setSelected(Node[] nodes) throws Exception { em.setSelectedNodes(nodes); } void performPreferredAction() { Node[] nodes = em.getSelectedNodes(); if (nodes.length == 1) { nodes[0].getPreferredAction().actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "")); } } void addRootPanel(JPanel panel) { layeredPane.add(panel, JLayeredPane.DEFAULT_LAYER); editLayer = new EditLayer(this, panel); layeredPane.add(editLayer, JLayeredPane.PALETTE_LAYER); content.add(editLayer); if (((ContainerProxy)root).getChildIDs().length == 0) { editLayer.setVisible(true); } editAction.setEnabled(true); } void removeRootPanel(JPanel panel) { layeredPane.remove(panel); layeredPane.remove(editLayer); content.remove(editLayer); editAction.setEnabled(false); editLayer = null; try { em.setSelectedNodes(new Node[0]); } catch (PropertyVetoException ex) { Logger.getLogger(GuiEditor.class.getName()).log(Level.SEVERE, null, ex); } } @Override public void componentActivated() { super.componentActivated(); DockableGuiRoot r = DockableGuiRoot.find(root.getAddress().getRootID()); if (r != null) { r.requestConnect(this); } } @Override public void dispose() { super.dispose(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { DockableGuiRoot r = DockableGuiRoot.find(root.getAddress().getRootID()); if (r != null) { r.requestDisconnect(GuiEditor.this); } } }); } private class EditAction extends AbstractAction implements Presenter.Toolbar { private JToggleButton button; private EditAction() { super("Edit"); putValue(SELECTED_KEY, Boolean.FALSE); setEnabled(false); } @Override public void actionPerformed(ActionEvent ae) { if (editLayer.isVisible()) { editLayer.setVisible(false); putValue(SELECTED_KEY, Boolean.FALSE); } else { editLayer.setVisible(true); putValue(SELECTED_KEY, Boolean.TRUE); } } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); if (enabled) { putValue(SELECTED_KEY, editLayer.isVisible()); } else { putValue(SELECTED_KEY, Boolean.FALSE); } } @Override public Component getToolbarPresenter() { if (button == null) { button = new JToggleButton(this); } return button; } } }