PTILayerpublic class PTILayer extends PopupLayer 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. |
Fields Summary |
---|
private String[] | listOptions have to be listed in the popup dialog | private int | selIdSelected option number | private TextInputSession | iSessionInstance of current input mode | private int | widthMaxmax text width visible on the screen | private static final String | SEPARATORseparator character between words within the list | private static final int | OUT_OF_BOUNDSpointer is clicked outside of any area | private static final int | LEFT_ARROW_AREApointer is clicked to left arrow | private static final int | RIGHT_ARROW_AREApointer is clicked to right arrow | private static final int | LIST_MATCHES_AREApointer is clicked to the word inside of list | private boolean | checkReleasedFlag indicates that pointer release event should be processed |
Constructors Summary |
---|
public PTILayer(TextInputSession inputSession)Create an instance of PTILayer //= false;
super(PTISkin.IMAGE_BG, PTISkin.COLOR_BG);
iSession = inputSession;
|
Methods Summary |
---|
private int | getAreaAtPointerPosition(int x, int y)Get the layer area the pointer is clicked in
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;
| public synchronized java.lang.String[] | getList()Get list of matches
return list;
| private int | getWordIdAtPointerPosition(int x, int y)Get id of the word inside of the list selected by pointer
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;
| public boolean | handlePoint(int x, int y)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.
return containsPoint(x, y);
| protected void | initialize()PTI layer initialization: init selected id, calculate available size
super.initialize();
setAnchor();
selId = 0;
| public boolean | keyInput(int type, int keyCode)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.
boolean ret = false;
String[] l = getList();
if (type == EventConstants.PRESSED && 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;
| protected void | paintBody(Graphics g)Paint layer body.
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);
}
int x = 0, y = 0;
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]);
x = 0;
y = PTISkin.FONT.getHeight() < bounds[H] ?
(bounds[H] - PTISkin.FONT.getHeight()) >> 1 : 0;
// 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]);
| public boolean | pointerInput(int type, int x, int y)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.
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;
| private void | setAnchor()Sets the anchor constants for rendering operation.
bounds[W] = ScreenSkin.WIDTH;
bounds[H] = PTISkin.HEIGHT;
bounds[X] = (ScreenSkin.WIDTH - bounds[W]) >> 1;
bounds[Y] = ScreenSkin.HEIGHT - 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();
}
| public synchronized void | setList(java.lang.String[] l)Set list of matches
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();
| public void | setVisible(boolean visible)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.
this.visible = visible;
| public void | update(CLayer[] layers)Update bounds of layer
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);
}
|
|