1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.editors.layout.gle2; 18 19 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtDrawingStyle.HOVER; 20 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtDrawingStyle.HOVER_SELECTION; 21 22 import org.eclipse.swt.graphics.Color; 23 import org.eclipse.swt.graphics.Device; 24 import org.eclipse.swt.graphics.GC; 25 import org.eclipse.swt.graphics.Rectangle; 26 27 import java.util.List; 28 29 /** 30 * The {@link HoverOverlay} paints an optional hover on top of the layout, 31 * highlighting the currently hovered view. 32 */ 33 public class HoverOverlay extends Overlay { 34 private final LayoutCanvas mCanvas; 35 36 /** Hover border color. Must be disposed, it's NOT a system color. */ 37 private Color mHoverStrokeColor; 38 39 /** Hover fill color. Must be disposed, it's NOT a system color. */ 40 private Color mHoverFillColor; 41 42 /** Hover border select color. Must be disposed, it's NOT a system color. */ 43 private Color mHoverSelectStrokeColor; 44 45 /** Hover fill select color. Must be disposed, it's NOT a system color. */ 46 private Color mHoverSelectFillColor; 47 48 /** Vertical scaling & scrollbar information. */ 49 private CanvasTransform mVScale; 50 51 /** Horizontal scaling & scrollbar information. */ 52 private CanvasTransform mHScale; 53 54 /** 55 * Current mouse hover border rectangle. Null when there's no mouse hover. 56 * The rectangle coordinates do not take account of the translation, which 57 * must be applied to the rectangle when drawing. 58 */ 59 private Rectangle mHoverRect; 60 61 /** 62 * Constructs a new {@link HoverOverlay} linked to the given view hierarchy. 63 * 64 * @param canvas the associated canvas 65 * @param hScale The {@link CanvasTransform} to use to transfer horizontal layout 66 * coordinates to screen coordinates. 67 * @param vScale The {@link CanvasTransform} to use to transfer vertical layout 68 * coordinates to screen coordinates. 69 */ 70 public HoverOverlay(LayoutCanvas canvas, CanvasTransform hScale, CanvasTransform vScale) { 71 mCanvas = canvas; 72 this.mHScale = hScale; 73 this.mVScale = vScale; 74 } 75 76 @Override 77 public void create(Device device) { 78 if (SwtDrawingStyle.HOVER.getStrokeColor() != null) { 79 mHoverStrokeColor = new Color(device, SwtDrawingStyle.HOVER.getStrokeColor()); 80 } 81 if (SwtDrawingStyle.HOVER.getFillColor() != null) { 82 mHoverFillColor = new Color(device, SwtDrawingStyle.HOVER.getFillColor()); 83 } 84 85 if (SwtDrawingStyle.HOVER_SELECTION.getStrokeColor() != null) { 86 mHoverSelectStrokeColor = new Color(device, 87 SwtDrawingStyle.HOVER_SELECTION.getStrokeColor()); 88 } 89 if (SwtDrawingStyle.HOVER_SELECTION.getFillColor() != null) { 90 mHoverSelectFillColor = new Color(device, 91 SwtDrawingStyle.HOVER_SELECTION.getFillColor()); 92 } 93 } 94 95 @Override 96 public void dispose() { 97 if (mHoverStrokeColor != null) { 98 mHoverStrokeColor.dispose(); 99 mHoverStrokeColor = null; 100 } 101 102 if (mHoverFillColor != null) { 103 mHoverFillColor.dispose(); 104 mHoverFillColor = null; 105 } 106 107 if (mHoverSelectStrokeColor != null) { 108 mHoverSelectStrokeColor.dispose(); 109 mHoverSelectStrokeColor = null; 110 } 111 112 if (mHoverSelectFillColor != null) { 113 mHoverSelectFillColor.dispose(); 114 mHoverSelectFillColor = null; 115 } 116 } 117 118 /** 119 * Sets the hover rectangle. The coordinates of the rectangle are in layout 120 * coordinates. The recipient is will own this rectangle. 121 * <p/> 122 * TODO: Consider switching input arguments to two {@link LayoutPoint}s so 123 * we don't have ambiguity about the coordinate system of these input 124 * parameters. 125 * <p/> 126 * 127 * @param x The top left x coordinate, in layout coordinates, of the hover. 128 * @param y The top left y coordinate, in layout coordinates, of the hover. 129 * @param w The width of the hover (in layout coordinates). 130 * @param h The height of the hover (in layout coordinates). 131 */ 132 public void setHover(int x, int y, int w, int h) { 133 mHoverRect = new Rectangle(x, y, w, h); 134 } 135 136 /** 137 * Removes the hover for the next paint. 138 */ 139 public void clearHover() { 140 mHoverRect = null; 141 } 142 143 @Override 144 public void paint(GC gc) { 145 if (mHoverRect != null) { 146 // Translate the hover rectangle (in canvas coordinates) to control 147 // coordinates 148 int x = mHScale.translate(mHoverRect.x); 149 int y = mVScale.translate(mHoverRect.y); 150 int w = mHScale.scale(mHoverRect.width); 151 int h = mVScale.scale(mHoverRect.height); 152 153 154 boolean hoverIsSelected = false; 155 List<SelectionItem> selections = mCanvas.getSelectionManager().getSelections(); 156 for (SelectionItem item : selections) { 157 if (mHoverRect.equals(item.getViewInfo().getSelectionRect())) { 158 hoverIsSelected = true; 159 break; 160 } 161 } 162 163 Color stroke = hoverIsSelected ? mHoverSelectStrokeColor : mHoverStrokeColor; 164 Color fill = hoverIsSelected ? mHoverSelectFillColor : mHoverFillColor; 165 166 if (stroke != null) { 167 int oldAlpha = gc.getAlpha(); 168 gc.setForeground(stroke); 169 gc.setLineStyle(hoverIsSelected ? 170 HOVER_SELECTION.getLineStyle() : HOVER.getLineStyle()); 171 gc.setAlpha(hoverIsSelected ? 172 HOVER_SELECTION.getStrokeAlpha() : HOVER.getStrokeAlpha()); 173 gc.drawRectangle(x, y, w, h); 174 gc.setAlpha(oldAlpha); 175 } 176 177 if (fill != null) { 178 int oldAlpha = gc.getAlpha(); 179 gc.setAlpha(hoverIsSelected ? 180 HOVER_SELECTION.getFillAlpha() : HOVER.getFillAlpha()); 181 gc.setBackground(fill); 182 gc.fillRectangle(x, y, w, h); 183 gc.setAlpha(oldAlpha); 184 } 185 } 186 } 187 } 188