/* * Copyright © 2011 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.wordpress.components; import com.nokia.example.wordpress.WordpressMidlet; import com.nokia.example.wordpress.helpers.KeyCodes; import com.nokia.example.wordpress.views.Visual; import java.util.Vector; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; /** * Options menu custom UI control */ public class OptionsMenu { protected WordpressMidlet midlet; private static final Font DEFAULT_FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL); private static final Font SOFTKEY_FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL); private final int softkeyBarHeight = SOFTKEY_FONT.getHeight(); private final int menuItemHeight = DEFAULT_FONT.getHeight(); private static final int margin = 10; private int screenHeight; private int screenWidth; public int x; public int y; public int width; public int height; private int rectWidth; private int rectHeight; private int highlightWidth; /** * Vector of Items */ private Vector menuitems; private boolean showSelf = false; private int currentHighlight = 0; private boolean backgroundDimmed; private Item selectedMenuItem = null; /** * Animation parameter. Target y-coordinate for the top left menu corner. */ public int targetY; /** * Animation parameter. Current y-coordinate of the top left menu corner. * This is animated towards targetY. */ public int currentY; /** * Animation parameter. Animation goes from 0 to 1. */ private float transitionCounter = 0; /** * Class describing one menu item, contains a name and info what * to call when user selects it. */ private class Item { /** * Constructor * @param name Menu item name * @param callback Callback to call when selected */ Item(String name, MenuItemCallback callback) { this.name = name; this.callback = callback; } public void select() { callback.select(); } MenuItemCallback callback; String name; } /** * Constructor. Takes the dimensions of the target screen as parameters. * @param screenWidth * @param screenHeight */ public OptionsMenu(int screenWidth, int screenHeight) { this.midlet = WordpressMidlet.getInstance(); this.screenWidth = screenWidth; this.screenHeight = screenHeight; x = 0; menuitems = new Vector(); } /** * Calculates the rectangle needed to display the menuitems. */ private void updateDimensions() { rectHeight = menuitems.size() * menuItemHeight + 2 * margin; height = rectHeight; y = screenHeight - rectHeight - softkeyBarHeight; currentY = y; targetY = y; int l = menuitems.size(); for (int i = 0; i < l; i++) { //MenuItem item = (MenuItem) menuitems.elementAt(i); Item item = (Item) menuitems.elementAt(i); int item_width = DEFAULT_FONT.stringWidth(item.name); if (item_width > rectWidth) { rectWidth = item_width; } } highlightWidth = rectWidth; rectWidth += 2 * margin; width = rectWidth; } /** * Adds one menuitem. * @param name Menu item name * @param callback Callback */ protected void addItem(String name, MenuItemCallback callback) { menuitems.addElement(new Item(name, callback)); updateDimensions(); } /** * Utility for adding the Exit. */ protected void addExitItem() { addItem("Exit", new MenuItemCallback() { public void select() { WordpressMidlet.getInstance().commandExit(); } }); } /** * Dims the screen, used before drawing the menu. * @param g */ private void renderDimmedBackground(Graphics g) { int[] pixels = new int[screenWidth * screenHeight]; for (int i = 0; i < screenWidth * screenHeight; i++) { pixels[i] = 0xaa000000; } g.drawRGB(pixels, 0, screenWidth, 0, 0, screenWidth, screenHeight - softkeyBarHeight, true); pixels = null; } /** * Draws the menu. * @param g */ public void draw(Graphics g) { if (!showSelf) { return; } if (backgroundDimmed == false) { backgroundDimmed = true; renderDimmedBackground(g); } // Softkey area g.setFont(SOFTKEY_FONT); g.setColor(Visual.BACKGROUND_COLOR); g.fillRect(x, screenHeight - softkeyBarHeight, screenWidth, softkeyBarHeight); g.setColor(0); g.drawString("Select", screenWidth / 2, screenHeight, g.HCENTER | g.BOTTOM); g.drawString("Back", screenWidth, screenHeight, g.RIGHT | g.BOTTOM); // Menu item box g.setColor(0); int prevClipX = g.getClipX(); int prevClipY = g.getClipY(); int prevClipWidth = g.getClipWidth(); int prevClipHeight = g.getClipHeight(); // Prevent painting over softkeys g.setClip(x, y, rectWidth, rectHeight); int y = currentY; g.fillRoundRect(x, y, rectWidth, rectHeight, 10, 10); g.setColor(0); g.setFont(DEFAULT_FONT); y += margin; for (int i = 0; i < menuitems.size(); i++) { Item item = (Item) menuitems.elementAt(i); if (i == currentHighlight) { g.setColor(0x890000); g.fillRect(margin - 2, y, highlightWidth + 2, DEFAULT_FONT.getHeight()); } g.setColor(0xFFFFFF); g.drawString(item.name, margin, y, g.LEFT | g.TOP); y += menuItemHeight; } g.setClip(prevClipX, prevClipY, prevClipWidth, prevClipHeight); } /** * Returns the visibility information. * @return */ public boolean isVisible() { return showSelf; } /** * Animates the menu. Should be called in regular intervals. * @return true if something was animated and the screen should be updated, false otherwise. */ public boolean animate() { if (currentY == targetY) { return false; } transitionCounter += 0.20f; if (transitionCounter > 1f) { transitionCounter = 1f; } if (currentY > targetY) { float progress = -transitionCounter * (transitionCounter - 2); currentY = y + rectHeight - (int) (((float) rectHeight) * progress); if (currentY < targetY) { currentY = targetY; } } return true; } /** * Stars the animation to open the menu. */ void appearAnimation() { currentY = screenHeight - softkeyBarHeight; targetY = y; transitionCounter = 0; } /** * Starts the animation to close the menu. Currently the menu * instantly disappears. * @param selectedItem */ private void disappearAnimation(Item selectedItem) { showSelf = false; if (selectedItem != null) { selectedItem.select(); } } /** * Key event handler. Opens and closes the menu. Selects the focused menu item. * @param keyCode * @return */ public boolean notifyKeyEvents(int keyCode) { switch (keyCode) { case KeyCodes.LEFT_SOFTKEY: if (!showSelf) { showSelf = true; backgroundDimmed = false; appearAnimation(); } else { disappearAnimation((Item) menuitems.elementAt(currentHighlight)); } return true; case KeyCodes.DOWN: if (showSelf) { if (currentHighlight == (menuitems.size() - 1)) { currentHighlight = 0; } else { currentHighlight++; } return true; } break; case KeyCodes.UP: if (showSelf) { if (currentHighlight == 0) { currentHighlight = (menuitems.size() - 1); } else { currentHighlight--; } return true; } break; case KeyCodes.MIDDLE_SOFTKEY: if (showSelf) { disappearAnimation((Item) menuitems.elementAt(currentHighlight)); return true; } break; case KeyCodes.RIGHT_SOFTKEY: if (showSelf) { disappearAnimation(null); return true; } break; } return false; } }