/*
* 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 de.sep2011.funckit.controller.CreateTool;
import de.sep2011.funckit.controller.DragViewportTool;
import de.sep2011.funckit.controller.MultiConnectTool;
import de.sep2011.funckit.controller.SelectTool;
import de.sep2011.funckit.controller.Tool;
import de.sep2011.funckit.controller.WireTool;
import de.sep2011.funckit.controller.listener.ELearningSubmitActionListener;
import de.sep2011.funckit.controller.listener.EditToolSelectionActionListener;
import de.sep2011.funckit.controller.listener.edit.RedoActionListener;
import de.sep2011.funckit.controller.listener.edit.UndoActionListener;
import de.sep2011.funckit.controller.listener.project.OpenActionListener;
import de.sep2011.funckit.controller.listener.project.SaveFileActionListener;
import de.sep2011.funckit.controller.listener.settings.GridLockActionListener;
import de.sep2011.funckit.controller.listener.settings.GridOnOffActionListener;
import de.sep2011.funckit.controller.listener.settings.RealTimeValidationOnOffActionListener;
import de.sep2011.funckit.controller.listener.settings.SimulationUndoActionListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationBackButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationDelaySpinnerListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationFasterButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationForwardButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationPauseButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationSlowerButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationSpeedSliderListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationStartButtonListener;
import de.sep2011.funckit.controller.listener.simulation.SimulationStopButtonListener;
import de.sep2011.funckit.controller.listener.view.ModelFitsIntoCircuitListener;
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.model.simulationmodel.Simulation;
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;
import de.sep2011.funckit.observer.SimulationModelInfo;
import de.sep2011.funckit.observer.SimulationModelObserver;
import de.sep2011.funckit.util.SpinnerWheelListener;
import de.sep2011.funckit.util.command.CommandDispatcher;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeListener;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import static de.sep2011.funckit.util.FunckitGuiUtil.addButtonClickKeystroke;
import static de.sep2011.funckit.util.FunckitGuiUtil.iconFromResource;
import static de.sep2011.funckit.util.internationalization.Language.tr;
import static java.awt.event.KeyEvent.VK_1;
import static java.awt.event.KeyEvent.VK_2;
import static java.awt.event.KeyEvent.VK_3;
import static java.awt.event.KeyEvent.VK_4;
import static java.awt.event.KeyEvent.VK_5;
import static java.lang.Math.round;
import static de.sep2011.funckit.util.FunckitGuiUtil.ctrlOrMeta;
import static de.sep2011.funckit.model.sessionmodel.SessionModel.ViewType.*;
/**
* Main toolbar of the application. Displays various Controls for editing and
* simulation.
*/
public class FunckitToolBar extends JToolBar implements SessionModelObserver, ProjectObserver,
SettingsObserver, SimulationModelObserver {
private static final long serialVersionUID = -6374770619968509711L;
private JButton startButton;
private JToggleButton newBrickButton;
private JToggleButton moveViewButton;
private JToggleButton selectMoveButton;
private JToggleButton invisibleDummyButton;
private Map<Class<? extends Tool>, JToggleButton> toolToButtonMap;
private JToggleButton wireButton;
private JToggleButton multiConnectButton;
final private View view;
private JButton stopButton;
private JToggleButton pauseButton;
private JButton stepBackButton;
private JButton stepNextButton;
private JToggleButton recordButton;
private JToggleButton gridlockButton;
private JToggleButton showGridButton;
private JButton openButton;
private JButton saveButton;
private JButton newProjectButton;
private JButton undoButton;
private JButton redoButton;
private JToggleButton liveCheckButton;
private JButton fitsInWindowButton;
private JButton submitButton;
private static final Icon NEW_PROJECT_ICON = iconFromResource("/icons/toolbar/newProject.png");
private static final Icon OPEN_ICON = iconFromResource("/icons/toolbar/open.png");
private static final Icon SAVE_ICON = iconFromResource("/icons/toolbar/disk.png");
private static final Icon SELECT_ICON = iconFromResource("/icons/toolbar/select_new.png");
private static final Icon NEW_BRICK_ICON = iconFromResource("/icons/toolbar/newBrick1.png");
private static final Icon WIRE_TOOL_ICON = iconFromResource("/icons/toolbar/wiretool.png");
private static final Icon MOVE_VIEWPORT_ICON = iconFromResource("/icons/toolbar/moveViewport.png");
private static final Icon START_ICON = iconFromResource("/icons/toolbar/control_play_blue.png");
private static final Icon STOP_ICON = iconFromResource("/icons/toolbar/control_stop_blue.png");
private static final Icon PAUSE_ICON = iconFromResource("/icons/toolbar/control_pause_blue.png");
private static final Icon BACKWARD_ICON = iconFromResource("/icons/toolbar/control_rewind_blue.png");
private static final Icon FORWARD_ICON = iconFromResource("/icons/toolbar/control_rewind_blue_TURNED.png");
private static final Icon RECORD_ICON = iconFromResource("/icons/toolbar/record.png");
private static final Icon FITS_IN_WINDOW_ICON = iconFromResource("/icons/toolbar/fitsInWindow.png");
private static final Icon GRIDLOCK_ICON = iconFromResource("/icons/toolbar/gridlock.png");
private static final Icon GRID_ICON = iconFromResource("/icons/toolbar/gridNew.png");
private static final Icon UNDO_ICON = iconFromResource("/icons/toolbar/stepBack.png");
private static final Icon REDO_ICON = iconFromResource("/icons/toolbar/stepForward.png");
private static final Icon LIVECHECK_ICON = iconFromResource("/icons/toolbar/livecheck.png");
private JSpinner timerDelaySpinner;
private JSlider simulationSpeedSlider;
private ChangeListener simulationSpeedListener;
private Multimap<Object, SessionModel.ViewType> viewTypeObjectMap;
/**
* Creates a new toolbar.
*
* @param view the associated View, not null.
*/
public FunckitToolBar(View view) {
super();
assert view != null;
this.view = view;
viewTypeObjectMap = HashMultimap.create();
initEditItems();
initSimulationItems();
initViewItems();
initFileItems();
initSettingsItems();
initEditItems();
initElearningItems();
addEverytimeTools();
view.getSessionModel().addObserver(this);
view.getSessionModel().getSettings().addObserver(this);
for (Project pro : view.getSessionModel().getProjects()) {
pro.addObserver(this);
}
}
private void initFileItems() {
saveButton = new JButton();
saveButton.addActionListener(new SaveFileActionListener(view, view.getController()));
saveButton.setIcon(SAVE_ICON);
saveButton.setToolTipText(tr("menuBar.file.save"));
viewTypeObjectMap.put(saveButton, VIEW_TYPE_STANDALONE);
newProjectButton = new JButton();
newProjectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
view.openNewProject(null);
}
});
newProjectButton.setIcon(NEW_PROJECT_ICON);
newProjectButton.setToolTipText(tr("menuBar.file.newProject"));
viewTypeObjectMap.put(newProjectButton, VIEW_TYPE_STANDALONE);
openButton = new JButton();
openButton.addActionListener(new OpenActionListener(view, view.getController()));
openButton.setIcon(OPEN_ICON);
openButton.setToolTipText(tr("menuBar.file.open..."));
viewTypeObjectMap.put(openButton, VIEW_TYPE_STANDALONE);
}
private void initSettingsItems() {
Settings settings = view.getSessionModel().getSettings();
gridlockButton = new JToggleButton();
gridlockButton.addActionListener(new GridLockActionListener(view, view.getController()));
gridlockButton.setIcon(GRIDLOCK_ICON);
gridlockButton.setSelected(true);
gridlockButton.setSelected(settings.getBoolean(Settings.GRID_LOCK));
gridlockButton.setToolTipText(tr("menuBar.settings.lockGrid"));
viewTypeObjectMap.put(gridlockButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(gridlockButton, VIEW_TYPE_ELEANING_SOLVE);
}
private void initViewItems() {
Settings settings = view.getSessionModel().getSettings();
fitsInWindowButton = new JButton();
fitsInWindowButton.addActionListener(new ModelFitsIntoCircuitListener(view, view
.getController()));
fitsInWindowButton.setIcon(FITS_IN_WINDOW_ICON);
fitsInWindowButton.setToolTipText(tr("menuBar.view.modelFitsInView"));
viewTypeObjectMap.put(fitsInWindowButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(fitsInWindowButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(fitsInWindowButton, VIEW_TYPE_PRESENTER);
showGridButton = new JToggleButton();
showGridButton.addActionListener(new GridOnOffActionListener(view, view.getController()));
showGridButton.setIcon(GRID_ICON);
showGridButton.setSelected(settings.getBoolean(Settings.SHOW_GRID));
showGridButton.setToolTipText(tr("menuBar.view.toggleGrid"));
viewTypeObjectMap.put(showGridButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(showGridButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(showGridButton, VIEW_TYPE_PRESENTER);
}
private void initSimulationItems() {
Settings settings = view.getSessionModel().getSettings();
Project pro = view.getSessionModel().getCurrentProject();
startButton = new JButton();
startButton.setToolTipText(tr("simulationToolbar.start"));
startButton
.addActionListener(new SimulationStartButtonListener(view, view.getController()));
startButton.setIcon(START_ICON);
viewTypeObjectMap.put(startButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(startButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(startButton, VIEW_TYPE_PRESENTER);
stopButton = new JButton();
stopButton.addActionListener(new SimulationStopButtonListener(view, view.getController()));
stopButton.setIcon(STOP_ICON);
stopButton.setToolTipText(tr("simulationToolbar.stop"));
viewTypeObjectMap.put(stopButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(stopButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(stopButton, VIEW_TYPE_PRESENTER);
pauseButton = new JToggleButton();
pauseButton
.addActionListener(new SimulationPauseButtonListener(view, view.getController()));
pauseButton.setIcon(PAUSE_ICON);
pauseButton.setSelected(pro == null ? false : pro.isSimulationPaused());
pauseButton.setToolTipText(tr("simulationToolbar.pause"));
viewTypeObjectMap.put(pauseButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(pauseButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(pauseButton, VIEW_TYPE_PRESENTER);
JButton fasterButton = new JButton(tr("simulationToolbar.faster"));
fasterButton.addActionListener(new SimulationFasterButtonListener(view, view
.getController()));
viewTypeObjectMap.put(fasterButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(fasterButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(fasterButton, VIEW_TYPE_PRESENTER);
JButton slowerButton = new JButton(tr("simulationToolbar.slower"));
slowerButton.addActionListener(new SimulationSlowerButtonListener(view, view
.getController()));
viewTypeObjectMap.put(slowerButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(slowerButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(slowerButton, VIEW_TYPE_PRESENTER);
recordButton = new JToggleButton();
recordButton
.addActionListener(new SimulationUndoActionListener(view, view.getController()));
recordButton.setIcon(RECORD_ICON);
recordButton.setSelected(true);
recordButton.setSelected(settings.getBoolean(Settings.SIMULATION_UNDO_ENABLED));
recordButton.setToolTipText(tr("menuBar.settings.simulationUndo"));
viewTypeObjectMap.put(recordButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(recordButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(recordButton, VIEW_TYPE_PRESENTER);
stepBackButton = new JButton();
stepBackButton.addActionListener(new SimulationBackButtonListener(view, view
.getController()));
stepBackButton.setIcon(BACKWARD_ICON);
stepBackButton.setEnabled(settings.getBoolean(Settings.SIMULATION_UNDO_ENABLED));
stepBackButton.setToolTipText(tr("simulationToolbar.stepBack"));
viewTypeObjectMap.put(stepBackButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(stepBackButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(stepBackButton, VIEW_TYPE_PRESENTER);
stepNextButton = new JButton();
stepNextButton.addActionListener(new SimulationForwardButtonListener(view, view
.getController()));
stepNextButton.setIcon(FORWARD_ICON);
stepNextButton.setToolTipText(tr("simulationToolbar.stepForward"));
viewTypeObjectMap.put(stepNextButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(stepNextButton, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(stepNextButton, VIEW_TYPE_PRESENTER);
int spinnerValue = pro == null ? 1 : pro.getTimerDelay();
timerDelaySpinner = new JSpinner(new SpinnerNumberModel(spinnerValue, 1, Integer.MAX_VALUE,
10));
final JSpinner.NumberEditor delayEditor = new JSpinner.NumberEditor(timerDelaySpinner);
delayEditor.getTextField().setFormatterFactory(
new JFormattedTextField.AbstractFormatterFactory() {
@Override
public AbstractFormatter getFormatter(JFormattedTextField tf) {
return new DelayFormater();
}
});
timerDelaySpinner.setEditor(delayEditor);
timerDelaySpinner.addMouseWheelListener(new SpinnerWheelListener(timerDelaySpinner));
timerDelaySpinner.addChangeListener(new SimulationDelaySpinnerListener(view, view
.getController(), timerDelaySpinner));
timerDelaySpinner.setMaximumSize(new Dimension(delayEditor.getTextField()
.getPreferredSize().width, timerDelaySpinner.getMaximumSize().height));
viewTypeObjectMap.put(timerDelaySpinner, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(timerDelaySpinner, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(timerDelaySpinner, VIEW_TYPE_PRESENTER);
simulationSpeedSlider = new JSlider(getOrientation(), 0, 100, 50);
simulationSpeedListener = new SimulationSpeedSliderListener(view, view.getController(),
simulationSpeedSlider.getModel());
simulationSpeedSlider.setMinorTickSpacing(5);
simulationSpeedSlider.setMajorTickSpacing(20);
simulationSpeedSlider.setPaintTicks(true);
simulationSpeedSlider.setPaintLabels(true);
double sliderFactor = settings.getDouble(Settings.SIMULATION_SLIDER_FACTOR);
int speedValue = pro == null ? 50 : (int) round(pro.getTimerDelay() / sliderFactor);
simulationSpeedSlider.getModel().setValue(speedValue);
simulationSpeedSlider.getModel().addChangeListener(simulationSpeedListener);
viewTypeObjectMap.put(simulationSpeedSlider, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(simulationSpeedSlider, VIEW_TYPE_ELEANING_SOLVE);
viewTypeObjectMap.put(simulationSpeedSlider, VIEW_TYPE_PRESENTER);
addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
simulationSpeedSlider.setOrientation(getOrientation());
}
@Override
public void componentResized(ComponentEvent e) {
simulationSpeedSlider.setOrientation(getOrientation());
}
@Override
public void componentMoved(ComponentEvent e) {
simulationSpeedSlider.setOrientation(getOrientation());
}
});
}
private void initEditItems() {
Settings settings = view.getSessionModel().getSettings();
toolToButtonMap = new HashMap<Class<? extends Tool>, JToggleButton>();
Project pro = view.getSessionModel().getCurrentProject();
createToolButtonGroup();
// init from model
selectButtonFromTool(view.getSessionModel().getTool().getClass());
// UNDO REDO
undoButton = new JButton();
undoButton.addActionListener(new UndoActionListener(view, view.getController()));
undoButton.setIcon(UNDO_ICON);
undoButton.setToolTipText(tr("menuBar.edit.undo"));
undoButton.setEnabled(pro != null && pro.getGraphCommandDispatcher().canStepBack());
viewTypeObjectMap.put(undoButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(undoButton, VIEW_TYPE_ELEANING_SOLVE);
redoButton = new JButton();
redoButton.addActionListener(new RedoActionListener(view, view.getController()));
redoButton.setIcon(REDO_ICON);
redoButton.setToolTipText(tr("menuBar.edit.redo"));
redoButton.setEnabled(pro != null && pro.getGraphCommandDispatcher().canStepForward());
viewTypeObjectMap.put(redoButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(redoButton, VIEW_TYPE_ELEANING_SOLVE);
//LIVECHECK
liveCheckButton = new JToggleButton();
liveCheckButton.addActionListener(new RealTimeValidationOnOffActionListener(view));
liveCheckButton.setIcon(LIVECHECK_ICON);
liveCheckButton.setToolTipText(tr("menuBar.settings.liveCheck"));
liveCheckButton.setSelected(settings.getBoolean(Settings.REALTIME_VALIDATION));
viewTypeObjectMap.put(liveCheckButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(liveCheckButton, VIEW_TYPE_ELEANING_SOLVE);
}
private void initElearningItems() {
submitButton = new JButton(tr("toolbar.elearning.submit"));
submitButton.addActionListener(new ELearningSubmitActionListener(view, view.getController()));
submitButton.setToolTipText(tr("toolbar.elearning.submit.tooltip"));
submitButton.setBackground(Color.GREEN);
viewTypeObjectMap.put(submitButton, VIEW_TYPE_ELEANING_SOLVE);
}
private void selectButtonFromTool(Class<? extends Tool> toolc) {
JToggleButton b = toolToButtonMap.get(toolc);
if (b == null) {
invisibleDummyButton.setSelected(true);
} else {
b.setSelected(true);
}
}
private void createToolButtonGroup() {
selectMoveButton = new JToggleButton();
selectMoveButton.setToolTipText(tr("editToolBar.selectMove"));
selectMoveButton.setActionCommand(SelectTool.class.getName());
toolToButtonMap.put(SelectTool.class, selectMoveButton);
selectMoveButton.addActionListener(new EditToolSelectionActionListener(view, view
.getController()));
selectMoveButton.setIcon(SELECT_ICON);
viewTypeObjectMap.put(selectMoveButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(selectMoveButton, VIEW_TYPE_ELEANING_SOLVE);
addButtonClickKeystroke(selectMoveButton, KeyStroke.getKeyStroke(VK_1, ctrlOrMeta()));
newBrickButton = new JToggleButton();
newBrickButton.setActionCommand(CreateTool.class.getName());
toolToButtonMap.put(CreateTool.class, newBrickButton);
newBrickButton.addActionListener(new EditToolSelectionActionListener(view, view
.getController()));
newBrickButton.setIcon(NEW_BRICK_ICON);
newBrickButton.setToolTipText(tr("editToolBar.newBrick"));
viewTypeObjectMap.put(newBrickButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(newBrickButton, VIEW_TYPE_ELEANING_SOLVE);
addButtonClickKeystroke(newBrickButton, KeyStroke.getKeyStroke(VK_2, ctrlOrMeta()));
wireButton = new JToggleButton();
wireButton.setActionCommand(WireTool.class.getName());
toolToButtonMap.put(WireTool.class, wireButton);
wireButton
.addActionListener(new EditToolSelectionActionListener(view, view.getController()));
wireButton.setIcon(WIRE_TOOL_ICON);
wireButton.setToolTipText(tr("editToolBar.wireTool"));
viewTypeObjectMap.put(wireButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(wireButton, VIEW_TYPE_ELEANING_SOLVE);
addButtonClickKeystroke(wireButton, KeyStroke.getKeyStroke(VK_3, ctrlOrMeta()));
multiConnectButton = new JToggleButton("Multi");
multiConnectButton.setActionCommand(MultiConnectTool.class.getName());
toolToButtonMap.put(MultiConnectTool.class, multiConnectButton);
multiConnectButton
.addActionListener(new EditToolSelectionActionListener(view, view.getController()));
//multiConnectButton.setIcon(WIRE_TOOL_ICON);
multiConnectButton.setToolTipText(tr("editToolBar.multiConnectTool"));
addButtonClickKeystroke(multiConnectButton, KeyStroke.getKeyStroke(VK_5, ctrlOrMeta()));
viewTypeObjectMap.put(multiConnectButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(multiConnectButton, VIEW_TYPE_ELEANING_SOLVE);
moveViewButton = new JToggleButton();
moveViewButton.setActionCommand(DragViewportTool.class.getName());
toolToButtonMap.put(DragViewportTool.class, moveViewButton);
moveViewButton.addActionListener(new EditToolSelectionActionListener(view, view
.getController()));
moveViewButton.setIcon(MOVE_VIEWPORT_ICON);
moveViewButton.setToolTipText(tr("editToolBar.moveViewport"));
viewTypeObjectMap.put(moveViewButton, VIEW_TYPE_STANDALONE);
viewTypeObjectMap.put(moveViewButton, VIEW_TYPE_ELEANING_SOLVE);
//addButtonClickKeystroke(moveViewButton, KeyStroke.getKeyStroke(VK_4, CTRL_DOWN_MASK));
addButtonClickKeystroke(moveViewButton, KeyStroke.getKeyStroke(VK_4, ctrlOrMeta()));
invisibleDummyButton = new JToggleButton("Dummy");
ButtonGroup group = new ButtonGroup();
group.add(selectMoveButton);
group.add(newBrickButton);
group.add(wireButton);
group.add(moveViewButton);
group.add(invisibleDummyButton);
group.add(multiConnectButton);
}
@Override
public void sessionModelChanged(SessionModel source, SessionModelInfo i) {
if (i.isToolChanged()) {
selectButtonFromTool(source.getTool().getClass());
}
if (i.hasProjectAdded()) {
i.getChangedProject().addObserver(this);
}
if (i.hasProjectRemoved()) {
i.getChangedProject().deleteObserver(this);
}
if (i.hasCurrentProjectChanged()) {
pauseButton.setSelected(source.getCurrentProject().isSimulationPaused());
timerDelaySpinner.setValue(source.getCurrentProject().getTimerDelay());
timerDelaySpinner.setEnabled(!source.getCurrentProject().isSimulationPaused());
updateSlider(source.getCurrentProject());
}
}
public void addViewTypeDependant(java.awt.Component component) {
if(viewTypeObjectMap.containsEntry(component, view.getSessionModel().getViewType())) {
add(component);
}
}
public void addSeparatorOnlyIfNotNeedless() {
if (getComponentCount() == 0) {
return;
}
if (getComponentAtIndex(getComponentCount() - 1) instanceof Separator) {
return;
}
addSeparator();
}
private void addELearningTools() {
addSeparatorOnlyIfNotNeedless();
addViewTypeDependant(submitButton);
}
public void showEditTools() {
removeAll();
addEverytimeTools();
addViewTypeDependant(startButton);
addViewTypeDependant(pauseButton);
addSeparatorOnlyIfNotNeedless();
addViewTypeDependant(selectMoveButton);
addViewTypeDependant(newBrickButton);
addViewTypeDependant(wireButton);
addViewTypeDependant(moveViewButton);
if (view.getSessionModel().getSettings().getBoolean(Settings.EXPERT_MODE)) {
addViewTypeDependant(multiConnectButton);
}
addSeparatorOnlyIfNotNeedless();
addViewTypeDependant(liveCheckButton);
addViewTypeDependant(undoButton);
addViewTypeDependant(redoButton);
addELearningTools();
actualizeView();
}
public void showSimulationTools() {
removeAll();
addEverytimeTools();
addViewTypeDependant(stopButton);
addViewTypeDependant(pauseButton);
addViewTypeDependant(stepBackButton);
addViewTypeDependant(stepNextButton);
addSeparatorOnlyIfNotNeedless();
if (view.getSessionModel().getSettings().getBoolean(Settings.EXPERT_MODE)) {
addViewTypeDependant(timerDelaySpinner);
} else {
addViewTypeDependant(simulationSpeedSlider);
}
actualizeView();
}
private void addEverytimeTools() {
addViewTypeDependant(newProjectButton);
addViewTypeDependant(openButton);
addViewTypeDependant(saveButton);
addSeparatorOnlyIfNotNeedless();
addViewTypeDependant(fitsInWindowButton);
addViewTypeDependant(gridlockButton);
addViewTypeDependant(showGridButton);
addSeparatorOnlyIfNotNeedless();
addViewTypeDependant(recordButton);
addSeparatorOnlyIfNotNeedless();
}
public void showEverytimeTools() {
removeAll();
addEverytimeTools();
actualizeView();
}
public void showOnlyStartTool() {
removeAll();
addEverytimeTools();
addViewTypeDependant(startButton);
addViewTypeDependant(pauseButton);
actualizeView();
}
void actualizeView() {
if (view.getMainRootPane() != null) {
view.getMainRootPane().validate();
}
revalidate();
repaint();
}
@Override
public void projectChanged(Project source, ProjectInfo i) {
if (i.isSimulationControlStateModified()) {
pauseButton.setSelected(source.isSimulationPaused());
timerDelaySpinner.setValue(source.getTimerDelay());
timerDelaySpinner.setEnabled(!source.isSimulationPaused());
updateSlider(source);
}
if (i.isSimulationChanged()) {
if (i.getOldSimulation() != null) {
i.getOldSimulation().deleteObserver(this);
}
Simulation simulation = source.getSimulation();
if (simulation != null) {
simulation.addObserver(this);
updateStepBackButton();
}
}
undoButton.setEnabled(source.getGraphCommandDispatcher().canStepBack());
redoButton.setEnabled(source.getGraphCommandDispatcher().canStepForward());
}
private void updateSlider(Project project) {
if (!simulationSpeedSlider.getModel().getValueIsAdjusting()) {
simulationSpeedSlider.getModel().removeChangeListener(simulationSpeedListener);
if (project.isSimulationPaused()) {
simulationSpeedSlider.setValue(0);
} else {
double sliderFactor = view.getSessionModel().getSettings()
.getDouble(Settings.SIMULATION_SLIDER_FACTOR);
simulationSpeedSlider.getModel().setValue(
100 - ((int) round(project.getTimerDelay() / sliderFactor)));
}
simulationSpeedSlider.getModel().addChangeListener(simulationSpeedListener);
}
}
private static class DelayFormater extends JFormattedTextField.AbstractFormatter {
private static final long serialVersionUID = 600115871763311301L;
private static final String prestr = "Delay: ";
private static final String poststr = " ms";
@Override
public Object stringToValue(String text) throws ParseException {
try {
return Integer.parseInt(text.replace(prestr, "").replace(poststr, ""));
} catch (NumberFormatException e) {
throw new ParseException(e.toString(), -1);
}
}
@Override
public String valueToString(Object value) throws ParseException {
return prestr + value + poststr;
}
}
@Override
public void settingsChanged(Settings source, SettingsInfo i) {
if (i.getChangedSetting().equals(Settings.SIMULATION_UNDO_ENABLED)) {
recordButton.setSelected(source.getBoolean(Settings.SIMULATION_UNDO_ENABLED));
updateStepBackButton();
}
if (i.getChangedSetting().equals(Settings.GRID_LOCK)) {
gridlockButton.setSelected(source.getBoolean(Settings.GRID_LOCK));
}
if (i.getChangedSetting().equals(Settings.SHOW_GRID)) {
showGridButton.setSelected(source.getBoolean(Settings.SHOW_GRID));
}
if (i.getChangedSetting().equals(Settings.REALTIME_VALIDATION)){
liveCheckButton.setSelected(source.getBoolean(Settings.REALTIME_VALIDATION));
}
}
private void updateStepBackButton() {
boolean enable;
Settings settings = view.getSessionModel().getSettings();
CommandDispatcher disp = view.getSessionModel().getCurrentSimulationCommandDispatcher();
enable = settings.getBoolean(Settings.SIMULATION_UNDO_ENABLED);
if (disp != null) {
enable = enable && disp.canStepBack();
}
stepBackButton.setEnabled(enable);
}
@Override
public void simulationModelChanged(Simulation source, SimulationModelInfo i) {
updateStepBackButton();
}
}