/*
* XCTrack - XContest Live Tracking client for J2ME devices
* Copyright (C) 2009 Petr Chromec <petr@xcontest.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.xcontest.xctrack.paint;
import java.io.IOException;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import org.xcontest.xctrack.util.Log;
import org.xcontest.xctrack.widget.WidgetPage;
public final class Menu {
public static final int ACTION_SUBMENU_CHANGED = -2;
public static final int ACTION_CLOSE_MENU = -1;
public static final int NOACTION = 0;
public static final int MENUITEM_MAX_HEIGHT = 96;
public Menu(String caption, MenuItem[] items) {
_caption = caption;
// delete NULL items to make variable configuration easier
int cnt = 0;
for (int i = 0; i < items.length; i ++)
if (items[i] != null)
cnt += 1;
if (cnt != items.length) {
MenuItem[] newItems = new MenuItem[cnt];
cnt = 0;
for (int i = 0; i < items.length; i ++)
if (items[i] != null)
newItems[cnt++] = items[i];
items = newItems;
}
_items = items;
_openedFrom = null;
_selIndex = 0;
_activeSubmenu = null;
_pointerPressed = false;
_isTouchscreen = false;
_font = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_MEDIUM);
_fontSmall = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_SMALL);
try {
_imgCursor = Image.createImage("/img/menu/menu-cursor.png");
}
catch (IOException e) {
Log.error("Cannot load menu cursor image");
}
}
public MenuItem[] getItems() {
return _items;
}
public void resetPosition(int w, int h, boolean touch) {
int fonth = _font.getHeight();
_isTouchscreen = touch;
_screenW = w;
_screenH = h;
_menuX = w/10;
_menuW = w-_menuX*2;
_menuTitleH = fonth;
_activeSubmenu = null;
_selIndex = 0;
for (int i = 0; i < _items.length; i ++) {
if (_items[i].isDefault()) {
_selIndex = i;
break;
}
}
if (_isTouchscreen)
_menuItemH = MENUITEM_MAX_HEIGHT;
else
_menuItemH = fonth;
if (_menuItemH*_items.length + _menuTitleH > h)
_menuItemH = (h - _menuTitleH)/_items.length;
_menuH = _menuItemH * _items.length;
_menuY = (h-_menuH-_menuTitleH)/2 + _menuTitleH;
}
public void paint(Graphics g) {
if (_activeSubmenu != null) {
_activeSubmenu.paint(g);
}
else {
int blp = _font.getBaselinePosition();
int fonthDefault = _font.getHeight();
int fonthSmall = _fontSmall.getHeight();
int fonth;
g.setColor(0xFFFFFF);
g.drawRect(_menuX-1, _menuY-_menuTitleH-1, _menuW+1, _menuH+_menuTitleH+1);
g.setColor(0x808080);
g.drawRect(_menuX-2, _menuY-_menuTitleH-2, _menuW+3, _menuH+_menuTitleH+3);
TransparentBox.paint(g,_menuX,_menuY-_menuTitleH,_menuW,_menuH,0xC0E0E0E0);
g.setColor(0x000000);
g.setFont(_font);
g.drawString(_caption,_menuX+_menuW/2,_menuY-_menuTitleH+blp,Graphics.HCENTER|Graphics.BASELINE);
for (int i = 0; i < _items.length; i ++) {
int style = _items[i].getStyle();
if (style == MenuItem.STYLE_SMALL) {
g.setFont(_fontSmall);
fonth = fonthSmall;
}
else {
g.setFont(_font);
fonth = fonthDefault;
}
if (i == _selIndex) {
Painter.drawBackground(g, _imgCursor, _menuX, _menuY+i*_menuItemH, _menuW, _menuItemH, Graphics.LEFT | Graphics.VCENTER);
g.setColor(0xffffff);
}
else {
TransparentBox.paint(g,_menuX,_menuY+i*_menuItemH,_menuW,_menuItemH,TransparentBox.WHITE);
g.setColor(style == MenuItem.STYLE_SMALL ? 0x808080 : 0x000000);
}
g.drawString(_items[i].getCaption(),_menuX+_menuW/16,_menuY+i*_menuItemH+(_menuItemH-fonth)/2,Graphics.LEFT|Graphics.TOP);
}
}
}
public void handlePointerPressed(int x, int y) {
if (_isTouchscreen) {
if (_activeSubmenu != null) {
_activeSubmenu.handlePointerPressed(x, y);
}
else {
_pointerPressed = true;
int idx = y<_menuY ? -1 : (y-_menuY)/_menuItemH;
if (idx >= 0 && idx < _items.length && idx != _selIndex)
_selIndex = idx;
}
}
}
public void handlePointerDragged(int x, int y) {
if (_isTouchscreen) {
if (_activeSubmenu != null)
_activeSubmenu.handlePointerDragged(x, y);
else {
int idx = y<_menuY ? -1 : (y-_menuY)/_menuItemH;
if (idx >= 0 && idx < _items.length && idx != _selIndex)
_selIndex = idx;
}
}
}
private int processMenuItemAction(MenuItem it, MenuResult res) {
if (it.getSubmenu() != null) {
_activeSubmenu = it.getSubmenu();
_activeSubmenu._openedFrom = this;
_activeSubmenu.resetPosition(_screenW,_screenH,_isTouchscreen);
if (res != null) {
res.customData = null;
}
return ACTION_SUBMENU_CHANGED;
}
int action = it.getAction();
if (action == ACTION_CLOSE_MENU && _openedFrom != null) {
_openedFrom._activeSubmenu = null;
if (res != null) {
res.customData = it.getCustomData();
}
return ACTION_SUBMENU_CHANGED;
}
else {
if (res != null) {
res.customData = it.getCustomData();
}
return action;
}
}
public int handlePointerReleased(int x, int y, MenuResult res) {
if (!_isTouchscreen) {
if (res != null)
res.customData = null;
return NOACTION;
}
if (_activeSubmenu != null)
return _activeSubmenu.handlePointerReleased(x, y, res);
if (!_pointerPressed) { // pointer was pressed in different context, not this menu - so this is probably unwanted release
if (res != null)
res.customData = null;
return NOACTION;
}
_pointerPressed = true;
int idx = y<_menuY ? -1 : (y-_menuY)/_menuItemH;
if (idx >= 0 && idx < _items.length) {
_selIndex = idx;
return processMenuItemAction(_items[idx],res);
}
if (res != null)
res.customData = null;
return NOACTION;
}
public int handleKey(int key, MenuResult res) {
if (_activeSubmenu != null) {
return _activeSubmenu.handleKey(key,res);
}
else {
if (res != null)
res.customData = null;
if (key == WidgetPage.KEY_LEFT) {
if (_openedFrom != null) {
_openedFrom._activeSubmenu = null;
return NOACTION;
}
else {
return ACTION_CLOSE_MENU;
}
}
else if (key == WidgetPage.KEY_UP) {
if (_selIndex > 0)
_selIndex --;
else
_selIndex = _items.length-1;
return NOACTION;
}
else if (key == WidgetPage.KEY_DOWN) {
if (_selIndex < _items.length-1)
_selIndex ++;
else
_selIndex = 0;
return NOACTION;
}
else if (key == WidgetPage.KEY_FIRE || key == WidgetPage.KEY_RIGHT) {
return processMenuItemAction(_items[_selIndex],res);
}
else {
return NOACTION;
}
}
}
public int getX() {
return _menuX-2;
}
public int getY() {
return _menuY-_menuTitleH-2;
}
public int getWidth() {
return _menuW+4;
}
public int getHeight() {
return _menuH+_menuTitleH+4;
}
private String _caption;
private MenuItem[] _items;
int _selIndex;
private Menu _activeSubmenu;
private Menu _openedFrom;
private boolean _isTouchscreen;
private boolean _pointerPressed;
private Font _font;
private Font _fontSmall;
private Image _imgCursor;
private int _menuTitleH,_menuItemH;
private int _menuX,_menuY,_menuW,_menuH;
private int _screenW,_screenH;
}