/******************************************************************************* * Jimm - Mobile Messaging - J2ME ICQ clone * Copyright (C) 2003-05 Jimm Project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. *getName * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************** * File: src/jimm/modules/photo/ViewFinder.java * Version: ###VERSION### Date: ###DATE### * Author(s): Andreas Rossbacher, Dmitry Tunin, Vladimir Kryukov *******************************************************************************/ // #sijapp cond.if modules_FILES="true"# package jimm.modules.photo; // #sijapp cond.if modules_ANDROID isnot "true" # import jimmui.view.text.*; import java.io.*; import javax.microedition.lcdui.*; import javax.microedition.media.*; import javax.microedition.media.control.*; import jimm.*; import jimm.cl.ContactList; import jimm.comm.Util; import jimm.modules.*; import jimmui.view.base.*; import jimm.util.JLocale; /** ************************************************************************* */ /** ************************************************************************* */ // Class for viewfinder public class ViewFinder extends Canvas implements Runnable { // Variables private Player player = null; private VideoControl videoControl = null; private MyActionBar bar = new MyActionBar(); private MySoftBar softBar = new MySoftBar(); private Par errorMessage = null; private byte[] data; private static final byte STATE_CAPTURE = 0; private static final byte STATE_PREEVIEW = 1; private static final byte STATE_DONE = 2; private byte state = STATE_CAPTURE; private static int takePhotoMethod = 0; private Image thumbnailImage = null; private PhotoListener listener; private final GraphicsEx gx = new GraphicsEx(); // #sijapp cond.if modules_TOUCH is "true"# private int touchKey = 0; private int touchStartX = 0; // #sijapp cond.end# private static int useSize = getPhotoSize(); private static final String[] sizes = {"", "320x240", "480x640", "640x480", "1280x960", "2048x1536"}; private static final String[] keys = {"", "width=320&height=240", "width=480&height=640", "width=640&height=480", "width=1280&height=960", "width=2048&height=1536"}; private int width = 0; private int height = 0; protected void sizeChanged(int w, int h) { if ((0 == w) || (0 == h)) return; boolean prev = width < height; boolean next = w < h; if (prev != next) { width = w; height = h; if (STATE_CAPTURE == state) { start(); repaint(); } } } private static int getPhotoSize() { if (Jimm.getJimm().phone.isPhone(PhoneInfo.PHONE_NOKIA)) { return 1; } if (Jimm.getJimm().phone.isPhone(PhoneInfo.PHONE_SE)) { return 3; } return 0; } public void show() { Jimm.getJimm().getDisplay().show(this); width = getWidth(); height = getHeight(); start(); } public void setPhotoListener(PhotoListener l) { listener = l; } private void back() { dismiss(); Jimm.getJimm().getDisplay().back(this); } public ViewFinder() { } private void setError(JimmException err) { state = STATE_PREEVIEW; Parser parser = new Parser(GraphicsEx.contactListFontSet, getWidth() * 8 / 10); byte color = CanvasEx.THEME_CAP_TEXT; if (0 < (gx.getThemeColor(CanvasEx.THEME_CAP_TEXT) & 0x808080)) { color = CanvasEx.THEME_CAP_BACKGROUND; } parser.addText(err.getMessage(), color, CanvasEx.FONT_STYLE_PLAIN); errorMessage = parser.getPar(); repaint(); } public void paint(Graphics g) { gx.setGraphics(g); String caption = (STATE_CAPTURE == state) ? "viewfinder" : "send_img"; caption = JLocale.getString(caption); if (0 < useSize) { caption += " " + sizes[useSize]; } bar.setCaption(caption); int captionHeight = bar.getHeight(); int softBarHeight = softBar.getHeight(); int scrWidth = getWidth(); int scrHeight = getHeight() - softBarHeight - captionHeight; g.setColor(0xffffffff); g.fillRect(0, captionHeight, scrWidth, scrHeight); g.setColor(0x00000000); if (STATE_PREEVIEW == state) { if (null != errorMessage) { errorMessage.paint(GraphicsEx.contactListFontSet, gx, scrWidth / 10, (scrHeight - errorMessage.getHeight()) / 2, 0, errorMessage.getHeight()); } else if (null != thumbnailImage) { g.drawImage(thumbnailImage, scrWidth / 2, scrHeight / 2, Graphics.VCENTER | Graphics.HCENTER); } else { g.drawString("...", scrWidth / 2 - 5, scrHeight / 2, Graphics.TOP | Graphics.LEFT); } } bar.paint(gx, null, getWidth()); softBar.setSoftBarLabels((null == errorMessage) ? JLocale.getString("ok") : "", "", JLocale.getString("back"), true); softBar.paint(gx, this); } private VideoControl createPlayer(String url) throws IOException, MediaException { player = Manager.createPlayer(url); player.realize(); return (VideoControl) player.getControl("VideoControl"); } private void updateVideoLocation(VideoControl vControl) { if (null == vControl) return; vControl.setVisible(false); int captionHeight = GraphicsEx.calcCaptionHeight(null, ""); int softBarHeight = gx.getSoftBarSize(); int canvasWidth = getWidth(); int canvasHeight = getHeight() - softBarHeight - captionHeight; try { vControl.setDisplayLocation(0, captionHeight); vControl.setDisplaySize(canvasWidth, canvasHeight); int displayWidth = vControl.getDisplayWidth(); int displayHeight = vControl.getDisplayHeight(); int x = (canvasWidth - displayWidth) / 2; int y = captionHeight + (canvasHeight - displayHeight) / 2; vControl.setDisplayLocation(x, y); } catch (MediaException me) { try { vControl.setDisplayFullScreen(true); } catch (MediaException ignored) { } } vControl.setVisible(true); } private void initVideo() throws JimmException { reset(); try { VideoControl vControl = null; // Create the player // #sijapp cond.if target is "MIDP2" # try { if (Jimm.getJimm().phone.isPhone(PhoneInfo.PHONE_NOKIA_S40)) { vControl = createPlayer("capture://image"); } } catch (Exception ignored) { } // #sijapp cond.end # if (null == vControl) { vControl = createPlayer("capture://video"); } if (null == vControl) { throw new JimmException(180, 0); } vControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this); updateVideoLocation(vControl); player.start(); videoControl = vControl; } catch (IOException ioe) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("initVideo (ioe)", ioe); // #sijapp cond.end# throw new JimmException(181, 0); } catch (MediaException me) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("initVideo (me)", me); // #sijapp cond.end# throw new JimmException(181, 1); } catch (SecurityException se) { throw new JimmException(181, 2); } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("initVideo (e)", e); // #sijapp cond.end# throw new JimmException(181, 3); } } // start the viewfinder private synchronized void start() { state = STATE_CAPTURE; stop(); try { initVideo(); } catch (JimmException e) { stop(); setError(e); } } private synchronized void reset() { thumbnailImage = null; data = null; } // stop the viewfinder private synchronized void stop() { if (null != videoControl) { try { videoControl.setVisible(false); // Remove video control at SE phones placing it beyond screen border // #sijapp cond.if target is "MIDP2" # if (Jimm.getJimm().phone.isPhone(PhoneInfo.PHONE_SE)) { videoControl.setDisplayLocation(1000, 1000); } // #sijapp cond.end # } catch (Exception ignored) { } } videoControl = null; if (null != player) { try { player.stop(); } catch (Exception ignored) { } try { player.close(); } catch (Exception ignored) { } } player = null; Jimm.gc(); } private byte[] getSnapshot(String type) { try { return videoControl.getSnapshot(type); } catch (SecurityException e) { return null; } catch (Exception ignored) { // #sijapp cond.if modules_DEBUGLOG is "true" # //DebugLog.panic("getSnapshot(" + type + ")", e); // #sijapp cond.end# return null; } } // take a snapshot form the viewfinder private byte[] takeSnapshot() { final String[] urls = {"encoding=jpeg&width=320&height=240", "encoding=jpeg&width=480&height=640", "encoding=jpeg&width=640&height=480", "encoding=jpeg", "JPEG", null}; byte[] photo = null; if (0 < useSize) { return getSnapshot("encoding=jpeg&" + keys[useSize]); } for (int i = takePhotoMethod; i < urls.length; ++i) { if (null != photo) { break; } photo = getSnapshot(urls[i]); if (null != photo) { takePhotoMethod = i; return photo; } } takePhotoMethod = 0; return null; } public void takePhoto() { if (null != player) { data = null; try { data = takeSnapshot(); } catch (OutOfMemoryError e) { data = null; } stop(); repaint(); if (null == data) { setError(new JimmException(183, 0)); } else { try { thumbnailImage = createImage(); repaint(); } catch (OutOfMemoryError e) { thumbnailImage = null; data = null; setError(new JimmException(183, 1)); } } } } private Image createImage() { Image img = Image.createImage(data, 0, data.length); int captionHeight = GraphicsEx.calcCaptionHeight(null, ""); int softBarHeight = gx.getSoftBarSize(); int scrWidth = getWidth(); int scrHeight = getHeight() - softBarHeight - captionHeight; return Util.createThumbnail(img, scrWidth, scrHeight); } public void dismiss() { state = STATE_DONE; stop(); data = null; thumbnailImage = null; listener = null; } public synchronized void run() { takePhoto(); } protected void keyPressed(int key) { // #sijapp cond.if modules_LIGHT is "true" # CustomLight.setLightMode(CustomLight.ACTION_KEY_PRESS); // #sijapp cond.end# int keyCode = Jimm.getJimm().getDisplay().getNativeCanvas().getKey(key); int action = Jimm.getJimm().getDisplay().getNativeCanvas().getAction(keyCode, key); doKeyPressed(keyCode, action); } // #sijapp cond.if modules_TOUCH is "true"# private int getTouchKey(int x) { switch (x / (getWidth() / 3)) { case 0: return NativeCanvas.LEFT_SOFT; case 1: return NativeCanvas.NAVIKEY_FIRE; case 2: return NativeCanvas.RIGHT_SOFT; } return 0; } protected void pointerReleased(int x, int y) { Jimm.getJimm().getCL().userActivity(); if (y > getClientHeight()) { final int key = getTouchKey(x); if (key == touchKey) { doKeyPressed(key, key); } } else { int delta = x - touchStartX; if (getWidth() / 3 < Math.abs(delta)) { final int key = (delta < 0) ? NativeCanvas.NAVIKEY_LEFT : NativeCanvas.NAVIKEY_RIGHT; doKeyPressed(key, key); } } touchKey = 0; } protected void pointerPressed(int x, int y) { Jimm.getJimm().getCL().userActivity(); // #sijapp cond.if modules_LIGHT is "true" # CustomLight.setLightMode(CustomLight.ACTION_KEY_PRESS); // #sijapp cond.end# touchKey = (y < getClientHeight()) ? 0 : getTouchKey(x); touchStartX = x; } protected void pointerDragged(int x, int y) { // #sijapp cond.if modules_LIGHT is "true" # CustomLight.setLightMode(CustomLight.ACTION_KEY_PRESS); // #sijapp cond.end# } private int getClientHeight() { return getHeight() - gx.getSoftBarSize(); } // #sijapp cond.end# // Key pressed public void doKeyPressed(int keyCode, int actionCode) { if ((STATE_CAPTURE == state) && (NativeCanvas.CAMERA_KEY == actionCode)) { actionCode = NativeCanvas.NAVIKEY_FIRE; } switch (actionCode) { case NativeCanvas.RIGHT_SOFT: case NativeCanvas.CLOSE_KEY: if ((STATE_CAPTURE == state) || (null != errorMessage)) { back(); } else if (STATE_PREEVIEW == state) { start(); } break; case NativeCanvas.LEFT_SOFT: case NativeCanvas.NAVIKEY_FIRE: if (STATE_CAPTURE == state) { state = STATE_PREEVIEW; new Thread(this).start(); } else if (null != thumbnailImage) { stop(); try { listener.processPhoto(data); dismiss(); } catch (Exception ignored) { setError(new JimmException(191, 4)); } } break; case NativeCanvas.NAVIKEY_LEFT: useSize = (useSize - 1 + sizes.length) % sizes.length; repaint(); break; case NativeCanvas.NAVIKEY_RIGHT: useSize = (useSize + 1) % sizes.length; repaint(); break; } } } // #sijapp cond.end # // #sijapp cond.end #