/* * 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.views; import com.nokia.example.wordpress.components.DataModel; import com.nokia.example.wordpress.WordpressMidlet; import com.nokia.example.wordpress.components.OptionsMenu; import com.nokia.example.wordpress.helpers.ImageLoader; import java.io.IOException; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; /** * Base class for views. */ public abstract class BaseView { /** * View identifier */ protected int id; /** * Position of the view on screen, x-coordinate. */ protected int x; /** * Position of the view on screen, y-coordinate. */ protected int y; /** * Available width on screen to be used. */ protected int width; /** * Available height on screen to be used. */ protected int height; /** * Midlet instance */ protected WordpressMidlet midlet = WordpressMidlet.getInstance(); /** * ViewMaster instance */ protected ViewMaster viewMaster = ViewMaster.getInstance(); /** * DataModel instance. */ protected DataModel data = DataModel.getInstance(); /** * Active state. Active views can be drawn and animated. */ public boolean active = false; /** * Options menu for the view. */ protected OptionsMenu menu = null; /** * Left softkey label */ protected String softkey1Label = ""; /** * Middle softkey label */ protected String softkey2Label = ""; /** * Right softkey label */ protected String softkey3Label = ""; /** * Tabbar image */ protected Image tabHeader; /** * Tab highlight flash color. */ public int tabHighlight = 0; /** * Tab highlight flash color delta value. */ public int tabHighlightDirection = 16; /** * Graphics to paint to the screen canvas. */ protected Graphics g; /** * If this is set to true, tab flashing animation and drawing are * enabled. */ protected boolean haveTabs = false; /** * If set to true, a busy animation is drawn on the screen. */ protected boolean busy = false; /** * Rotating busy indicator orb state. */ private int busyIndicatorAngle = 0; BaseView(Graphics g, int id, int x, int y, int width, int height) { this.id = id; this.x = x; this.y = y; this.width = width; this.height = height; this.g = g; try { tabHeader = ImageLoader.getInstance().loadImage("/header.png"); } catch (IOException e) { } } /** * After this call the view will be painted on screen by calling draw(). */ public void activate() { System.out.println("activating " + id()); busy = false; active = true; } /** * After this call the view should not do anything. */ public void deactivate() { System.out.println("deactivating " + id()); active = false; } /** * Empty implementation. * Draw event. */ public void draw(int x, int y, int width, int height) { } /** * Empty implementation * Key press event. */ public void keyPressed(int keyCode) { } /** * Empty implementation. * Key released event. */ public void keyReleased(int keyCode) { } /** * Empty implementation. * Called when view transition animation is done. */ public void transitionFinished() { } /** * Returns the view id. */ public int id() { return id; } /** * Draws the sofkeys. */ protected void drawSoftkeys() { if (menu != null && menu.isVisible()) { return; } // Visual enchancement in the form of a grey line g.setColor(Visual.SOFTKEY_DECORATOR_COLOR); g.drawLine(30, height - Visual.SOFTKEYBAR_HEIGHT + 2, width - 30, height - Visual.SOFTKEYBAR_HEIGHT + 2); g.setColor(Visual.BACKGROUND_COLOR); g.fillRect(0, height - Visual.SOFTKEY_FONT.getHeight(), width, Visual.SOFTKEY_FONT.getHeight()); g.setFont(Visual.SOFTKEY_FONT); g.setColor(Visual.SOFTKEY_TEXT_COLOR); g.drawString(softkey1Label, 0, height, g.LEFT | g.BOTTOM); g.drawString(softkey2Label, width / 2, height, g.HCENTER | g.BOTTOM); g.drawString(softkey3Label, width, height, g.RIGHT | g.BOTTOM); } public int tabsHeight() { return tabHeader.getHeight(); } /** * Draws the tabs. */ protected void drawTabs() { if (!haveTabs) { return; } int selectorX1 = 10; int selectorX2 = 110; if (id() == ViewMaster.VIEW_COMMENTS || id() == ViewMaster.VIEW_SINGLECOMMENT || id() == ViewMaster.VIEW_COMMENTSFORPOST) { selectorX1 = 122; selectorX2 = 222; } g.setColor(0); g.fillRect(0, 0, width, tabsHeight()); g.setColor(0, tabHighlight, tabHighlight); g.fillRect(selectorX1, 0, selectorX2 - selectorX1, tabsHeight()); g.drawImage(tabHeader, 0, 0, g.TOP | g.LEFT); } /** * Draws a red object that acts as an update indicator. Used when doing * some lenghty operations, such as posting. Animation is provided in * animationRunner(). */ private void drawBusyIndicator(Graphics g) { // Draw an animating red orb. int size = 40; g.setColor((busyIndicatorAngle * 256) / 360, 0, 0); g.fillArc(width / 2 - size / 2, height / 2 - size / 2, size, size, busyIndicatorAngle, busyIndicatorAngle + 10); viewMaster.updateScreen(width / 2 - size / 2, height / 2 - size / 2, size, size); } /** * Animation runner, called from the timer thread. * Graphics contexts are accessed synchronously so as to avoid * drawing unexpected things as drawing is also done in the main * application thread. */ public void animate() { if (!viewMaster.isShown() || !active) { return; } // Check if menu is being animated. if (menu != null && menu.isVisible()) { if (menu.animate()) { synchronized (g) { menu.draw(g); viewMaster.updateScreen(menu.x, menu.y, menu.width, menu.height); } } return; } // Flashing tabs... if (haveTabs && !busy) { // Tab bar blinking animation: tabHighlight += tabHighlightDirection; if (tabHighlight > 255) { tabHighlight = 255; tabHighlightDirection = -tabHighlightDirection; } if (tabHighlight < 0) { tabHighlight = 0; tabHighlightDirection = -tabHighlightDirection; } // Flush only tab bar area synchronized (g) { drawTabs(); viewMaster.updateScreen(0, 0, width, tabsHeight()); } } // ...and the busy indicator if (busy) { busyIndicatorAngle = (busyIndicatorAngle + 7) % 360; synchronized (g) { drawBusyIndicator(g); } } } /** * Graphics setter. This is used to change the target when * doing view transitions. * @param g */ public void setGraphics(Graphics g) { this.g = g; } }