/** * Copyright (c) 2012-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.rlinks.view.item; import com.nokia.example.rlinks.model.Voteable; import com.nokia.example.rlinks.network.HttpOperation; import com.nokia.example.rlinks.network.operation.VotePostOperation; import com.nokia.example.rlinks.network.operation.VotePostOperation.PostVoteListener; import com.nokia.example.rlinks.SessionManager; import com.nokia.example.rlinks.VisualStyles; import com.nokia.example.rlinks.util.TouchChecker; import com.nokia.example.rlinks.view.BaseFormView; import com.nokia.mid.ui.LCDUIUtil; import java.io.IOException; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; /** * A custom view item for voting on a Voteable (a LinkThing or a CommentThing). */ public class VoteItem extends AbstractCustomItem { protected static final int H_SPACE = VisualStyles.LINK_H_SPACE; protected static final int V_SPACE = VisualStyles.LINK_V_SPACE / 2; protected static final Font FONT = VisualStyles.MEDIUM_BOLD_FONT; protected static Image voteDownImage = Image.createImage(28, 29); protected static Image voteDownActiveImage = voteDownImage; protected static Image voteUpImage = voteDownImage; protected static Image voteUpActiveImage = voteDownImage; protected final int voteImageHeight; protected final int voteImageWidth; protected final int height; protected int centerX; protected final VoteListener listener; protected final Voteable item; protected final VoteItem self = this; protected final SessionManager session = SessionManager.getInstance(); protected final BaseFormView parent; /** * Listener interface used to signal an item has been voted on. */ public interface VoteListener { public void voteSubmitted(int vote); } // Load the images once static { try { voteDownImage = Image.createImage("/midlets/rlinks/images/down_inactive.png"); voteDownActiveImage = Image.createImage("/midlets/rlinks/images/down_active.png"); voteUpImage = Image.createImage("/midlets/rlinks/images/up_inactive.png"); voteUpActiveImage = Image.createImage("/midlets/rlinks/images/up_active.png"); } catch (IOException ex) { System.out.println("Can't load image: " + ex.getMessage()); } } /** * Create a VoteItem. * * @param item Item we're voting on * @param preferredWidth Preferred width * @param listener Listener to signal of vote results * @param form parent BaseFormView */ public VoteItem(Voteable item, int preferredWidth, VoteListener listener, Form form, BaseFormView parent) { super(form, preferredWidth, null); this.item = item; this.parent = parent; this.voteImageWidth = voteDownImage.getWidth(); this.voteImageHeight = voteDownImage.getHeight(); this.height = getPrefContentHeight(width); this.listener = listener != null ? listener : new VoteListener() { public void voteSubmitted(int vote) { } }; this.centerX = width / 2; if (TouchChecker.DIRECT_TOUCH_SUPPORTED) { LCDUIUtil.setObjectTrait(this, "nokia.ui.s40.item.direct_touch", new Boolean(true)); } } protected int getMinContentWidth() { return width; } protected int getMinContentHeight() { return height; } protected int getPrefContentWidth(int height) { return width; } protected int getPrefContentHeight(int width) { return V_SPACE * 2 + voteImageHeight + V_SPACE * 2; } /** * Detect touches (left side = vote down, right side = vote up). */ public void pointerReleased(int x, int y) { if (!dragging) { if (!session.isLoggedIn()) { parent.showLoginRequiredMessage(); return; } // Vote down or up, depending on which side of the Item was clicked voteItemPressed(x < centerX ? VotePostOperation.VOTE_DOWN : VotePostOperation.VOTE_UP); } super.pointerReleased(x, y); } /** * Act on a voting request: down or up. * * - Selecting an already active vote item nullifies the existing vote. * - Selecting a previously unselected up or down changes the vote. * * @param requestedVote */ private void voteItemPressed(int requestedVote) { // Nullifying vote if the same option is selected again final int oldVote = item.getVote(); if (requestedVote == oldVote) { requestedVote = VotePostOperation.VOTE_NONE; } // Store the old vote in case the voting fails item.setVote(requestedVote); repaint(); listener.voteSubmitted(requestedVote); HttpOperation voteOperation = new VotePostOperation( item.getName(), requestedVote, session.getModhash(), new PostVoteListener() { public void votingSucceeded(String thingName, int vote) { listener.voteSubmitted(vote); } public void votingFailed(String thingName, int vote) { // In case the vote wasn't successful, reflect that in the UI item.setVote(oldVote); repaint(); listener.voteSubmitted(oldVote); } }); voteOperation.start(); } /** * Draw the item. */ protected void paint(final Graphics g, final int w, final int h) { g.setColor(VisualStyles.COLOR_FOREGROUND_DIM); g.setFont(FONT); final int y = V_SPACE * 2; final int fontOffset = FONT.getHeight() / 2; final int vote = item.getVote(); final int leftX = H_SPACE * 2; final int rightX = w - 2 * H_SPACE; g.drawImage(vote == -1 ? voteDownActiveImage : voteDownImage, leftX, y, Graphics.TOP | Graphics.LEFT); g.drawImage(vote == 1 ? voteUpActiveImage : voteUpImage, rightX, y, Graphics.TOP | Graphics.RIGHT); g.drawString("Vote down", leftX + voteImageWidth + H_SPACE, y + fontOffset, Graphics.TOP | Graphics.LEFT); g.drawString("Vote up", rightX - voteImageWidth - H_SPACE, y + fontOffset, Graphics.TOP | Graphics.RIGHT); } protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout) { return false; } }