1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.hierarchyviewerlib.ui; 18 19 import com.android.hierarchyviewerlib.models.PixelPerfectModel; 20 import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener; 21 22 import org.eclipse.swt.SWT; 23 import org.eclipse.swt.events.DisposeEvent; 24 import org.eclipse.swt.events.DisposeListener; 25 import org.eclipse.swt.events.PaintEvent; 26 import org.eclipse.swt.events.PaintListener; 27 import org.eclipse.swt.graphics.Color; 28 import org.eclipse.swt.graphics.Image; 29 import org.eclipse.swt.graphics.Point; 30 import org.eclipse.swt.graphics.RGB; 31 import org.eclipse.swt.widgets.Canvas; 32 import org.eclipse.swt.widgets.Composite; 33 import org.eclipse.swt.widgets.Display; 34 35 public class PixelPerfectPixelPanel extends Canvas implements IImageChangeListener { 36 private PixelPerfectModel mModel; 37 38 private Image mImage; 39 40 private Image mOverlayImage; 41 42 private Point mCrosshairLocation; 43 44 public static final int PREFERRED_WIDTH = 180; 45 46 public static final int PREFERRED_HEIGHT = 52; 47 48 public PixelPerfectPixelPanel(Composite parent) { 49 super(parent, SWT.NONE); 50 mModel = PixelPerfectModel.getModel(); 51 mModel.addImageChangeListener(this); 52 53 addPaintListener(mPaintListener); 54 addDisposeListener(mDisposeListener); 55 56 imageLoaded(); 57 } 58 59 @Override 60 public Point computeSize(int wHint, int hHint, boolean changed) { 61 int height = PREFERRED_HEIGHT; 62 int width = (wHint == SWT.DEFAULT) ? PREFERRED_WIDTH : wHint; 63 return new Point(width, height); 64 } 65 66 private DisposeListener mDisposeListener = new DisposeListener() { 67 @Override 68 public void widgetDisposed(DisposeEvent e) { 69 mModel.removeImageChangeListener(PixelPerfectPixelPanel.this); 70 } 71 }; 72 73 private PaintListener mPaintListener = new PaintListener() { 74 @Override 75 public void paintControl(PaintEvent e) { 76 synchronized (PixelPerfectPixelPanel.this) { 77 e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); 78 e.gc.fillRectangle(0, 0, getBounds().width, getBounds().height); 79 if (mImage != null) { 80 RGB pixel = 81 mImage.getImageData().palette.getRGB(mImage.getImageData().getPixel( 82 mCrosshairLocation.x, mCrosshairLocation.y)); 83 Color rgbColor = new Color(Display.getDefault(), pixel); 84 e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); 85 e.gc.setBackground(rgbColor); 86 e.gc.drawRectangle(4, 4, 60, 30); 87 e.gc.fillRectangle(5, 5, 59, 29); 88 rgbColor.dispose(); 89 e.gc.drawText("#" 90 + Integer 91 .toHexString( 92 (1 << 24) + (pixel.red << 16) + (pixel.green << 8) 93 + pixel.blue).substring(1), 4, 35, true); 94 e.gc.drawText("R:", 80, 4, true); 95 e.gc.drawText("G:", 80, 20, true); 96 e.gc.drawText("B:", 80, 35, true); 97 e.gc.drawText(Integer.toString(pixel.red), 97, 4, true); 98 e.gc.drawText(Integer.toString(pixel.green), 97, 20, true); 99 e.gc.drawText(Integer.toString(pixel.blue), 97, 35, true); 100 e.gc.drawText("X:", 132, 4, true); 101 e.gc.drawText("Y:", 132, 20, true); 102 e.gc.drawText(Integer.toString(mCrosshairLocation.x) + " px", 149, 4, true); 103 e.gc.drawText(Integer.toString(mCrosshairLocation.y) + " px", 149, 20, true); 104 105 if (mOverlayImage != null) { 106 int xInOverlay = mCrosshairLocation.x; 107 int yInOverlay = 108 mCrosshairLocation.y 109 - (mImage.getBounds().height - mOverlayImage.getBounds().height); 110 if (xInOverlay >= 0 && yInOverlay >= 0 111 && xInOverlay < mOverlayImage.getBounds().width 112 && yInOverlay < mOverlayImage.getBounds().height) { 113 pixel = 114 mOverlayImage.getImageData().palette.getRGB(mOverlayImage 115 .getImageData().getPixel(xInOverlay, yInOverlay)); 116 rgbColor = new Color(Display.getDefault(), pixel); 117 e.gc 118 .setForeground(Display.getDefault().getSystemColor( 119 SWT.COLOR_WHITE)); 120 e.gc.setBackground(rgbColor); 121 e.gc.drawRectangle(204, 4, 60, 30); 122 e.gc.fillRectangle(205, 5, 59, 29); 123 rgbColor.dispose(); 124 e.gc.drawText("#" 125 + Integer.toHexString( 126 (1 << 24) + (pixel.red << 16) + (pixel.green << 8) 127 + pixel.blue).substring(1), 204, 35, true); 128 e.gc.drawText("R:", 280, 4, true); 129 e.gc.drawText("G:", 280, 20, true); 130 e.gc.drawText("B:", 280, 35, true); 131 e.gc.drawText(Integer.toString(pixel.red), 297, 4, true); 132 e.gc.drawText(Integer.toString(pixel.green), 297, 20, true); 133 e.gc.drawText(Integer.toString(pixel.blue), 297, 35, true); 134 } 135 } 136 } 137 } 138 } 139 }; 140 141 private void doRedraw() { 142 Display.getDefault().syncExec(new Runnable() { 143 @Override 144 public void run() { 145 redraw(); 146 } 147 }); 148 } 149 150 @Override 151 public void crosshairMoved() { 152 synchronized (this) { 153 mCrosshairLocation = mModel.getCrosshairLocation(); 154 } 155 doRedraw(); 156 } 157 158 @Override 159 public void imageChanged() { 160 synchronized (this) { 161 mImage = mModel.getImage(); 162 } 163 doRedraw(); 164 } 165 166 @Override 167 public void imageLoaded() { 168 synchronized (this) { 169 mImage = mModel.getImage(); 170 mCrosshairLocation = mModel.getCrosshairLocation(); 171 mOverlayImage = mModel.getOverlayImage(); 172 } 173 doRedraw(); 174 } 175 176 @Override 177 public void overlayChanged() { 178 synchronized (this) { 179 mOverlayImage = mModel.getOverlayImage(); 180 } 181 doRedraw(); 182 } 183 184 @Override 185 public void overlayTransparencyChanged() { 186 // pass 187 } 188 189 @Override 190 public void selectionChanged() { 191 // pass 192 } 193 194 @Override 195 public void treeChanged() { 196 // pass 197 } 198 199 @Override 200 public void zoomChanged() { 201 // pass 202 } 203 } 204