import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
provider = new MemoryTableContentProvider();
displaySettings = new DisplaySettings();
- parent.setLayout(new GridLayout(7, false));
-
+ parent.setLayout(new GridLayout(8, false));
createHeader(parent);
createViewer(parent);
@SuppressWarnings("unused") // RadixSelector and exceptions
private void createHeader(Composite parent)
{
- Label fromLabel = new Label(parent, SWT.NONE);
- fromLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
- fromLabel.setText("Address: ");
-
- Text fromText = new Text(parent, SWT.BORDER);
- fromText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ Text gotoText = new Text(parent, SWT.BORDER);
+ gotoText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
NumberVerifyListener vl = new NumberVerifyListener();
- fromText.addVerifyListener(vl);
- fromText.setText("0");
- fromText.addModifyListener(e ->
+ gotoText.addVerifyListener(vl);
+ gotoText.setText("0");
+
+ Runnable gotoAction = () ->
{
try
{
- provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
- viewer.refresh();
+ loadAround((int) (AsmNumberUtil.valueOf(gotoText.getText()).longValue() - provider.getLowerBound()));
+ viewer.getTable().deselectAll();
}
catch (NumberFormatException x)
{
// Nothing to do here
}
+ };
+
+ gotoText.addTraverseListener((e) ->
+ {
+ if (e.detail == SWT.TRAVERSE_RETURN)
+ gotoAction.run();
});
- Label amountLabel = new Label(parent, SWT.NONE);
- amountLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
- amountLabel.setText("Number of cells: ");
- Text amountText = new Text(parent, SWT.BORDER);
- amountText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- amountText.addVerifyListener(vl);
- amountText.addModifyListener(e ->
+
+ Button gotoButton = new Button(parent, SWT.PUSH);
+ gotoButton.setText("Go to");
+ gotoButton.addListener(SWT.Selection, e ->
{
- try
- {
- if (provider != null)
- provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
- if (viewer != null)
- viewer.refresh();
- }
- catch (NumberFormatException x)
- {
- // Nothing to do here
- }
+ gotoAction.run();
});
- amountText.setText("100");// do this after registering the ModifyListener
+
+ new Label(parent, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
new RadixSelector(parent, displaySettings);
}
table.setLinesVisible(true);
viewer.setUseHashlookup(true);
viewer.setContentProvider(provider);
- getSite().setSelectionProvider(viewer);// TODO what does this do?
- viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 7, 1));
+ getSite().setSelectionProvider(viewer);
+ viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 8, 1));
+
+ // TODO: Also support keyboard inputs for flexible scrolling
+ ScrollBar vBar = table.getVerticalBar();
+ vBar.addListener(SWT.Selection, (e) ->
+ {
+ int sel;
+ if ((sel = vBar.getSelection()) < vBar.getMinimum() + vBar.getThumb() * 2 || sel > vBar.getMaximum() - vBar.getThumb() * 2)
+ {
+ loadAround(table.getTopIndex());
+ table.deselectAll();
+ }
+ });
IThemeManager themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
themeManager.addPropertyChangeListener(fontChangeListener = (e) ->
fontDependent.forEach(c -> c.setFont(newFont));
}
+ private void loadAround(int row)
+ {
+ long prevLb = provider.getLowerBound();
+ long address = prevLb + row;
+ long actualLb = Long.max(address - MemoryTableContentProvider.MAX_VISIBLE_ROWS / 2, memory.getDefinition().getMinimalAddress());
+
+ long prevHb = provider.getUpperBound();
+ // +- 1 row is not really important
+ long actualHb = Long.min(address + MemoryTableContentProvider.MAX_VISIBLE_ROWS / 2, memory.getDefinition().getMaximalAddress());
+
+ if (actualLb != prevLb || actualHb != prevHb)
+ {
+ Table table = viewer.getTable();
+ provider.setBounds(actualLb, actualHb);
+ int rowIndex = (int) (address - actualLb);
+ if (rowIndex >= 0 && rowIndex < table.getItemCount())
+ table.showItem(table.getItem(rowIndex));
+ viewer.refresh();
+ }
+ }
+
private void createColumns()
{
TableViewerColumn addrCol = createTableViewerColumn("Address", 100);
import org.eclipse.swt.widgets.Display;
import net.mograsim.machine.MainMemory;
+import net.mograsim.machine.MainMemoryDefinition;
import net.mograsim.machine.Memory.MemoryCellModifiedListener;
public class MemoryTableContentProvider implements ILazyContentProvider, MemoryCellModifiedListener
{
- private long lower;
+ private long lower, upper;
private TableViewer viewer;
- private final static int limit = 10_000;
- private int amount = 0;
+ public final static int MAX_VISIBLE_ROWS = 1_000;
private MainMemory memory;
- public void setLowerBound(long lower)
+ public void setBounds(long lower, long upper)
{
if (memory != null)
- this.lower = Long.min(memory.getDefinition().getMaximalAddress(), Long.max(memory.getDefinition().getMinimalAddress(), lower));
- else
+ {
+ MainMemoryDefinition definition = memory.getDefinition();
+ this.lower = Long.min(definition.getMaximalAddress(), Long.max(definition.getMinimalAddress(), lower));
+ this.upper = Long.max(this.lower, Long.min(definition.getMaximalAddress(), upper));
+ } else
+ {
this.lower = lower;
+ this.upper = Long.max(this.lower, upper);
+ }
updateItemCount();
}
public void updateItemCount()
{
if (viewer != null)
- if (memory != null)
- {
- long size = memory.getDefinition().getMaximalAddress() - lower;
- viewer.setItemCount(size > amount ? amount : (int) size);
- } else
- viewer.setItemCount(0);
+ viewer.setItemCount(getAmount());
}
public long getLowerBound()
return lower;
}
- public void setAmount(int amount)
+ public long getUpperBound()
{
- this.amount = Integer.min(amount, limit);
- updateItemCount();
+ return upper;
}
public int getAmount()
{
- return amount;
+ return (int) (upper - lower);
}
@Override
public void updateElement(int index)
{
- if (index < amount)
+ if (index < getAmount())
{
long address = lower + index;
if (address <= memory.getDefinition().getMaximalAddress())
((MainMemory) oldInput).deregisterCellModifiedListener(this);
if (memory != null)
memory.registerCellModifiedListener(this);
- setLowerBound(0L);
+ setBounds(0, MAX_VISIBLE_ROWS);
}
@Override