/* * 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.drumkit.views; import com.nokia.example.drumkit.components.Button; import com.nokia.example.drumkit.components.Pad; import com.nokia.example.drumkit.components.AnimatedButton; import com.nokia.example.drumkit.components.WheelMenu; import com.nokia.example.drumkit.components.Rectangle; import com.nokia.example.drumkit.Main; import com.nokia.example.drumkit.helpers.ImageLoader; import com.nokia.example.drumkit.helpers.Sample; import com.nokia.example.drumkit.SoundManager; import java.util.Timer; import java.util.TimerTask; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import javax.microedition.lcdui.game.GameCanvas; import java.util.Vector; public class Drumkit extends GameCanvas implements Button.Listener, WheelMenu.Listener { private boolean playback = false; private boolean recording = false; private boolean pressed = false; private boolean kitEnabled = true; private int centerX = 0; private int centerY = 0; private int acivePad = -1; private final WheelMenu wheel; private final Image background; private final Image splash; private final Image appName; private final Pad pads[] = new Pad[4]; private Button startPlaybackBtn; private Button stopPlaybackBtn; private Button playBtn; private AnimatedButton recordBtn; private Button exitBtn; private Timer timer; private Timer drummer = new Timer(); private Timer longTapTimer; private Graphics g; private Vector tape; /** * Class containing the drumkit logic */ public Drumkit() { super(false); setFullScreenMode(true); centerX = getWidth() / 2; centerY = getHeight() / 2; // Load image resources background = ImageLoader.loadImage("/pads.png"); splash = ImageLoader.loadImage("/hit.png"); appName = ImageLoader.loadImage("/app_name.png"); createButtons(); createPads(); wheel = new WheelMenu(this); } /** * Create UI buttons */ public final void createButtons() { int y = getHeight() - 56; startPlaybackBtn = new Button("/play.png", "/play_pressed.png", "/play_disabled.png", this); startPlaybackBtn.setPosition(59, y); stopPlaybackBtn = new Button("/stop.png", "/stop_pressed.png", "/play_disabled.png", this); stopPlaybackBtn.setPosition(59, y); recordBtn = new AnimatedButton("/record_off.png", "/recording.png", "/record_disabled.png", 50, this); recordBtn.setPosition(9, y); recordBtn.setSelectable(true); exitBtn = new Button("/exit.png", "/exit_pressed.png", "/exit.png", this); exitBtn.setPosition(getWidth() - 48, 4); playBtn = startPlaybackBtn; playBtn.disable(); } /** * Define touch sensitive areas */ public final void createPads() { pads[0] = new Pad(SoundManager.SAMPLE_KICK, centerX - 0, centerY + 36, 107, 112); pads[1] = new Pad(SoundManager.SAMPLE_SNARE, centerX - 111, centerY - 38, 113, 113); pads[2] = new Pad(SoundManager.SAMPLE_TOM2, centerX + 8, centerY - 95, 105, 104); pads[3] = new Pad(SoundManager.SAMPLE_CRASH, centerX - 95, centerY - 148, 93, 93); } /** * Handle show events */ protected void showNotify() { timer = new Timer(); g = getGraphics(); /** * Start UI rendering loop */ TimerTask ui = new TimerTask() { public void run() { render(g); flushGraphics(); } }; timer.schedule(ui, 0, 50); } /** * Handle hide events */ protected void hideNotify() { timer.cancel(); } /** * Render graphics * @param g */ public void render(Graphics g) { int anchor = Graphics.HCENTER | Graphics.VCENTER; g.setColor(0xf0f0f0); g.fillRect(0, 0, getWidth(), getHeight()); g.drawImage(background, centerX, centerY, anchor); playBtn.paint(g); recordBtn.paint(g); exitBtn.paint(g); g.drawImage(appName, centerX + 34, 28, anchor); for (int i = 0; i < pads.length; i++) { Pad pad = pads[i]; if (pad != null && pad.isHit()) { Rectangle boundingBox = pad.getBoundingBox(); g.drawImage(splash, boundingBox.getCenterX(), boundingBox.getCenterY(), anchor); pad.setHit(false); } } wheel.paint(g); g.setColor(0xff0000); } /** * Start playback */ public void playTape() { if (tape != null && tape.size() > 0) { playback = true; recordBtn.disable(); playBtn = stopPlaybackBtn; int length = tape.size(); int i = 0; long startTime = ((Sample) tape.elementAt(0)).time; // Schedule recorded samples while (i < length) { final Sample sample = (Sample) tape.elementAt(i); drummer.schedule(new TimerTask() { public void run() { SoundManager.playSound(sample.sound); sample.pad.setHit(true); } }, sample.time - startTime); i++; } // Schedule task for stopping the playback TimerTask end = new TimerTask() { public void run() { stopTape(); } }; drummer.schedule(end, ((Sample) tape.lastElement()).time - startTime + 100); } } /** * Stop playback */ private void stopTape() { drummer.cancel(); drummer = new Timer(); playback = false; playBtn = startPlaybackBtn; recordBtn.enable(); } /** * Start recording */ private void startRecording() { playBtn.disable(); recordBtn.select(); tape = new Vector(); recording = true; } /** * Stop recording */ private void stopRecording() { playBtn.enable(); recording = false; } /** * Deliver pressed events * @param x * @param y */ protected void pointerPressed(int x, int y) { pressed = true; if (kitEnabled) { for (int i = 0; i < 4; i++) { Pad pad = pads[i]; if (pad.contains(x, y)) { if (recording) { // Record sample tape.addElement(new Sample(pad)); } // Play sound assigned to the pad SoundManager.playSound(pad.getSound()); pad.setHit(true); // Set timer for monitoring long tap if (!recording) { acivePad = i; monitorLongTap(x, y); } break; } } } playBtn.pointerPressed(x, y); recordBtn.pointerPressed(x, y); exitBtn.pointerPressed(x, y); wheel.pointerPressed(x, y); } /** * Deliver dragged events * @param x * @param y */ protected void pointerDragged(int x, int y) { playBtn.pointerDragged(x, y); recordBtn.pointerDragged(x, y); exitBtn.pointerDragged(x, y); wheel.pointerDragged(x, y); } /** * Deliver released events * @param x * @param y */ protected void pointerReleased(int x, int y) { playBtn.pointerReleased(x, y); recordBtn.pointerReleased(x, y); exitBtn.pointerReleased(x, y); wheel.pointerReleased(x, y); // Stop monitoring long taps if (longTapTimer != null) { longTapTimer.cancel(); longTapTimer = null; } pressed = false; } /** * Custom implementation for long tap gesture * @param x * @param y */ private void monitorLongTap(final int x, final int y) { // Reset long tap timer if (longTapTimer != null) { longTapTimer.cancel(); } longTapTimer = new Timer(); final int pad = acivePad; // Task that shows prepares wheel menu to show up in the right place longTapTimer.schedule( new TimerTask() { public void run() { if (pressed) { wheel.setOrigin(x, y); // Calculate destination coordinates for the wheel menu centerX = getWidth() / 2; centerY = getHeight() / 2; int destinationX = centerX - (int) (0.2 * (centerX - x)); int destinationY = centerY - (int) (0.5 * (centerY - y)); wheel.setDestination(destinationX, destinationY); stopTape(); // Disable buttons exitBtn.disable(); recordBtn.disable(); playBtn.disable(); // Preselect a percussion and open the menu wheel.select(pads[pad].getSound()); wheel.show(); kitEnabled = false; } } }, 1000); } /** * Handle button clicks * @param button */ public void clicked(Button button) { if (button == playBtn) { if (playback) { stopTape(); } else { playTape(); } } else if (button == recordBtn) { if (recording) { stopRecording(); } else { startRecording(); } } else if (button == exitBtn) { Main.getInstance().destroyApp(true); Main.getInstance().notifyDestroyed(); } } /** * Handle wheelOpened event */ public void wheelOpened() { } /** * Handle wheelClosed event */ public void wheelClosed() { exitBtn.enable(); recordBtn.enable(); if (tape != null) { playBtn.enable(); } kitEnabled = true; } /** * Handle wheelItemSelected event */ public void wheelItemSelected(Button button) { int percussion = wheel.getSelectedIndex(); if (percussion > -1) { // Load and play the selected sample pads[acivePad].setSound(percussion); SoundManager.playSound(percussion); } } }