/*
* Menu.java
*
* Copyright (C) 2005-2010 Tommi Laukkanen
* http://www.substanceofcode.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.substanceofcode.twitter.views;
import com.substanceofcode.infrastructure.Device;
import com.substanceofcode.twitter.TwitterController;
import com.substanceofcode.utils.Log;
import com.substanceofcode.utils.TimeUtil;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
/**
* Menu implementation that will render an overlay menu.
* @author Tommi Laukkanen
*/
public class Menu {
private String[] labels;
private MenuAction[] actions;
private int screenWidth;
private int screenHeight;
private int top = 0;
private int height;
private int selectedIndex;
private boolean active;
private String title;
private int rowHeight = 10;
private boolean alignLeft;
private int rowsPerScreen;
private int boxHeight = 24;
private int boxWidth = 32;
private int longestLabelWidth = 10;
private static final Font TITLE_FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL);
private static final Font LABEL_FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
private static final int BACK_COLOR = 0xaaaaaa;
private static final int SELECTED_COLOR = 0xffffff;
private static final int LABEL_COLOR = 0x000000;
private static final int TITLE_COLOR = 0x666666;
private static final int BORDER_COLOR = 0x666666;
/** Create new Menu instance
* @param labels
* @param screenWidth
* @param screenHeight
*/
public Menu(String[] labels, MenuAction[] actions, int screenWidth, int screenHeight) {
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.actions = actions;
selectedIndex = 0;
active = false;
title = "Menu";
alignLeft = false;
calculateSize();
setLabels(labels);
}
public void alignLeft(boolean align) {
this.alignLeft = align;
}
/**
* Draw menu
* @param g Application graphics.
*/
public void draw(Graphics g) {
if(active==false) {
return;
}
if(alignLeft==true) {
top = 11;
if(selectedIndex>(rowsPerScreen-3)) {
top -= (selectedIndex-(rowsPerScreen-3))*rowHeight;
}
}
int menuWidth = (alignLeft ? screenWidth-4 : longestLabelWidth);
/** Draw background and borders */
g.setColor(BACK_COLOR);
g.fillRect(screenWidth/2 - menuWidth/2, top-2, menuWidth, height+4);
g.setColor(BORDER_COLOR);
g.drawRect(screenWidth/2 - menuWidth/2, top-2, menuWidth, height+4);
/** Draw menu items */
g.setFont(TITLE_FONT);
/** Draw time stamp */
if(!alignLeft) {
g.setColor(0xAAAAAA);
String currentTime = TimeUtil.getCurrentTime();
if(currentTime!=null) {
g.drawString(
currentTime,
screenWidth/2 - LABEL_FONT.stringWidth(currentTime)/2,
LABEL_FONT.getHeight(),
Graphics.BOTTOM|Graphics.LEFT);
}
}
/** Title */
g.setColor(TITLE_COLOR);
g.drawString(
title,
screenWidth/2 - LABEL_FONT.stringWidth(title)/2,
top + TITLE_FONT.getHeight(),
Graphics.LEFT|Graphics.BOTTOM);
g.setFont(LABEL_FONT);
/** Labels */
g.setColor(LABEL_COLOR);
int col = (alignLeft ? 13 : 0 );
for(int menuIndex=0; menuIndex<labels.length; menuIndex++) {
if(menuIndex==selectedIndex) {
g.setColor(SELECTED_COLOR);
g.fillRect(screenWidth/2 - menuWidth/2+1, top+(menuIndex+1)*rowHeight, menuWidth-2, rowHeight);
g.setColor(LABEL_COLOR);
}
String label = labels[ menuIndex ];
int labelWidth = LABEL_FONT.stringWidth(label);
if(alignLeft==false) {
col = screenWidth/2 - labelWidth/2;
}
g.drawString(labels[menuIndex], col, top + (menuIndex+2)*rowHeight-(rowHeight/2-LABEL_FONT.getHeight()/2), Graphics.LEFT|Graphics.BOTTOM);
}
if(Device.isTouch()) {
drawBackButton(g);
}
}
private void drawBackButton(Graphics g) {
Font f = g.getFont();
int textWidth = f.stringWidth("Menu");
boxHeight = 24;
boxWidth = 32;
if(textWidth>32) {
boxWidth = textWidth + 2;
}
boxHeight = f.getHeight()*2;
g.setColor(0xaaaaaa);
g.fillRect(0, screenHeight-boxHeight, screenWidth, boxHeight);
g.setColor(0x999999);
g.drawLine(screenWidth/2, screenHeight-boxHeight+2, screenWidth/2, screenHeight-4);
g.setColor(0x444444);
g.drawLine(0, screenHeight-boxHeight, screenWidth, screenHeight-boxHeight);
g.drawString("Back", screenWidth-boxWidth+boxWidth/2-textWidth/2, screenHeight-boxHeight/2+f.getHeight()/2, Graphics.LEFT|Graphics.BOTTOM);
}
public void selectNext() {
selectedIndex++;
if(selectedIndex>labels.length-1) {
selectedIndex = 0;
}
}
public void selectPrevious() {
selectedIndex--;
if(selectedIndex<0) {
selectedIndex = labels.length-1;
}
}
public int getSelectedIndex() {
return selectedIndex;
}
String getSelectedLabel() {
if(labels==null || selectedIndex<0 || selectedIndex>labels.length-1) {
return null;
}
return labels[selectedIndex];
}
boolean isActive() {
return active;
}
public void activate() {
active = true;
if(Device.isTouch()) {
selectedIndex = -1;
} else {
selectedIndex = 0;
}
}
public void activateSelected() {
if(actions!=null) {
actions[ getSelectedIndex() ].activate();
}
}
public void deactivate() {
active = false;
}
/**
* Set labels for the menu.
* @param labels
*/
void setLabels(String[] labels) {
this.labels = labels;
/** Check for longest line */
if(labels!=null) {
longestLabelWidth = TITLE_FONT.stringWidth(title);
for(int i=0; i<labels.length; i++) {
String label = labels[i];
int labelWidth = LABEL_FONT.stringWidth(label);
if(labelWidth>longestLabelWidth) {
longestLabelWidth = labelWidth;
}
}
longestLabelWidth += LABEL_FONT.getHeight()*2;
}
calculateSize();
selectedIndex = 0;
}
void setLabel(int index, String label) {
labels[index] = label;
}
void setTitle(String title) {
this.title = title;
}
/**
* Select menu item with touch screen
* @param x coordinate
* @param y coordinate
*/
public void selectWithPointer(int x, int y, boolean isPress) {
/** Check for back button */
Log.debug("x: " + x + " y: " + y);
if(Device.isTouch() && x>screenWidth/2 && y>screenHeight-boxHeight && isPress) {
TwitterController.getInstance().showTimeline();
return;
}
/** Check that pointer is on top of menu item */
int menuWidth = (alignLeft ? screenWidth : longestLabelWidth);
if( x>screenWidth/2-menuWidth/2 &&
x<screenWidth/2+menuWidth/2) {
int canvasY = y-top;
int pointerIndex = canvasY / rowHeight - 1;
selectedIndex = pointerIndex;
} else {
selectedIndex = -1;
}
}
private void calculateSize() {
if(Device.isTouch()) {
rowHeight = LABEL_FONT.getHeight()+LABEL_FONT.getHeight()/2;
} else {
rowHeight = LABEL_FONT.getHeight();
}
if(labels!=null) {
this.height = (labels.length+1) * rowHeight;
this.top = screenHeight/2 - height/2;
}
rowsPerScreen = screenHeight/rowHeight;
}
public void setSize(int width, int height) {
screenWidth = width;
screenHeight = height;
calculateSize();
}
}