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 LogicUICanvas canvas;
46 private Label noMachineLabel;
49 public void createPartControl(Composite parent)
53 parent.setLayout(new GridLayout());
55 noMachineLabel = new Label(parent, SWT.NONE);
56 noMachineLabel.setText("No machine present...");// TODO internationalize?
57 addSimulationControlWidgets(parent);
58 recreateContextDependentControls();
61 private void recreateContextDependentControls()
64 // createPartControls has not been called yet
70 exec.stopLiveExecution();
72 Optional<Machine> machineOptional;
73 if (context != null && (machineOptional = context.getActiveMachine()).isPresent())
75 noMachineLabel.setVisible(false);
76 machine = machineOptional.get();
77 canvas = new LogicUICanvas(parent, SWT.NONE, machine.getModel());
78 ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas);
79 userInput.buttonDrag = 3;
80 userInput.buttonZoom = 2;
81 userInput.enableUserInput();
83 GridData uiData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
84 canvas.setLayoutData(uiData);
86 // initialize executer
87 exec = new LogicExecuter(machine.getTimeline());
88 exec.startLiveExecution();
90 noMachineLabel.setVisible(true);
93 private void addSimulationControlWidgets(Composite parent)
95 Composite c = new Composite(parent, SWT.NONE);
96 c.setLayout(new GridLayout(7, false));
98 Button sbseButton = new Button(c, SWT.CHECK);
99 Button pauseButton = new Button(c, SWT.TOGGLE);
100 LogicObserver clockObserver = o ->
102 if (((CoreClock) o).isOn())
104 exec.pauseLiveExecution();
105 Display.getDefault().asyncExec(() ->
107 pauseButton.setSelection(false);
108 setPauseText(pauseButton, false);
113 sbseButton.addListener(SWT.Selection, e ->
115 String statusString = "disabled";
116 CoreClock cl = machine.getClock();
117 if (sbseButton.getSelection())
119 cl.registerObserver(clockObserver);
120 statusString = "enabled";
122 cl.deregisterObserver(clockObserver);
123 sbseButton.setToolTipText(String.format("Step by step execution: %s", statusString));
125 sbseButton.setSelection(false);
127 pauseButton.setSelection(true);
128 setPauseText(pauseButton, false);
130 pauseButton.addListener(SWT.Selection, e ->
132 setPauseText(pauseButton, false);
133 if (pauseButton.getSelection())
135 exec.unpauseLiveExecution();
138 exec.pauseLiveExecution();
141 pauseButton.addMouseTrackListener(new MouseTrackListener()
144 public void mouseHover(MouseEvent e)
150 public void mouseExit(MouseEvent e)
152 setPauseText(pauseButton, false);
156 public void mouseEnter(MouseEvent e)
158 setPauseText(pauseButton, true);
162 Label speedLabel = new Label(c, SWT.NONE);
163 speedLabel.setText("Simulation Speed: ");
165 Slider slider = new Slider(c, SWT.NONE);
166 slider.setMinimum(1);
167 slider.setMaximum(100 + slider.getThumb());
168 slider.setIncrement(1);
170 Label speedPercentageLabel = new Label(c, SWT.NONE);
171 speedPercentageLabel.setText("100%");
173 slider.addListener(SWT.Selection, e ->
175 int selection = slider.getSelection();
176 speedPercentageLabel.setText(selection + "%");
178 exec.setSpeedPercentage(slider.getSelection());
180 slider.setSelection(100);
182 c.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
187 private static void setPauseText(Button pauseButton, boolean hovered)
190 if (pauseButton.getSelection())
191 pauseButton.setText("Pause?");
193 pauseButton.setText("Resume?");
194 else if (pauseButton.getSelection())
195 pauseButton.setText("Running");
197 pauseButton.setText("Paused");
201 public void init(IEditorSite site, IEditorInput input) throws PartInitException
203 if (input instanceof IFileEditorInput)
205 IFileEditorInput fileInput = (IFileEditorInput) input;
206 context = ProjectMachineContext.getMachineContextOf(fileInput.getFile().getProject());
207 recreateContextDependentControls();
209 setPartName(fileInput.getName());
210 open(fileInput.getFile());
212 throw new IllegalArgumentException("SimulationViewEditor can only be used with Files");
219 public void doSave(IProgressMonitor monitor)
221 IEditorInput input = getEditorInput();
222 if (input instanceof IFileEditorInput)
223 SafeRunnable.getRunner().run(() -> save(((IFileEditorInput) input).getFile(), monitor));
225 throw new IllegalArgumentException("SimulationViewEditor can only be used with Files");
228 private void save(IFile file, IProgressMonitor monitor) throws CoreException
230 file.setContents(new ByteArrayInputStream("actual contents will go here".getBytes()), 0, monitor);
233 private void open(IFile file)
239 public void doSaveAs()
241 throw new UnsupportedOperationException();
245 public boolean isDirty()
251 public boolean isSaveAsAllowed()
257 public void setFocus()
263 public void dispose()
265 exec.stopLiveExecution();