| 1 | /********************************************************************** |
| 2 | * Copyright (c) 2005, 2008, 2011 IBM Corporation and others. |
| 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the Eclipse Public License v1.0 |
| 5 | * which accompanies this distribution, and is available at |
| 6 | * http://www.eclipse.org/legal/epl-v10.html |
| 7 | * $Id: DrawableToolTip.java,v 1.3 2008/01/24 02:29:01 apnan Exp $ |
| 8 | * |
| 9 | * Contributors: |
| 10 | * IBM - Initial API and implementation |
| 11 | * Bernd Hufmann - Updated for TMF |
| 12 | **********************************************************************/ |
| 13 | package org.eclipse.linuxtools.tmf.ui.views.uml2sd; |
| 14 | |
| 15 | import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; |
| 16 | import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp; |
| 17 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.SDMessages; |
| 18 | import org.eclipse.swt.SWT; |
| 19 | import org.eclipse.swt.events.PaintEvent; |
| 20 | import org.eclipse.swt.events.PaintListener; |
| 21 | import org.eclipse.swt.graphics.Color; |
| 22 | import org.eclipse.swt.graphics.Point; |
| 23 | import org.eclipse.swt.layout.RowLayout; |
| 24 | import org.eclipse.swt.widgets.Composite; |
| 25 | import org.eclipse.swt.widgets.Display; |
| 26 | import org.eclipse.swt.widgets.Shell; |
| 27 | |
| 28 | /** |
| 29 | * This class is used to reproduce the same tooltip behavior on Windows and Linux when the mouse move hover the time |
| 30 | * compression bar used to display elapsed time using a tooltip. The tooltip is composed of 2 parts, the text value and |
| 31 | * below, a scale to visually locate the value in a time range (usually the min an max elapsed time in the whole |
| 32 | * diagram) |
| 33 | * |
| 34 | * @author sveyrier |
| 35 | */ |
| 36 | public class DrawableToolTip implements PaintListener { |
| 37 | |
| 38 | /** |
| 39 | * The parent control where the tooltip must be drawn |
| 40 | */ |
| 41 | protected Composite parent = null; |
| 42 | /** |
| 43 | * The tooltip shell |
| 44 | */ |
| 45 | protected Shell toolTipShell = null; |
| 46 | /** |
| 47 | * Time range data |
| 48 | */ |
| 49 | protected TmfTimeRange minMaxRange; |
| 50 | protected TmfTimestamp currentValue; |
| 51 | |
| 52 | private static int H_MARGIN = 10; |
| 53 | private static int V_MARGIN = 10; |
| 54 | |
| 55 | private static int TEXT_SCALE_MARGIN = 20; |
| 56 | private static int SCALE_LENGTH = 100; |
| 57 | |
| 58 | protected String msg; |
| 59 | |
| 60 | /** |
| 61 | * The color array used to represent the 10 time range slices |
| 62 | */ |
| 63 | protected Color[] col; |
| 64 | |
| 65 | public DrawableToolTip(Composite _parent) { |
| 66 | parent = _parent; |
| 67 | toolTipShell = new Shell(parent.getShell(), SWT.ON_TOP); |
| 68 | toolTipShell.setLayout(new RowLayout()); |
| 69 | toolTipShell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); |
| 70 | toolTipShell.addPaintListener(this); |
| 71 | toolTipShell.setSize(200, 50); |
| 72 | |
| 73 | col = new Color[10]; |
| 74 | col[0] = new Color(Display.getDefault(), 255, 229, 229); |
| 75 | col[1] = new Color(Display.getDefault(), 255, 204, 204); |
| 76 | col[2] = new Color(Display.getDefault(), 255, 178, 178); |
| 77 | col[3] = new Color(Display.getDefault(), 255, 153, 153); |
| 78 | col[4] = new Color(Display.getDefault(), 255, 127, 127); |
| 79 | col[5] = new Color(Display.getDefault(), 255, 102, 102); |
| 80 | col[6] = new Color(Display.getDefault(), 255, 76, 76); |
| 81 | col[7] = new Color(Display.getDefault(), 255, 51, 51); |
| 82 | col[8] = new Color(Display.getDefault(), 255, 25, 25); |
| 83 | col[9] = new Color(Display.getDefault(), 255, 0, 0); |
| 84 | } |
| 85 | |
| 86 | /** |
| 87 | * Display the tooltip using the given time range(min,max) the current value and the time unit The tooltip will stay |
| 88 | * on screen until it is told otherwise |
| 89 | * |
| 90 | * @param _value the current in the scale |
| 91 | * @param _min the scale min |
| 92 | * @param _max the scale max |
| 93 | * @param unit the scale unit |
| 94 | */ |
| 95 | public void showToolTip(TmfTimestamp _value, TmfTimestamp min, TmfTimestamp max) { |
| 96 | minMaxRange = new TmfTimeRange(min.clone(), max.clone()); |
| 97 | currentValue = _value.clone(); |
| 98 | |
| 99 | int w = toolTipShell.getBounds().width; |
| 100 | int h = toolTipShell.getBounds().height; |
| 101 | Point hr = Display.getDefault().getCursorLocation(); |
| 102 | toolTipShell.setBounds(hr.x, hr.y + 26, w, h); |
| 103 | toolTipShell.setVisible(true); |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Hide the tooltip |
| 108 | */ |
| 109 | public void hideToolTip() { |
| 110 | toolTipShell.setVisible(false); |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * Draw the tooltip text on the control widget when a paint event is received |
| 115 | */ |
| 116 | @Override |
| 117 | public void paintControl(PaintEvent event) { |
| 118 | msg = SDMessages._138 + " " + currentValue.toString(); //$NON-NLS-1$ |
| 119 | Point size = event.gc.textExtent(msg); |
| 120 | if (size.x < SCALE_LENGTH) |
| 121 | size.x = SCALE_LENGTH; |
| 122 | event.gc.drawText(msg, H_MARGIN, V_MARGIN, true); |
| 123 | event.gc.drawLine(H_MARGIN, V_MARGIN + TEXT_SCALE_MARGIN + size.y, H_MARGIN + SCALE_LENGTH, V_MARGIN + TEXT_SCALE_MARGIN + size.y); |
| 124 | |
| 125 | int step = SCALE_LENGTH / 10; |
| 126 | |
| 127 | // double gr = (max - min) / 10; |
| 128 | TmfTimestamp minMaxdelta = minMaxRange.getEndTime().getDelta(minMaxRange.getStartTime()); |
| 129 | double gr = (minMaxdelta.getValue()) / (double) 10; |
| 130 | |
| 131 | // double delta = currentValue-min; |
| 132 | TmfTimestamp delta = currentValue.getDelta(minMaxRange.getStartTime()); |
| 133 | long absDelta = Math.abs(delta.getValue()); |
| 134 | |
| 135 | int colIndex = 0; |
| 136 | if (gr != 0) { |
| 137 | // colIndex = Math.round((float)(Math.log(1+delta)/gr)); |
| 138 | colIndex = Math.round((float) (absDelta / gr)); |
| 139 | if (colIndex > col.length) |
| 140 | colIndex = col.length; |
| 141 | else if (colIndex <= 1) |
| 142 | colIndex = 1; |
| 143 | } else |
| 144 | colIndex = 1; |
| 145 | |
| 146 | for (int i = 0; i <= 10; i++) { |
| 147 | if (i < 10) |
| 148 | event.gc.setBackground(col[i]); |
| 149 | if ((i < colIndex) && (i < 10)) |
| 150 | event.gc.fillRectangle(H_MARGIN + i * step, V_MARGIN + TEXT_SCALE_MARGIN + size.y - 5, step, 11); |
| 151 | if (i == 0) |
| 152 | event.gc.drawText(SDMessages._56, H_MARGIN, size.y + 2 * V_MARGIN + TEXT_SCALE_MARGIN, true); |
| 153 | if (i == 0) { |
| 154 | int len = event.gc.textExtent(SDMessages._55).x; |
| 155 | event.gc.drawText(SDMessages._55, H_MARGIN + SCALE_LENGTH - len + 1, size.y + 2 * V_MARGIN + TEXT_SCALE_MARGIN, true); |
| 156 | } |
| 157 | int lineWidth = 10; |
| 158 | if ((i == 0) || (i == 10)) |
| 159 | lineWidth = 14; |
| 160 | event.gc.drawLine(H_MARGIN + i * step, V_MARGIN + TEXT_SCALE_MARGIN + size.y - lineWidth / 2, H_MARGIN + i * step, V_MARGIN + TEXT_SCALE_MARGIN + size.y + lineWidth / 2); |
| 161 | } |
| 162 | toolTipShell.setSize(size.x + 2 * H_MARGIN + 2, 2 * size.y + 3 * V_MARGIN + TEXT_SCALE_MARGIN); |
| 163 | } |
| 164 | |
| 165 | public String getText() { |
| 166 | return msg; |
| 167 | } |
| 168 | |
| 169 | public String getAccessibleText() { |
| 170 | return currentValue.toString(); |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * Dispose the system resource used by this kind of toolTips (a colors array essentially) |
| 175 | * |
| 176 | */ |
| 177 | public void dispose() { |
| 178 | for (int i = 0; i < col.length; i++) |
| 179 | col[i].dispose(); |
| 180 | } |
| 181 | |
| 182 | protected static int getHorizontalMargin() { |
| 183 | return H_MARGIN; |
| 184 | } |
| 185 | |
| 186 | protected static void setHorizontalMargin(int margin) { |
| 187 | H_MARGIN = margin; |
| 188 | } |
| 189 | |
| 190 | protected static int getVerticalMargin() { |
| 191 | return V_MARGIN; |
| 192 | } |
| 193 | |
| 194 | protected static void setVerticalMargin(int margin) { |
| 195 | V_MARGIN = margin; |
| 196 | } |
| 197 | |
| 198 | protected static int getTestScaleMargin() { |
| 199 | return TEXT_SCALE_MARGIN; |
| 200 | } |
| 201 | |
| 202 | protected static void setTestScaleMargin(int testScaleMargin) { |
| 203 | TEXT_SCALE_MARGIN = testScaleMargin; |
| 204 | } |
| 205 | |
| 206 | protected static int getScaleLength() { |
| 207 | return SCALE_LENGTH; |
| 208 | } |
| 209 | |
| 210 | protected static void setScaleLength(int scaleLength) { |
| 211 | SCALE_LENGTH = scaleLength; |
| 212 | } |
| 213 | |
| 214 | } |