aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java267
1 files changed, 267 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java
new file mode 100644
index 000000000..353312c85
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/StretchesViewer.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.draw9patch.ui;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.GraphicsUtilities;
+import com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImage;
+import com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImage.Projection;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Preview 9-patched image pane.
+ */
+public class StretchesViewer extends Composite {
+ private static final boolean DEBUG = false;
+
+ private static final int PADDING_COLOR = 0x0000CC;
+
+ private static final int PADDING_COLOR_ALPHA = 100;
+
+ private static final PaletteData PADDING_PALLET
+ = new PaletteData(new RGB[] {new RGB(0x00, 0x00, 0xCC)});
+
+ private static final String CHECKER_PNG_PATH = "/icons/checker.png";
+
+ private Image mBackgroundLayer = null;
+
+ private final StretchView mHorizontal;
+ private final StretchView mVertical;
+
+ private final StretchView mBoth;
+
+ private NinePatchedImage mNinePatchedImage = null;
+
+ private ImageData mContentAreaImageData = null;
+
+ private boolean mIsContentAreaShown = false;
+
+ private Image mContentAreaImage = null;
+
+ private int mScale = 2;
+
+ public StretchesViewer(Composite parent, int style) {
+ super(parent, style);
+
+ mBackgroundLayer = AdtPlugin.getImageDescriptor(CHECKER_PNG_PATH).createImage();
+
+ setLayout(new FillLayout(SWT.VERTICAL));
+
+ mHorizontal = new StretchView(this, SWT.NULL);
+ mVertical = new StretchView(this, SWT.NULL);
+ mBoth = new StretchView(this, SWT.NULL);
+ }
+
+ /**
+ * Set show/not show content area.
+ * @param If show, true
+ */
+ public void setShowContentArea(boolean show) {
+ mIsContentAreaShown = show;
+ redraw();
+ }
+
+ private static final boolean equalSize(ImageData image1, ImageData image2) {
+ return (image1.width == image2.width && image1.height == image2.height);
+ }
+
+ /**
+ * Update preview image.
+ */
+ public void updatePreview(NinePatchedImage image) {
+ mNinePatchedImage = image;
+ ImageData base = mNinePatchedImage.getImageData();
+
+ if (mContentAreaImageData == null
+ || (mContentAreaImageData != null && !equalSize(base, mContentAreaImageData))) {
+ mContentAreaImageData = new ImageData(
+ base.width,
+ base.height,
+ 1,
+ PADDING_PALLET);
+ } else {
+ GraphicsUtilities.clearImageData(mContentAreaImageData);
+ }
+
+ mHorizontal.setImage(mNinePatchedImage);
+ mVertical.setImage(mNinePatchedImage);
+ mBoth.setImage(mNinePatchedImage);
+
+ mContentAreaImage = buildContentAreaPreview();
+
+ setScale(mScale);
+ }
+
+ private Image buildContentAreaPreview() {
+ if (mContentAreaImage != null) {
+ mContentAreaImage.dispose();
+ }
+
+ Rectangle rect = mNinePatchedImage.getContentArea();
+
+ int yLen = rect.y + rect.height;
+ for (int y = rect.y; y < yLen; y++) {
+ int xLen = rect.x + rect.width;
+ for (int x = rect.x; x < xLen; x++) {
+ mContentAreaImageData.setPixel(x, y, PADDING_COLOR);
+ mContentAreaImageData.setAlpha(x, y, PADDING_COLOR_ALPHA);
+ }
+ }
+ return new Image(AdtPlugin.getDisplay(), mContentAreaImageData);
+ }
+
+ public void setScale(int scale) {
+ if (DEBUG) {
+ System.out.println("scale = " + scale);
+ }
+
+ mScale = scale;
+ int imageWidth = mNinePatchedImage.getWidth();
+ int imageHeight = mNinePatchedImage.getHeight();
+
+ mHorizontal.setSize(imageWidth * scale, imageHeight);
+ mVertical.setSize(imageWidth, imageHeight * scale);
+ mBoth.setSize(imageWidth * scale, imageHeight * scale);
+
+ redraw();
+ }
+
+ @Override
+ public void dispose() {
+ mBackgroundLayer.dispose();
+ super.dispose();
+ }
+
+ private class StretchView extends Canvas implements PaintListener {
+
+ private final Point mSize = new Point(0, 0);
+ private final Rectangle mPadding = new Rectangle(0, 0, 0, 0);
+ private Projection[][] mProjection = null;
+
+ public StretchView(Composite parent, int style) {
+ super(parent, style);
+ addPaintListener(this);
+ }
+
+ private void setImage(NinePatchedImage image) {
+ setSize(image.getWidth(), image.getHeight());
+ }
+
+ @Override
+ public void setSize(int width, int heigh) {
+ mSize.x = width;
+ mSize.y = heigh;
+ mProjection = mNinePatchedImage.getProjections(mSize.x, mSize.y, mProjection);
+ }
+
+ private synchronized void calcPaddings(int width, int height) {
+ Point canvasSize = getSize();
+
+ mPadding.x = (canvasSize.x - width) / 2;
+ mPadding.y = (canvasSize.y - height) / 2;
+
+ mPadding.width = width;
+ mPadding.height = height;
+ }
+
+ @Override
+ public void paintControl(PaintEvent pe) {
+ if (mNinePatchedImage == null || mProjection == null) {
+ return;
+ }
+
+ Point size = getSize();
+
+ // relative scaling
+ float ratio = 1.0f;
+ float wRatio = ((float) size.x / mSize.x);
+ ratio = Math.min(wRatio, ratio);
+ float hRatio = ((float) size.y / mSize.y);
+ ratio = Math.min(hRatio, ratio);
+
+ int width = Math.round(mSize.x * ratio);
+ int height = Math.round(mSize.y * ratio);
+
+ calcPaddings(width, height);
+
+ Rectangle dest = new Rectangle(0, 0, 0, 0);
+
+ GC gc = pe.gc;
+
+ int backgroundLayerWidth = mBackgroundLayer.getImageData().width;
+ int backgroundLayerHeight = mBackgroundLayer.getImageData().height;
+
+ int yCount = size.y / backgroundLayerHeight
+ + ((size.y % backgroundLayerHeight) > 0 ? 1 : 0);
+ int xCount = size.x / backgroundLayerWidth
+ + ((size.x % backgroundLayerWidth) > 0 ? 1 : 0);
+
+ // draw background layer
+ for (int y = 0; y < yCount; y++) {
+ for (int x = 0; x < xCount; x++) {
+ gc.drawImage(mBackgroundLayer,
+ x * backgroundLayerWidth,
+ y * backgroundLayerHeight);
+ }
+ }
+
+ // draw the border line
+ gc.setAlpha(0x88);
+ gc.drawRectangle(0, 0, size.x, size.y);
+ gc.setAlpha(0xFF);
+
+ int yLen = mProjection.length;
+ int xLen = mProjection[0].length;
+ for (int yPos = 0; yPos < yLen; yPos++) {
+ for (int xPos = 0; xPos < xLen; xPos++) {
+ Projection p = mProjection[yPos][xPos];
+
+ // consider the scale
+ dest.x = (int) Math.ceil(p.dest.x * ratio);
+ dest.y = (int) Math.ceil(p.dest.y * ratio);
+ dest.width = (int) Math.ceil(p.dest.width * ratio);
+ dest.height = (int) Math.ceil(p.dest.height * ratio);
+
+ gc.drawImage(mNinePatchedImage.getImage(), p.src.x, p.src.y,
+ p.src.width, p.src.height,
+ (mPadding.x + dest.x), (mPadding.y + dest.y),
+ dest.width, dest.height);
+
+ if (mIsContentAreaShown) {
+ gc.drawImage(mContentAreaImage, p.src.x, p.src.y,
+ p.src.width, p.src.height,
+ (mPadding.x + dest.x), (mPadding.y + dest.y),
+ dest.width, dest.height);
+ }
+ }
+ }
+ }
+ }
+}