Fields Summary |
---|
protected String[] | labelsLabels for each of the softbuttons. |
protected Command[] | scrCmdsA cached copy of the set of screen commands sent from
the Display. |
protected CommandListener | scrListenerThe CommandListener to notify for any screen commands executed. |
protected Command[] | itmCmdsA cached copy of the set of item commands sent from
the Display. |
protected ItemCommandListener | itemListenerThe ItemCommandListener to notify for any item commands executed. |
protected Command | soft1The command associated with soft button #1.
null if there is no command associated with button #1. |
protected Command[] | soft2The set of commands associated with soft button #2.
null if there are no commands associated with button #2.
If there is only one element in this array, there is no need
for a menu and soft button #2 will behave similar to soft
button #1 and invoke the listener directly upon button press. |
protected SubMenuCommand | subMenuWhen a sub menu is currently active, this reference is non-null. |
private CLayer | cachedScrollablekeep scrollable and scrollListener to recover them after menu dismiss |
private ScrollListener | cachedListener |
protected static final int[] | cmdWeightsA set of weights assigned to each of the types of Commands.
The array is set up to return the weight of the Command type
for each index, ie. Command.BACK has a defined value of 2 from
the MIDP specification, cmdWieghts[Command.BACK] == 4, that is,
there are three other Command types which sort higher than BACK
(ITEM, SCREEN, and OK). The weighting is specified in the
MIDP Human Interface Specification (Sun Internal). |
protected MenuLayer | menuLayerA System menu to popup and display when a set of commands
needs to be displayed. |
protected boolean | menuUPA flag indicating the system menu is up. |
protected boolean | alertUPA flag indicating the alert is up. |
protected ChamDisplayTunnel | tunnelA tunnel to utilize to notify of command invocation. |
protected Command | swapAn internal variable defined once to avoid costly heap thrashing. |
protected int | typeXInternal variables defined once to avoid costly heap thrashing. |
protected int | typeY |
protected int | buttonxInternal variables for the paint loop. |
protected int | buttony |
protected int | buttonw |
protected int | buttonh |
private boolean | isInteractiveTrue if user is interacting with the layer |
Methods Summary |
---|
public boolean | belongToCmdLayers(int x, int y)Returns true if the point lies in the bounds of commnad layers
subset like buttons, menu, submenu
return containsPoint(x,y) ||
(menuLayer != null &&
(menuLayer.containsPoint(x,y) ||
(menuLayer.cascadeMenu != null &&
menuLayer.cascadeMenu.containsPoint(x,y))
)
);
|
public void | commandAction(Command c, Displayable d)Commandlistener interface implementation. Handle softbuton commands.
dismissMenu();
|
public void | commandSelected(Command cmd)Selects a command.
if (cmd == null) {
return;
}
dismissMenu();
processCommand(cmd);
|
protected int | compare(Command a, Command b)Compares two commands.
if (a == null || b == null) {
return 0;
}
typeX = a.getCommandType();
typeY = b.getCommandType();
if (typeX != typeY) {
return cmdWeights[typeX] - cmdWeights[typeY];
} else {
return a.getPriority() - b.getPriority();
}
|
public void | dismissMenu()Dismiss menu layer.
if (menuUP) {
menuUP = false;
menuLayer.dismiss();
if (owner != null) {
menuLayer.setScrollInd(null);
owner.removeLayer(menuLayer);
}
}
toggleMenu(menuUP);
|
public Command | getSoftOne()Returns the left soft button (one).
return soft1;
|
public Command[] | getSoftTwo()Returns the command array tied to the right soft button (two).
return soft2;
|
protected void | initMenu()Initializes the menu from menu resources.
MenuResources.load();
menuLayer = new MenuLayer();
Command menuClose = new Command(SoftButtonSkin.TEXT_BACKCMD,
Command.BACK, 1);
menuLayer.setCommands(new Command[]{menuClose});
menuLayer.setCommandListener(this);
|
protected void | initialize()Initializes the soft button layer.
super.initialize();
setAnchor();
|
protected boolean | isCommandActive(Command cmd)Determines if it is possible to process the command.
if (tunnel == null || cmd == null) {
return false;
}
if ((isItemCommand(cmd) && (itemListener != null))
|| (scrListener != null)) {
return true;
}
return false;
|
public boolean | isInteractive()Returnes true if user is interacting with the layer,
false otherwise.
used by MIDPWindow to check if the layer should become
visible.
return isInteractive;
|
protected boolean | isItemCommand(Command cmd)Checks if the item is a command.
if (itmCmds.length == 0) {
return false;
}
for (int i = 0; i < itmCmds.length; i++) {
if (itmCmds[i] == cmd) {
return true;
}
}
return false;
|
protected boolean | isSoft1Active()Determines if soft button 1 will be processed by the layer.
Called by keyInput to determine if the corresponding key event
should be absorbed by SoftButtonLayer.
// when MIDPWindow is not in full screen mode, we absorb
// all key events reserved for the delivery of commands
if (!((MIDPWindow)owner).isInFullScreenMode()) {
return true;
}
// for full screen mode we should check if soft key is useful
if (menuUP) {
return true;
} else {
return isCommandActive(soft1);
}
|
protected boolean | isSoft2Active()Determines if soft button 2 will be processed by the layer.
Called by keyInput to determine if the corresponding key event
should be absorbed by SoftButtonLayer.
// when MIDPWindow is not in full screen mode, we absorb
// all key events reserved for the delivery of commands
if (!((MIDPWindow)owner).isInFullScreenMode()) {
return true;
}
// for full screen mode we should check if soft key is useful
if (menuUP) {
return true;
} else if (soft2 != null) {
if (soft2.length == 1 &&
soft2[0] instanceof SubMenuCommand) {
return true;
}
// search for at least one active command
for (int i = 0; i < soft2.length; i++) {
if (isCommandActive(soft2[i])) {
return true;
}
}
}
return false;
|
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)
// SoftButtonLayer absorbs soft button
// event only if corresponding soft button is "active".
// For further clarification please refer to
// isSoft1Active() and isSoft2Active() methods.
boolean ret = false;
if (keyCode == EventConstants.SOFT_BUTTON1) {
if (isSoft1Active()) {
if (type == EventConstants.PRESSED) {
setInteractive(true);
ret = true;
} else if (type == EventConstants.RELEASED) {
soft1();
ret = true;
}
}
} else if (keyCode == EventConstants.SOFT_BUTTON2) {
if (isSoft2Active()) {
if (type == EventConstants.PRESSED) {
setInteractive(true);
ret = true;
} else if (type == EventConstants.RELEASED) {
soft2();
ret = true;
}
}
}
return ret;
|
protected void | paintBody(Graphics g)Renders the soft button layer.
g.setFont(SoftButtonSkin.FONT);
for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
if (labels[i] == null) {
continue;
}
buttonw = SoftButtonSkin.FONT.stringWidth(labels[i]);
if (buttonw > SoftButtonSkin.BUTTON_MAX_WIDTH[i]) {
buttonw = SoftButtonSkin.BUTTON_MAX_WIDTH[i];
}
switch (SoftButtonSkin.BUTTON_ALIGN_X[i]) {
case Graphics.HCENTER:
buttonx =
SoftButtonSkin.BUTTON_ANCHOR_X[i] - (buttonw / 2);
break;
case Graphics.RIGHT:
buttonx = SoftButtonSkin.BUTTON_ANCHOR_X[i] - buttonw;
break;
case Graphics.LEFT:
default:
buttonx = SoftButtonSkin.BUTTON_ANCHOR_X[i];
break;
}
buttony = SoftButtonSkin.BUTTON_ANCHOR_Y[i];
//buttonh = SoftButtonSkin.FONT.getHeight();
g.translate(buttonx, buttony);
Text.drawTruncStringShadowed(g, labels[i], SoftButtonSkin.FONT,
SoftButtonSkin.COLOR_FG, SoftButtonSkin.COLOR_FG_SHD,
SoftButtonSkin.BUTTON_SHD_ALIGN, buttonw);
}
|
public boolean | pointerInput(int type, int x, int y)Handles pointer input events.
if (type != EventConstants.PRESSED) {
return true;
}
for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
switch (SoftButtonSkin.BUTTON_ALIGN_X[i]) {
case Graphics.LEFT:
if (x < SoftButtonSkin.BUTTON_ANCHOR_X[i] ||
(x > SoftButtonSkin.BUTTON_ANCHOR_X[i] +
SoftButtonSkin.BUTTON_MAX_WIDTH[i])) {
continue;
}
break;
case Graphics.RIGHT:
if (x > SoftButtonSkin.BUTTON_ANCHOR_X[i] ||
(x < SoftButtonSkin.BUTTON_ANCHOR_X[i] -
SoftButtonSkin.BUTTON_MAX_WIDTH[i])) {
continue;
}
break;
default:
continue;
}
if (y >= SoftButtonSkin.BUTTON_ANCHOR_Y[i]
&& y <= bounds[H]) {
softPress(i);
}
}
// SoftButtonLayer always swallows any pointer input, as there is no
// need to forward the press on to any other layer.
return true;
|
protected void | processCommand(Command cmd)Processes commands.
setInteractive(false);
if (tunnel == null || cmd == null) {
return;
}
if (subMenu != null) {
subMenu.notifyListener(cmd);
subMenu = null;
} else if (isItemCommand(cmd)) {
tunnel.callItemListener(cmd, itemListener);
} else {
tunnel.callScreenListener(cmd, scrListener);
}
|
public void | setAnchor()Sets the anchor constraints for rendering operation.
bounds[X] = 0;
bounds[Y] = ScreenSkin.HEIGHT - SoftButtonSkin.HEIGHT;
bounds[W] = ScreenSkin.WIDTH;
bounds[H] = SoftButtonSkin.HEIGHT;
|
private void | setBackground()Sets the background based on current menu and alert
settings.
if (menuUP) {
setBackground(SoftButtonSkin.IMAGE_MU_BG,
SoftButtonSkin.COLOR_MU_BG);
} else if (alertUP) {
setBackground(SoftButtonSkin.IMAGE_AU_BG,
SoftButtonSkin.COLOR_AU_BG);
} else {
setBackground(SoftButtonSkin.IMAGE_BG,
SoftButtonSkin.COLOR_BG);
}
|
protected void | setButtonLabels()Sets the button labels.
// reset all the labels
for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
labels[i] = null;
}
// Port me : If a port had more than 2 soft buttons, adjust
// the behavior here for extra buttons
labels[0] = (soft1 == null) ? null : soft1.getLabel();
if (soft2 == null) {
labels[1] = null;
} else if (soft2.length == 1) {
labels[1] = soft2[0].getLabel();
} else {
labels[1] = SoftButtonSkin.TEXT_MENUCMD;
}
addDirtyRegion();
requestRepaint();
|
private boolean | setCommands(int cmdNum, int start, Command[] cmds)Assigns the commands to soft1 and soft2 buttons .
int setSoft1 = 0;
if (cmdNum > 0) {
sortCommands(cmds, cmdNum);
for (int i = 0; i < cmdNum; i++) {
if (soft1 == null && !(cmds[i] instanceof SubMenuCommand)) {
soft1 = cmds[i];
setSoft1++;
} else {
soft2[start + i - setSoft1] = cmds[i];
}
}
if (setSoft1 > 0) {
// decrement the soft2 array length
Command[] soft2temp = new Command[soft2.length - 1];
System.arraycopy(soft2, 0, soft2temp, 0, soft2temp.length);
soft2 = soft2temp;
}
}
return setSoft1 > 0;
|
private void | setInteractive(boolean interactive)Assigns new value to isInteractive and signals MIDPWindow.
if (isInteractive != interactive) {
isInteractive = interactive;
if (owner instanceof MIDPWindow) {
((MIDPWindow)owner).updateLayout();
}
}
|
protected void | soft1()Soft button 1 handler.
if (menuUP) {
dismissMenu();
subMenu = null;
requestRepaint();
setButtonLabels();
setInteractive(false);
} else {
processCommand(soft1);
}
|
protected void | soft2()Soft button 2 handler.
if (soft2 != null) {
if (soft2.length == 1 &&
soft2[0] instanceof SubMenuCommand) {
subMenu = (SubMenuCommand) soft2[0];
}
if (soft2.length > 1 ||
subMenu != null) {
if (menuLayer == null) {
initMenu();
}
menuLayer.setMenuCommands(soft2, this, 0);
menuUP = true;
toggleMenu(menuUP);
// Show the menu
if (owner != null) {
owner.addLayer(menuLayer);
menuLayer.setScrollInd(ScrollIndLayer.getInstance(ScrollIndSkin.MODE));
}
requestRepaint();
} else if (soft2.length == 1) {
// command action
processCommand(soft2[0]);
}
} else {
setInteractive(false);
}
|
protected void | softPress(int buttonID)Switch based on soft button pressed.
switch (buttonID) {
case 0:
soft1();
break;
case 1:
soft2();
break;
}
|
protected void | sortCommands(Command[] cmds, int num)Rearranges the commands based on weights and priority.
// The number of commands is small, so we use a simple
// Insertion sort that requires little heap
for (int i = 1; i < num; i++) {
for (int j = i; j > 0; j--) {
if (compare(cmds[j], cmds[j - 1]) < 0) {
swap = cmds[j];
cmds[j] = cmds[j - 1];
cmds[j - 1] = swap;
} else break;
}
}
|
public boolean | systemMenuUp()Returns true if system menu is currently up, false otherwise.
return menuUP;
|
public void | toggleAlert(boolean alertUp)Toggles the alert. Grabs the background and requests a
repaint.
alertUP = alertUp;
setBackground();
requestRepaint();
|
public void | toggleMenu(boolean menuUp)Toggles the current menu selection.
Grabs the background and requests a repaint.
if (owner instanceof MIDPWindow) {
((MIDPWindow) owner).paintWash(menuUp);
}
setBackground();
requestRepaint();
|
public void | update(CLayer[] layers)Update bounds of layer
super.update(layers);
setAnchor();
if (null != menuLayer) {
menuLayer.update(layers);
}
|
public void | updateCommandSet(Command[] itemCmds, int numI, ItemCommandListener itemListener, Command[] screenCmds, int numS, CommandListener scrListener)Called by the system to update the set of commands associated
with this button bar and its subsequent system menu.
// Cache the values for later
this.itmCmds = new Command[numI];
if (numI > 0) {
System.arraycopy(itemCmds, 0, this.itmCmds, 0, numI);
}
this.itemListener = itemListener;
this.scrCmds = new Command[numS];
if (numS > 0) {
System.arraycopy(screenCmds, 0, this.scrCmds, 0, numS);
}
this.scrListener = scrListener;
// reset the commands
soft1 = null;
if (numS > 0) {
int index = -1;
int type = -1;
for (int i = 0; i < numS; i++) {
if (!(this.scrCmds[i] instanceof SubMenuCommand)) {
switch (this.scrCmds[i].getCommandType()) {
case Command.BACK:
index = i;
type = Command.BACK;
break;
case Command.EXIT:
if (type != Command.BACK) {
index = i;
type = Command.EXIT;
}
break;
case Command.CANCEL:
if (type != Command.BACK && type != Command.EXIT) {
index = i;
type = Command.CANCEL;
}
break;
case Command.STOP:
if (type != Command.BACK && type != Command.EXIT &&
type != Command.CANCEL) {
index = i;
type = Command.STOP;
}
break;
default:
break;
}
} // if
// We can short circuit the search if we find
// a BACK command, because that is the highest weighted
// Command for the left soft button
if (type == Command.BACK) {
break;
}
} // for
// If we have a command for the left button, we pop it out
// of the array and decrement the number in the array - because
// we'll sort them all together to form the right button (or menu)
if (type > -1) {
numS--;
soft1 = this.scrCmds[index];
System.arraycopy(screenCmds, index + 1,
scrCmds, index, numS - index);
}
}
// Now fill in the 'right' soft button, possibly with a menu
// of Commands
switch (numI + numS) {
case 0:
soft2 = null;
break;
case 1:
soft2 = new Command[1];
soft2[0] = (numI > 0) ? this.itmCmds[0] : this.scrCmds[0];
break;
default:
soft2 = new Command[numI + numS];
if (setCommands(numI, 0, this.itmCmds)) {
numI--;
}
setCommands(numS, numI, this.scrCmds);
break;
}
setButtonLabels();
|