/* * Copyright © 2012 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See LICENSE.TXT for license information. */ package com.nokia.example.paint.views; import com.nokia.example.paint.Main; import com.nokia.example.paint.helpers.DrawableLine; import com.nokia.example.paint.touch.MultiTouchListener; import com.nokia.example.paint.touch.MultiTouch; import com.nokia.example.paint.views.components.ColorChangeListener; import com.nokia.example.paint.views.components.ColorPicker; import com.nokia.example.paint.views.components.ColorTool; import com.nokia.example.paint.views.components.ColorToolS60; import com.nokia.example.paint.views.components.FileSaveDialog; import com.nokia.example.paint.views.components.Toolbar; import java.util.Timer; import java.util.TimerTask; import java.util.Vector; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import javax.microedition.lcdui.game.GameCanvas; public class DrawArea extends GameCanvas implements ColorChangeListener, MultiTouchListener { public static final int SMALL_BRUSH = 4; public static final int MEDIUM_BRUSH = 6; public static final int LARGE_BRUSH = 8; public static final int XL_BRUSH = 10; private final int TOUCH_POINTS; private Graphics g; private Timer mTimer; private int[] previousX; private int[] previousY; private int brushWidth = SMALL_BRUSH; private Image drawing; private Graphics dg; private Toolbar toolbar; private ColorPicker colorpicker; private FileSaveDialog savedialog; private boolean drawingAllowed = true; private boolean renderDrawing = false; private Vector[] buffers; public DrawArea() { super(false); setFullScreenMode(true); int width = getWidth(); int height = getHeight(); drawing = Image.createImage(width, height - Toolbar.HEIGHT); dg = drawing.getGraphics(); toolbar = new Toolbar(width); ColorTool colortool = width > 240 ? new ColorToolS60() : new ColorTool(); colortool.colorChanged(0x000000); // initial color toolbar.addTool(colortool, 1); colorpicker = new ColorPicker(width); colorpicker.addListener(this); colorpicker.addListener(colortool); savedialog = new FileSaveDialog(this); MultiTouch.setTouchListener(this); TOUCH_POINTS = MultiTouch.getMaxPointers(); buffers = new Vector[TOUCH_POINTS]; previousX = new int[TOUCH_POINTS]; previousY = new int[TOUCH_POINTS]; for (int i = 0; i < TOUCH_POINTS; i++) { buffers[i] = new Vector(); previousX[i] = -1; previousY[i] = -1; } } protected void showNotify() { mTimer = new Timer(); g = getGraphics(); g.drawImage(drawing, 0, Toolbar.HEIGHT, Graphics.LEFT | Graphics.TOP); TimerTask ui = new TimerTask() { public void run() { render(); flushGraphics(); } }; mTimer.schedule(ui, 0, 60); } protected void hideNotify() { mTimer.cancel(); } protected void render() { g.setClip(0, 0, getWidth(), getHeight()); toolbar.render(g); if (renderDrawing) { g.drawImage(drawing, 0, Toolbar.HEIGHT, Graphics.LEFT | Graphics.TOP); renderDrawing = false; } else { if (drawingAllowed) { boolean changed = false; for (int i = 0; i < TOUCH_POINTS; i++) { Vector buffer = buffers[i]; if (!buffer.isEmpty()) { renderLines(buffer); changed = true; } } if (changed) { g.drawImage(drawing, 0, Toolbar.HEIGHT, Graphics.LEFT | Graphics.TOP); } } else { g.drawImage(drawing, 0, Toolbar.HEIGHT, Graphics.LEFT | Graphics.TOP); } colorpicker.render(g); savedialog.render(g); } } private void renderLines(Vector buffer) { int l = buffer.size(); DrawableLine[] currentLines = new DrawableLine[buffer.size()]; for (int i = 0; i < l; i++) { currentLines[i] = (DrawableLine) buffer.elementAt(i); } int s = currentLines.length; float divider = brushWidth / 3; for (int j = 0; j < s; j++) { DrawableLine line = currentLines[j]; buffer.removeElement(line); int startX = line.startX; int startY = line.startY; int endX = line.endX; int endY = line.endY; if (startX > 0 && startY > 0 && endX > 0 && endY > 0) { float d = calcDistance(startX , startY , endX, endY); if (d > divider) { int steps = (int) (d / divider + 0.5); float dx = (endX - startX ) / (float) steps; float dy = (endY - startY ) / (float) steps; for (int i = 0; i < steps; i++) { int x = (int) (startX + dx * i + 0.5); int y = (int) (startY + dy * i + 0.5); dg.fillArc(x, y - ToolBar.HEIGHT, brushWidth, brushWidth, 0, 360); } } dg.fillArc((int) endX, (int) endY - ToolBar.HEIGHT, brushWidth, brushWidth, 0, 360); } } } private float calcDistance(float x1, float y1, float x2, float y2) { return (float) (Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))); } public void pointerPressed(int x, int y) { if (TOUCH_POINTS == 1) { // Prevent redundant calls pointerPressed(x, y, 0); } } public void pointerDragged(int x, int y) { if (TOUCH_POINTS == 1) { pointerDragged(x, y, 0); } } public void pointerReleased(int x, int y) { if (TOUCH_POINTS == 1) { pointerReleased(x, y, 0); } } public void pointerPressed(int x, int y, int id) { if (drawingAllowed) { if (y > Toolbar.HEIGHT) { buffers[id].addElement(new DrawableLine(x, y, x, y)); previousX[id] = x; previousY[id] = y; } else { toolbar.pointerPressed(x, y); } } else if (savedialog.isVisible()) { savedialog.pointerPressed(x, y); } } public void pointerDragged(int x, int y, int id) { if (!drawingAllowed && colorpicker.isVisible()) { colorpicker.dragged(x, y); } else if (y > Toolbar.HEIGHT) { buffers[id].addElement(new DrawableLine(previousX[id], previousY[id], x, y)); previousX[id] = x; previousY[id] = y; } } public void pointerReleased(int x, int y, int id) { if (!drawingAllowed) { if (colorpicker.isVisible()) { colorpicker.pressed(x, y); } else if (savedialog.isVisible()) { savedialog.pointerUnpressed(x, y); } } else { previousX[id] = -1; previousY[id] = -1; toolbar.pointerUnpressed(x, y); } } public Image getDrawing() { return drawing; } public void setBrush(final int brushsize) { brushWidth = brushsize; } public void showColorPicker() { drawingAllowed = false; colorpicker.show(); } public void hideColorPicker() { colorpicker.hide(); g.drawImage(drawing, 0, Toolbar.HEIGHT, Graphics.TOP | Graphics.LEFT); drawingAllowed = true; } public void colorChanged(int brushColor) { dg.setColor(brushColor); } public void clearDrawing() { int oldcolor = dg.getColor(); dg.setColor(0xffffff); dg.fillRect(0, 0, drawing.getWidth(), drawing.getHeight()); dg.setColor(oldcolor); renderDrawing = true; } public void showSaveDialog() { drawingAllowed = false; String keyboard = System.getProperty("com.nokia.keyboard.type"); if ((keyboard != null && keyboard.equals("None")) || getWidth() > 240) { Main.getInstance().showSaveDialogS60(); } else { savedialog.show(); } } public void allowDrawing(boolean value) { if (value) { renderDrawing = true; } drawingAllowed = value; } }