diff options
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.java | 267 |
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); + } + } + } + } + } +} |