ptilayer.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 424 行
JAVA
424 行
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.chameleon.layers;import com.sun.midp.chameleon.*;import javax.microedition.lcdui.*;import com.sun.midp.chameleon.skins.PTISkin;import com.sun.midp.lcdui.EventConstants;import com.sun.midp.configurator.Constants;import com.sun.midp.chameleon.input.*;/** * A "PTILayer" layer is a special kind of layer which can * be visible when the predictive text input mode is active. * This layer is added to a MIDPWindow when more than one match * exists for the predictive input method. This layer lists the * possible words to give user a chance to select word you like. * User can traverse the list of words using up/down navigation * keys. User may press select bhutton to accept highlighted word. */public class PTILayer extends PopupLayer { /** Options have to be listed in the popup dialog */ private String[] list; /** Selected option number */ private int selId; /** Instance of current input mode */ private TextInputSession iSession; /** max text width visible on the screen */ private int widthMax; /** separator character between words within the list */ private static final String SEPARATOR = " "; /** pointer is clicked outside of any area */ private static final int OUT_OF_BOUNDS = -1; /** pointer is clicked to left arrow */ private static final int LEFT_ARROW_AREA = 0; /** pointer is clicked to right arrow */ private static final int RIGHT_ARROW_AREA = 1; /** pointer is clicked to the word inside of list */ private static final int LIST_MATCHES_AREA = 2; /** Flag indicates that pointer release event should be processed */ private boolean checkReleased ; //= false; /** * Create an instance of PTILayer * @param inputSession current input session */ public PTILayer(TextInputSession inputSession) { super(PTISkin.IMAGE_BG, PTISkin.COLOR_BG); iSession = inputSession; } /** * The setVisible() method is overridden in PTILayer * so as not to have any effect. PopupLayers are always * visible by their very nature. In order to hide a * PopupLayer, it should be removed from its containing * MIDPWindow. * @param visible if true the pti layer has to be shown, * if false the layer has to be hidden */ public void setVisible(boolean visible) { this.visible = visible; } /** PTI layer initialization: init selected id, calculate available size */ protected void initialize() { super.initialize(); setAnchor(); selId = 0; } /** * Sets the anchor constants for rendering operation. */ private void setAnchor() { if (owner == null) { return; } bounds[W] = owner.bounds[W]; bounds[H] = PTISkin.HEIGHT; bounds[X] = (owner.bounds[W] - bounds[W]) >> 1; bounds[Y] = owner.bounds[H] - bounds[H]; widthMax = bounds[W] - PTISkin.MARGIN; if (PTISkin.LEFT_ARROW != null && PTISkin.RIGHT_ARROW != null) { widthMax -= 4 * PTISkin.MARGIN + PTISkin.LEFT_ARROW.getWidth() + PTISkin.RIGHT_ARROW.getWidth(); } } /** * Set list of matches * @param l list of matches */ public synchronized void setList(String[] l) { list = new String[l.length]; System.arraycopy(l, 0, list, 0, l.length); visible = (list != null && list.length > 1); // IMPL_NOTE: has to be set externally as parameter selId = 0; setDirty(); } /** * Get list of matches * @return list of matches */ public synchronized String[] getList() { return list; } /** * Handle key input from a keypad. Parameters describe * the type of key event and the platform-specific * code for the key. (Codes are translated using the * lcdui.Canvas) UP/DOWN/SELECT key press are processed if * is visible. * * @param type the type of key event * @param keyCode the numeric code assigned to the key * @return true if key has been handled by PTI layer, false otherwise */ public boolean keyInput(int type, int keyCode) { boolean ret = false; String[] l = getList(); if (( (type == EventConstants.PRESSED) || (type == EventConstants.REPEATED) ) && visible) { switch (keyCode) { case Constants.KEYCODE_UP: case Constants.KEYCODE_LEFT: selId = (selId - 1 + l.length) % l.length; iSession.processKey(Canvas.UP, false); ret = true; break; case Constants.KEYCODE_DOWN: case Constants.KEYCODE_RIGHT: selId = (selId + 1) % l.length; iSession.processKey(Canvas.DOWN, false); ret = true; break; case Constants.KEYCODE_SELECT: iSession.processKey(keyCode, false); ret = true; break; default: break; } } // process key by input mode requestRepaint(); return ret; } /** * Get id of the word inside of the list selected by pointer * @param x - x coordinate of pointer * @param y - y coordinate of pointer * @return word index in the range of 0 and list length - 1. * If the pointer does not point to any word return -1 */ private int getWordIdAtPointerPosition(int x, int y) { String[] l = getList(); int id = 0; int start = PTISkin.MARGIN; if (PTISkin.LEFT_ARROW != null) { start += PTISkin.LEFT_ARROW.getWidth(); } while (id < l.length) { int w = PTISkin.FONT.stringWidth(SEPARATOR + l[id]); if (x > start && x <= start + w) { break; } start += w; id++; } return id < l.length ? id : -1; } /** * Utility method to determine if this layer wanna handle * the given point. PTI layer handles the point if it * lies within the bounds of this layer. The point should be in * the coordinate space of this layer's containing CWindow. * * @param x the "x" coordinate of the point * @param y the "y" coordinate of the point * @return true if the coordinate lies in the bounds of this layer */ public boolean handlePoint(int x, int y) { return containsPoint(x, y); } /** * Get the layer area the pointer is clicked in * @param x - x coordinate of pointer * @param y - y coordinate of pointer * @return retuen the area. It can be either OUT_OF_BOUNDS or * LEFT_ARROW_AREA or RIGHT_ARROW_AREA or LIST_MATCHES_AREA */ private int getAreaAtPointerPosition(int x, int y) { int area = OUT_OF_BOUNDS; if (x >= PTISkin.MARGIN && x <= bounds[W] - PTISkin.MARGIN) { if (PTISkin.LEFT_ARROW != null && x <= PTISkin.MARGIN + PTISkin.LEFT_ARROW.getWidth()) { area = LEFT_ARROW_AREA; } else if (PTISkin.RIGHT_ARROW != null && x >= bounds[W] - PTISkin.MARGIN - PTISkin.RIGHT_ARROW.getWidth()) { area = RIGHT_ARROW_AREA; } else { area = LIST_MATCHES_AREA; } } return area; } /** * Allow this window to process pointer input. The type of pointer input * will be press, release, drag, etc. The x and y coordinates will * identify the point at which the pointer event occurred in the coordinate * system of this window. This window will translate the coordinates * appropriately for each layer contained in this window. This method will * return true if the event was processed by this window or one of its * layers, false otherwise. * * @param type the type of pointer event (press, release, drag) * @param x the x coordinate of the location of the event * @param y the y coordinate of the location of the event * @return true if this window or one of its layers processed the event */ public boolean pointerInput(int type, int x, int y) { if (visible) { String[] l = getList(); int area = getAreaAtPointerPosition(x, y); switch(type) { case EventConstants.PRESSED: switch (area) { case LEFT_ARROW_AREA: selId = (selId - 1 + l.length) % l.length; iSession.processKey(Canvas.UP, false); requestRepaint(); break; case RIGHT_ARROW_AREA: selId = (selId + 1) % l.length; iSession.processKey(Canvas.DOWN, false); requestRepaint(); break; case LIST_MATCHES_AREA: // move focus to the selected word int id = getWordIdAtPointerPosition(x, y); if (id >= 0) { checkReleased = true; int i = selId; if (id > selId) { while (i < id) { iSession.processKey(Canvas.DOWN, false); i++; } } else if (id < selId) { while (i > id) { iSession.processKey(Canvas.UP, false); i--; } } requestRepaint(); } break; } break; case EventConstants.RELEASED: if (area == LIST_MATCHES_AREA && checkReleased // IMPL_NOTE: move the focus in the standart maner, // doon't move the selected item at the head of the list // && getWordIdAtPointerPosition(x, y) == selId ) { iSession.processKey(Constants.KEYCODE_SELECT, false); requestRepaint(); } checkReleased = false; break; default: break; } } return true; } /** * Paint layer body. * @param g - Graphics */ protected void paintBody(Graphics g) { String[] l = getList(); if (l == null || l.length < 1) return; // draw outer frame g.setColor(PTISkin.COLOR_BDR); g.drawRect(0, 0, bounds[W] - 1, bounds[H] - 1); // draw arrows if (PTISkin.LEFT_ARROW != null) { g.drawImage(PTISkin.LEFT_ARROW, PTISkin.MARGIN, bounds[H] >> 1, Graphics.VCENTER | Graphics.LEFT); } if (PTISkin.RIGHT_ARROW != null) { g.drawImage(PTISkin.RIGHT_ARROW, bounds[W] - PTISkin.MARGIN, bounds[H] >> 1, Graphics.VCENTER | Graphics.RIGHT); } String text_b = "", text_a = ""; for (int i = -1; ++i < l.length; ) { if (i < selId) { text_a += l[i] + SEPARATOR; } else if (i > selId) { text_b += l[i] + SEPARATOR; } } g.translate((bounds[W] - widthMax) >> 1, 0); g.setClip(0, 0, widthMax, bounds[H]); int x = 0; int y = (bounds[H] - PTISkin.FONT.getHeight()) >> 1; // prevent the overlapping of the outline if (y <= 0) y = 1; // draw before words if (text_a.length() > 0) { g.setColor(PTISkin.COLOR_FG); g.drawString(text_a, x, y, Graphics.LEFT | Graphics.TOP); x += PTISkin.FONT.stringWidth(text_a); } if (l[selId].length() > 0) { // draw highlighted word // draw highlighted fill rectangle g.setColor(PTISkin.COLOR_BG_HL); g.fillRect(x - PTISkin.FONT.stringWidth(SEPARATOR) / 2, y < PTISkin.MARGIN ? y : PTISkin.MARGIN, PTISkin.FONT.stringWidth(l[selId] + SEPARATOR), bounds[H] - (y < PTISkin.MARGIN ? y : PTISkin.MARGIN) * 2); g.setColor(PTISkin.COLOR_FG_HL); g.drawString(l[selId] + SEPARATOR, x, y, Graphics.LEFT | Graphics.TOP); x += PTISkin.FONT.stringWidth(l[selId] + SEPARATOR); } // draw after words if (text_b.length() > 0) { g.setColor(PTISkin.COLOR_FG); g.drawString(text_b, x, y, Graphics.LEFT | Graphics.TOP); } g.translate(-((bounds[W] - widthMax) >> 1), 0); g.setClip(0, 0, bounds[W], bounds[H]); } /** * Update bounds of layer * @param layers - current layer can be dependant on this parameter */ public void update(CLayer[] layers) { super.update(layers); if (visible) { setAnchor(); bounds[Y] -= (layers[MIDPWindow.BTN_LAYER].isVisible() ? layers[MIDPWindow.BTN_LAYER].bounds[H] : 0) + (layers[MIDPWindow.TICKER_LAYER].isVisible() ? layers[MIDPWindow.TICKER_LAYER].bounds[H] : 0); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?