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 org.eclipse.swt.graphics.Color; 20 import org.eclipse.swt.graphics.Device; 21 import org.eclipse.swt.graphics.GC; 22 import org.eclipse.swt.graphics.Rectangle; 23 24 /** 25 * The {@link OutlineOverlay} paints an optional outline on top of the layout, 26 * showing the structure of the individual Android View elements. 27 */ 28 public class OutlineOverlay extends Overlay { 29 /** The {@link ViewHierarchy} this outline visualizes */ 30 private final ViewHierarchy mViewHierarchy; 31 32 /** Outline color. Must be disposed, it's NOT a system color. */ 33 private Color mOutlineColor; 34 35 /** Vertical scaling & scrollbar information. */ 36 private CanvasTransform mVScale; 37 38 /** Horizontal scaling & scrollbar information. */ 39 private CanvasTransform mHScale; 40 41 /** 42 * Constructs a new {@link OutlineOverlay} linked to the given view 43 * hierarchy. 44 * 45 * @param viewHierarchy The {@link ViewHierarchy} to render 46 * @param hScale The {@link CanvasTransform} to use to transfer horizontal layout 47 * coordinates to screen coordinates 48 * @param vScale The {@link CanvasTransform} to use to transfer vertical layout 49 * coordinates to screen coordinates 50 */ 51 public OutlineOverlay( 52 ViewHierarchy viewHierarchy, 53 CanvasTransform hScale, 54 CanvasTransform vScale) { 55 super(); 56 mViewHierarchy = viewHierarchy; 57 mHScale = hScale; 58 mVScale = vScale; 59 } 60 61 @Override 62 public void create(Device device) { 63 mOutlineColor = new Color(device, SwtDrawingStyle.OUTLINE.getStrokeColor()); 64 } 65 66 @Override 67 public void dispose() { 68 if (mOutlineColor != null) { 69 mOutlineColor.dispose(); 70 mOutlineColor = null; 71 } 72 } 73 74 @Override 75 public void paint(GC gc) { 76 CanvasViewInfo lastRoot = mViewHierarchy.getRoot(); 77 if (lastRoot != null) { 78 gc.setForeground(mOutlineColor); 79 gc.setLineStyle(SwtDrawingStyle.OUTLINE.getLineStyle()); 80 int oldAlpha = gc.getAlpha(); 81 gc.setAlpha(SwtDrawingStyle.OUTLINE.getStrokeAlpha()); 82 drawOutline(gc, lastRoot); 83 gc.setAlpha(oldAlpha); 84 } 85 } 86 87 private void drawOutline(GC gc, CanvasViewInfo info) { 88 Rectangle r = info.getAbsRect(); 89 90 int x = mHScale.translate(r.x); 91 int y = mVScale.translate(r.y); 92 int w = mHScale.scale(r.width); 93 int h = mVScale.scale(r.height); 94 95 // Add +1 to the width and +1 to the height such that when you have a 96 // series of boxes (in say a LinearLayout), instead of the bottom of one 97 // box and the top of the next box being -adjacent-, they -overlap-. 98 // This makes the outline nicer visually since you don't get 99 // "double thickness" lines for all adjacent boxes. 100 gc.drawRectangle(x, y, w + 1, h + 1); 101 102 for (CanvasViewInfo vi : info.getChildren()) { 103 drawOutline(gc, vi); 104 } 105 } 106 107 } 108