/** * Copyright (c) 2013 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.musicexplorer.ui; import javax.microedition.lcdui.CustomItem; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import org.tantalum.Task; import org.tantalum.util.L; import com.nokia.mid.ui.DirectGraphics; import com.nokia.mid.ui.DirectUtils; import com.nokia.example.musicexplorer.data.ApiCache; import com.nokia.example.musicexplorer.data.model.AlbumModel; import com.nokia.example.musicexplorer.data.model.ArtistModel; import com.nokia.example.musicexplorer.data.model.GenericProductModel; import com.nokia.example.musicexplorer.settings.Placeholders; import com.nokia.example.musicexplorer.settings.ThumbnailSizes; /** * Displays ArtistModel info: thumbnail, artist name, genre, etc. */ public class ListItem extends CustomItem { private static final int POINTER_JITTER = 10; private static final String THUMBNAIL_SIZE = ThumbnailSizes.SIZE_50X50; private static final int LIST_ITEM_SIDE = 50; private static final int LIST_ITEM_WIDTH = 230; private static final int LIST_ITEM_HEIGHT = LIST_ITEM_SIDE; private static final int TEXT_OFFSET_X = LIST_ITEM_SIDE + 5; private static final int TEXT_OFFSET_Y = 16; private static final int TITLE_COLOR_HEX_RGB = 0x2AA7CC; private static final int TEXT_COLOR_HEX_RGB = 0x4C4C4C; private static final int HIGHLIGHT_COLOR_HEX_ARGB = 0x88FFFFFF; public String thumbnailSize; protected ViewManager viewManager; private String text; private int width; private int height; private Image thumbnail; private int lastX; private int lastY; private boolean pointerActive; private boolean pointerEnabled = true; private GenericProductModel model; private String albumOrTrackAmountText = ""; private Task getThumbnailTask; /** * Constructor. * @param viewManager * @param model */ public ListItem(ViewManager viewManager, GenericProductModel model) { this(); this.viewManager = viewManager; this.model = model; this.height = ListItem.LIST_ITEM_HEIGHT; this.width = ListItem.LIST_ITEM_WIDTH; } /** * Private default constructor. */ private ListItem() { super(null); } public void sizeChanged(int w, int h) { } public void pointerPressed(int x, int y) { if (pointerEnabled) { this.lastX = x; this.lastY = y; this.pointerActive = true; } } /** * Detect if pointer gets dragged outside of the item's bounds. */ public void pointerDragged(int x, int y) { if (pointerEnabled && !(Math.abs(x - lastX) < ListItem.POINTER_JITTER && Math.abs(y - lastY) < ListItem.POINTER_JITTER)) { pointerActive = false; } } /** * If pointer is still inside bounds then select it. */ public void pointerReleased(int x, int y) { if (pointerEnabled && pointerActive) { pointerReleaseAction(); } pointerActive = false; repaint(); // Called to de-highlight } public String toString() { return "ListItem: " + this.text; } protected int getMinContentHeight() { return height; } protected int getMinContentWidth() { return width; } protected int getPrefContentHeight(int arg0) { return height; } protected int getPrefContentWidth(int arg0) { return width; } /** * @see javax.microedition.lcdui.CustomItem#paint(Graphics, int, int) */ public void paint(Graphics graphics, int width, int height) { paint(graphics, 0, 0, width, height); } public void setThumbnail(Image thumbnail) { this.thumbnail = thumbnail; } /** * For convenience. Paints this item in the given position. * * @param graphics The Graphics instance. * @param x The X coordinate of the item. * @param y The Y coordinate of the item. */ public void paintXY(Graphics graphics, int x, int y) { paint(graphics, x, y, width, height); } public void disablePointer() { this.pointerEnabled = false; } public void setAlbumOrTrackAmountText(String text) { this.albumOrTrackAmountText = text; repaint(); } /** * For convenience. */ protected void paint(Graphics graphics, int x, int y, int width, int height) { graphics.setColor(TEXT_COLOR_HEX_RGB); // Paints the first two rows of text. if (this.model instanceof ArtistModel) { paintArtistDetails(graphics, x, y); } else if (this.model instanceof AlbumModel) { paintAlbumDetails(graphics, x, y); } // Paints the third row of text if it is set. paintAlbumOrTrackAmountText(graphics, x, y); if (thumbnail != null) { graphics.drawImage(thumbnail, x, y, Graphics.TOP | Graphics.LEFT); } else { // Paint a placeholder image if thumbnail is not yet loaded Placeholders.paint(graphics, model, x, y, Graphics.TOP | Graphics.LEFT); // Begin loading thumbnail image getThumbnail(); } if(pointerActive) { paintHighlight(graphics, x, y); } } protected void paintHighlight(Graphics graphics, int x, int y) { int originalColor = graphics.getColor(); // Save color DirectGraphics directGraphics = DirectUtils.getDirectGraphics(graphics); directGraphics.setARGBColor(HIGHLIGHT_COLOR_HEX_ARGB); graphics.fillRect( x, y, ListItem.LIST_ITEM_SIDE, ListItem.LIST_ITEM_SIDE); graphics.setColor(originalColor); // Restore original color } /** * Paints the third row of text if the text is set. * @param graphics * @param x * @param y */ protected void paintAlbumOrTrackAmountText( Graphics graphics, int x, int y) { if (this.albumOrTrackAmountText.length() > 0) { graphics.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_SMALL)); graphics.drawString( this.albumOrTrackAmountText, x + ListItem.TEXT_OFFSET_X, y + ListItem.TEXT_OFFSET_Y * 2, Graphics.TOP | Graphics.LEFT); } } protected void paintArtistDetails(Graphics graphics, int x, int y) { // Paint artist's name. graphics.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL)); graphics.setColor(TITLE_COLOR_HEX_RGB); graphics.drawString( this.model.name, x + ListItem.TEXT_OFFSET_X, y, Graphics.TOP | Graphics.LEFT); // Paint the genre(s). graphics.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL)); graphics.setColor(TEXT_COLOR_HEX_RGB); graphics.drawString( this.model.getGenres(), x + ListItem.TEXT_OFFSET_X, y + ListItem.TEXT_OFFSET_Y, Graphics.TOP | Graphics.LEFT); } protected void paintAlbumDetails(Graphics graphics, int x, int y) { // Paint album's name. graphics.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL)); graphics.setColor(TITLE_COLOR_HEX_RGB); graphics.drawString( this.model.name, x + ListItem.TEXT_OFFSET_X, y, Graphics.TOP | Graphics.LEFT); // Paint performers. graphics.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL)); graphics.setColor(TEXT_COLOR_HEX_RGB); graphics.drawString( ((AlbumModel) this.model).getPerformerNames(), x + ListItem.TEXT_OFFSET_X, y + ListItem.TEXT_OFFSET_Y, Graphics.TOP | Graphics.LEFT); } /** * Currently opens only an artist view. */ private void pointerReleaseAction() { if (this.model instanceof ArtistModel) { ArtistView artistView = new ArtistView( viewManager, (ArtistModel) this.model); // Artist view is added to view manager by using addtoStack(). viewManager.addToStack(artistView); } else if (this.model instanceof AlbumModel) { AlbumView albumView = new AlbumView( viewManager, (AlbumModel) this.model, true); viewManager.showView(albumView); } } private void getThumbnail() { // Checks if task is already triggered if (this.thumbnail == null && this.getThumbnailTask == null) { try { this.getThumbnailTask = ApiCache.getImage( this.model.getThumbnailUrl(ListItem.THUMBNAIL_SIZE), new PlaceImageTask(this)); } catch (Exception e) { L.e("No thumbnail available or not loaded yet for item", this.toString(), e); } } } public class PlaceImageTask extends Task { private ListItem item; public PlaceImageTask(ListItem item) { super(Task.NORMAL_PRIORITY); this.item = item; } public Object exec(Object thumbnail) { if (thumbnail instanceof Image) { this.item.setThumbnail((Image) thumbnail); this.item.repaint(); } return thumbnail; } } }