package edu.ysu.itrace; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; import edu.ysu.itrace.gaze.IGazeResponse; import edu.ysu.itrace.gaze.IStyledTextGazeResponse; import edu.ysu.itrace.gaze.handlers.StyledTextGazeHandler; import java.awt.Dimension; import java.awt.Toolkit; import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.source.projection.ProjectionViewer; public class TokenHighlighter implements PaintListener, EventHandler { private StyledText styledText; private ProjectionViewer projviewer; private Rectangle boundingBox; private Point[] points; private int pointIndex; private int numberOfPoints; private int nulls; private boolean show; private IEventBroker eventBroker; @Override public void paintControl(PaintEvent pe) { if(boundingBox != null && show){ pe.gc.setBackground(new Color(pe.gc.getDevice(),15,252,212)); pe.gc.setForeground(new Color(pe.gc.getDevice(),0,230,172)); pe.gc.drawRectangle(boundingBox); pe.gc.setAlpha(125); pe.gc.fillRectangle(boundingBox); }else if(boundingBox == null){ boundingBox = new Rectangle(-1,-1,0,0); pe.gc.drawRectangle(boundingBox); pe.gc.setAlpha(125); pe.gc.fillRectangle(boundingBox); } } public void redraw(){ styledText.redraw(); } public void update(int lineIndex, int column, int x, int y){ if(projviewer.modelLine2WidgetLine(lineIndex) == -1) return; int lineOffset = styledText.getOffsetAtLine(projviewer.modelLine2WidgetLine(lineIndex)); String lineContent = styledText.getLine(projviewer.modelLine2WidgetLine(lineIndex)); //System.out.println(lineOffset); //System.out.println(lineContent); boundingBox = getBoundingBox(lineOffset,lineContent,x,y); //if(tokenOffsetSpan == null) boundingBox = null; //else boundingBox = styledText.getTextBounds(tokenOffsetSpan.startOffset,tokenOffsetSpan.endOffset); styledText.redraw(); } public boolean boundingBoxContains(int x,int y){ if(boundingBox != null) return boundingBox.contains(x,y); else return false; } public int getOffsetAtPoint(Point point){ try{ int offset = styledText.getOffsetAtLocation(point); return offset; } catch(Exception e){ return -1; } } public void setShow(boolean show){ this.show = show; //if(show) this.start(); } private Rectangle getBoundingBox(int lineOffset, String lineContent, int x, int y){ Rectangle box = null; points[pointIndex] = new Point(x,y); pointIndex++; if(pointIndex > numberOfPoints-1) pointIndex = pointIndex%numberOfPoints; if(containsPoints(boundingBox)) return boundingBox; int startOffset = 0; int endOffset; while(startOffset < lineContent.length()){ while(startOffset < lineContent.length() && checkChar(lineContent.charAt(startOffset))) startOffset++; endOffset = startOffset; while(endOffset < lineContent.length()-1 && !checkChar(lineContent.charAt(endOffset+1))) endOffset++; box = styledText.getTextBounds(lineOffset+startOffset, lineOffset+endOffset); if(containsPoints(box)) break; startOffset = endOffset+1; } if(box != null && !containsPoints(box)){ box = null; } return box; } private boolean containsPoints(Rectangle box){ for(Point p: points){ if(p != null && box != null && !box.contains(p)) return false; } return true; } private boolean checkChar(char c){ char[] delimeters = {' ', '\t','(',')','[',']','{','}','.',','}; for(char delimeter: delimeters){ if(c == delimeter) return true; } return false; } public TokenHighlighter(StyledText styledText, boolean show, ProjectionViewer projviewer){ this.styledText = styledText; this.projviewer = projviewer; this.styledText.addPaintListener(this); this.show = show; this.numberOfPoints = 1; this.points = new Point[numberOfPoints]; this.pointIndex = 0; this.nulls = 0; this.eventBroker = PlatformUI.getWorkbench().getService(IEventBroker.class); this.eventBroker.subscribe("iTrace/newstresponse", this); //this.gazeQueue = Activator.getDefault().gazeTransport.createClient(); //System.out.println("gazeQueue"); } @Override public void handleEvent(Event event) { String[] propertyNames = event.getPropertyNames(); //System.out.println(event.getProperty(propertyNames[0])); IStyledTextGazeResponse response = (IStyledTextGazeResponse)event.getProperty(propertyNames[0]); Rectangle mBounds = ITrace.getDefault().getRootShell().getBounds(); int screenX = (int) (response.getGaze().getX() * mBounds.width); int screenY = (int) (response.getGaze().getY() * mBounds.height); //Rectangle monitorBounds = ITrace.getDefault().monitorBounds; if(styledText.isDisposed()) return; Rectangle editorBounds = styledText.getBounds(); Point screenPos = styledText.toDisplay(0, 0); editorBounds.x = screenPos.x - mBounds.x; editorBounds.y = screenPos.y - mBounds.y; if(editorBounds.contains(screenX, screenY)){ int relativeX = screenX-editorBounds.x; int relativeY = screenY-editorBounds.y; update(response.getLine()-1,response.getCol(), relativeX, relativeY); } } }