/******************************************************************************* * This file is part of logisim-evolution. * * logisim-evolution 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. * * logisim-evolution 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 logisim-evolution. If not, see <http://www.gnu.org/licenses/>. * * Original code by Carl Burch (http://www.cburch.com), 2011. * Subsequent modifications by : * + Haute École Spécialisée Bernoise * http://www.bfh.ch * + Haute École du paysage, d'ingénierie et d'architecture de Genève * http://hepia.hesge.ch/ * + Haute École d'Ingénierie et de Gestion du Canton de Vaud * http://www.heig-vd.ch/ * The project is currently maintained by : * + REDS Institute - HEIG-VD * Yverdon-les-Bains, Switzerland * http://reds.heig-vd.ch *******************************************************************************/ package com.cburch.logisim.gui.main; import javax.swing.JPopupMenu; import com.cburch.logisim.circuit.Circuit; import com.cburch.logisim.circuit.SubcircuitFactory; import com.cburch.logisim.comp.ComponentFactory; import com.cburch.logisim.data.AttributeEvent; import com.cburch.logisim.data.AttributeListener; import com.cburch.logisim.data.AttributeSet; import com.cburch.logisim.file.LibraryEvent; import com.cburch.logisim.file.LibraryEventSource; import com.cburch.logisim.file.LibraryListener; import com.cburch.logisim.file.LogisimFile; import com.cburch.logisim.file.LogisimFileActions; import com.cburch.logisim.gui.generic.AttrTableModel; import com.cburch.logisim.gui.generic.ProjectExplorer; import com.cburch.logisim.gui.generic.ProjectExplorerEvent; import com.cburch.logisim.gui.generic.ProjectExplorerLibraryNode; import com.cburch.logisim.gui.generic.ProjectExplorerListener; import com.cburch.logisim.gui.generic.ProjectExplorerToolNode; import com.cburch.logisim.gui.menu.Popups; import com.cburch.logisim.gui.menu.ProjectCircuitActions; import com.cburch.logisim.gui.menu.ProjectLibraryActions; import com.cburch.logisim.proj.Project; import com.cburch.logisim.proj.ProjectEvent; import com.cburch.logisim.proj.ProjectListener; import com.cburch.logisim.tools.AddTool; import com.cburch.logisim.tools.Library; import com.cburch.logisim.tools.Tool; class ToolboxManip implements ProjectExplorerListener { private class MyListener implements ProjectListener, LibraryListener, AttributeListener { private LogisimFile curFile = null; private void addLibrary(Library lib) { if (lib instanceof LibraryEventSource) { ((LibraryEventSource) lib).addLibraryListener(this); } for (Tool tool : lib.getTools()) { AttributeSet attrs = tool.getAttributeSet(); if (attrs != null) attrs.addAttributeListener(this); } } public void attributeListChanged(AttributeEvent e) { } public void attributeValueChanged(AttributeEvent e) { explorer.repaint(); } public void libraryChanged(LibraryEvent event) { int action = event.getAction(); if (action == LibraryEvent.ADD_LIBRARY) { if (event.getSource() == curFile) { addLibrary((Library) event.getData()); } } else if (action == LibraryEvent.REMOVE_LIBRARY) { if (event.getSource() == curFile) { removeLibrary((Library) event.getData()); } } else if (action == LibraryEvent.ADD_TOOL) { Tool tool = (Tool) event.getData(); AttributeSet attrs = tool.getAttributeSet(); if (attrs != null) attrs.addAttributeListener(this); } else if (action == LibraryEvent.REMOVE_TOOL) { Tool tool = (Tool) event.getData(); AttributeSet attrs = tool.getAttributeSet(); if (attrs != null) attrs.removeAttributeListener(this); } explorer.repaint(); } public void projectChanged(ProjectEvent event) { int action = event.getAction(); if (action == ProjectEvent.ACTION_SET_FILE) { setFile((LogisimFile) event.getOldData(), (LogisimFile) event.getData()); explorer.repaint(); } } private void removeLibrary(Library lib) { if (lib instanceof LibraryEventSource) { ((LibraryEventSource) lib).removeLibraryListener(this); } for (Tool tool : lib.getTools()) { AttributeSet attrs = tool.getAttributeSet(); if (attrs != null) attrs.removeAttributeListener(this); } } private void setFile(LogisimFile oldFile, LogisimFile newFile) { if (oldFile != null) { removeLibrary(oldFile); for (Library lib : oldFile.getLibraries()) { removeLibrary(lib); } } curFile = newFile; if (newFile != null) { addLibrary(newFile); for (Library lib : newFile.getLibraries()) { addLibrary(lib); } } } } private Project proj; private ProjectExplorer explorer; private MyListener myListener = new MyListener(); private Tool lastSelected = null; ToolboxManip(Project proj, ProjectExplorer explorer) { this.proj = proj; this.explorer = explorer; proj.addProjectListener(myListener); myListener.setFile(null, proj.getLogisimFile()); } public void deleteRequested(ProjectExplorerEvent event) { Object request = event.getTarget(); if (request instanceof ProjectExplorerLibraryNode) { Library lib = ((ProjectExplorerLibraryNode) request).getValue(); ProjectLibraryActions.doUnloadLibrary(proj, lib); } else if (request instanceof ProjectExplorerToolNode) { Tool tool = ((ProjectExplorerToolNode) request).getValue(); if (tool instanceof AddTool) { ComponentFactory factory = ((AddTool) tool).getFactory(); if (factory instanceof SubcircuitFactory) { SubcircuitFactory circFact = (SubcircuitFactory) factory; ProjectCircuitActions.doRemoveCircuit(proj, circFact.getSubcircuit()); } } } } public void doubleClicked(ProjectExplorerEvent event) { Object clicked = event.getTarget(); if (clicked instanceof ProjectExplorerToolNode) { Tool baseTool = ((ProjectExplorerToolNode) clicked).getValue(); if (baseTool instanceof AddTool) { AddTool tool = (AddTool) baseTool; ComponentFactory source = tool.getFactory(); if (source instanceof SubcircuitFactory) { SubcircuitFactory circFact = (SubcircuitFactory) source; proj.setCurrentCircuit(circFact.getSubcircuit()); proj.getFrame().setEditorView(Frame.EDIT_LAYOUT); if (lastSelected != null){ proj.setTool(lastSelected); } else { Library base = proj.getLogisimFile().getLibrary("Base"); if (base != null) proj.setTool(base.getTool("Edit Tool")); } } } } } public JPopupMenu menuRequested(ProjectExplorerEvent event) { Object clicked = event.getTarget(); if (clicked instanceof ProjectExplorerToolNode) { Tool baseTool = ((ProjectExplorerToolNode) clicked).getValue(); if (baseTool instanceof AddTool) { AddTool tool = (AddTool) baseTool; ComponentFactory source = tool.getFactory(); if (source instanceof SubcircuitFactory) { Circuit circ = ((SubcircuitFactory) source).getSubcircuit(); return Popups.forCircuit(proj, tool, circ); } else { return null; } } else { return null; } } else if (clicked instanceof ProjectExplorerLibraryNode) { Library lib = ((ProjectExplorerLibraryNode) clicked).getValue(); if (lib == proj.getLogisimFile()) { return Popups.forProject(proj); } else { boolean is_top = event.getTreePath().getPathCount() <= 2; return Popups.forLibrary(proj, lib, is_top); } } else { return null; } } public void moveRequested(ProjectExplorerEvent event, AddTool dragged, AddTool target) { LogisimFile file = proj.getLogisimFile(); int draggedIndex = file.getTools().indexOf(dragged); int targetIndex = file.getTools().indexOf(target); if (targetIndex > draggedIndex) targetIndex++; proj.doAction(LogisimFileActions.moveCircuit(dragged, targetIndex)); } public void selectionChanged(ProjectExplorerEvent event) { Object selected = event.getTarget(); if (selected instanceof ProjectExplorerToolNode) { Tool tool = ((ProjectExplorerToolNode) selected).getValue(); if (selected instanceof AddTool) { AddTool addTool = (AddTool) tool; ComponentFactory source = addTool.getFactory(); if (source instanceof SubcircuitFactory) { SubcircuitFactory circFact = (SubcircuitFactory) source; Circuit circ = circFact.getSubcircuit(); if (proj.getCurrentCircuit() == circ) { AttrTableModel m = new AttrTableCircuitModel(proj, circ); proj.getFrame().setAttrTableModel(m); return; } } } // This was causing the selection to lag behind double-clicks, // commented-out // lastSelected = proj.getTool(); proj.setTool(tool); proj.getFrame().viewAttributes(tool); } } }