]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.threadlog / src / org / simantics / threadlog / ui / TimeLineViewer.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.threadlog.ui;\r
13 \r
14 import java.awt.Color;\r
15 import java.awt.Dimension;\r
16 import java.awt.Graphics;\r
17 import java.awt.Graphics2D;\r
18 import java.awt.Shape;\r
19 import java.awt.event.MouseAdapter;\r
20 import java.awt.event.MouseEvent;\r
21 import java.awt.event.MouseMotionAdapter;\r
22 import java.awt.event.MouseWheelEvent;\r
23 import java.awt.event.MouseWheelListener;\r
24 import java.awt.geom.Rectangle2D;\r
25 import java.awt.geom.RoundRectangle2D;\r
26 import java.text.DecimalFormat;\r
27 import java.text.Format;\r
28 import java.util.ArrayList;\r
29 import java.util.List;\r
30 import java.util.Timer;\r
31 import java.util.TimerTask;\r
32 \r
33 import javax.swing.JPanel;\r
34 \r
35 public class TimeLineViewer extends JPanel {\r
36 \r
37     private static final long serialVersionUID = -7410066541298449720L;\r
38     \r
39     public static long TOOL_TIP_DELAY = 500;\r
40         public static double MIN_GRID_LINE_SEPARATION = 15;\r
41         \r
42         // Time line data\r
43         List<Lane> lanes = new ArrayList<Lane>();\r
44         \r
45         // For panning and zooming\r
46         double xScale = 100.0;\r
47         double xOffset = 0.0;\r
48         double yOffset = 0.0;\r
49         int oldX;\r
50         int oldY;\r
51         \r
52         // Tool tips\r
53         Timer toolTipTimer = new Timer();\r
54         class ToolTipTask extends TimerTask {\r
55 \r
56                 @Override\r
57                 public void run() {\r
58                         System.out.println("show tooltip");                     \r
59                 }\r
60                 \r
61         }\r
62         \r
63         public TimeLineViewer() {\r
64                 addMouseListener(new MouseAdapter() {\r
65                 @Override\r
66                 public void mousePressed(MouseEvent e) {\r
67                         oldX = e.getX();\r
68                         oldY = e.getY();\r
69                 }\r
70                 });\r
71         addMouseMotionListener(new MouseMotionAdapter() {               \r
72                 @Override\r
73                 public void mouseDragged(MouseEvent e) {\r
74                         int curX = e.getX();\r
75                         int curY = e.getY();\r
76                         int diffX = curX - oldX;\r
77                         int diffY = curY - oldY;\r
78                         oldX = curX;\r
79                         oldY = curY;\r
80                         \r
81                         xOffset -= diffX/xScale;\r
82                         yOffset -= diffY;\r
83                         repaint();\r
84                 }\r
85                 TimerTask toolTipTask;\r
86                         @Override\r
87                 public void mouseMoved(MouseEvent e) {\r
88                                 if(toolTipTask != null)\r
89                                         toolTipTask.cancel();\r
90                                 toolTipTask = new ToolTipTask();\r
91                         toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY);\r
92                 }\r
93         });\r
94         addMouseWheelListener(new MouseWheelListener() {                        \r
95                         @Override\r
96                         public void mouseWheelMoved(MouseWheelEvent e) {\r
97                                 xOffset += e.getX() / xScale;\r
98                                 xScale *= Math.pow(1.25, -e.getWheelRotation());\r
99                                 xOffset -= e.getX() / xScale;\r
100                                 repaint();\r
101                         }\r
102                 });\r
103         }\r
104         \r
105         public void addLane(Lane lane) {\r
106                 lanes.add(lane);\r
107         }\r
108         \r
109         public void clear() {\r
110                 lanes.clear();\r
111         }\r
112         \r
113         public void paintIntervals(Graphics2D g) {              \r
114                 for(int laneId=0;laneId < lanes.size();++laneId) {\r
115                         Lane lane = lanes.get(laneId);\r
116                         \r
117                         double y = 35.0*laneId - yOffset;\r
118                         double height = 30.0;\r
119                         \r
120                         for(Interval interval : lane.intervals) {\r
121                                 double x = (interval.begin - xOffset) * xScale; \r
122                                 double width = (interval.end - interval.begin) * xScale;\r
123                                 \r
124                                 Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0);\r
125                                 g.setColor(Color.WHITE);\r
126                                 g.fill(shape);\r
127                                 g.setColor(Color.BLACK);\r
128                                 g.draw(shape);\r
129                                 \r
130                                 Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g);\r
131                                 if(bounds.getWidth() < width)\r
132                                         g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0));\r
133                         }\r
134                 }\r
135         }\r
136         \r
137         public void paintGrid(Graphics2D g) {\r
138                 Dimension dim = getSize();\r
139                 \r
140                 g.setBackground(Color.WHITE);\r
141                 g.clearRect(0, 0, dim.width, dim.height);\r
142                 \r
143                 double stepsize = 0.001;\r
144                 double majorStepsize;\r
145                 while(true) {\r
146                         majorStepsize = stepsize * 5.0;\r
147                         if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
148                                 break;\r
149                         stepsize = majorStepsize;\r
150                         majorStepsize = stepsize * 2.0;\r
151                         if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
152                                 break;\r
153                         stepsize = majorStepsize;\r
154                 }\r
155                 \r
156                 double firstP = Math.ceil(xOffset / stepsize) * stepsize;\r
157                 double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize;\r
158                 if(firstP < 0.0)\r
159                         firstP = 0.0;\r
160 \r
161                 Format format = new DecimalFormat();\r
162                 for(double p = firstP;p <= lastP; p+=stepsize) {\r
163                         int x = (int)((p - xOffset) * xScale);\r
164                         if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) {\r
165                                 g.setColor(Color.BLACK);\r
166                                 String text = format.format(p);\r
167                                 Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);\r
168                                 g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f);                            \r
169                         }\r
170                         else\r
171                                 g.setColor(Color.LIGHT_GRAY);\r
172                         g.drawLine(x, 14, x, (int)dim.getHeight());\r
173                 }\r
174         }\r
175         \r
176         @Override\r
177         public void paint(Graphics _g) {\r
178                 Graphics2D g = (Graphics2D)_g;  \r
179                                 \r
180                 paintGrid(g);\r
181                 paintIntervals(g);\r
182         }\r
183         \r
184 }\r