323 lines
8.9 KiB
Java
323 lines
8.9 KiB
Java
package edu.fichte.pbi.ide.views;
|
|
|
|
import java.io.File;
|
|
|
|
import org.eclipse.swt.custom.CLabel;
|
|
import org.eclipse.swt.custom.StackLayout;
|
|
import org.eclipse.swt.events.SelectionAdapter;
|
|
import org.eclipse.swt.events.SelectionEvent;
|
|
import org.eclipse.swt.graphics.Image;
|
|
import org.eclipse.swt.layout.GridLayout;
|
|
import org.eclipse.swt.widgets.Button;
|
|
import org.eclipse.swt.widgets.Composite;
|
|
import org.eclipse.swt.widgets.Display;
|
|
import org.eclipse.swt.widgets.Label;
|
|
import org.eclipse.ui.part.ViewPart;
|
|
import org.osgi.framework.Bundle;
|
|
|
|
import edu.fichte.pbi.ide.Activator;
|
|
import edu.fichte.pbi.util.CallbackVariableListener;
|
|
import edu.fichte.pbi.vm.IRunWatcher;
|
|
import edu.fichte.pbi.vm.Machine;
|
|
import edu.fichte.pbi.vm.var.IVariable;
|
|
|
|
public class DebugView extends ViewPart implements IRunWatcher {
|
|
|
|
public static String ID = "edu.fichte.pbi.ide.debugView";
|
|
|
|
private Machine machine;
|
|
|
|
//GUI elements
|
|
private Label[] label = new Label[8];
|
|
private CLabel[] labelInOut = new CLabel[8];
|
|
private CLabel[] labelHighLow = new CLabel[8];
|
|
private Button[] buttonHighLow = new Button[8];
|
|
private Composite[] widgetPin = new Composite[8];
|
|
private StackLayout[] stackLayout = new StackLayout[8];
|
|
|
|
//load icons
|
|
private Image imageHigh = loadIcon("status_red.gif");
|
|
private Image imageLow = loadIcon("status_black.gif");
|
|
|
|
private Image imageInput = loadIcon("InputArrowSmall.gif");
|
|
private Image imageOutput = loadIcon("OutputArrowSmall.gif");
|
|
|
|
|
|
|
|
@Override
|
|
public void createPartControl(Composite parent) {
|
|
//create layout Parent with GridLayout
|
|
Composite layoutParent = new Composite(parent, 0);
|
|
layoutParent.setLayout(new GridLayout(3, true));
|
|
|
|
//create Labels
|
|
Label pin = new Label(layoutParent, 0);
|
|
pin.setText("PIN");
|
|
Label io = new Label(layoutParent, 0);
|
|
io.setText("I/O");
|
|
Label hl = new Label(layoutParent, 0);
|
|
hl.setText("High/Low");
|
|
|
|
for (int i = widgetPin.length - 1; i >= 0; i--) {
|
|
//first column: Pin Label
|
|
label[i] = new Label(layoutParent, 0);
|
|
label[i].setText("P" + String.valueOf(i));
|
|
|
|
//second column: Pin direction (Input/Output)
|
|
labelInOut[i] = new CLabel(layoutParent, 0);
|
|
labelInOut[i].setText("Input");
|
|
labelInOut[i].setImage(imageInput);
|
|
//default is input, see:
|
|
//(http://www.parallax.com/go/PBASICHelp/Content\
|
|
///LanguageTopics/Commands/INPUT.htm -> Explanation)
|
|
|
|
//third column: Pin state (High/Low)
|
|
//changes between CLabel and Button, depending on if an
|
|
//input is accepted or not (uses StackLayout for that)
|
|
stackLayout[i] = new StackLayout();
|
|
//create new composite in which stackLayout is active
|
|
widgetPin[i] = new Composite(layoutParent, 0);
|
|
widgetPin[i].setLayout(stackLayout[i]);
|
|
//create first "page" of stackLayout: label (if pin is output)
|
|
labelHighLow[i] = new CLabel(widgetPin[i], 0);
|
|
labelHighLow[i].setText("Low");
|
|
labelHighLow[i].setImage(imageLow);
|
|
labelHighLow[i].pack();
|
|
//create second "page" of stackLayout: button (if pin is input)
|
|
buttonHighLow[i] = new Button(widgetPin[i], 0);
|
|
buttonHighLow[i].setText("Low");
|
|
buttonHighLow[i].setImage(imageLow);
|
|
buttonHighLow[i].pack();
|
|
//show second "page" first as pin is initialized as input pin
|
|
stackLayout[i].topControl = buttonHighLow[i];
|
|
//actions listeners are defined outside of the loop
|
|
}
|
|
//action listeners as you are not allowed to use
|
|
//non-final variables in an inner class
|
|
buttonHighLow[0].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(0);
|
|
}
|
|
});
|
|
buttonHighLow[1].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(1);
|
|
}
|
|
});
|
|
buttonHighLow[2].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(2);
|
|
}
|
|
});
|
|
buttonHighLow[3].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(3);
|
|
}
|
|
});
|
|
buttonHighLow[4].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(4);
|
|
}
|
|
});
|
|
buttonHighLow[5].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(5);
|
|
}
|
|
});
|
|
buttonHighLow[6].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(6);
|
|
}
|
|
});
|
|
buttonHighLow[7].addSelectionListener(new SelectionAdapter() {
|
|
|
|
@Override
|
|
public void widgetSelected(SelectionEvent arg0) {
|
|
toggleVariable(7);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void setFocus() {
|
|
|
|
}
|
|
|
|
private void toggleVariable(int varNum) {
|
|
IVariable variable = machine.parseIVariable("PIN" + varNum);
|
|
long value = variable.getValue();
|
|
if (value == 0) {
|
|
value = 1;
|
|
} else {
|
|
value = 0;
|
|
}
|
|
variable.setValue(value);
|
|
}
|
|
|
|
public void setMachine(Machine machine) {
|
|
this.machine = machine;
|
|
|
|
IVariable[] listener = new IVariable[labelHighLow.length];
|
|
for (int i = 0; i < labelHighLow.length; i++) {
|
|
listener[i] = this.machine.parseIVariable("PIN" + String.valueOf(i));
|
|
listener[i].setVariableListener(
|
|
new CallbackVariableListener(
|
|
new PinCommObject(labelHighLow[i], buttonHighLow[i])) {
|
|
|
|
@Override
|
|
public void variableChanged(IVariable variable) {
|
|
final long value = variable.getValue();
|
|
final boolean[] newState = new boolean[1];
|
|
if (value == 1) {
|
|
newState[0] = true;
|
|
}
|
|
getSite().getShell().getDisplay().syncExec(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
PinCommObject obj = (PinCommObject) callback;
|
|
if (newState[0]) {
|
|
obj.label.setText("High");
|
|
obj.label.setImage(imageHigh);
|
|
obj.button.setText("High");
|
|
obj.button.setImage(imageHigh);
|
|
} else {
|
|
obj.label.setText("Low");
|
|
obj.label.setImage(imageLow);
|
|
obj.button.setText("Low");
|
|
obj.button.setImage(imageLow);
|
|
}
|
|
}
|
|
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
IVariable[] dirListener = new IVariable[labelInOut.length];
|
|
for (int i = 0; i < labelInOut.length; i++) {
|
|
dirListener[i] = this.machine.parseIVariable("DIR"
|
|
+ String.valueOf(i));
|
|
dirListener[i].setVariableListener(
|
|
new CallbackVariableListener(
|
|
new DirCommObject(
|
|
labelInOut[i],
|
|
labelHighLow[i],
|
|
buttonHighLow[i],
|
|
stackLayout[i],
|
|
widgetPin[i])) {
|
|
|
|
@Override
|
|
public void variableChanged(IVariable variable) {
|
|
final long value = variable.getValue();
|
|
final boolean[] newState = new boolean[1];
|
|
if (value == 1) {
|
|
newState[0] = true;
|
|
}
|
|
getSite().getShell().getDisplay().syncExec(
|
|
new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
DirCommObject obj = (DirCommObject) callback;
|
|
if (newState[0]) {
|
|
obj.labelDir.setText("Output");
|
|
obj.labelDir.pack();
|
|
obj.labelDir.setImage(imageOutput);
|
|
obj.labelState.setVisible(true);
|
|
obj.buttonState.setVisible(false);
|
|
obj.stackLayout.topControl = obj.labelState;
|
|
} else {
|
|
obj.labelDir.setText("Input");
|
|
obj.labelDir.pack();
|
|
obj.labelDir.setImage(imageInput);
|
|
obj.labelState.setVisible(false);
|
|
obj.buttonState.setVisible(true);
|
|
obj.stackLayout.topControl = obj.buttonState;
|
|
}
|
|
obj.widgetPin.layout();
|
|
}
|
|
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private static Image loadIcon(String iconFilename) {
|
|
Bundle bundle = Activator.getDefault().getBundle();
|
|
File targetRoot = bundle.getDataFile("");
|
|
|
|
File file = new File(targetRoot, "icons/" + iconFilename);
|
|
if (!file.canRead()) {
|
|
HelpView.copyPathFromBundleToFSRecursive(bundle, "icons",
|
|
targetRoot);
|
|
}
|
|
return new Image(Display.getCurrent(), file.getAbsolutePath());
|
|
}
|
|
|
|
public void lockPinState() {
|
|
for (int i = 0; i < buttonHighLow.length; i++) {
|
|
buttonHighLow[i].setEnabled(false);
|
|
}
|
|
}
|
|
|
|
public void unlockPinState() {
|
|
for (int i = 0; i < buttonHighLow.length; i++) {
|
|
buttonHighLow[i].setEnabled(true);
|
|
}
|
|
}
|
|
|
|
private class PinCommObject {
|
|
|
|
protected CLabel label;
|
|
|
|
protected Button button;
|
|
|
|
private PinCommObject(CLabel label, Button button) {
|
|
this.label = label;
|
|
this.button = button;
|
|
}
|
|
}
|
|
|
|
private class DirCommObject {
|
|
|
|
protected CLabel labelDir;
|
|
|
|
protected CLabel labelState;
|
|
|
|
protected Button buttonState;
|
|
|
|
protected StackLayout stackLayout;
|
|
|
|
protected Composite widgetPin;
|
|
|
|
private DirCommObject(
|
|
CLabel labelDir,
|
|
CLabel labelState,
|
|
Button buttonState,
|
|
StackLayout stackLayout,
|
|
Composite widgetPin) {
|
|
this.labelDir = labelDir;
|
|
this.labelState = labelState;
|
|
this.buttonState = buttonState;
|
|
this.stackLayout = stackLayout;
|
|
this.widgetPin = widgetPin;
|
|
}
|
|
|
|
}
|
|
|
|
}
|