List.java
/*
* 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.views.ViewMaster;
import com.nokia.example.wordpress.views.Visual;
import java.util.Vector;
import javax.microedition.lcdui.Graphics;
/**
* List view custom UI control.
* Provides a cursor for focus and a scrollbar for visualization.
* Uses a ListDrawer based class for drawing each line of the list.
*/
public class List {
/**
* Width of the scrollbar in pixels.
*/
private final static int SCROLLBAR_WIDTH = 4;
/**
* The index of the top visible row. Index points to the items in the ListDrawer.
*/
//private int topRowIndex = 0;
/**
* The index of the focused row, ie. where the cursor is. Index points to the items in the ListDrawer.
*/
private int focusedRowIndex = 0;
/**
* Number of visible rows to be displayed. Calculated using the available
* height and the height of a list row given by ListDrawer.
*/
private int listRows = 0;
/**
* Drawer instance for doing the drawing of rows.
*/
private ListDrawer drawer;
/**
* Top left x coordinage
*/
private int x;
/**
* Top left y coordinate
*/
private int y;
/**
* Width for the list
*/
private int width;
/**
* Height for the list
*/
private int height;
/**
* Actual list data.
*/
Vector data = null;
/**
* View reference for background drawing.
*/
private ViewMaster view;
/**
* Constructor. Dimensions and position given as parameters.
* @param view
* @param x
* @param y
* @param width
* @param height
*/
public List(ViewMaster view, int x, int y, int width, int height, ListDrawer drawer) {
this.view = view;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.drawer = drawer;
listRows = height / drawer.itemHeight();
}
/**
* Returns the drawer instance.
* @return
*/
public ListDrawer getDrawer() {
return drawer;
}
/**
* Sets the data to be displayed.
* @param data
*/
public void setData(Vector data) {
this.data = data;
}
/**
* Returns the data for accessing.
* @return
*/
public Vector getData() {
return data;
}
/**
* Paints the list.
* @param g
*/
public void draw(Graphics g) {
if (drawer == null) {
return;
}
if (focusedRowIndex < 0) {
focusedRowIndex = 0;
}
if (focusedRowIndex >= data.size()) {
focusedRowIndex = data.size() - 1;
}
// Focus on the middle when scrolling
int topRowIndex = focusedRowIndex - listRows / 2;
if (topRowIndex < 0) {
topRowIndex = 0;
}
int maxTopRowIndex = data.size() - listRows;
if (maxTopRowIndex < 0) {
maxTopRowIndex = 0;
}
if (topRowIndex + listRows >= data.size()) {
topRowIndex = maxTopRowIndex;
}
int prevClipX = g.getClipX();
int prevClipY = g.getClipY();
int prevClipWidth = g.getClipWidth();
int prevClipHeight = g.getClipHeight();
// Ensure that text does not overlap outside our allocated area.
g.setClip(x, y, width, height);
// Scrollbar background
view.drawBackground(g, width - SCROLLBAR_WIDTH, y, SCROLLBAR_WIDTH, height, false);
// Row drawing loop
int y = 0;
for (int i = topRowIndex; i < data.size(); i++) {
drawer.drawItem(data, g, i, this.x, this.y + y, width - SCROLLBAR_WIDTH, height, i == focusedRowIndex);
y += drawer.itemHeight();
if (y >= height) {
break;
}
}
// Fill the rest of the area (if any) with background. Rely on clip
// to avoid drawing over softkey labels.
if (y < height) {
view.drawBackground(g, this.x, this.y+y, width, height, false);
}
// Detemine the need for scrollbar, and the height for it.
float scrollBarPercentage = (float) listRows / (float) data.size();
if (scrollBarPercentage < 1) {
int scrollBarHeight = (int) (height * scrollBarPercentage);
int yPos = (height - scrollBarHeight) * topRowIndex / maxTopRowIndex;
g.setColor(Visual.LIST_SCROLLBAR_COLOR);
g.fillRect(width - SCROLLBAR_WIDTH, yPos + this.y, SCROLLBAR_WIDTH, scrollBarHeight);
}
g.setClip(prevClipX, prevClipY, prevClipWidth, prevClipHeight);
}
/**
* Move cursor up one row.
*/
public void focusUp() {
focusedRowIndex--;
}
/**
* Move cursor down one row.
*/
public void focusDown() {
focusedRowIndex++;
}
/**
* Returns the focused row index in the ListDrawer.
* @return
*/
public int focusIndex() {
return focusedRowIndex;
}
}