package com.alibaba.luaview.debugger.ui;
/**
* AWT Sample application
*
* @author
* @version 1.00 05/09/22
*/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import com.alibaba.luaview.debugger.Center;
import com.alibaba.luaview.debugger.ClientCmd;
// 类的作用:树结构的浏览器
/**
*
* @author dongxicheng
*
*/
public final class SrcCodeViewer extends SrcCodeScrollPanel {
private static final long serialVersionUID = -196018687886621L;
private static final Color currentLineColor = new Color(221, 234, 207);
private static final Color breakPointBGColor = null;
// new Color(251, 238, 235);
public boolean canBreakPoint = true;
public final String fileName;
private final Vector<Line> lines = new Vector<Line>();
private FontMetrics fontMetrics;
private Center center;
private Font font16 = new Font("黑体", Font.PLAIN, 13);
private Font font12 = new Font("黑体", Font.PLAIN, 10);
SrcCodeViewer(String fileName, String content, Center center) {
super();
this.center = center;
this.setFont(font16);
fontMetrics = getFontMetrics(getFont());
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent arg0) {
if (arg0.getKeyCode() == KeyEvent.VK_W) {
} else if (arg0.getKeyCode() == KeyEvent.VK_S) {
} else if (arg0.getKeyCode() == KeyEvent.VK_A) {
} else if (arg0.getKeyCode() == KeyEvent.VK_D) {
}
updateUI();
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
});
this.fileName = fileName;
this.setFileSting(content);
int len = (this.lines.size() + "").length();
if (len < 2) {
len = 2;
}
this.X0_TAG = (int) (LINE_H * 0.5) * len;
this.X0 = this.X0_TAG + LINE_H;
}
private void setFileSting(String s) {
this.lines.removeAllElements();
String[] arr = s.split("\n");
for (int i = 0; i < arr.length; i++) {
Line line = new Line(arr[i]);
line.index = i + 1;// 设置行号
this.lines.add(line);
}
}
private final int X0_TAG;// LINE_H * 5 / 2;
private final int X0;// LINE_H * 5 / 2;
private final int Y0 = LINE_H * 2;
public void myPaint(Graphics2D g) {
g.setColor(new Color(0xf0f0f0));
{
int h = (this.lines.size() + 5) * LINE_H;
if (h < this.getHeight()) {
h = this.getHeight();
}
g.fillRect(0, 0, X0, h);
g.setColor(new Color(217, 217, 217));
g.drawLine(X0, 0, X0, h);
}
resetMaxWH();
try {
setNodeX(X0);
setNodeY(Y0);
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < this.lines.size(); i++) {
Line line = this.lines.elementAt(i);
line.tag = "" + (i + 1);
drawOneLine(true, line, g, line.x, line.y);
}
this.clearPoint();
}
BasicStroke stroke = new BasicStroke(1);
/**
* 显示root
*
* @param line
* @param g
* @param topX
* @param topY
*/
private void drawOneLine(boolean yes, Line line, Graphics2D g, int topX, int topY) {
if (line == null)
return;
int x = line.x;
int y = line.y;
if (isYOnView(y - LINE_H) || isYOnView(y + LINE_H)) {
if (line.isBreakPoint && breakPointBGColor != null) {
g.setColor(breakPointBGColor);
g.fillRect(X0 + 1, y - LINE_H, this.getWidth(), LINE_H);
}
if (line.isCurrentLine) {
g.setColor(currentLineColor);
g.fillRect(X0 + 1, y - LINE_H, this.getWidth(), LINE_H);
}
g.setColor(Color.BLACK);
line.draw(g, x + 2, y - 3);
if (line.isBreakPoint) {// 断点
int dx = 2;
g.setColor(Color.red);
g.fillArc(this.X0_TAG + 3, y - LINE_H + dx, LINE_H - dx * 2, LINE_H - dx * 2, 0, 360);
}
g.setColor(Color.GRAY);
g.setFont(font12);
int w = g.getFontMetrics().stringWidth(line.tag);
g.drawString(line.tag, X0_TAG - w, y - 3);
g.setFont(font16);
}
if (this.pressedPointX() < X0 && this.canBreakPoint && isPressTheLine(x, y, LINE_H)) {
line.isBreakPoint = !line.isBreakPoint;
updateUI();
if (line.isBreakPoint) {
String s = "b " + this.fileName + ":" + line.index;
center.cmdBuffer.pushCmd(new ClientCmd(s));
} else {
String s = "rb " + this.fileName + ":" + line.index;
center.cmdBuffer.pushCmd(new ClientCmd(s));
}
}
if (X0 < this.pressedPointX() && isPressTheLine(x, y, LINE_H)) {
String s = line.getPressedString(this.pressedPointX(), this.pressedPointY());
if (s != null && s.length() > 0) {
if (s.indexOf('.') < 0) {
center.cmdBuffer.pushCmd(new ClientCmd("p " + s));
} else {
center.cmdBuffer.pushCmd(new ClientCmd("run print(\"" + s + " =\" , " + s + ")"));
}
}
}
}
/**
* 设置x坐标
*
* @param node
* @param x0
* @param PER_WIDTH
*/
private void setNodeX(int x0) {
for (int i = 0; i < this.lines.size(); i++) {
Line node = this.lines.elementAt(i);
if (node == null) {
return;
}
node.x = x0;
node.width = fontMetrics.stringWidth(node.text) + 16;
int tempX = node.x + node.width + 100;
this.setMaxW(tempX);
}
}
/**
* 设置y坐标
*
* @param node
* @return
*/
private void setNodeY(int y0) {
for (int i = 0; i < this.lines.size(); i++) {
Line obj = this.lines.elementAt(i);
obj.y = y0 + i * LINE_H;
setMaxH(obj.y + 50);
}
}
public void gotoLine(int lineNumber) {
lineNumber -= 1;
for (int i = 0; i < this.lines.size(); i++) {
Line line = this.lines.elementAt(i);
if (lineNumber == i) {
line.isCurrentLine = true;
} else {
line.isCurrentLine = false;
}
}
this.setNextYOnView(lineNumber * LINE_H + Y0);
this.updateUI();
}
public void clearGotoLine() {
this.gotoLine(-100);
}
}