X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.threadlog%2Fsrc%2Forg%2Fsimantics%2Fthreadlog%2Fui%2FTimeLineViewer.java;fp=bundles%2Forg.simantics.threadlog%2Fsrc%2Forg%2Fsimantics%2Fthreadlog%2Fui%2FTimeLineViewer.java;h=40aefb05526439a010c637bad8e4a88ab3920765;hb=2531cdf245f42bce854d43f4d49a23983c79db96;hp=0000000000000000000000000000000000000000;hpb=857dbc869796d772864327ce02f19dc252b159fc;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java new file mode 100644 index 000000000..40aefb055 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.text.DecimalFormat; +import java.text.Format; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.JPanel; + +public class TimeLineViewer extends JPanel { + + private static final long serialVersionUID = -7410066541298449720L; + + public static long TOOL_TIP_DELAY = 500; + public static double MIN_GRID_LINE_SEPARATION = 15; + + // Time line data + List lanes = new ArrayList(); + + // For panning and zooming + double xScale = 100.0; + double xOffset = 0.0; + double yOffset = 0.0; + int oldX; + int oldY; + + // Tool tips + Timer toolTipTimer = new Timer(); + class ToolTipTask extends TimerTask { + + @Override + public void run() { + System.out.println("show tooltip"); + } + + } + + public TimeLineViewer() { + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + oldX = e.getX(); + oldY = e.getY(); + } + }); + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + int curX = e.getX(); + int curY = e.getY(); + int diffX = curX - oldX; + int diffY = curY - oldY; + oldX = curX; + oldY = curY; + + xOffset -= diffX/xScale; + yOffset -= diffY; + repaint(); + } + TimerTask toolTipTask; + @Override + public void mouseMoved(MouseEvent e) { + if(toolTipTask != null) + toolTipTask.cancel(); + toolTipTask = new ToolTipTask(); + toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY); + } + }); + addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + xOffset += e.getX() / xScale; + xScale *= Math.pow(1.25, -e.getWheelRotation()); + xOffset -= e.getX() / xScale; + repaint(); + } + }); + } + + public void addLane(Lane lane) { + lanes.add(lane); + } + + public void clear() { + lanes.clear(); + } + + public void paintIntervals(Graphics2D g) { + for(int laneId=0;laneId < lanes.size();++laneId) { + Lane lane = lanes.get(laneId); + + double y = 35.0*laneId - yOffset; + double height = 30.0; + + for(Interval interval : lane.intervals) { + double x = (interval.begin - xOffset) * xScale; + double width = (interval.end - interval.begin) * xScale; + + Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0); + g.setColor(Color.WHITE); + g.fill(shape); + g.setColor(Color.BLACK); + g.draw(shape); + + Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g); + if(bounds.getWidth() < width) + g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0)); + } + } + } + + public void paintGrid(Graphics2D g) { + Dimension dim = getSize(); + + g.setBackground(Color.WHITE); + g.clearRect(0, 0, dim.width, dim.height); + + double stepsize = 0.001; + double majorStepsize; + while(true) { + majorStepsize = stepsize * 5.0; + if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION) + break; + stepsize = majorStepsize; + majorStepsize = stepsize * 2.0; + if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION) + break; + stepsize = majorStepsize; + } + + double firstP = Math.ceil(xOffset / stepsize) * stepsize; + double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize; + if(firstP < 0.0) + firstP = 0.0; + + Format format = new DecimalFormat(); + for(double p = firstP;p <= lastP; p+=stepsize) { + int x = (int)((p - xOffset) * xScale); + if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) { + g.setColor(Color.BLACK); + String text = format.format(p); + Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g); + g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f); + } + else + g.setColor(Color.LIGHT_GRAY); + g.drawLine(x, 14, x, (int)dim.getHeight()); + } + } + + @Override + public void paint(Graphics _g) { + Graphics2D g = (Graphics2D)_g; + + paintGrid(g); + paintIntervals(g); + } + +}