/*
* Copyright (C) 2010 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.hierarchyviewerlib.ui;
import com.android.hierarchyviewerlib.models.PixelPerfectModel;
import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
public class PixelPerfectPixelPanel extends Canvas implements IImageChangeListener {
private PixelPerfectModel mModel;
private Image mImage;
private Image mOverlayImage;
private Point mCrosshairLocation;
public static final int PREFERRED_WIDTH = 180;
public static final int PREFERRED_HEIGHT = 52;
public PixelPerfectPixelPanel(Composite parent) {
super(parent, SWT.NONE);
mModel = PixelPerfectModel.getModel();
mModel.addImageChangeListener(this);
addPaintListener(mPaintListener);
addDisposeListener(mDisposeListener);
imageLoaded();
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
int height = PREFERRED_HEIGHT;
int width = (wHint == SWT.DEFAULT) ? PREFERRED_WIDTH : wHint;
return new Point(width, height);
}
private DisposeListener mDisposeListener = new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
mModel.removeImageChangeListener(PixelPerfectPixelPanel.this);
}
};
private PaintListener mPaintListener = new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
synchronized (PixelPerfectPixelPanel.this) {
e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
e.gc.fillRectangle(0, 0, getBounds().width, getBounds().height);
if (mImage != null) {
RGB pixel =
mImage.getImageData().palette.getRGB(mImage.getImageData().getPixel(
mCrosshairLocation.x, mCrosshairLocation.y));
Color rgbColor = new Color(Display.getDefault(), pixel);
e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
e.gc.setBackground(rgbColor);
e.gc.drawRectangle(4, 4, 60, 30);
e.gc.fillRectangle(5, 5, 59, 29);
rgbColor.dispose();
e.gc.drawText("#"
+ Integer
.toHexString(
(1 << 24) + (pixel.red << 16) + (pixel.green << 8)
+ pixel.blue).substring(1), 4, 35, true);
e.gc.drawText("R:", 80, 4, true);
e.gc.drawText("G:", 80, 20, true);
e.gc.drawText("B:", 80, 35, true);
e.gc.drawText(Integer.toString(pixel.red), 97, 4, true);
e.gc.drawText(Integer.toString(pixel.green), 97, 20, true);
e.gc.drawText(Integer.toString(pixel.blue), 97, 35, true);
e.gc.drawText("X:", 132, 4, true);
e.gc.drawText("Y:", 132, 20, true);
e.gc.drawText(Integer.toString(mCrosshairLocation.x) + " px", 149, 4, true);
e.gc.drawText(Integer.toString(mCrosshairLocation.y) + " px", 149, 20, true);
if (mOverlayImage != null) {
int xInOverlay = mCrosshairLocation.x;
int yInOverlay =
mCrosshairLocation.y
- (mImage.getBounds().height - mOverlayImage.getBounds().height);
if (xInOverlay >= 0 && yInOverlay >= 0
&& xInOverlay < mOverlayImage.getBounds().width
&& yInOverlay < mOverlayImage.getBounds().height) {
pixel =
mOverlayImage.getImageData().palette.getRGB(mOverlayImage
.getImageData().getPixel(xInOverlay, yInOverlay));
rgbColor = new Color(Display.getDefault(), pixel);
e.gc
.setForeground(Display.getDefault().getSystemColor(
SWT.COLOR_WHITE));
e.gc.setBackground(rgbColor);
e.gc.drawRectangle(204, 4, 60, 30);
e.gc.fillRectangle(205, 5, 59, 29);
rgbColor.dispose();
e.gc.drawText("#"
+ Integer.toHexString(
(1 << 24) + (pixel.red << 16) + (pixel.green << 8)
+ pixel.blue).substring(1), 204, 35, true);
e.gc.drawText("R:", 280, 4, true);
e.gc.drawText("G:", 280, 20, true);
e.gc.drawText("B:", 280, 35, true);
e.gc.drawText(Integer.toString(pixel.red), 297, 4, true);
e.gc.drawText(Integer.toString(pixel.green), 297, 20, true);
e.gc.drawText(Integer.toString(pixel.blue), 297, 35, true);
}
}
}
}
}
};
private void doRedraw() {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
redraw();
}
});
}
@Override
public void crosshairMoved() {
synchronized (this) {
mCrosshairLocation = mModel.getCrosshairLocation();
}
doRedraw();
}
@Override
public void imageChanged() {
synchronized (this) {
mImage = mModel.getImage();
}
doRedraw();
}
@Override
public void imageLoaded() {
synchronized (this) {
mImage = mModel.getImage();
mCrosshairLocation = mModel.getCrosshairLocation();
mOverlayImage = mModel.getOverlayImage();
}
doRedraw();
}
@Override
public void overlayChanged() {
synchronized (this) {
mOverlayImage = mModel.getOverlayImage();
}
doRedraw();
}
@Override
public void overlayTransparencyChanged() {
// pass
}
@Override
public void selectionChanged() {
// pass
}
@Override
public void treeChanged() {
// pass
}
@Override
public void zoomChanged() {
// pass
}
}