diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java | 645 |
1 files changed, 0 insertions, 645 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java deleted file mode 100644 index 354517e76..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.layout.gle2; - -import com.android.annotations.NonNull; -import com.android.ide.common.api.DrawingStyle; -import com.android.ide.common.api.IColor; -import com.android.ide.common.api.IGraphics; -import com.android.ide.common.api.IViewRule; -import com.android.ide.common.api.Point; -import com.android.ide.common.api.Rect; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.RGB; - -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Wraps an SWT {@link GC} into an {@link IGraphics} interface so that {@link IViewRule} objects - * can directly draw on the canvas. - * <p/> - * The actual wrapped GC object is only non-null during the context of a paint operation. - */ -public class GCWrapper implements IGraphics { - - /** - * The actual SWT {@link GC} being wrapped. This can change during the lifetime of the - * object. It is generally set to something during an onPaint method and then changed - * to null when not in the context of a paint. - */ - private GC mGc; - - /** - * Current style being used for drawing. - */ - private SwtDrawingStyle mCurrentStyle = SwtDrawingStyle.INVALID; - - /** - * Implementation of IColor wrapping an SWT color. - */ - private static class ColorWrapper implements IColor { - private final Color mColor; - - public ColorWrapper(Color color) { - mColor = color; - } - - public Color getColor() { - return mColor; - } - } - - /** A map of registered colors. All these colors must be disposed at the end. */ - private final HashMap<Integer, ColorWrapper> mColorMap = new HashMap<Integer, ColorWrapper>(); - - /** - * A map of the {@link SwtDrawingStyle} stroke colors that we have actually - * used (to be disposed) - */ - private final Map<DrawingStyle, Color> mStyleStrokeMap = new EnumMap<DrawingStyle, Color>( - DrawingStyle.class); - - /** - * A map of the {@link SwtDrawingStyle} fill colors that we have actually - * used (to be disposed) - */ - private final Map<DrawingStyle, Color> mStyleFillMap = new EnumMap<DrawingStyle, Color>( - DrawingStyle.class); - - /** The cached pixel height of the default current font. */ - private int mFontHeight = 0; - - /** The scaling of the canvas in X. */ - private final CanvasTransform mHScale; - /** The scaling of the canvas in Y. */ - private final CanvasTransform mVScale; - - public GCWrapper(CanvasTransform hScale, CanvasTransform vScale) { - mHScale = hScale; - mVScale = vScale; - mGc = null; - } - - void setGC(GC gc) { - mGc = gc; - } - - private GC getGc() { - return mGc; - } - - void checkGC() { - if (mGc == null) { - throw new RuntimeException("IGraphics used without a valid context."); - } - } - - void dispose() { - for (ColorWrapper c : mColorMap.values()) { - c.getColor().dispose(); - } - mColorMap.clear(); - - for (Color c : mStyleStrokeMap.values()) { - c.dispose(); - } - mStyleStrokeMap.clear(); - - for (Color c : mStyleFillMap.values()) { - c.dispose(); - } - mStyleFillMap.clear(); - } - - //------------- - - @Override - public @NonNull IColor registerColor(int rgb) { - checkGC(); - - Integer key = Integer.valueOf(rgb); - ColorWrapper c = mColorMap.get(key); - if (c == null) { - c = new ColorWrapper(new Color(getGc().getDevice(), - (rgb >> 16) & 0xFF, - (rgb >> 8) & 0xFF, - (rgb >> 0) & 0xFF)); - mColorMap.put(key, c); - } - - return c; - } - - /** Returns the (cached) pixel height of the current font. */ - @Override - public int getFontHeight() { - if (mFontHeight < 1) { - checkGC(); - FontMetrics fm = getGc().getFontMetrics(); - mFontHeight = fm.getHeight(); - } - return mFontHeight; - } - - @Override - public @NonNull IColor getForeground() { - Color c = getGc().getForeground(); - return new ColorWrapper(c); - } - - @Override - public @NonNull IColor getBackground() { - Color c = getGc().getBackground(); - return new ColorWrapper(c); - } - - @Override - public int getAlpha() { - return getGc().getAlpha(); - } - - @Override - public void setForeground(@NonNull IColor color) { - checkGC(); - getGc().setForeground(((ColorWrapper) color).getColor()); - } - - @Override - public void setBackground(@NonNull IColor color) { - checkGC(); - getGc().setBackground(((ColorWrapper) color).getColor()); - } - - @Override - public void setAlpha(int alpha) { - checkGC(); - try { - getGc().setAlpha(alpha); - } catch (SWTException e) { - // This means that we cannot set the alpha on this platform; this is - // an acceptable no-op. - } - } - - @Override - public void setLineStyle(@NonNull LineStyle style) { - int swtStyle = 0; - switch (style) { - case LINE_SOLID: - swtStyle = SWT.LINE_SOLID; - break; - case LINE_DASH: - swtStyle = SWT.LINE_DASH; - break; - case LINE_DOT: - swtStyle = SWT.LINE_DOT; - break; - case LINE_DASHDOT: - swtStyle = SWT.LINE_DASHDOT; - break; - case LINE_DASHDOTDOT: - swtStyle = SWT.LINE_DASHDOTDOT; - break; - default: - assert false : style; - break; - } - - if (swtStyle != 0) { - checkGC(); - getGc().setLineStyle(swtStyle); - } - } - - @Override - public void setLineWidth(int width) { - checkGC(); - if (width > 0) { - getGc().setLineWidth(width); - } - } - - // lines - - @Override - public void drawLine(int x1, int y1, int x2, int y2) { - checkGC(); - useStrokeAlpha(); - x1 = mHScale.translate(x1); - y1 = mVScale.translate(y1); - x2 = mHScale.translate(x2); - y2 = mVScale.translate(y2); - getGc().drawLine(x1, y1, x2, y2); - } - - @Override - public void drawLine(@NonNull Point p1, @NonNull Point p2) { - drawLine(p1.x, p1.y, p2.x, p2.y); - } - - // rectangles - - @Override - public void drawRect(int x1, int y1, int x2, int y2) { - checkGC(); - useStrokeAlpha(); - int x = mHScale.translate(x1); - int y = mVScale.translate(y1); - int w = mHScale.scale(x2 - x1); - int h = mVScale.scale(y2 - y1); - getGc().drawRectangle(x, y, w, h); - } - - @Override - public void drawRect(@NonNull Point p1, @NonNull Point p2) { - drawRect(p1.x, p1.y, p2.x, p2.y); - } - - @Override - public void drawRect(@NonNull Rect r) { - checkGC(); - useStrokeAlpha(); - int x = mHScale.translate(r.x); - int y = mVScale.translate(r.y); - int w = mHScale.scale(r.w); - int h = mVScale.scale(r.h); - getGc().drawRectangle(x, y, w, h); - } - - @Override - public void fillRect(int x1, int y1, int x2, int y2) { - checkGC(); - useFillAlpha(); - int x = mHScale.translate(x1); - int y = mVScale.translate(y1); - int w = mHScale.scale(x2 - x1); - int h = mVScale.scale(y2 - y1); - getGc().fillRectangle(x, y, w, h); - } - - @Override - public void fillRect(@NonNull Point p1, @NonNull Point p2) { - fillRect(p1.x, p1.y, p2.x, p2.y); - } - - @Override - public void fillRect(@NonNull Rect r) { - checkGC(); - useFillAlpha(); - int x = mHScale.translate(r.x); - int y = mVScale.translate(r.y); - int w = mHScale.scale(r.w); - int h = mVScale.scale(r.h); - getGc().fillRectangle(x, y, w, h); - } - - // circles (actually ovals) - - public void drawOval(int x1, int y1, int x2, int y2) { - checkGC(); - useStrokeAlpha(); - int x = mHScale.translate(x1); - int y = mVScale.translate(y1); - int w = mHScale.scale(x2 - x1); - int h = mVScale.scale(y2 - y1); - getGc().drawOval(x, y, w, h); - } - - public void drawOval(Point p1, Point p2) { - drawOval(p1.x, p1.y, p2.x, p2.y); - } - - public void drawOval(Rect r) { - checkGC(); - useStrokeAlpha(); - int x = mHScale.translate(r.x); - int y = mVScale.translate(r.y); - int w = mHScale.scale(r.w); - int h = mVScale.scale(r.h); - getGc().drawOval(x, y, w, h); - } - - public void fillOval(int x1, int y1, int x2, int y2) { - checkGC(); - useFillAlpha(); - int x = mHScale.translate(x1); - int y = mVScale.translate(y1); - int w = mHScale.scale(x2 - x1); - int h = mVScale.scale(y2 - y1); - getGc().fillOval(x, y, w, h); - } - - public void fillOval(Point p1, Point p2) { - fillOval(p1.x, p1.y, p2.x, p2.y); - } - - public void fillOval(Rect r) { - checkGC(); - useFillAlpha(); - int x = mHScale.translate(r.x); - int y = mVScale.translate(r.y); - int w = mHScale.scale(r.w); - int h = mVScale.scale(r.h); - getGc().fillOval(x, y, w, h); - } - - - // strings - - @Override - public void drawString(@NonNull String string, int x, int y) { - checkGC(); - useStrokeAlpha(); - x = mHScale.translate(x); - y = mVScale.translate(y); - // Background fill of text is not useful because it does not - // use the alpha; we instead supply a separate method (drawBoxedStrings) which - // first paints a semi-transparent mask for the text to sit on - // top of (this ensures that the text is readable regardless of - // colors of the pixels below the text) - getGc().drawString(string, x, y, true /*isTransparent*/); - } - - @Override - public void drawBoxedStrings(int x, int y, @NonNull List<?> strings) { - checkGC(); - - x = mHScale.translate(x); - y = mVScale.translate(y); - - // Compute bounds of the box by adding up the sum of the text heights - // and the max of the text widths - int width = 0; - int height = 0; - int lineHeight = getGc().getFontMetrics().getHeight(); - for (Object s : strings) { - org.eclipse.swt.graphics.Point extent = getGc().stringExtent(s.toString()); - height += extent.y; - width = Math.max(width, extent.x); - } - - // Paint a box below the text - int padding = 2; - useFillAlpha(); - getGc().fillRectangle(x - padding, y - padding, width + 2 * padding, height + 2 * padding); - - // Finally draw strings on top - useStrokeAlpha(); - int lineY = y; - for (Object s : strings) { - getGc().drawString(s.toString(), x, lineY, true /* isTransparent */); - lineY += lineHeight; - } - } - - @Override - public void drawString(@NonNull String string, @NonNull Point topLeft) { - drawString(string, topLeft.x, topLeft.y); - } - - // Styles - - @Override - public void useStyle(@NonNull DrawingStyle style) { - checkGC(); - - // Look up the specific SWT style which defines the actual - // colors and attributes to be used for the logical drawing style. - SwtDrawingStyle swtStyle = SwtDrawingStyle.of(style); - RGB stroke = swtStyle.getStrokeColor(); - if (stroke != null) { - Color color = getStrokeColor(style, stroke); - mGc.setForeground(color); - } - RGB fill = swtStyle.getFillColor(); - if (fill != null) { - Color color = getFillColor(style, fill); - mGc.setBackground(color); - } - mGc.setLineWidth(swtStyle.getLineWidth()); - mGc.setLineStyle(swtStyle.getLineStyle()); - if (swtStyle.getLineStyle() == SWT.LINE_CUSTOM) { - mGc.setLineDash(new int[] { - 8, 4 - }); - } - mCurrentStyle = swtStyle; - } - - /** Uses the stroke alpha for subsequent drawing operations. */ - private void useStrokeAlpha() { - mGc.setAlpha(mCurrentStyle.getStrokeAlpha()); - } - - /** Uses the fill alpha for subsequent drawing operations. */ - private void useFillAlpha() { - mGc.setAlpha(mCurrentStyle.getFillAlpha()); - } - - /** - * Get the SWT stroke color (foreground/border) to use for the given style, - * using the provided color description if we haven't seen this color yet. - * The color will also be placed in the {@link #mStyleStrokeMap} such that - * it can be disposed of at cleanup time. - * - * @param style The drawing style for which we want a color - * @param defaultColorDesc The RGB values to initialize the color to if we - * haven't seen this color before - * @return The color object - */ - private Color getStrokeColor(DrawingStyle style, RGB defaultColorDesc) { - return getStyleColor(style, defaultColorDesc, mStyleStrokeMap); - } - - /** - * Get the SWT fill (background/interior) color to use for the given style, - * using the provided color description if we haven't seen this color yet. - * The color will also be placed in the {@link #mStyleStrokeMap} such that - * it can be disposed of at cleanup time. - * - * @param style The drawing style for which we want a color - * @param defaultColorDesc The RGB values to initialize the color to if we - * haven't seen this color before - * @return The color object - */ - private Color getFillColor(DrawingStyle style, RGB defaultColorDesc) { - return getStyleColor(style, defaultColorDesc, mStyleFillMap); - } - - /** - * Get the SWT color to use for the given style, using the provided color - * description if we haven't seen this color yet. The color will also be - * placed in the map referenced by the map parameter such that it can be - * disposed of at cleanup time. - * - * @param style The drawing style for which we want a color - * @param defaultColorDesc The RGB values to initialize the color to if we - * haven't seen this color before - * @param map The color map to use - * @return The color object - */ - private Color getStyleColor(DrawingStyle style, RGB defaultColorDesc, - Map<DrawingStyle, Color> map) { - Color color = map.get(style); - if (color == null) { - color = new Color(getGc().getDevice(), defaultColorDesc); - map.put(style, color); - } - - return color; - } - - // dots - - @Override - public void drawPoint(int x, int y) { - checkGC(); - useStrokeAlpha(); - x = mHScale.translate(x); - y = mVScale.translate(y); - - getGc().drawPoint(x, y); - } - - // arrows - - private static final int MIN_LENGTH = 10; - - - @Override - public void drawArrow(int x1, int y1, int x2, int y2, int size) { - int arrowWidth = size; - int arrowHeight = size; - - checkGC(); - useStrokeAlpha(); - x1 = mHScale.translate(x1); - y1 = mVScale.translate(y1); - x2 = mHScale.translate(x2); - y2 = mVScale.translate(y2); - GC graphics = getGc(); - - // Make size adjustments to ensure that the arrow has enough width to be visible - if (x1 == x2 && Math.abs(y1 - y2) < MIN_LENGTH) { - int delta = (MIN_LENGTH - Math.abs(y1 - y2)) / 2; - if (y1 < y2) { - y1 -= delta; - y2 += delta; - } else { - y1 += delta; - y2-= delta; - } - - } else if (y1 == y2 && Math.abs(x1 - x2) < MIN_LENGTH) { - int delta = (MIN_LENGTH - Math.abs(x1 - x2)) / 2; - if (x1 < x2) { - x1 -= delta; - x2 += delta; - } else { - x1 += delta; - x2-= delta; - } - } - - graphics.drawLine(x1, y1, x2, y2); - - // Arrowhead: - - if (x1 == x2) { - // Vertical - if (y2 > y1) { - graphics.drawLine(x2 - arrowWidth, y2 - arrowHeight, x2, y2); - graphics.drawLine(x2 + arrowWidth, y2 - arrowHeight, x2, y2); - } else { - graphics.drawLine(x2 - arrowWidth, y2 + arrowHeight, x2, y2); - graphics.drawLine(x2 + arrowWidth, y2 + arrowHeight, x2, y2); - } - } else if (y1 == y2) { - // Horizontal - if (x2 > x1) { - graphics.drawLine(x2 - arrowHeight, y2 - arrowWidth, x2, y2); - graphics.drawLine(x2 - arrowHeight, y2 + arrowWidth, x2, y2); - } else { - graphics.drawLine(x2 + arrowHeight, y2 - arrowWidth, x2, y2); - graphics.drawLine(x2 + arrowHeight, y2 + arrowWidth, x2, y2); - } - } else { - // Compute angle: - int dy = y2 - y1; - int dx = x2 - x1; - double angle = Math.atan2(dy, dx); - double lineLength = Math.sqrt(dy * dy + dx * dx); - - // Imagine a line of the same length as the arrow, but with angle 0. - // Its two arrow lines are at (-arrowWidth, -arrowHeight) relative - // to the endpoint (x1 + lineLength, y1) stretching up to (x2,y2). - // We compute the positions of (ax,ay) for the point above and - // below this line and paint the lines to it: - double ax = x1 + lineLength - arrowHeight; - double ay = y1 - arrowWidth; - int rx = (int) (Math.cos(angle) * (ax-x1) - Math.sin(angle) * (ay-y1) + x1); - int ry = (int) (Math.sin(angle) * (ax-x1) + Math.cos(angle) * (ay-y1) + y1); - graphics.drawLine(x2, y2, rx, ry); - - ay = y1 + arrowWidth; - rx = (int) (Math.cos(angle) * (ax-x1) - Math.sin(angle) * (ay-y1) + x1); - ry = (int) (Math.sin(angle) * (ax-x1) + Math.cos(angle) * (ay-y1) + y1); - graphics.drawLine(x2, y2, rx, ry); - } - - /* TODO: Experiment with filled arrow heads? - if (x1 == x2) { - // Vertical - if (y2 > y1) { - for (int i = 0; i < arrowWidth; i++) { - graphics.drawLine(x2 - arrowWidth + i, y2 - arrowWidth + i, - x2 + arrowWidth - i, y2 - arrowWidth + i); - } - } else { - for (int i = 0; i < arrowWidth; i++) { - graphics.drawLine(x2 - arrowWidth + i, y2 + arrowWidth - i, - x2 + arrowWidth - i, y2 + arrowWidth - i); - } - } - } else if (y1 == y2) { - // Horizontal - if (x2 > x1) { - for (int i = 0; i < arrowHeight; i++) { - graphics.drawLine(x2 - arrowHeight + i, y2 - arrowHeight + i, x2 - - arrowHeight + i, y2 + arrowHeight - i); - } - } else { - for (int i = 0; i < arrowHeight; i++) { - graphics.drawLine(x2 + arrowHeight - i, y2 - arrowHeight + i, x2 - + arrowHeight - i, y2 + arrowHeight - i); - } - } - } else { - // Arbitrary angle -- need to use trig - // TODO: Implement this - } - */ - } -} |