OptionsDialog.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.sudokumaster;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
public class OptionsDialog extends ImageView {
private static final String[] ITEMS = {"Restart", "New Game", "Exit"};
private static final int TEXT_COLOR = 0x00000000;
private static final int HIGHLIGHT_COLOR = 0x00ffff99;
private static final int ANIMATION_STEPS = 5;
private int[] itemYs = null;
private final Listener listener;
private int highlighted = -1;
private int highlightAnimationCounter = 0;
public OptionsDialog(Image backgroundImage, Listener listener) {
super(backgroundImage);
this.listener = listener;
}
public void update() {
if (highlighted < 0) {
highlightAnimationCounter = 0;
}
if (highlightAnimationCounter > 0) {
int h = highlightHeight();
highlightAnimationCounter = Math.max(highlightAnimationCounter - 1, 0);
int newH = highlightHeight();
if (h != newH) {
invalidate();
}
}
}
public void setTop(int top) {
super.setTop(top);
itemYs = null;
}
public void setBottom(int bottom) {
super.setBottom(bottom);
itemYs = null;
}
public void setHeight(int height) {
super.setHeight(height);
itemYs = null;
}
private int highlightHeight() {
return (height / 6 - height * highlightAnimationCounter / ANIMATION_STEPS / 12) / 2 * 2;
}
protected void paint(Graphics g) {
super.paint(g);
if (itemYs == null) {
itemYs = new int[ITEMS.length];
int padding = height / 10;
int itemHeight = (height - padding) / ITEMS.length;
int itemCenter = top + (padding + itemHeight) / 2;
for (int i = 0; i < ITEMS.length; i++) {
itemYs[i] = itemCenter + i * itemHeight;
}
}
if (highlighted >= 0) {
int w = width - (width > 128 ? 8 : 6);
int h = highlightHeight();
int x = left + (width - w) / 2;
int y = itemYs[highlighted] - h / 2;
g.setColor(HIGHLIGHT_COLOR);
g.fillRect(x, y, w, h);
}
int x, y;
x = left + width / 2;
g.setColor(TEXT_COLOR);
for (int i = 0; i < ITEMS.length; i++) {
y = itemYs[i] - g.getFont().getHeight() / 2;
g.drawString(ITEMS[i], x, y, Graphics.HCENTER | Graphics.TOP);
}
}
public void setVisible(boolean visible) {
super.setVisible(visible);
highlighted = -1;
highlightAnimationCounter = 0;
}
public boolean handlePointerEvent(int type, int x, int y) {
boolean ret = false;
if (!isVisible()) {
return ret;
}
final int oldHighlighted = highlighted;
if (hits(x, y)) {
highlighted = getItemIndex(x, y);
if (type == View.POINTER_RELEASED && highlighted >= 0) {
listener.onItemClick(highlighted);
}
ret = true;
}
else {
highlighted = -1;
}
if (oldHighlighted != highlighted) {
highlightAnimationCounter = ANIMATION_STEPS;
invalidate();
}
return ret;
}
public void keyEvent(int type, int key) {
if (type == KEY_RELEASED) {
return;
}
switch (key) {
case KEY_UP:
highlightItem(highlighted < 0 ? 0 : (highlighted - 1 + ITEMS.length) % ITEMS.length);
break;
case KEY_DOWN:
highlightItem(highlighted < 0 ? 0 : (highlighted + 1) % ITEMS.length);
break;
case KEY_SELECT:
if (highlighted < 0) {
highlightItem(0);
}
else if (type == KEY_PRESSED) {
listener.onItemClick(highlighted);
}
break;
default:
break;
}
}
private int getItemIndex(int x, int y) {
if (x < left + width / 6 || x > left + width * 5 / 6) {
return -1;
}
else {
return Math.min((y - top) / (height / 3), ITEMS.length - 1);
}
}
public void highlightItem(int i) {
highlighted = i;
highlightAnimationCounter = ANIMATION_STEPS;
invalidate();
}
public static interface Listener {
void onItemClick(int itemIndex);
}
}