Menu.java
/*
* 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.amaze.ui;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import com.nokia.example.amaze.Main;
/**
* A generic game menu.
*/
public class Menu {
// Constants
private static final int MAX_MENU_ITEM_COUNT = 4;
// Members
private Listener _listener = null;
private Object[] _items = null;
private Font _font = null;
private final Image _itemBackgroundImage = Main.makeImage("/graphics/menu-item-bg.png");
private int _width;
private int _height;
private int _fontHeight;
private int _pressedIndex = -1;
/**
* Constructor.
* @param width
* @param height
*/
public Menu(Listener listener, int width, int height) {
_items = new Object[MAX_MENU_ITEM_COUNT];
setSize(width, height);
_listener = listener;
_font = Font.getDefaultFont();
_fontHeight = _font.getHeight();
}
/**
* Sets the menu size.
* @param width
* @param height
*/
public void setSize(int width, int height) {
_width = width;
_height = height;
}
/**
* Adds a new item to the menu with the given text.
* @param text The text of the menu item.
* @return True if the menu item was added successfully, false otherwise.
*/
public boolean addItem(String text) {
for (int i = 0; i < MAX_MENU_ITEM_COUNT; ++i) {
if (_items[i] == null) {
MenuItem item = new MenuItem(text);
_items[i] = item;
return true;
}
}
return false;
}
/**
* For convenience.
* Adds the given menu item to the menu.
* @param item The item to add.
* @return True if the menu item was added successfully, false otherwise.
*/
public boolean addItem(MenuItem item) {
for (int i = 0; i < MAX_MENU_ITEM_COUNT; ++i) {
if (_items[i] == null) {
_items[i] = item;
return true;
}
}
return false;
}
/**
* Returns a menu item at the given index or null if not found.
* @param index The index of the menu item.
* @return A menu item or null.
*/
public MenuItem itemAt(final int index) {
if (_items != null && index >= 0 && index < menuItemCount()) {
return (MenuItem)_items[index];
}
return null;
}
/**
* Clears all menu items.
*/
public void clear() {
for (int i = 0; i < MAX_MENU_ITEM_COUNT; ++i) {
_items[i] = null;
}
}
/**
* Handles "on pressed" events.
* @param x
* @param y
*/
public void onPressed(final int x, final int y) {
final int count = menuItemCount();
final int startY = _height / 2 - count * MenuItem.MENU_ITEM_HEIGHT / 2;
if (y < startY || y > count * MenuItem.MENU_ITEM_HEIGHT + startY) {
setPressed(_pressedIndex, false);
_pressedIndex = -1;
return;
}
int prevPressedIndex = _pressedIndex;
_pressedIndex = (y - startY) / MenuItem.MENU_ITEM_HEIGHT;
if (prevPressedIndex != _pressedIndex) {
setPressed(prevPressedIndex, false);
}
if (!setPressed(_pressedIndex, true)) {
_pressedIndex = -1;
}
}
/**
* Handles "on released" events.
* @param x
* @param y
*/
public void onReleased(final int x, final int y) {
final int count = menuItemCount();
final int startY = _height / 2 - count * MenuItem.MENU_ITEM_HEIGHT / 2;
if (y < startY || y > count * MenuItem.MENU_ITEM_HEIGHT + startY) {
setPressed(_pressedIndex, false);
_pressedIndex = -1;
return;
}
if (_listener != null
&& _pressedIndex == (y - startY) / MenuItem.MENU_ITEM_HEIGHT)
{
System.out.println("Menu::onReleased(): " + _pressedIndex);
_listener.onMenuItemSelected(_pressedIndex);
}
setPressed(_pressedIndex, false);
_pressedIndex = -1;
}
/**
* Paints the menu.
* @param graphics
*/
public void paint(Graphics graphics) {
final int count = menuItemCount();
MenuItem item = null;
String text = null;
int y = _height / 2 - count * MenuItem.MENU_ITEM_HEIGHT / 2;
for (int i = 0; i < count; ++i) {
item = (MenuItem)_items[i];
text = item.text();
if (text == null) {
continue;
}
if (item.pressed()) {
graphics.setColor(MenuItem.COLOR);
graphics.fillRect(0, y, _width, MenuItem.MENU_ITEM_HEIGHT);
graphics.setColor(0x00000000);
}
else {
graphics.drawImage(_itemBackgroundImage, 0, y,
Graphics.TOP | Graphics.LEFT);
graphics.setColor(MenuItem.COLOR);
}
graphics.drawString(text, (_width - _font.stringWidth(text)) / 2,
(y + MenuItem.MENU_ITEM_HEIGHT / 2) - _fontHeight / 2,
Graphics.TOP | Graphics.LEFT);
y += MenuItem.MENU_ITEM_HEIGHT;
}
}
/**
* @return The number of items in the menu.
*/
private final int menuItemCount() {
int retval = 0;
for (int i = 0; i < MAX_MENU_ITEM_COUNT; ++i) {
if (_items[i] != null) {
retval++;
}
else {
break;
}
}
return retval;
}
/**
* Sets the menu item with the given index pressed/unpressed.
* @param index The index of a menu item-
* @param pressed Whether to item should be pressed or unpressed.
* @return True if the pressed property of the item was set successfully,
* false otherwise.
*/
private boolean setPressed(int index, boolean pressed) {
if (index >= 0 && index < menuItemCount()) {
MenuItem item = (MenuItem)_items[index];
if (item != null && !item.disabled()) {
item.setPressed(pressed);
return true;
}
}
return false;
}
/**
* Menu listener interface.
*/
public interface Listener {
void onMenuItemSelected(int index);
}
}