aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/ImageViewer.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/ImageViewer.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/ImageViewer.java774
1 files changed, 774 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/ImageViewer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/ImageViewer.java
new file mode 100644
index 000000000..2414a39d7
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/draw9patch/ui/ImageViewer.java
@@ -0,0 +1,774 @@
+/*
+ * 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.NinePatchedImage;
+import com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImage.Chunk;
+import com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImage.Tick;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+
+/**
+ * View and edit Draw 9-patch image.
+ */
+public class ImageViewer extends Canvas implements PaintListener, KeyListener, MouseListener,
+ MouseMoveListener {
+ private static final boolean DEBUG = false;
+
+ public static final String HELP_MESSAGE_KEY_TIPS = "Press Shift to erase pixels."
+ + " Press Control to draw layout bounds.";
+
+ public static final String HELP_MESSAGE_KEY_TIPS2 = "Release Shift to draw pixels.";
+
+ private static final Color BLACK_COLOR = AdtPlugin.getDisplay().getSystemColor(SWT.COLOR_BLACK);
+ private static final Color RED_COLOR = AdtPlugin.getDisplay().getSystemColor(SWT.COLOR_RED);
+
+ private static final Color BACK_COLOR
+ = new Color(AdtPlugin.getDisplay(), new RGB(0x00, 0xFF, 0x00));
+ private static final Color LOCK_COLOR
+ = new Color(AdtPlugin.getDisplay(), new RGB(0xFF, 0x00, 0x00));
+ private static final Color PATCH_COLOR
+ = new Color(AdtPlugin.getDisplay(), new RGB(0xFF, 0xFF, 0x00));
+ private static final Color PATCH_ONEWAY_COLOR
+ = new Color(AdtPlugin.getDisplay(), new RGB(0x00, 0x00, 0xFF));
+ private static final Color CORRUPTED_COLOR
+ = new Color(AdtPlugin.getDisplay(), new RGB(0xFF, 0x00, 0x00));
+
+ private static final int NONE_ALPHA = 0xFF;
+ private static final int LOCK_ALPHA = 50;
+ private static final int PATCH_ALPHA = 50;
+ private static final int GUIDE_ALPHA = 60;
+
+ private static final int MODE_NONE = 0x00;
+ private static final int MODE_BLACK_TICK = 0x01;
+ private static final int MODE_RED_TICK = 0x02;
+ private static final int MODE_ERASE = 0xFF;
+
+ private int mDrawMode = MODE_NONE;
+
+ private static final int MARGIN = 5;
+ private static final String CHECKER_PNG_PATH = "/icons/checker.png";
+
+ private Image mBackgroundLayer = null;
+
+ private NinePatchedImage mNinePatchedImage = null;
+
+ private Chunk[][] mChunks = null;
+ private Chunk[][] mBadChunks = null;
+
+ private boolean mIsLockShown = true;
+ private boolean mIsPatchesShown = false;
+ private boolean mIsBadPatchesShown = false;
+
+ private ScrollBar mHorizontalBar;
+ private ScrollBar mVerticalBar;
+
+ private int mZoom = 500;
+
+ private int mHorizontalScroll = 0;
+ private int mVerticalScroll = 0;
+
+ private final Rectangle mPadding = new Rectangle(0, 0, 0, 0);
+
+ // one pixel size that considered zoom
+ private int mZoomedPixelSize = 1;
+
+ private Image mBufferImage = null;
+
+ private boolean isCtrlPressed = false;
+ private boolean isShiftPressed = false;
+
+ private final List<UpdateListener> mUpdateListenerList
+ = new ArrayList<UpdateListener>();
+
+ private final Point mCursorPoint = new Point(0, 0);
+
+ private static final int DEFAULT_UPDATE_QUEUE_SIZE = 10;
+
+ private final ArrayBlockingQueue<NinePatchedImage> mUpdateQueue
+ = new ArrayBlockingQueue<NinePatchedImage>(DEFAULT_UPDATE_QUEUE_SIZE);
+
+ private final Runnable mUpdateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (isDisposed()) {
+ return;
+ }
+
+ redraw();
+
+ fireUpdateEvent();
+ }
+ };
+
+ private final Thread mUpdateThread = new Thread() {
+ @Override
+ public void run() {
+ while (!isDisposed()) {
+ try {
+ mUpdateQueue.take();
+ mNinePatchedImage.findPatches();
+ mNinePatchedImage.findContentsArea();
+
+ mChunks = mNinePatchedImage.getChunks(mChunks);
+ mBadChunks = mNinePatchedImage.getCorruptedChunks(mBadChunks);
+
+ AdtPlugin.getDisplay().asyncExec(mUpdateRunnable);
+
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ };
+
+ private StatusChangedListener mStatusChangedListener = null;
+
+ public void addUpdateListener(UpdateListener l) {
+ mUpdateListenerList.add(l);
+ }
+
+ public void removeUpdateListener(UpdateListener l) {
+ mUpdateListenerList.remove(l);
+ }
+
+ private void fireUpdateEvent() {
+ int len = mUpdateListenerList.size();
+ for(int i=0; i < len; i++) {
+ mUpdateListenerList.get(i).update(mNinePatchedImage);
+ }
+ }
+
+ public void setStatusChangedListener(StatusChangedListener l) {
+ mStatusChangedListener = l;
+ if (mStatusChangedListener != null) {
+ mStatusChangedListener.helpTextChanged(HELP_MESSAGE_KEY_TIPS);
+ }
+ }
+
+ void setShowLock(boolean show) {
+ mIsLockShown = show;
+ redraw();
+ }
+
+ void setShowPatchesArea(boolean show) {
+ mIsPatchesShown = show;
+ redraw();
+ }
+
+ void setShowBadPatchesArea(boolean show) {
+ mIsBadPatchesShown = show;
+ redraw();
+ }
+
+ void setZoom(int zoom) {
+ mZoom = zoom;
+ mZoomedPixelSize = getZoomedPixelSize(1);
+ redraw();
+ }
+
+ public ImageViewer(Composite parent, int style) {
+ super(parent, style);
+
+ mUpdateThread.start();
+
+ mBackgroundLayer = AdtPlugin.getImageDescriptor(CHECKER_PNG_PATH).createImage();
+
+ addMouseListener(this);
+ addMouseMoveListener(this);
+ addPaintListener(this);
+
+ mHorizontalBar = getHorizontalBar();
+ mHorizontalBar.setThumb(1);
+ mHorizontalBar.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ super.widgetSelected(event);
+ ScrollBar bar = (ScrollBar) event.widget;
+ if (mHorizontalBar.isVisible()
+ && mHorizontalScroll != bar.getSelection()) {
+ mHorizontalScroll = bar.getSelection();
+ redraw();
+ }
+ }
+ });
+
+ mVerticalBar = getVerticalBar();
+ mVerticalBar.setThumb(1);
+ mVerticalBar.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ super.widgetSelected(event);
+ ScrollBar bar = (ScrollBar) event.widget;
+ if (mVerticalBar.isVisible()
+ && mVerticalScroll != bar.getSelection()) {
+ mVerticalScroll = bar.getSelection();
+ redraw();
+ }
+ }
+ });
+ }
+
+ /**
+ * Load the image file.
+ *
+ * @param fileName must be absolute path
+ */
+ public NinePatchedImage loadFile(String fileName) {
+ mNinePatchedImage = new NinePatchedImage(fileName);
+
+ return mNinePatchedImage;
+ }
+
+ /**
+ * Start displaying the image.
+ */
+ public void startDisplay() {
+ mZoomedPixelSize = getZoomedPixelSize(1);
+
+ scheduleUpdate();
+ }
+
+ private void draw(int x, int y, int drawMode) {
+ if (drawMode == MODE_ERASE) {
+ erase(x, y);
+ } else {
+ int color = (drawMode == MODE_RED_TICK) ? NinePatchedImage.RED_TICK
+ : NinePatchedImage.BLACK_TICK;
+ mNinePatchedImage.setPatch(x, y, color);
+ redraw();
+
+ scheduleUpdate();
+ }
+ }
+
+ private void erase(int x, int y) {
+ mNinePatchedImage.erase(x, y);
+ redraw();
+
+ scheduleUpdate();
+ }
+
+ private void scheduleUpdate() {
+ try {
+ mUpdateQueue.put(mNinePatchedImage);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ @Override
+ public void mouseDown(MouseEvent event) {
+ if (event.button == 1 && !isShiftPressed) {
+ mDrawMode = !isCtrlPressed ? MODE_BLACK_TICK : MODE_RED_TICK;
+ draw(mCursorPoint.x, mCursorPoint.y, mDrawMode);
+ } else if (event.button == 3 || isShiftPressed) {
+ mDrawMode = MODE_ERASE;
+ erase(mCursorPoint.x, mCursorPoint.y);
+ }
+ }
+
+ @Override
+ public void mouseUp(MouseEvent event) {
+ mDrawMode = MODE_NONE;
+ }
+
+ @Override
+ public void mouseDoubleClick(MouseEvent event) {
+ }
+
+ private int getLogicalPositionX(int x) {
+ return Math.round((x - mPadding.x + mHorizontalScroll) / ((float) mZoom / 100));
+ }
+
+ private int getLogicalPositionY(int y) {
+ return Math.round((y - mPadding.y + mVerticalScroll) / ((float) mZoom / 100));
+ }
+
+ @Override
+ public void mouseMove(MouseEvent event) {
+ int posX = getLogicalPositionX(event.x);
+ int posY = getLogicalPositionY(event.y);
+
+ int width = mNinePatchedImage.getWidth();
+ int height = mNinePatchedImage.getHeight();
+
+ if (posX < 0) {
+ posX = 0;
+ }
+ if (posX >= width) {
+ posX = width - 1;
+ }
+ if (posY < 0) {
+ posY = 0;
+ }
+ if (posY >= height) {
+ posY = height - 1;
+ }
+
+ if (mDrawMode != MODE_NONE) {
+ int drawMode = mDrawMode;
+ if (isShiftPressed) {
+ drawMode = MODE_ERASE;
+ } else if (mDrawMode != MODE_ERASE) {
+ drawMode = !isCtrlPressed ? MODE_BLACK_TICK : MODE_RED_TICK;
+ }
+
+ /*
+ * Consider the previous cursor position because mouseMove events are
+ * scatter.
+ */
+ int x = mCursorPoint.x;
+ int y = mCursorPoint.y;
+ for (; y != posY; y += (y > posY) ? -1 : 1) {
+ draw(x, y, drawMode);
+ }
+
+ x = mCursorPoint.x;
+ y = mCursorPoint.y;
+ for (; x != posX; x += (x > posX) ? -1 : 1) {
+ draw(x, y, drawMode);
+ }
+ }
+ mCursorPoint.x = posX;
+ mCursorPoint.y = posY;
+
+ redraw();
+
+ if (mStatusChangedListener != null) {
+ // Update position on status panel if position is in logical size.
+ if (posX >= 0 && posY >= 0
+ && posX <= mNinePatchedImage.getWidth()
+ && posY <= mNinePatchedImage.getHeight()) {
+ mStatusChangedListener.cursorPositionChanged(posX + 1, posY + 1);
+ }
+ }
+ }
+
+ private synchronized void calcPaddings(int width, int height) {
+ Point canvasSize = getSize();
+
+ mPadding.width = getZoomedPixelSize(width);
+ mPadding.height = getZoomedPixelSize(height);
+
+ int margin = getZoomedPixelSize(MARGIN);
+
+ if (mPadding.width < canvasSize.x) {
+ mPadding.x = (canvasSize.x - mPadding.width) / 2;
+ } else {
+ mPadding.x = margin;
+ }
+
+ if (mPadding.height < canvasSize.y) {
+ mPadding.y = (canvasSize.y - mPadding.height) / 2;
+ } else {
+ mPadding.y = margin;
+ }
+ }
+
+ private void calcScrollBarSettings() {
+ Point size = getSize();
+ int screenWidth = size.x;
+ int screenHeight = size.y;
+
+ int imageWidth = getZoomedPixelSize(mNinePatchedImage.getWidth() + 1);
+ int imageHeight = getZoomedPixelSize(mNinePatchedImage.getHeight() + 1);
+
+ // consider the scroll bar sizes
+ int verticalBarSize = mVerticalBar.getSize().x;
+ int horizontalBarSize = mHorizontalBar.getSize().y;
+
+ int horizontalScroll = imageWidth - (screenWidth - verticalBarSize);
+ int verticalScroll = imageHeight - (screenHeight - horizontalBarSize);
+
+ int margin = getZoomedPixelSize(MARGIN) * 2;
+
+ if (horizontalScroll > 0) {
+ mHorizontalBar.setVisible(true);
+
+ // horizontal maximum
+ int max = horizontalScroll + verticalBarSize + margin;
+ mHorizontalBar.setMaximum(max);
+
+ // set corrected scroll size
+ int value = mHorizontalBar.getSelection();
+ value = max < value ? max : value;
+
+ mHorizontalBar.setSelection(value);
+ mHorizontalScroll = value;
+
+ } else {
+ mHorizontalBar.setSelection(0);
+ mHorizontalBar.setMaximum(0);
+ mHorizontalBar.setVisible(false);
+ }
+
+ if (verticalScroll > 0) {
+ mVerticalBar.setVisible(true);
+
+ // vertical maximum
+ int max = verticalScroll + horizontalBarSize + margin;
+ mVerticalBar.setMaximum(max);
+
+ // set corrected scroll size
+ int value = mVerticalBar.getSelection();
+ value = max < value ? max : value;
+
+ mVerticalBar.setSelection(value);
+ mVerticalScroll = value;
+
+ } else {
+ mVerticalBar.setSelection(0);
+ mVerticalBar.setMaximum(0);
+ mVerticalBar.setVisible(false);
+ }
+ }
+
+ private int getZoomedPixelSize(int val) {
+ return Math.round(val * (float) mZoom / 100);
+ }
+
+ @Override
+ public void paintControl(PaintEvent pe) {
+ if (mNinePatchedImage == null) {
+ return;
+ }
+
+ // Use buffer
+ GC bufferGc = null;
+ if (mBufferImage == null) {
+ mBufferImage = new Image(AdtPlugin.getDisplay(), pe.width, pe.height);
+ } else {
+ int width = mBufferImage.getBounds().width;
+ int height = mBufferImage.getBounds().height;
+ if (width != pe.width || height != pe.height) {
+ mBufferImage = new Image(AdtPlugin.getDisplay(), pe.width, pe.height);
+ }
+ }
+
+ // Draw previous image once for prevent flicking
+ pe.gc.drawImage(mBufferImage, 0, 0);
+
+ bufferGc = new GC(mBufferImage);
+ bufferGc.setAdvanced(true);
+
+ // Make interpolation disable
+ bufferGc.setInterpolation(SWT.NONE);
+
+ // clear buffer
+ bufferGc.fillRectangle(0, 0, pe.width, pe.height);
+
+ calcScrollBarSettings();
+
+ // padding from current zoom
+ int width = mNinePatchedImage.getWidth();
+ int height = mNinePatchedImage.getHeight();
+ calcPaddings(width, height);
+
+ int baseX = mPadding.x - mHorizontalScroll;
+ int baseY = mPadding.y - mVerticalScroll;
+
+ // draw checker image
+ bufferGc.drawImage(mBackgroundLayer,
+ 0, 0, mBackgroundLayer.getImageData().width,
+ mBackgroundLayer.getImageData().height,
+ baseX, baseY, mPadding.width, mPadding.height);
+
+ if (DEBUG) {
+ System.out.println(String.format("%d,%d %d,%d %d,%d",
+ width, height, baseX, baseY, mPadding.width, mPadding.height));
+ }
+
+ // draw image
+ /* TODO: Do not draw invisible area, for better performance. */
+ bufferGc.drawImage(mNinePatchedImage.getImage(), 0, 0, width, height, baseX, baseY,
+ mPadding.width, mPadding.height);
+
+ bufferGc.setBackground(BLACK_COLOR);
+
+ // draw patch ticks
+ drawHorizontalPatches(bufferGc, baseX, baseY);
+ drawVerticalPatches(bufferGc, baseX, baseY);
+
+ // draw content ticks
+ drawHorizontalContentArea(bufferGc, baseX, baseY);
+ drawVerticalContentArea(bufferGc, baseX, baseY);
+
+ if (mNinePatchedImage.isValid(mCursorPoint.x, mCursorPoint.y)) {
+ bufferGc.setForeground(BLACK_COLOR);
+ } else if (mIsLockShown) {
+ drawLockArea(bufferGc, baseX, baseY);
+ }
+
+ // Patches
+ if (mIsPatchesShown) {
+ drawPatchAreas(bufferGc, baseX, baseY);
+ }
+
+ // Bad patches
+ if (mIsBadPatchesShown) {
+ drawBadPatchAreas(bufferGc, baseX, baseY);
+ }
+
+ if (mNinePatchedImage.isValid(mCursorPoint.x, mCursorPoint.y)) {
+ bufferGc.setForeground(BLACK_COLOR);
+ } else {
+ bufferGc.setForeground(RED_COLOR);
+ }
+
+ drawGuideLine(bufferGc, baseX, baseY);
+
+ bufferGc.dispose();
+
+ pe.gc.drawImage(mBufferImage, 0, 0);
+ }
+
+ private static final Color getColor(int color) {
+ switch (color) {
+ case NinePatchedImage.RED_TICK:
+ return RED_COLOR;
+ default:
+ return BLACK_COLOR;
+ }
+ }
+
+ private void drawVerticalPatches(GC gc, int baseX, int baseY) {
+ List<Tick> verticalPatches = mNinePatchedImage.getVerticalPatches();
+ for (Tick t : verticalPatches) {
+ if (t.color != NinePatchedImage.TRANSPARENT_TICK) {
+ gc.setBackground(getColor(t.color));
+ gc.fillRectangle(
+ baseX,
+ baseY + getZoomedPixelSize(t.start),
+ mZoomedPixelSize,
+ getZoomedPixelSize(t.getLength()));
+ }
+ }
+ }
+
+ private void drawHorizontalPatches(GC gc, int baseX, int baseY) {
+ List<Tick> horizontalPatches = mNinePatchedImage.getHorizontalPatches();
+ for (Tick t : horizontalPatches) {
+ if (t.color != NinePatchedImage.TRANSPARENT_TICK) {
+ gc.setBackground(getColor(t.color));
+ gc.fillRectangle(
+ baseX + getZoomedPixelSize(t.start),
+ baseY,
+ getZoomedPixelSize(t.getLength()),
+ mZoomedPixelSize);
+ }
+ }
+ }
+
+ private void drawHorizontalContentArea(GC gc, int baseX, int baseY) {
+ List<Tick> horizontalContentArea = mNinePatchedImage.getHorizontalContents();
+ for (Tick t : horizontalContentArea) {
+ if (t.color != NinePatchedImage.TRANSPARENT_TICK) {
+ gc.setBackground(getColor(t.color));
+ gc.fillRectangle(
+ baseX + getZoomedPixelSize(t.start),
+ baseY + getZoomedPixelSize(mNinePatchedImage.getHeight() - 1),
+ getZoomedPixelSize(t.getLength()),
+ mZoomedPixelSize);
+ }
+ }
+
+ }
+
+ private void drawVerticalContentArea(GC gc, int baseX, int baseY) {
+ List<Tick> verticalContentArea = mNinePatchedImage.getVerticalContents();
+ for (Tick t : verticalContentArea) {
+ if (t.color != NinePatchedImage.TRANSPARENT_TICK) {
+ gc.setBackground(getColor(t.color));
+ gc.fillRectangle(
+ baseX + getZoomedPixelSize(mNinePatchedImage.getWidth() - 1),
+ baseY + getZoomedPixelSize(t.start),
+ mZoomedPixelSize,
+ getZoomedPixelSize(t.getLength()));
+ }
+ }
+ }
+
+ private void drawLockArea(GC gc, int baseX, int baseY) {
+ gc.setAlpha(LOCK_ALPHA);
+ gc.setForeground(LOCK_COLOR);
+ gc.setBackground(LOCK_COLOR);
+
+ gc.fillRectangle(
+ baseX + mZoomedPixelSize,
+ baseY + mZoomedPixelSize,
+ getZoomedPixelSize(mNinePatchedImage.getWidth() - 2),
+ getZoomedPixelSize(mNinePatchedImage.getHeight() - 2));
+ gc.setAlpha(NONE_ALPHA);
+
+ }
+
+ private void drawPatchAreas(GC gc, int baseX, int baseY) {
+ if (mChunks != null) {
+ int yLen = mChunks.length;
+ int xLen = mChunks[0].length;
+
+ gc.setAlpha(PATCH_ALPHA);
+
+ for (int yPos = 0; yPos < yLen; yPos++) {
+ for (int xPos = 0; xPos < xLen; xPos++) {
+ Chunk c = mChunks[yPos][xPos];
+
+ if (c.type == Chunk.TYPE_FIXED) {
+ gc.setBackground(BACK_COLOR);
+ } else if (c.type == Chunk.TYPE_HORIZONTAL) {
+ gc.setBackground(PATCH_ONEWAY_COLOR);
+ } else if (c.type == Chunk.TYPE_VERTICAL) {
+ gc.setBackground(PATCH_ONEWAY_COLOR);
+ } else if (c.type == Chunk.TYPE_HORIZONTAL + Chunk.TYPE_VERTICAL) {
+ gc.setBackground(PATCH_COLOR);
+ }
+ Rectangle r = c.rect;
+ gc.fillRectangle(
+ baseX + getZoomedPixelSize(r.x),
+ baseY + getZoomedPixelSize(r.y),
+ getZoomedPixelSize(r.width),
+ getZoomedPixelSize(r.height));
+ }
+ }
+ }
+ gc.setAlpha(NONE_ALPHA);
+ }
+
+ private void drawBadPatchAreas(GC gc, int baseX, int baseY) {
+ if (mBadChunks != null) {
+ int yLen = mBadChunks.length;
+ int xLen = mBadChunks[0].length;
+
+ gc.setAlpha(NONE_ALPHA);
+ gc.setForeground(CORRUPTED_COLOR);
+ gc.setBackground(CORRUPTED_COLOR);
+
+ for (int yPos = 0; yPos < yLen; yPos++) {
+ for (int xPos = 0; xPos < xLen; xPos++) {
+ Chunk c = mBadChunks[yPos][xPos];
+ if ((c.type & Chunk.TYPE_CORRUPT) != 0) {
+ Rectangle r = c.rect;
+ gc.drawRectangle(
+ baseX + getZoomedPixelSize(r.x),
+ baseY + getZoomedPixelSize(r.y),
+ getZoomedPixelSize(r.width),
+ getZoomedPixelSize(r.height));
+ }
+ }
+ }
+ }
+ }
+
+ private void drawGuideLine(GC gc, int baseX, int baseY) {
+ gc.setAntialias(SWT.ON);
+ gc.setInterpolation(SWT.HIGH);
+
+ int x = Math.round((mCursorPoint.x * ((float) mZoom / 100) + baseX)
+ + ((float) mZoom / 100 / 2));
+ int y = Math.round((mCursorPoint.y * ((float) mZoom / 100) + baseY)
+ + ((float) mZoom / 100 / 2));
+ gc.setAlpha(GUIDE_ALPHA);
+
+ Point size = getSize();
+ gc.drawLine(x, 0, x, size.y);
+ gc.drawLine(0, y, size.x, y);
+
+ gc.setAlpha(NONE_ALPHA);
+ }
+
+ @Override
+ public void keyPressed(KeyEvent event) {
+ int keycode = event.keyCode;
+ if (keycode == SWT.CTRL) {
+ isCtrlPressed = true;
+ }
+ if (keycode == SWT.SHIFT) {
+ isShiftPressed = true;
+ if (mStatusChangedListener != null) {
+ mStatusChangedListener.helpTextChanged(HELP_MESSAGE_KEY_TIPS2);
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event) {
+ int keycode = event.keyCode;
+ if (keycode == SWT.CTRL) {
+ isCtrlPressed = false;
+ }
+ if (keycode == SWT.SHIFT) {
+ isShiftPressed = false;
+ if (mStatusChangedListener != null) {
+ mStatusChangedListener.helpTextChanged(HELP_MESSAGE_KEY_TIPS);
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ mBackgroundLayer.dispose();
+ super.dispose();
+ }
+
+ /**
+ * Listen image updated event.
+ */
+ public interface UpdateListener {
+ /**
+ * 9-patched image has been updated.
+ */
+ public void update(NinePatchedImage image);
+ }
+
+ /**
+ * Listen status changed event.
+ */
+ public interface StatusChangedListener {
+ /**
+ * Mouse cursor position has been changed.
+ */
+ public void cursorPositionChanged(int x, int y);
+
+ /**
+ * Help text has been changed.
+ */
+ public void helpTextChanged(String text);
+ }
+}