/******************************************************************************* * 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.proj; import java.awt.Dimension; import java.awt.Point; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.WeakHashMap; import com.cburch.logisim.file.Loader; import com.cburch.logisim.gui.main.Frame; import com.cburch.logisim.util.MacCompatibility; import com.cburch.logisim.util.PropertyChangeWeakSupport; public class Projects { private static class MyListener extends WindowAdapter { @Override public void windowActivated(WindowEvent event) { mostRecentFrame = (Frame) event.getSource(); } @Override public void windowClosed(WindowEvent event) { Frame frame = (Frame) event.getSource(); Project proj = frame.getProject(); if (frame == proj.getFrame()) { projectRemoved(proj, frame, this); } if (openProjects.isEmpty() && !MacCompatibility.isSwingUsingScreenMenuBar()) { ProjectActions.doQuit(); } } @Override public void windowClosing(WindowEvent event) { Frame frame = (Frame) event.getSource(); if ((frame.getExtendedState() & Frame.ICONIFIED) == 0) { mostRecentFrame = frame; try { frameLocations.put(frame, frame.getLocationOnScreen()); } catch (Exception t) { } } } @Override public void windowOpened(WindowEvent event) { Frame frame = (Frame) event.getSource(); Project proj = frame.getProject(); if (frame == proj.getFrame() && !openProjects.contains(proj)) { openProjects.add(proj); propertySupport.firePropertyChange(projectListProperty, null, null); } } } // // PropertyChangeSource methods // public static void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } public static void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(propertyName, listener); } public static Project findProjectFor(File query) { for (Project proj : openProjects) { Loader loader = proj.getLogisimFile().getLoader(); if (loader == null) { continue; } File f = loader.getMainFile(); if (query.equals(f)) { return proj; } } return null; } public static Point getCenteredLoc(int width, int height) { int x, y; x = getTopFrame().getX() + getTopFrame().getWidth() / 2; x -= width / 2; y = getTopFrame().getY() + getTopFrame().getHeight() / 2; y -= height / 2; return new Point(x, y); } public static Point getLocation(Window win) { Point ret = frameLocations.get(win); return ret == null ? null : (Point) ret.clone(); } public static List<Project> getOpenProjects() { return Collections.unmodifiableList(openProjects); } public static Frame getTopFrame() { Frame ret = mostRecentFrame; if (ret == null) { Frame backup = null; for (Project proj : openProjects) { Frame frame = proj.getFrame(); if (ret == null) { ret = frame; } if (ret.isVisible() && (ret.getExtendedState() & Frame.ICONIFIED) != 0) { backup = ret; } } if (ret == null) { ret = backup; } } return ret; } private static void projectRemoved(Project proj, Frame frame, MyListener listener) { frame.removeWindowListener(listener); openProjects.remove(proj); proj.getSimulator().shutDown(); propertySupport.firePropertyChange(projectListProperty, null, null); } public static void removePropertyChangeListener( PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } public static void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(propertyName, listener); } static void windowCreated(Project proj, Frame oldFrame, Frame frame) { if (oldFrame != null) { projectRemoved(proj, oldFrame, myListener); } if (frame == null) { return; } // locate the window Point lowest = null; for (Project p : openProjects) { Frame f = p.getFrame(); if (f == null) { continue; } Point loc = p.getFrame().getLocation(); if (lowest == null || loc.y > lowest.y) { lowest = loc; } } if (lowest != null) { Dimension sz = frame.getToolkit().getScreenSize(); int x = Math.min(lowest.x + 20, sz.width - 200); int y = Math.min(lowest.y + 20, sz.height - 200); if (x < 0) { x = 0; } if (y < 0) { y = 0; } frame.setLocation(x, y); } if (frame.isVisible() && !openProjects.contains(proj)) { openProjects.add(proj); propertySupport.firePropertyChange(projectListProperty, null, null); } frame.addWindowListener(myListener); } public static boolean windowNamed(String name) { for (Project proj : openProjects) { if (proj.getLogisimFile().getName().equals(name)) { return true; } } return false; } public static final String projectListProperty = "projectList"; private static final WeakHashMap<Window, Point> frameLocations = new WeakHashMap<Window, Point>(); private static final MyListener myListener = new MyListener(); private static final PropertyChangeWeakSupport propertySupport = new PropertyChangeWeakSupport( Projects.class); private static ArrayList<Project> openProjects = new ArrayList<Project>(); private static Frame mostRecentFrame = null; private Projects() { } }