/* * funCKit - functional Circuit Kit * Copyright (C) 2013 Lukas Elsner <open@mindrunner.de> * Copyright (C) 2013 Peter Dahlberg <catdog2@tuxzone.org> * Copyright (C) 2013 Julian Stier <mail@julian-stier.de> * Copyright (C) 2013 Sebastian Vetter <mail@b4sti.eu> * Copyright (C) 2013 Thomas Poxrucker <poxrucker_t@web.de> * Copyright (C) 2013 Alexander Treml <alex.treml@directbox.com> * * This program 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. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.sep2011.funckit.view; import static de.sep2011.funckit.util.Log.gl; import static de.sep2011.funckit.util.internationalization.Language.tr; import java.awt.Container; import java.awt.Dimension; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.LinkedHashMap; import java.util.Map; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import com.jidesoft.swing.JideTabbedPane; import net.miginfocom.swing.MigLayout; import de.sep2011.funckit.controller.listener.editpanel.TabbedPaneChangeListener; import de.sep2011.funckit.controller.listener.project.ProjectTreeListener; import de.sep2011.funckit.controller.listener.settings.ToggleExpertModeActionListener; import de.sep2011.funckit.model.sessionmodel.Project; import de.sep2011.funckit.model.sessionmodel.SessionModel; import de.sep2011.funckit.model.sessionmodel.Settings; import de.sep2011.funckit.observer.ProjectInfo; import de.sep2011.funckit.observer.ProjectObserver; import de.sep2011.funckit.observer.SessionModelInfo; import de.sep2011.funckit.observer.SessionModelObserver; import de.sep2011.funckit.observer.SettingsInfo; import de.sep2011.funckit.observer.SettingsObserver; /** * FunckitFrame is the main-view of the program. Creates the layout of the view. */ public class FunckitRootPane extends JRootPane implements SessionModelObserver, ProjectObserver, SettingsObserver { /** * Unique identifier for serialization. */ private static final long serialVersionUID = -8480228957905762293L; private static final JideTabbedPane EMPTY_TABS = new JideTabbedPane(); final private View view; private Map<Project, ProjectTabs> projectsTabs; private FunckitMenuBar menuBar; private JPanel projectExplorerPanel; private NewBrickListPanel newBrickListPanel; private StatusBar statusBar; private FunckitToolBar toolBar; private JSplitPane mainSplitPane; /** * Create a new {@link FunckitRootPane}. * @param view the view this is part of * */ public FunckitRootPane(View view) { super(); this.view = view; switch (view.getSessionModel().getViewType()) { case VIEW_TYPE_ELEANING_SOLVE: initializeElearningSolveRootPane(); break; case VIEW_TYPE_STANDALONE: initializeStandaloneRootPane(); break; case VIEW_TYPE_PRESENTER: initializeCircuitPresenterRootPane(); default: new RuntimeException("ViewType " + view.getSessionModel().getViewType() + " Not implemented."); break; } } /** * Initializes object with the given parameters. * * @param boundingRect * The rectangle of the frame */ private void initializeStandaloneRootPane() { projectsTabs = new LinkedHashMap<Project, ProjectTabs>(); // create menu bar FunckitMenuBar menuBar = new FunckitMenuBar(view); setFunckitMenuBar(menuBar); // create the toolbar toolBar = new FunckitToolBar(view); // create project explorer createProjectTreePanel(); // create new brick list panel newBrickListPanel = new NewBrickListPanel(view); // create status bar statusBar = new StatusBar(view); Container c = getContentPane(); c.setLayout(new MigLayout("fill")); c.add(toolBar, "dock north, growx"); c.add(statusBar, "dock south, growx"); // c.add(editToolBar, "dock east, growy"); c.add(newBrickListPanel, "dock east, growy"); mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, null, EMPTY_TABS); mainSplitPane.setOneTouchExpandable(true); mainSplitPane.setLeftComponent(projectExplorerPanel); c.add(mainSplitPane, "grow"); view.getSessionModel().addObserver(this); view.getSessionModel().getSettings().addObserver(this); // init cursor from model handleCursorChange(view.getSessionModel()); createToogleExpertModeShortcut(); } private void initializeCircuitPresenterRootPane() { projectsTabs = new LinkedHashMap<Project, ProjectTabs>(); // create menu bar FunckitMenuBar menuBar = new FunckitMenuBar(view); setFunckitMenuBar(menuBar); // create the toolbar toolBar = new FunckitToolBar(view); // create project explorer createProjectTreePanel(); // create new brick list panel newBrickListPanel = new NewBrickListPanel(view); // create status bar statusBar = new StatusBar(view); Container c = getContentPane(); c.setLayout(new MigLayout("fill")); c.add(toolBar, "dock north, growx"); c.add(statusBar, "dock south, growx"); // c.add(editToolBar, "dock east, growy"); mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, null, EMPTY_TABS); mainSplitPane.setOneTouchExpandable(true); mainSplitPane.setLeftComponent(projectExplorerPanel); // collapse splitpane mainSplitPane.setDividerLocation(0.3d); mainSplitPane.getLeftComponent().setMinimumSize(new Dimension()); mainSplitPane.setDividerLocation(0.0d); c.add(mainSplitPane, "grow"); view.getSessionModel().addObserver(this); view.getSessionModel().getSettings().addObserver(this); // init cursor from model handleCursorChange(view.getSessionModel()); createToogleExpertModeShortcut(); } private void initializeElearningSolveRootPane() { projectsTabs = new LinkedHashMap<Project, ProjectTabs>(); // create menu bar FunckitMenuBar menuBar = new FunckitMenuBar(view); setFunckitMenuBar(menuBar); // create the toolbar toolBar = new FunckitToolBar(view); // create project explorer createProjectTreePanel(); // create new brick list panel newBrickListPanel = new NewBrickListPanel(view); // create status bar statusBar = new StatusBar(view); Container c = getContentPane(); c.setLayout(new MigLayout("fill")); c.add(toolBar, "dock north, growx"); c.add(statusBar, "dock south, growx"); // c.add(editToolBar, "dock east, growy"); c.add(newBrickListPanel, "dock east, growy"); mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, null, EMPTY_TABS); mainSplitPane.setOneTouchExpandable(true); mainSplitPane.setLeftComponent(projectExplorerPanel); // collapse splitpane mainSplitPane.setDividerLocation(0.3d); mainSplitPane.getLeftComponent().setMinimumSize(new Dimension()); mainSplitPane.setDividerLocation(0.0d); c.add(mainSplitPane, "grow"); view.getSessionModel().addObserver(this); view.getSessionModel().getSettings().addObserver(this); // init cursor from model handleCursorChange(view.getSessionModel()); createToogleExpertModeShortcut(); } private void createToogleExpertModeShortcut() { getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), "expertMode"); getRootPane().getActionMap().put("expertMode", new ToggleExpertModeActionListener(view, view.getController())); } private void createProjectTreePanel() { ProjectTree projectTree = new ProjectTree(view); for (Project project : view.getSessionModel().getProjects()) { project.addObserver(this); } ProjectTreeListener projectTreeListener = new ProjectTreeListener(view, view.getController(), projectTree); projectTree.addMouseListener(projectTreeListener); projectTree.addMouseMotionListener(projectTreeListener); // projectTree.addMouseWheelListener(projectTreeListener); projectTree.addKeyListener(projectTreeListener); projectTree.addTreeExpansionListener(projectTreeListener); projectTree.addTreeSelectionListener(projectTreeListener); projectExplorerPanel = new JPanel(new MigLayout("insets 0, wrap", "[grow]", "[][grow]")); JScrollPane projectTreeScrollList = new JScrollPane(projectTree); projectExplorerPanel.add(new JLabel(tr("FunckitFrame.project"))); projectExplorerPanel.add(projectTreeScrollList, "grow 100 100"); } /** * Returns the main menu bar of the Application. * * @return the main menu bar of the Application */ public FunckitMenuBar getFunckitMenuBar() { return menuBar; } /** * Sets the main menu bar of the Application. * * @param menuBar * the menubar */ public void setFunckitMenuBar(FunckitMenuBar menuBar) { this.setJMenuBar(menuBar); this.menuBar = menuBar; } /** * Sets the test of the status bar. * * @param text * the text that will be displayed inside the statusbar. */ public void setStatusText(String text) { statusBar.setLabel(text); } /** * Returns the main tabbed pane (EditPanels as tabs). * * @return the main tabbed pane */ public JTabbedPane getTabbedPane() { return (JTabbedPane) mainSplitPane.getRightComponent(); } @Override public void sessionModelChanged(SessionModel source, SessionModelInfo i) { if (i.hasCursorChanged()) { handleCursorChange(source); } if (i.hasProjectAdded()) { Project p = i.getChangedProject(); p.addObserver(this); openProjectTabs(p); } if (i.hasProjectRemoved()) { Project p = i.getChangedProject(); p.deleteObserver(this); closeProjectTabs(p); } if (i.hasCurrentProjectChanged()) { Project p = source.getCurrentProject(); ProjectTabs tabs; if (p == null) { mainSplitPane.setRightComponent(EMPTY_TABS); return; } tabs = projectsTabs.get(p); if (tabs == null) { tabs = openProjectTabs(p); } mainSplitPane.setRightComponent(tabs); gl().debug("tabs set"); if (p.hasSimulation()) { enableSimulationMode(); } else if (p.getSelectedEditPanelModel() != null) { enableEditMode(p); } } } private void enableSimulationMode() { newBrickListPanel.hidePanel(); toolBar.showSimulationTools(); } private void enableEditMode(Project p) { if (p.getSelectedEditPanelModel() == null) { newBrickListPanel.hidePanel(); toolBar.showEverytimeTools(); } else if (p.getSelectedEditPanelModel() != null && p.getSelectedEditPanelModel().hasMainCircuit()) { newBrickListPanel.showPanel(); toolBar.showEditTools(); } else { newBrickListPanel.hidePanel(); toolBar.showOnlyStartTool(); } } private void closeProjectTabs(Project p) { ProjectTabs tabs = projectsTabs.get(p); // currently opened? if (tabs == mainSplitPane.getRightComponent()) { mainSplitPane.setRightComponent(EMPTY_TABS); } if (tabs != null) { tabs.cleanObserved(); } projectsTabs.remove(p); } private ProjectTabs openProjectTabs(Project p) { gl().debug("Opening Tabs for loaded project..."); // setup of tabs ProjectTabs tabs = new ProjectTabs(p, view); tabs.setCloseTabOnMouseMiddleButton(true); tabs.setShowCloseButtonOnSelectedTab(true); tabs.setShowCloseButtonOnTab(true); tabs.setTabShape(JideTabbedPane.SHAPE_ROUNDED_VSNET); TabbedPaneChangeListener listener = new TabbedPaneChangeListener(view, view.getController(), tabs); tabs.addChangeListener(listener); tabs.setCloseAction(listener); projectsTabs.put(p, tabs); return tabs; } private void handleCursorChange(SessionModel source) { setCursor(source.getCurrentCursor()); } @Override public void projectChanged(Project source, ProjectInfo i) { if (!(source == view.getSessionModel().getCurrentProject())) { return; } if (i.isSimulationChanged() || i.isActiveEditPanelModelChanged()) { if (source.hasSimulation()) { enableSimulationMode(); } else { enableEditMode(source); } } if (i.isCircuitChanged() && source.getCircuit() == null) { enableEditMode(source); } } @Override public void settingsChanged(Settings source, SettingsInfo i) { } }