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 com.android.ide.eclipse.adt.editors.layout.gscripts.IColor; 20 import com.android.ide.eclipse.adt.editors.layout.gscripts.IGraphics; 21 import com.android.ide.eclipse.adt.editors.layout.gscripts.IViewRule; 22 import com.android.ide.eclipse.adt.editors.layout.gscripts.Point; 23 import com.android.ide.eclipse.adt.editors.layout.gscripts.Rect; 24 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.SWTException; 27 import org.eclipse.swt.graphics.Color; 28 import org.eclipse.swt.graphics.FontMetrics; 29 import org.eclipse.swt.graphics.GC; 30 31 import java.util.HashMap; 32 33 /** 34 * Wraps an SWT {@link GC} into an {@link IGraphics} interface so that {@link IViewRule} objects 35 * can directly draw on the canvas. 36 * </p> 37 * The actual wrapped GC object is only non-null during the context of a paint operation. 38 */ 39 public class GCWrapper implements IGraphics { 40 41 /** 42 * The actual SWT {@link GC} being wrapped. This can change during the lifetime of the 43 * object. It is generally set to something during an onPaint method and then changed 44 * to null when not in the context of a paint. 45 */ 46 private GC mGc; 47 48 /** 49 * Implementation of IColor wrapping an SWT color. 50 */ 51 private class ColorWrapper implements IColor { 52 private final Color mColor; 53 ColorWrapper(Color color)54 public ColorWrapper(Color color) { 55 mColor = color; 56 } 57 getColor()58 public Color getColor() { 59 return mColor; 60 } 61 } 62 63 /** A map of registered colors. All these colors must be disposed at the end. */ 64 private final HashMap<Integer, ColorWrapper> mColorMap = new HashMap<Integer, ColorWrapper>(); 65 66 /** The cached pixel height of the default current font. */ 67 private int mFontHeight = 0; 68 69 /** The scaling of the canvas in X. */ 70 private final ICanvasTransform mHScale; 71 /** The scaling of the canvas in Y. */ 72 private final ICanvasTransform mVScale; 73 GCWrapper(ICanvasTransform hScale, ICanvasTransform vScale)74 public GCWrapper(ICanvasTransform hScale, ICanvasTransform vScale) { 75 mHScale = hScale; 76 mVScale = vScale; 77 mGc = null; 78 } 79 setGC(GC gc)80 void setGC(GC gc) { 81 mGc = gc; 82 } 83 getGc()84 private GC getGc() { 85 return mGc; 86 } 87 checkGC()88 void checkGC() { 89 if (mGc == null) { 90 throw new RuntimeException("IGraphics used without a valid context."); 91 } 92 } 93 dispose()94 void dispose() { 95 for (ColorWrapper c : mColorMap.values()) { 96 c.getColor().dispose(); 97 } 98 mColorMap.clear(); 99 } 100 101 //------------- 102 registerColor(int rgb)103 public IColor registerColor(int rgb) { 104 checkGC(); 105 106 Integer key = Integer.valueOf(rgb); 107 ColorWrapper c = mColorMap.get(key); 108 if (c == null) { 109 c = new ColorWrapper(new Color(getGc().getDevice(), 110 (rgb >> 16) & 0xFF, 111 (rgb >> 8) & 0xFF, 112 (rgb >> 0) & 0xFF)); 113 mColorMap.put(key, c); 114 } 115 116 return c; 117 } 118 119 /** Returns the (cached) pixel height of the current font. */ getFontHeight()120 public int getFontHeight() { 121 if (mFontHeight < 1) { 122 checkGC(); 123 FontMetrics fm = getGc().getFontMetrics(); 124 mFontHeight = fm.getHeight(); 125 } 126 return mFontHeight; 127 } 128 setForeground(IColor color)129 public void setForeground(IColor color) { 130 checkGC(); 131 getGc().setForeground(((ColorWrapper) color).getColor()); 132 } 133 setBackground(IColor color)134 public void setBackground(IColor color) { 135 checkGC(); 136 getGc().setBackground(((ColorWrapper) color).getColor()); 137 } 138 setAlpha(int alpha)139 public boolean setAlpha(int alpha) { 140 checkGC(); 141 try { 142 getGc().setAlpha(alpha); 143 return true; 144 } catch (SWTException e) { 145 return false; 146 } 147 } 148 setLineStyle(LineStyle style)149 public void setLineStyle(LineStyle style) { 150 int swtStyle = 0; 151 switch (style) { 152 case LINE_SOLID: 153 swtStyle = SWT.LINE_SOLID; 154 break; 155 case LINE_DASH: 156 swtStyle = SWT.LINE_DASH; 157 break; 158 case LINE_DOT: 159 swtStyle = SWT.LINE_DOT; 160 break; 161 case LINE_DASHDOT: 162 swtStyle = SWT.LINE_DASHDOT; 163 break; 164 case LINE_DASHDOTDOT: 165 swtStyle = SWT.LINE_DASHDOTDOT; 166 break; 167 } 168 169 if (swtStyle != 0) { 170 checkGC(); 171 getGc().setLineStyle(swtStyle); 172 } 173 } 174 setLineWidth(int width)175 public void setLineWidth(int width) { 176 checkGC(); 177 if (width > 0) { 178 getGc().setLineWidth(width); 179 } 180 } 181 182 // lines 183 drawLine(int x1, int y1, int x2, int y2)184 public void drawLine(int x1, int y1, int x2, int y2) { 185 checkGC(); 186 x1 = mHScale.translate(x1); 187 y1 = mVScale.translate(y1); 188 x2 = mHScale.translate(x2); 189 y2 = mVScale.translate(y2); 190 getGc().drawLine(x1, y1, x2, y2); 191 } 192 drawLine(Point p1, Point p2)193 public void drawLine(Point p1, Point p2) { 194 drawLine(p1.x, p1.y, p2.x, p2.y); 195 } 196 197 // rectangles 198 drawRect(int x1, int y1, int x2, int y2)199 public void drawRect(int x1, int y1, int x2, int y2) { 200 checkGC(); 201 int x = mHScale.translate(x1); 202 int y = mVScale.translate(y1); 203 int w = mHScale.scale(x2 - x1); 204 int h = mVScale.scale(y2 - y1); 205 getGc().drawRectangle(x, y, w, h); 206 } 207 drawRect(Point p1, Point p2)208 public void drawRect(Point p1, Point p2) { 209 drawRect(p1.x, p1.y, p2.x, p2.y); 210 } 211 drawRect(Rect r)212 public void drawRect(Rect r) { 213 checkGC(); 214 int x = mHScale.translate(r.x); 215 int y = mVScale.translate(r.y); 216 int w = mHScale.scale(r.w); 217 int h = mVScale.scale(r.h); 218 getGc().drawRectangle(x, y, w, h); 219 } 220 fillRect(int x1, int y1, int x2, int y2)221 public void fillRect(int x1, int y1, int x2, int y2) { 222 checkGC(); 223 int x = mHScale.translate(x1); 224 int y = mVScale.translate(y1); 225 int w = mHScale.scale(x2 - x1); 226 int h = mVScale.scale(y2 - y1); 227 getGc().fillRectangle(x, y, w, h); 228 } 229 fillRect(Point p1, Point p2)230 public void fillRect(Point p1, Point p2) { 231 fillRect(p1.x, p1.y, p2.x, p2.y); 232 } 233 fillRect(Rect r)234 public void fillRect(Rect r) { 235 checkGC(); 236 int x = mHScale.translate(r.x); 237 int y = mVScale.translate(r.y); 238 int w = mHScale.scale(r.w); 239 int h = mVScale.scale(r.h); 240 getGc().fillRectangle(x, y, w, h); 241 } 242 243 // circles (actually ovals) 244 drawOval(int x1, int y1, int x2, int y2)245 public void drawOval(int x1, int y1, int x2, int y2) { 246 checkGC(); 247 int x = mHScale.translate(x1); 248 int y = mVScale.translate(y1); 249 int w = mHScale.scale(x2 - x1); 250 int h = mVScale.scale(y2 - y1); 251 getGc().drawOval(x, y, w, h); 252 } 253 drawOval(Point p1, Point p2)254 public void drawOval(Point p1, Point p2) { 255 drawOval(p1.x, p1.y, p2.x, p2.y); 256 } 257 drawOval(Rect r)258 public void drawOval(Rect r) { 259 checkGC(); 260 int x = mHScale.translate(r.x); 261 int y = mVScale.translate(r.y); 262 int w = mHScale.scale(r.w); 263 int h = mVScale.scale(r.h); 264 getGc().drawOval(x, y, w, h); 265 } 266 fillOval(int x1, int y1, int x2, int y2)267 public void fillOval(int x1, int y1, int x2, int y2) { 268 checkGC(); 269 int x = mHScale.translate(x1); 270 int y = mVScale.translate(y1); 271 int w = mHScale.scale(x2 - x1); 272 int h = mVScale.scale(y2 - y1); 273 getGc().fillOval(x, y, w, h); 274 } 275 fillOval(Point p1, Point p2)276 public void fillOval(Point p1, Point p2) { 277 fillOval(p1.x, p1.y, p2.x, p2.y); 278 } 279 fillOval(Rect r)280 public void fillOval(Rect r) { 281 checkGC(); 282 int x = mHScale.translate(r.x); 283 int y = mVScale.translate(r.y); 284 int w = mHScale.scale(r.w); 285 int h = mVScale.scale(r.h); 286 getGc().fillOval(x, y, w, h); 287 } 288 289 290 // strings 291 drawString(String string, int x, int y)292 public void drawString(String string, int x, int y) { 293 checkGC(); 294 x = mHScale.translate(x); 295 y = mVScale.translate(y); 296 getGc().drawString(string, x, y, true /*isTransparent*/); 297 } 298 drawString(String string, Point topLeft)299 public void drawString(String string, Point topLeft) { 300 drawString(string, topLeft.x, topLeft.y); 301 } 302 } 303