ef685f4c8a57370c245bd39df7940ea058b6518a
[Mograsim.git] / net.mograsim.plugin.core / src / net / mograsim / plugin / tables / memory / MemoryView.java
1 package net.mograsim.plugin.tables.memory;
2
3 import java.math.BigInteger;
4 import java.util.Optional;
5
6 import org.eclipse.jface.viewers.ColumnLabelProvider;
7 import org.eclipse.jface.viewers.TableViewer;
8 import org.eclipse.jface.viewers.TableViewerColumn;
9 import org.eclipse.swt.SWT;
10 import org.eclipse.swt.events.VerifyListener;
11 import org.eclipse.swt.layout.GridData;
12 import org.eclipse.swt.layout.GridLayout;
13 import org.eclipse.swt.widgets.Composite;
14 import org.eclipse.swt.widgets.Label;
15 import org.eclipse.swt.widgets.Table;
16 import org.eclipse.swt.widgets.TableColumn;
17 import org.eclipse.swt.widgets.Text;
18 import org.eclipse.ui.part.ViewPart;
19
20 import net.mograsim.machine.Machine;
21 import net.mograsim.machine.MainMemory;
22 import net.mograsim.machine.MainMemoryDefinition;
23 import net.mograsim.machine.standard.memory.WordAddressableMemory;
24 import net.mograsim.plugin.MachineContext;
25 import net.mograsim.plugin.MachineContext.ContextObserver;
26 import net.mograsim.plugin.asm.AsmNumberUtil;
27 import net.mograsim.plugin.tables.DisplaySettings;
28 import net.mograsim.plugin.tables.NumberColumnLabelProvider;
29 import net.mograsim.plugin.tables.RadixSelector;
30
31 public class MemoryView extends ViewPart implements ContextObserver
32 {
33         private TableViewer viewer;
34         private MemoryTableContentProvider provider;
35         private DisplaySettings displaySettings;
36         private String addressFormat;
37
38         @Override
39         public void createPartControl(Composite parent)
40         {
41                 provider = new MemoryTableContentProvider();
42                 displaySettings = new DisplaySettings();
43
44                 GridLayout layout = new GridLayout(6, false);
45                 parent.setLayout(layout);
46
47                 createHeader(parent);
48                 createViewer(parent);
49
50                 displaySettings.addObserver(() -> viewer.refresh());
51
52                 setupContextBinding();
53         }
54
55         @SuppressWarnings("unused")
56         private void createHeader(Composite parent)
57         {
58                 Label fromLabel = new Label(parent, SWT.NONE);
59                 fromLabel.setText("Address: ");
60                 Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
61                 fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
62                 VerifyListener vl = new NumberVerifyListener();
63                 fromText.addVerifyListener(vl);
64                 fromText.setText("0");
65                 fromText.addModifyListener(e ->
66                 {
67                         try
68                         {
69                                 provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
70                                 viewer.refresh();
71                         }
72                         catch (NumberFormatException ex)
73                         {
74                                 // Nothing to do here
75                         }
76                 });
77
78                 Label amountLabel = new Label(parent, SWT.NONE);
79                 amountLabel.setText("Number of cells: ");
80                 Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
81                 amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
82                 amountText.addVerifyListener(vl);
83                 amountText.setText("0");
84                 amountText.addModifyListener(e ->
85                 {
86                         try
87                         {
88                                 provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
89                                 viewer.refresh();
90                         }
91                         catch (NumberFormatException ex)
92                         {
93                                 // Nothing to do here
94                         }
95                 });
96                 new RadixSelector(parent, displaySettings);
97         }
98
99         private void createViewer(Composite parent)
100         {
101                 viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
102                 createColumns();
103                 Table table = viewer.getTable();
104                 table.setHeaderVisible(true);
105                 table.setLinesVisible(true);
106                 viewer.setUseHashlookup(true);
107                 viewer.setContentProvider(provider);
108                 bindMainMemory(new WordAddressableMemory(MainMemoryDefinition.create(8, 8, 8L, Long.MAX_VALUE)));
109                 getSite().setSelectionProvider(viewer);
110
111                 GridData gd = new GridData();
112                 gd.verticalAlignment = GridData.FILL;
113                 gd.horizontalSpan = 6;
114                 gd.grabExcessHorizontalSpace = true;
115                 gd.grabExcessVerticalSpace = true;
116                 gd.horizontalAlignment = GridData.FILL;
117                 viewer.getControl().setLayoutData(gd);
118         }
119
120         private void createColumns()
121         {
122                 String[] titles = { "Address", "Data" };
123                 int[] bounds = { 100, 100 };
124
125                 TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
126                 col.setLabelProvider(new ColumnLabelProvider()
127                 {
128                         @Override
129                         public String getText(Object element)
130                         {
131                                 MemoryTableRow row = (MemoryTableRow) element;
132                                 return String.format(addressFormat, row.address);
133                         }
134                 });
135
136                 col = createTableViewerColumn(titles[1], bounds[1]);
137                 col.setLabelProvider(new NumberColumnLabelProvider(displaySettings)
138                 {
139                         @Override
140                         public BigInteger getAsBigInteger(Object element)
141                         {
142                                 MemoryTableRow row = (MemoryTableRow) element;
143                                 return row.getMemory().getCellAsBigInteger(row.address);
144                         }
145
146                 });
147                 col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
148         }
149
150         private TableViewerColumn createTableViewerColumn(String title, int bound)
151         {
152                 TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
153                 TableColumn column = viewerColumn.getColumn();
154                 column.setText(title);
155                 column.setWidth(bound);
156                 column.setResizable(true);
157                 column.setMoveable(false);
158                 return viewerColumn;
159         }
160
161         @Override
162         public void setFocus()
163         {
164                 viewer.getControl().setFocus();
165         }
166
167         private void bindMainMemory(MainMemory m)
168         {
169                 int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
170                 addressFormat = "0x%0" + hexAddressLength + "X";
171                 viewer.setInput(m);
172         }
173
174         private void setupContextBinding()
175         {
176                 MachineContext.getInstance().registerObserver(this);
177         }
178
179         @Override
180         public void setMachine(Optional<Machine> machine)
181         {
182                 if (machine.isPresent())
183                         bindMainMemory(machine.get().getMainMemory());
184         }
185 }