package modules.image; // переведен import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; import java.util.Timer; import java.io.*; import com.vmx.*; import com.one.*; import com.one.vector.*; import com.one.file.*; import filemanager.ColorScheme; import filemanager.images; import filemanager.main; import java.util.Enumeration; import java.util.TimerTask; /** * Класс - просмотрщик картинок */ public class cvsImageView extends gkcCanvas implements Runnable { public static final int MODE_NULL = 0; public static final int MODE_NORMAL = 1; public static final int MODE_VECTOR = 2; private ImageContainer currentImage = null; private int mode; private boolean rotate; private int trans; private boolean scaled; private boolean enableUI = true; private int pictureWidth, pictureHeight; private int currWidth, currHeight; private double pictureAspect; private int w, h; private double aspect; private int curposx, curposy; private String OnlyFileName = ""; private Font nameFont; private int hstep, vstep; private int navx, navy, navw, navh; // большой прямоугольник private int navcx, navcy, navcw, navch; // малый примоугольник private Timer timer = null; private boolean isshown; private int runpanel; private PlayList playlist; private boolean allowKeyRelease = true; protected static class AnimationTask extends TimerTask { protected ImageContainer image; protected PaintableObject canvas; public AnimationTask(ImageContainer image, PaintableObject canvas) { this.image = image; this.canvas = canvas; } public void run() { synchronized(image) { image.nextFrame(); } canvas.repaint(); canvas.serviceRepaints(); } } private static cvsImageView instance; public static void loadInstance() { if(instance == null) { instance = new cvsImageView(); } } public static cvsImageView getInstance() { loadInstance(); return instance; } /** * Конструктор */ public cvsImageView() { setFullScreenMode(true); w = getWidth(); h = getHeight(); aspect = (double)w / (double)h; nameFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL); //fgimage = images.createUI(w, h); runpanel = -1; } public void setPlayList(PlayList newlist) { playlist = newlist; } public void setPlayList(Enumeration newlist) { playlist = new PlayList(newlist); } protected void initPanels() { if(timer != null) { timer.cancel(); timer = null; } mode = MODE_NULL; currentImage = null; if(runpanel < 0) { runpanel = main.manager.currentPanel(); } main.manager.setCurrent(this, runpanel); main.manager.updateAssociation(runpanel, playlist.getCurrentElement()); main.manager.changePanel(runpanel); } protected void initPlayList(String file) { OnlyFileName = file.substring(file.lastIndexOf('/') + 1); if(playlist == null) { playlist = new PlayList(file); } playlist.selectElement(file); } protected void initDisplay() { // Прячем картинку за пределы экрана на время curposx = w; curposy = h; pictureWidth = currentImage.getWidth(); pictureHeight = currentImage.getHeight(); switch(ImageOptions.rotateMode) { default: case 0: rotate = false; trans = Sprite.TRANS_NONE; break; case 1: rotate = true; trans = Sprite.TRANS_ROT90; break; case 2: rotate = false; trans = Sprite.TRANS_ROT180; break; case 3: rotate = true; trans = Sprite.TRANS_ROT270; break; case 4: if(pictureWidth > pictureHeight) { rotate = true; trans = Sprite.TRANS_ROT90; } break; case 5: if(pictureWidth > pictureHeight) { rotate = true; trans = Sprite.TRANS_ROT270; } break; } if(ImageOptions.scaleImages) { pictureAspect = (double)pictureWidth / (double)pictureHeight; if(rotate) //если поворачиваем { /* экран повернут, так что ширина это h и высота это w */ if(pictureAspect > (1 / aspect)) //вписываем по ширине { currentImage.scale(h, (int)(h / pictureAspect)); } else //вписываем по высоте { currentImage.scale((int)(w * pictureAspect), w); } } else //если не поворачиваем { if(pictureAspect > aspect) //вписываем по ширине { currentImage.scale(w, (int)(w / pictureAspect)); } else //вписываем по высоте { currentImage.scale((int)(h * pictureAspect), h); } } // SHIT! Что-то мне подсказывает, что это можно было сделать проще... } currWidth = currentImage.getWidth(); currHeight = currentImage.getHeight(); if(currWidth != pictureWidth || currHeight != pictureHeight) { scaled = true; hstep = vstep = 0; } else { scaled = false; hstep = vstep = (w + h) / 6; } if(rotate) { currWidth ^= currHeight; currHeight ^= currWidth; currWidth ^= currHeight; } if(currWidth > currHeight) // изображение горизонтальное { navw = w / 4; navh = navw * currHeight / currWidth; } else { navh = w / 4; navw = navh * currWidth / currHeight; } navx = w - navw - 4; navy = 3; curposx = (w - currWidth) / 2; curposy = (h - currHeight) / 2; } public void displayImageFromStream(InputStream is, String imgName) { initPanels(); mode = MODE_NORMAL; initPlayList(imgName); repaint(); serviceRepaints(); try { currentImage = new GenericImageContainer(Image.createImage(is)); is.close(); } catch(Exception x) { ErrScreen.showErrMsg(123, x); // x.printStackTrace(); // // currentImage = new TestImageContainer(); // OnlyFileName = x.toString(); } initDisplay(); repaint(); } public void displayImage(String imgName) { try { FileConnection fc = (FileConnection)Connector.open("file:///" + imgName, Connector.READ); displayImageFromStream(fc.openInputStream(), imgName); } catch(Exception e) { } } public void displayVectorImageFromStream(InputStream is, String imgName) { initPanels(); mode = MODE_VECTOR; currentImage = null; initPlayList(imgName); repaint(); try { is = new DataInputStream(is); currentImage = new VectorImageContainer(new VectorImage((DataInputStream)is)); is.close(); } catch(Exception x) { ErrScreen.showErrMsg(124, x); // x.printStackTrace(); // // currentImage = new TestImageContainer(); // OnlyFileName = x.toString(); } initDisplay(); repaint(); } public void displayVectorImage(String imgName) { try { FileConnection fc = (FileConnection)Connector.open("file:///" + imgName, Connector.READ); displayVectorImageFromStream(fc.openInputStream(), imgName); } catch(Exception e) { } } /** * Функция отрисовки */ public void paint(Graphics g) { g.setColor(images.cImgBack); // 0x000000); g.fillRect(0, 0, w, h); // фон if(currentImage != null) { currentImage.paint(g, curposx, curposy, trans); } if(enableUI) { if(currentImage != null && (currWidth > w || currHeight > h)) { // ----- прямоугольники в правом верхнем углу ----- g.setColor(ColorScheme.colors[ColorScheme.back1]); g.fillRect(navx, navy, navw, navh); if(currWidth > w) { navcw = navw * w / currWidth; navcx = navx - curposx * navw / currWidth; } else { navcw = navw; navcx = navx; } if(currHeight > h) { navch = navh * h / currHeight; navcy = navy - curposy * navh / currHeight; } else { navch = navh; navcy = navy; } /* - такого не должно быть - см. условия выше if(navcw > navw) { navcw = navw; } if(navch > navh) { navch = navh; } if(navcx < navx) { navcx = navx; } else if(navcx + navcw > navx + navw) { navcx = navx + navw - navcw; } if(navcy < navy) { navcy = navy; } else if(navcy + navch > navy + navh) { navcy = navy + navh - navch; } */ g.setColor(ColorScheme.colors[ColorScheme.fore]); g.fillRect(navcx + 1, navcy + 1, navcw, navch); g.setColor(ColorScheme.colors[ColorScheme.dkborder]); g.drawRect(navx, navy, navw, navh); // ----- закончились прямоугольники ----- } if(images.minUI != null) { g.drawImage(images.minUI, 0, h, Graphics.LEFT | Graphics.BOTTOM); } g.setFont(nameFont); g.setColor(images.cPlayFore1); //0x800000); g.drawString(OnlyFileName, w / 2, h - images.uiBottomHeight + images.uiBottomVSpace, Graphics.TOP | Graphics.HCENTER); if(currentImage != null) { String tmp = pictureWidth + " x " + pictureHeight + " ("; if(scaled) { tmp += Locale.getString(this, Locale.IMAGEVIEW_SCALED) + ", "; } if(mode == MODE_VECTOR && currentImage != null) { tmp += Integer.toString(currentImage.currentFrame()); } else { switch(trans) { case Sprite.TRANS_NONE: tmp += "0°"; break; case Sprite.TRANS_ROT90: tmp += "90°"; break; case Sprite.TRANS_ROT180: tmp += "180°"; break; case Sprite.TRANS_ROT270: tmp += "270°"; break; } } tmp += ")"; g.setColor(images.cPlayFore2); //0x000080); g.drawString(tmp, w / 2, h - images.uiBottomVSpace, Graphics.BOTTOM | Graphics.HCENTER); } } } public void keyReleased(int keyCode) { if(allowKeyRelease) { handleKeyAction(keyCode); } else { allowKeyRelease = true; } } public void keyRepeated(int keyCode) { allowKeyRelease = false; handleKeyAction(keyCode); } /** * Обработчик нажатий клавиш */ public void handleKeyAction(int keyCode) { keyCode = rotateKey(keyCode, trans); if(keyCode == KEY_POUND) { enableUI = !enableUI; repaint(); } else if(keyCode == KEY_DOWN || keyCode == KEY_RIGHT) // Следующая картинка { nextPicture(); } else if(keyCode == KEY_UP || keyCode == KEY_LEFT) // Предыдущ картинка { prevPicture(); } else if(keyCode == KEY_LSK) { if(mode == MODE_VECTOR) { if(timer != null) { timer.cancel(); timer = null; } else { timer = new Timer(); timer.scheduleAtFixedRate(new AnimationTask(currentImage, this), 0, currentImage.getFrameDelay()); } } } else if(keyCode == KEY_RSK) // Выход { if(timer != null) { timer.cancel(); timer = null; } mode = MODE_NULL; playlist.cancelSearch(); playlist = null; main.manager.ret(); runpanel = -1; } else if(keyCode == KEY_CANCEL) // сворачиваемся { main.manager.minimizePanel(); } else if(keyCode == KEY_NUM4) { curposx += hstep; if(curposx > 0) { curposx = 0; } repaint(); } else if(keyCode == KEY_NUM6) { curposx -= hstep; if(curposx < w - currWidth) { curposx = w - currWidth; } repaint(); } else if(keyCode == KEY_NUM2) { curposy += vstep; if(curposy > 0) { curposy = 0; } repaint(); } else if(keyCode == KEY_NUM8) { curposy -= vstep; if(curposy < h - currHeight) { curposy = h - currHeight; } repaint(); } else if(keyCode == KEY_NUM5) { curposx = (w - currWidth) / 2; curposy = (h - currHeight) / 2; repaint(); } else if(keyCode == KEY_STAR) { if(++ImageOptions.rotateMode > 3) { ImageOptions.rotateMode = 0; } redisplay(); } else if(keyCode == KEY_NUM0) { // если не вышло масштабировать, // то нечего и переключать boolean wasrunning = timer != null; int prevframe = currentImage.currentFrame(); if(wasrunning) { timer.cancel(); timer = null; } ImageOptions.scaleImages = !scaled; redisplay(); currentImage.gotoFrame(prevframe); if(wasrunning) { timer = new Timer(); timer.scheduleAtFixedRate(new AnimationTask(currentImage, this), 0, currentImage.getFrameDelay()); } } else if(keyCode == KEY_NUM1) { if(timer == null) { if(mode == MODE_VECTOR) { currentImage.prevFrame(); repaint(); } } } else if(keyCode == KEY_NUM3) { if(timer == null) { if(mode == MODE_VECTOR) { currentImage.nextFrame(); repaint(); } } } else if(keyCode == KEY_NUM7) { if(timer == null) { if(mode == MODE_VECTOR) { currentImage.gotoFrame(currentImage.currentFrame() - 10); repaint(); } } } else if(keyCode == KEY_NUM9) { if(timer == null) { if(mode == MODE_VECTOR) { currentImage.gotoFrame(currentImage.currentFrame() + 10); repaint(); } } } } /** * следующая картинка */ public void nextPicture() { playlist.nextElement(false); main.FileSelect.executeFile(playlist, null, runpanel); } /** * предыдущая картинка */ public void prevPicture() { playlist.prevElement(false); main.FileSelect.executeFile(playlist, null, runpanel); } private void redisplay() { if(mode == MODE_VECTOR) { currentImage.scale(-1, -1); initDisplay(); repaint(); } else { main.FileSelect.executeFile(playlist, null, runpanel); } } public void showNotify() { isshown = true; if(ImageOptions.useAccelerometer) { (new Thread(this, "ImageView/AccelEvent")).start(); } } public void hideNotify() { isshown = false; } public void run() { while(isshown) { int delta = main.accelerometer.getDelta(0, 1200); if(currentImage != null || currentImage != null) { if(delta != 0) { if(delta > 0) { nextPicture(); } else { prevPicture(); } } } try { Thread.sleep(300); } catch(InterruptedException ie) { } } } }