Added Step by step execution to LogicUIPart
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / views / LogicUIPart.java
1 package net.mograsim.plugin.views;
2
3 import javax.inject.Inject;
4
5 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
6 import org.eclipse.swt.SWT;
7 import org.eclipse.swt.events.MouseEvent;
8 import org.eclipse.swt.events.MouseTrackListener;
9 import org.eclipse.swt.layout.GridData;
10 import org.eclipse.swt.layout.GridLayout;
11 import org.eclipse.swt.widgets.Button;
12 import org.eclipse.swt.widgets.Composite;
13 import org.eclipse.swt.widgets.Display;
14 import org.eclipse.swt.widgets.Label;
15 import org.eclipse.swt.widgets.Slider;
16 import org.eclipse.ui.PlatformUI;
17 import org.eclipse.ui.part.ViewPart;
18
19 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;
20 import net.mograsim.logic.core.LogicObserver;
21 import net.mograsim.logic.core.components.CoreClock;
22 import net.mograsim.logic.model.LogicExecuter;
23 import net.mograsim.logic.model.LogicUICanvas;
24 import net.mograsim.machine.Machine;
25 import net.mograsim.machine.mi.AssignableMicroInstructionMemory;
26 import net.mograsim.plugin.EclipsePreferences;
27 import net.mograsim.plugin.MachineContext;
28 import net.mograsim.plugin.MograsimActivator;
29 import net.mograsim.plugin.tables.DisplaySettings;
30 import net.mograsim.plugin.tables.mi.ActiveInstructionPreviewContentProvider;
31 import net.mograsim.plugin.tables.mi.InstructionTable;
32 import net.mograsim.preferences.Preferences;
33
34 public class LogicUIPart extends ViewPart
35 {
36         @Inject
37         private MPart part;
38
39         private LogicExecuter exec;
40         private LogicUICanvas ui;
41         private Machine m;
42
43         @Override
44         public void dispose()
45         {
46                 if (exec != null)
47                         exec.stopLiveExecution();
48         }
49
50         @Override
51         public void createPartControl(Composite parent)
52         {
53                 // set preferences
54                 Preferences.setPreferences(new EclipsePreferences(PlatformUI.getWorkbench().getThemeManager().getCurrentTheme(),
55                                 MograsimActivator.instance().getPreferenceStore()));
56
57                 m = MachineContext.getInstance().getMachine();
58
59                 // initialize UI
60                 GridLayout layout = new GridLayout(1, true);
61                 parent.setLayout(layout);
62
63                 addSimulationControlWidgets(parent);
64
65                 ui = new LogicUICanvas(parent, SWT.NONE, m.getModel());
66                 ui.addTransformListener((x, y, z) -> part.setDirty(z < 1));
67                 ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(ui);
68                 userInput.buttonDrag = 3;
69                 userInput.buttonZoom = 2;
70                 userInput.enableUserInput();
71
72                 GridData uiData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
73                 ui.setLayoutData(uiData);
74
75                 // initialize Instruction preview
76                 InstructionTable instPreview = new InstructionTable(parent, new DisplaySettings());
77                 instPreview.setContentProvider(new ActiveInstructionPreviewContentProvider(instPreview.getTableViewer()));
78                 AssignableMicroInstructionMemory mIMemory = m.getMicroInstructionMemory();
79                 instPreview.bindMicroInstructionMemory(mIMemory);
80                 mIMemory.registerCellModifiedListener(a -> instPreview.refresh());
81                 mIMemory.registerMemoryReassignedListener(n -> instPreview.refresh());
82
83                 GridData previewData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
84                 instPreview.getTableViewer().getTable().setLayoutData(previewData);
85
86                 // initialize executer
87                 exec = new LogicExecuter(m.getTimeline());
88
89                 // run it
90                 exec.startLiveExecution();
91         }
92
93         private void addSimulationControlWidgets(Composite parent)
94         {
95                 Composite c = new Composite(parent, SWT.NONE);
96                 c.setLayout(new GridLayout(5, false));
97                 Button sbseButton = new Button(c, SWT.CHECK);
98                 Button pauseButton = new Button(c, SWT.TOGGLE);
99
100                 LogicObserver clockObserver = o ->
101                 {
102                         if (((CoreClock) o).isOn())
103                         {
104                                 exec.pauseLiveExecution();
105                                 Display.getDefault().asyncExec(() ->
106                                 {
107                                         pauseButton.setSelection(false);
108                                         setPauseText(pauseButton, false);
109                                 });
110                         }
111                 };
112
113                 sbseButton.addListener(SWT.Selection, e ->
114                 {
115                         String statusString = "disabled";
116                         CoreClock cl = m.getClock();
117                         if (sbseButton.getSelection())
118                         {
119                                 cl.registerObserver(clockObserver);
120                                 statusString = "enabled";
121                         } else
122                                 cl.deregisterObserver(clockObserver);
123                         sbseButton.setToolTipText(String.format("Step by step execution: %s", statusString));
124                 });
125                 sbseButton.setSelection(false);
126
127                 pauseButton.setSelection(true);
128                 setPauseText(pauseButton, false);
129
130                 pauseButton.addListener(SWT.Selection, e ->
131                 {
132                         if (pauseButton.getSelection())
133                         {
134                                 exec.unpauseLiveExecution();
135                         } else
136                         {
137                                 exec.pauseLiveExecution();
138                         }
139                 });
140
141                 pauseButton.addMouseTrackListener(new MouseTrackListener()
142                 {
143                         @Override
144                         public void mouseHover(MouseEvent e)
145                         {
146                                 // nothing
147                         }
148
149                         @Override
150                         public void mouseExit(MouseEvent e)
151                         {
152                                 setPauseText(pauseButton, false);
153                         }
154
155                         @Override
156                         public void mouseEnter(MouseEvent e)
157                         {
158                                 setPauseText(pauseButton, true);
159                         }
160                 });
161
162                 Label speedLabel = new Label(c, SWT.NONE);
163                 speedLabel.setText("Simulation Speed: ");
164
165                 Slider slider = new Slider(c, SWT.NONE);
166                 slider.setMinimum(1);
167                 slider.setMaximum(100 + slider.getThumb());
168                 slider.setIncrement(1);
169
170                 Label speedPercentageLabel = new Label(c, SWT.NONE);
171                 speedPercentageLabel.setText("100%");
172
173                 slider.addListener(SWT.Selection, e ->
174                 {
175                         int selection = slider.getSelection();
176                         speedPercentageLabel.setText(selection + "%");
177
178                         exec.setSpeedPercentage(slider.getSelection());
179                 });
180                 slider.setSelection(100);
181
182                 c.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
183                 c.pack();
184                 c.setVisible(true);
185         }
186
187         private static void setPauseText(Button pauseButton, boolean hovered)
188         {
189                 if (hovered)
190                 {
191                         if (pauseButton.getSelection())
192                         {
193                                 pauseButton.setText("Pause?");
194                         } else
195                         {
196                                 pauseButton.setText("Resume?");
197                         }
198                 } else
199                 {
200                         if (pauseButton.getSelection())
201                         {
202                                 pauseButton.setText("Running");
203                         } else
204                         {
205                                 pauseButton.setText("Paused");
206                         }
207                 }
208         }
209
210         @Override
211         public void setFocus()
212         {
213                 ui.setFocus();
214         }
215 }