www.pudn.com > Bluegammon蓝牙的应用编程.rar > DefaultMenuPainter.java
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB // // This software is provided "AS IS," without a warranty of any kind. // ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, // INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. // // THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se) package bluegammon.gui.menu; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Image; import javax.microedition.lcdui.Graphics; /** * A default implementation ofMenuPainter. Transitions are implemented * as an horizontal movement. Items a rendered using normal MIDP text * methods. * @author Peter Andersson */ public class DefaultMenuPainter implements MenuPainter { /** Font of the page title */ protected Font m_titleFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE); /** Font of items */ protected Font m_itemFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM); /** Page title color */ protected int m_titleColor = 0xffffff; /** Page title back color */ protected int m_titleBackColor = 0x880000; /** Enabled item label color */ protected int m_itemColor = 0x00ffff; /** Disabled item label color */ protected int m_itemColorDisabled = 0x888888; /** Selected item label color */ protected int m_selItemColor = 0xffffff; protected int m_imgPadding = 4; public void paintMenu(Graphics g, MenuPage menu, int x, int y, int width, int height) { paintMenu(g, menu, x, y, width, height, false, false); } /** * Paints a menu. * * @param g The graphics context to draw to. * @param menu The menu to draw. * @param x Offset x coordinate. * @param y Offset y coordinate. * @param width The width of the menu. * @param height The height of the menu. * @param to True if transition to this page, false if transition from * or no transition. * @param from True if transition from this page, false if transition to * or no transition. */ protected void paintMenu(Graphics g, MenuPage page, int x, int y, int width, int height, boolean to, boolean from) { if (page == null) return; int tHeight = m_titleFont.getHeight(); int iHeight = m_itemFont.getHeight(); paintTitle(g, page, x + width / 2, y, width); paintItems(g, page, x, y + getTitleHeight(page) + 8, width, height, to, from); } /** * Calls paintMenu twice with the two pages, plus an x offset for each menu * to visualize the transition. */ public void paintTransition(Graphics g, MenuPage fromMenu, MenuPage toMenu, int x, int y, int width, int height, int frame, int frames, boolean back) { double percent = (double) frame / (double) frames; int dx = (int) (width * Math.sin(Math.PI / 2d * percent)); int sign = back ? -1 : 1; paintMenu(g, fromMenu, -dx * sign, y, width, height, false, true); paintMenu(g, toMenu, sign * (width - dx), y, width, height, true, false); } /** * Draws a page title horizontally centered around specified coordinates. * * @param g Graphics context to paint on. * @param page The page with the title. * @param x X coordinate of title, title is centered around this. * @param y Y coordinate of title, denoting top of text. * @param w Width of the menu. */ protected void paintTitle(Graphics g, MenuPage page, int x, int y, int w) { char[] title = page.getTitle(); Image img = page.getTitleImage(); int imgW = 0; int imgH = 0; int txtW = 0; int txtH = m_itemFont.getHeight(); int layout = page.getLayout(); boolean imgLeft = layout == MenuPage.LAYOUT_LEFT; if (title != null) { txtW = m_itemFont.charsWidth(title, 0, title.length); } if (img != null) { imgW = img.getWidth(); imgH = img.getHeight(); } int totW = imgW + txtW + ((imgW == 0 || txtW == 0) ? 0 : m_imgPadding); int totH = Math.max(imgH, txtH); // draw image if any if (img != null) { int dx = imgLeft ? (-totW/2 - imgW) : (txtW/2); g.drawImage(img, x + dx, y + (totH - imgH) / 2, Graphics.TOP | Graphics.LEFT); imgW += m_imgPadding; } // draw title if any if (title != null) { int dx = imgLeft ? (imgW/2) : (-imgW/2); g.setFont(m_titleFont); g.setColor(m_titleBackColor); g.drawChars(title, 0, title.length, x + dx + 1, y + (totH - txtH) / 2 + 1, Graphics.TOP | Graphics.HCENTER); g.setColor(m_titleColor); g.drawChars(title, 0, title.length, x + dx, y + (totH - txtH) / 2, Graphics.TOP | Graphics.HCENTER); } } /** * Paints all items in a page. This methods checks height of each * item and sorts out exactly what items to paint according to * currently selected item. CallsgetItemHeightfor * items to determine how to fit items, and then callspaintItem* for those items it seems fit to draw. * * @param g Graphics context to draw to. * @param page The page containing all items. * @param x X offset coordinate. * @param y Y offset coordinate. * @param w Width of menu, to determine how to horizontally centralize items. * @param h Height of menu, to determine how many items to draw. * @param to True if transition to this item, false if transition from * or no transition. * @param from True if transition from this item, false if transition to * or no transition. */ protected void paintItems(Graphics g, MenuPage page, int x, int y, int w, int h, boolean to, boolean from) { int selectedIndex = page.getSelectedIndex(); PageItem selectedItem = page.itemAt(selectedIndex); PageItem itemBelow = page.itemAt(selectedIndex + 1); itemBelow = itemBelow == null ? selectedItem : itemBelow; // Find number of items that we can show in the viewport, // try having the selected near middle int startIndex = selectedIndex < 0 ? 0 : selectedIndex; int size = page.size(); if (selectedItem != null) { int topIndex = selectedIndex; int endIndex = selectedIndex; int yLeft = h - y - getItemHeight(selectedItem) - getItemHeight(itemBelow); // check item under and above // until viewport is filled or all items are added do { if (endIndex < size - 1) { endIndex++; yLeft -= getItemHeight(page.itemAt(endIndex)); } if (yLeft > 0 && topIndex > 0) { topIndex--; yLeft -= getItemHeight(page.itemAt(topIndex)); } } while (yLeft > 0 && (topIndex > 0 || endIndex < size - 1)); startIndex = topIndex; } // Find max width int iMaxW = 0; for (int i = startIndex < 0 ? 0 : startIndex; i < size; i++) { iMaxW = Math.max(iMaxW, getItemWidth(page.itemAt(i))); } // Draw items for (int i = startIndex < 0 ? 0 : startIndex; i < size; i++) { boolean selected = i == selectedIndex; PageItem item = page.itemAt(i); paintItem(g, item, selected, x + w / 2, y, w, iMaxW, to, from); y += getItemHeight(item); if (y >= h) { break; } } } /** * Paints one single item. If the item has an image, the image will * be painted to the left of the label text. * * @param g The graphics context to draw to. * @param item The item to paint. * @param selected If this item is selected or not. * @param x X coordinate, item will be centered around this. * @param y Y coordinate, denoting top of item * @param w Width of menu, to determine center. * @param iMaxW Maximum width of all visible items, for alignment. * @param to True if transition to this item, false if transition from * or no transition. * @param from True if transition from this item, false if transition to * or no transition. */ protected void paintItem(Graphics g, PageItem item, boolean selected, int x, int y, int w, int iMaxW, boolean to, boolean from) { char[] label = item.getLabel(); boolean enabled = item.isEnabled(); Image img = item.getImage(); int imgW = 0; int imgH = 0; int txtW = 0; int txtH = m_itemFont.getHeight(); int layout = item.getLayout(); boolean align = layout == PageItem.LAYOUT_ALIGN_LEFT | layout == PageItem.LAYOUT_ALIGN_RIGHT; boolean imgLeft = layout == PageItem.LAYOUT_CENTERED_LEFT | layout == PageItem.LAYOUT_ALIGN_LEFT; if (label != null) { txtW = m_itemFont.charsWidth(label, 0, label.length); } if (img != null) { imgW = img.getWidth(); imgH = img.getHeight(); } int totW = imgW + txtW + ((imgW == 0 || txtW == 0) ? 0 : m_imgPadding); int totH = Math.max(imgH, txtH); // draw image if any if (img != null) { int dx = 0; if (align) { dx = imgLeft ? (-iMaxW/2) : (iMaxW/2 - imgW); } else { dx = imgLeft ? (-totW/2 - imgW) : (txtW/2); } g.drawImage(img, x + dx, y + (totH - imgH) / 2, Graphics.TOP | Graphics.LEFT); imgW += m_imgPadding; } // draw label if any if (label != null) { if (!selected) { g.setColor(enabled ? m_itemColor : m_itemColorDisabled); } else { g.setColor(m_selItemColor); } int dx = 0; if (align) { dx = imgLeft ? ((iMaxW - txtW)/2) : (-(iMaxW - txtW)/2); } else { dx = imgLeft ? (imgW/2) : (-imgW/2); } g.setFont(m_itemFont); g.drawChars(label, 0, label.length, x + dx, y + (totH - txtH) / 2, Graphics.TOP | Graphics.HCENTER); } } /** * Returns the height of a title. Simply returns height of * title font. * @param menu The menu with title whose height to return. * @return The title height. */ protected int getTitleHeight(MenuPage menu) { return m_titleFont.getHeight(); } /** * Returns the height of an item. Takes the maximum value of * height of image and height of item font. * @param item The item whose height to return. * @return The height of the item. */ protected int getItemHeight(PageItem item) { int fHeight = m_itemFont.getHeight(); Image image = item.getImage(); int iHeight = (image == null ? 0 : image.getHeight()); return Math.max(fHeight, iHeight); } /** * Returns the width of an item. Summarizes image width, * padding and label width. * @param item The item whose width to return. * @return The width of the item. */ protected int getItemWidth(PageItem item) { Image image = item.getImage(); char[] text = item.getLabel(); int w = (image == null ? 0 : image.getWidth()); w += (text == null ? 0 : m_itemFont.charsWidth(text, 0, text.length)); w += (image == null || text == null) ? 0 : m_imgPadding; return w; } }