1 package net.mograsim.plugin.editors;
3 import java.io.ByteArrayInputStream;
4 import java.util.Optional;
6 import org.eclipse.core.resources.IFile;
7 import org.eclipse.core.runtime.CoreException;
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.jface.util.SafeRunnable;
10 import org.eclipse.swt.SWT;
11 import org.eclipse.swt.events.MouseEvent;
12 import org.eclipse.swt.events.MouseTrackListener;
13 import org.eclipse.swt.layout.GridData;
14 import org.eclipse.swt.layout.GridLayout;
15 import org.eclipse.swt.widgets.Button;
16 import org.eclipse.swt.widgets.Composite;
17 import org.eclipse.swt.widgets.Display;
18 import org.eclipse.swt.widgets.Label;
19 import org.eclipse.swt.widgets.Slider;
20 import org.eclipse.ui.IEditorInput;
21 import org.eclipse.ui.IEditorSite;
22 import org.eclipse.ui.IFileEditorInput;
23 import org.eclipse.ui.PartInitException;
24 import org.eclipse.ui.part.EditorPart;
26 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;
27 import net.mograsim.logic.core.LogicObserver;
28 import net.mograsim.logic.core.components.CoreClock;
29 import net.mograsim.logic.model.LogicExecuter;
30 import net.mograsim.logic.model.LogicUICanvas;
31 import net.mograsim.machine.Machine;
32 import net.mograsim.plugin.nature.MachineContext;
33 import net.mograsim.plugin.nature.ProjectMachineContext;
35 //TODO what if we open multiple editors?
36 //TODO actually save / load register and latch states
37 public class SimulationViewEditor extends EditorPart
39 private MachineContext context;
41 private LogicExecuter exec;
42 private Machine machine;
44 private Composite parent;
45 private Button sbseButton;
46 private Button pauseButton;
47 private Slider simSpeedSlider;
48 private LogicUICanvas canvas;
49 private Label noMachineLabel;
52 public void createPartControl(Composite parent)
56 parent.setLayout(new GridLayout());
58 noMachineLabel = new Label(parent, SWT.NONE);
59 noMachineLabel.setText("No machine present...");// TODO internationalize?
60 addSimulationControlWidgets(parent);
61 recreateContextDependentControls();
64 private void recreateContextDependentControls()
67 // createPartControls has not been called yet
73 exec.stopLiveExecution();
75 Optional<Machine> machineOptional;
76 if (context != null && (machineOptional = context.getActiveMachine()).isPresent())
78 noMachineLabel.setVisible(false);
79 sbseButton.setEnabled(true);
80 pauseButton.setEnabled(true);
81 simSpeedSlider.setEnabled(true);
82 machine = machineOptional.get();
83 canvas = new LogicUICanvas(parent, SWT.NONE, machine.getModel());
84 ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas);
85 userInput.buttonDrag = 3;
86 userInput.buttonZoom = 2;
87 userInput.enableUserInput();
89 GridData uiData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
90 canvas.setLayoutData(uiData);
92 // initialize executer
93 exec = new LogicExecuter(machine.getTimeline());
94 exec.startLiveExecution();
97 noMachineLabel.setVisible(true);
98 sbseButton.setEnabled(false);
99 pauseButton.setEnabled(false);
100 simSpeedSlider.setEnabled(false);
104 private void addSimulationControlWidgets(Composite parent)
106 Composite c = new Composite(parent, SWT.NONE);
107 c.setLayout(new GridLayout(7, false));
109 sbseButton = new Button(c, SWT.CHECK);
110 pauseButton = new Button(c, SWT.TOGGLE);
111 LogicObserver clockObserver = o ->
113 if (((CoreClock) o).isOn())
115 exec.pauseLiveExecution();
116 if (!pauseButton.isDisposed())
117 Display.getDefault().asyncExec(() ->
119 if (!pauseButton.isDisposed())
120 pauseButton.setSelection(false);
121 setPauseText(pauseButton, false);
126 sbseButton.setText("Step by step execution");
127 sbseButton.addListener(SWT.Selection, e ->
129 CoreClock cl = machine.getClock();
130 if (sbseButton.getSelection())
131 cl.registerObserver(clockObserver);
133 cl.deregisterObserver(clockObserver);
135 sbseButton.setSelection(false);
137 pauseButton.setSelection(true);
138 setPauseText(pauseButton, false);
140 pauseButton.addListener(SWT.Selection, e ->
142 setPauseText(pauseButton, false);
143 if (pauseButton.getSelection())
145 exec.unpauseLiveExecution();
148 exec.pauseLiveExecution();
151 pauseButton.addMouseTrackListener(new MouseTrackListener()
154 public void mouseHover(MouseEvent e)
160 public void mouseExit(MouseEvent e)
162 setPauseText(pauseButton, false);
166 public void mouseEnter(MouseEvent e)
168 setPauseText(pauseButton, true);
172 Label speedLabel = new Label(c, SWT.NONE);
173 speedLabel.setText("Simulation Speed: ");
175 simSpeedSlider = new Slider(c, SWT.NONE);
176 simSpeedSlider.setMinimum(1);
177 simSpeedSlider.setMaximum(100 + simSpeedSlider.getThumb());
178 simSpeedSlider.setIncrement(1);
180 Label speedPercentageLabel = new Label(c, SWT.NONE);
181 speedPercentageLabel.setText("100%");
183 simSpeedSlider.addListener(SWT.Selection, e ->
185 int selection = simSpeedSlider.getSelection();
186 speedPercentageLabel.setText(selection + "%");
188 exec.setSpeedPercentage(simSpeedSlider.getSelection());
190 simSpeedSlider.setSelection(100);
192 c.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
196 private static void setPauseText(Button pauseButton, boolean hovered)
199 if (pauseButton.getSelection())
200 pauseButton.setText("Pause?");
202 pauseButton.setText("Resume?");
203 else if (pauseButton.getSelection())
204 pauseButton.setText("Running");
206 pauseButton.setText("Paused");
210 public void init(IEditorSite site, IEditorInput input) throws PartInitException
212 if (input instanceof IFileEditorInput)
214 IFileEditorInput fileInput = (IFileEditorInput) input;
215 context = ProjectMachineContext.getMachineContextOf(fileInput.getFile().getProject());
216 recreateContextDependentControls();
218 setPartName(fileInput.getName());
219 open(fileInput.getFile());
221 throw new IllegalArgumentException("SimulationViewEditor can only be used with Files");
228 public void doSave(IProgressMonitor monitor)
230 IEditorInput input = getEditorInput();
231 if (input instanceof IFileEditorInput)
232 SafeRunnable.getRunner().run(() -> save(((IFileEditorInput) input).getFile(), monitor));
234 throw new IllegalArgumentException("SimulationViewEditor can only be used with Files");
237 private void save(IFile file, IProgressMonitor monitor) throws CoreException
239 file.setContents(new ByteArrayInputStream("actual contents will go here".getBytes()), 0, monitor);
242 private void open(IFile file)
248 public void doSaveAs()
250 throw new UnsupportedOperationException();
254 public boolean isDirty()
260 public boolean isSaveAsAllowed()
266 public void setFocus()
272 public void dispose()
274 exec.stopLiveExecution();