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