package minime.ui;
import javax.microedition.lcdui.Graphics;
import minime.Image;
import minime.Logger;
import minime.Portability;
import minime.core.Component;
import minime.core.Event;
import minime.core.EventDispatcher;
import minime.core.ResourceManager;
import minime.font.Font;
import minime.ui.style.StyleManager;
/**
* The SoftBar class is used to hold softkey buttons at the bottom of the
* screen.It mostly has three softkey buttons:left softkey button, right softkey
* button and the middle softkey button,you can use one or two or three of them.
* Each button may have images for being pressed down and up.Also, buttons can
* have the same size or have different sizes, if like this, you have to set
* buttons x positions.
*
* @author yishu
*
*/
public class SoftBar extends Component
{
private static Logger LOG=Logger.getLogger("SoftBar");
/** The left softkey button index */
public final static int LEFT = 0;
/** The middle softkey button index */
public final static int MIDDLE = 1;
/** The right softkey button index */
public final static int RIGHT = 2;
/** SoftBar can have 3 soft key maximal */
public final static int NUM_SOFTBUTTON = 3;
private static SoftBar inst ;
private Button[] softKeys;
private Font font;
private boolean hasPointedXPos = false;
private int[] offsetXPos;
private boolean keyEventConsumed = false;
private boolean pointerEventConsumed = false;
private int textColorSelected = Portability.defaultFontTextColor;
private int textColorDefault = Portability.defaultFontTextColor;
public void setTextColorDefault(int textColorDefault) {
this.textColorDefault = textColorDefault;
}
/**
* Sets SoftKey color when selected
* @param softKeyColorSelected
*/
public void setTextColorSelected(int textColorSelected) {
this.textColorSelected = textColorSelected;
}
public static SoftBar getInstance()
{
if (inst==null)
inst = new SoftBar() ;
return inst ;
}
/**
* Creates a new SoftBar object with the default
* font:FontManager.BUTTON_FONT, it doesn't have buttons.
*
*/
protected SoftBar()
{
this(StyleManager.getStyleFont(StyleManager.SOFTBAR_FONT));
}
/**
* Creates a new SoftBar object with the given font, but doesn't have
* buttons.
*
* @param font
* the preferred font to use to render the button's label
*/
private SoftBar(Font font)
{
this.font = font;
softKeys = new Button[NUM_SOFTBUTTON];
setNeedLayout() ;
}
/**
* Calculates the buttons size the sets their positions.
*/
public void layoutImp()
{
// set position of each key. Will be relative to Softbar position
if (!hasPointedXPos)
{
// standard key width if 1/3 of the view width
int keyWidth = getWidth() / NUM_SOFTBUTTON ;
// cal. buttons positions and sizes if not pointed position,set
// button 0 as high because high will be re-calculated button layout
for (int i = LEFT; i <= RIGHT; i++)
{
if (softKeys[i] == null)
continue;
softKeys[i].setWidth(keyWidth);
softKeys[i].setFont(font);
softKeys[i].layout();
softKeys[i].setPosition(keyWidth * i, 0);
}
}
else
{
for (int i = LEFT; i <= RIGHT; i++)
{
if (softKeys[i] == null)
continue;
softKeys[i].setFont(font);
softKeys[i].layout();
softKeys[i].setPosition(offsetXPos[i], 0);
}
}
// if soktkeys exit, set softkey high as softbar high, or set softbar
// hight as font high plus 2
int maxH = 0 ;
if (softKeys[LEFT] != null)
maxH = Math.max(maxH, softKeys[LEFT].getHeight());
if (softKeys[MIDDLE] != null)
maxH = Math.max(maxH, softKeys[MIDDLE].getHeight());
if (softKeys[RIGHT] != null)
maxH = Math.max(maxH, softKeys[RIGHT].getHeight());
maxH = Math.max(maxH, font.getHeight() + 2);
setHeight(maxH) ;
}
/**
* set softkey text
*
* @param pos
* the position of soktkey
* @param label
* the label for soktkey
*/
public void setSoftkeyLabel(int pos, String label)
{
setSoftKey(pos, label, 0, 0);
}
/**
* set softkey text, If want to set text to null, set txRscId to
* ResourceManager.NONE_RESOURCE.
*
* @param pos
* the position of soktkey
* @param txRscId
* the text index id for text for soktkey,If want to set text to
* null, set txRscId to ResourceManager.NONE_RESOURCE.
*/
public void setSoftkeyLabel(int pos, int txRscId)
{
setSoftkeyLabel(pos, ResourceManager.getString(txRscId));
softKeys[pos].setRscId(txRscId) ;
}
/**
* set soft key with given position, label and frame thickness and frame
* color
*
* @param pos
* the button position, just LEFT, MIDDLE, or RIGHT
* @param label
* the label for button
* @param framethickness
* the thickness for button frame
* @param frameColor
* the color for button frame
*/
public void setSoftKey(int pos, String label, int framethickness, int frameColor)
{
setSoftKey(pos, label, null, null, framethickness, frameColor);
}
/**
* @param pos
* @param label
* @param bgBitmapUp
* @param bgBitmapDown
* @param framethickness
* @param frameColor
*/
public void setSoftKey(int pos, String label, Image bgBitmapUp, Image bgBitmapDown, int framethickness,
int frameColor)
{
if (softKeys[pos] == null)
softKeys[pos] = new Button(label, Portability.defaultFontTextColor, bgBitmapUp, bgBitmapDown);
else
softKeys[pos].setString(label);
// softKeys[pos].setVisible((null != label));
// set the frame
softKeys[pos].setFrameThicknessAndColor(framethickness, frameColor);
if (framethickness>0)
softKeys[pos].setFramed(true);
else
softKeys[pos].setFramed(false);
//when set a softKey, we should set it as unpressed.
softKeys[pos].setKeyPressed(false);
softKeys[pos].setTextColor(Portability.defaultFontTextColor);
setNeedLayout() ;
}
/**
* set sofkt key with given position, button text , button background image
* for up and down, and frame thickness and frame color.Button text is
* drawed from resource file based on txRscId by ResourceManager.If want to
* set button text to null, set txRscId to ResourceManager.NONE_RESOURCE.
*
* @param pos
* the button position, just LEFT, MIDDLE, or RIGHT
* @param txRscId
* the button text index id,If want to set text to null, set
* txRscId to ResourceManager.NONE_RESOURCE.
* @param bgBitmapUp
* background bitmap index id for button up
* @param bgBitmapDown
* background bitmap index id for button down
* @param framethickness
* the thickness for button frame
* @param frameColor
* the color for button frame
*/
public void setSoftKey(int pos, int txRscId, int bgBitmapUp, int bgBitmapDown, int framethickness, int frameColor)
{
setSoftKey(pos, ResourceManager.getString(txRscId), new Image(ResourceManager.getImage(bgBitmapUp)), new Image(ResourceManager.getImage(bgBitmapDown)), framethickness, frameColor);
}
/**
* @param pos
* @return
*/
public int getSoftkey(int pos)
{
if (softKeys[pos] != null)
return softKeys[pos].getRscId() ;
return ResourceManager.NONE_RESOURCE ;
}
/**
* set softkeys x coordinates
*
* @param offsetX
* x coordinates for softkeys
*/
private void setSoftKeysXPos(int[] offsetX)
{
hasPointedXPos = true;
this.offsetXPos = offsetX;
setNeedLayout() ;
}
/**
* Utility method to get portable soft key value
* @param keyIndex LEFT, MIDDLE or RIGHT
* @return corresponding key value in Portability
*/
private int translateKey (int keyIndex) {
switch (keyIndex) {
case LEFT:
return Portability.KEY_SOFT_LEFT;
case MIDDLE:
return Portability.KEY_FIRE;
case RIGHT:
return Portability.KEY_SOFT_RIGHT;
default:
// we got an unknown key
return -1;
}
}
public boolean onPointerPressed(int x, int y) {
boolean eventConsumed = false;
int vx = x;
int vy = y;
// check if pointer event lies within SoftBar
if (containsPoint(vx, vy)) {
int keyIndex = -1; // index of soft key pressed or released
// translate the coordinates to this SoftBar
vx -= getLeft();
vy -= getTop();
// decides which soft button is pressed or released
for (int i = 0; i < NUM_SOFTBUTTON; i++) {
if (softKeys[i] != null && softKeys[i].containsPoint(vx, vy)) {
keyIndex = i;
break;
}
}
if (keyIndex != -1) { // found the key
eventConsumed = onKeyPressed(Event.createEvent(Event.KEY_DOWN_EVENT, translateKey(keyIndex), 0));
} else {
// pressed on a softkey that are not set
}
}
return eventConsumed;
}
public boolean onKeyPressed(Event evt) {
if (evt.paramA == Portability.KEY_SOFT_LEFT && softKeys[LEFT] != null && softKeys[LEFT].isVisible())
{
EventDispatcher.getInstance().fire(
Event.createEvent(Event.SB_EVENT, Portability.KEY_SOFT_LEFT, softKeys[LEFT].getRscId()));
softKeys[LEFT].setKeyPressed(true);
softKeys[LEFT].setTextColor(this.textColorSelected);
minime.core.Runtime.getInstance().repaint();
keyEventConsumed = true;
}
else if (evt.paramA == Portability.KEY_FIRE && softKeys[MIDDLE] != null && softKeys[MIDDLE].isVisible())
{
EventDispatcher.getInstance().fire(
Event.createEvent(Event.SB_EVENT, Portability.KEY_FIRE, softKeys[MIDDLE].getRscId()));
softKeys[MIDDLE].setKeyPressed(true);
softKeys[MIDDLE].setTextColor(this.textColorSelected);
minime.core.Runtime.getInstance().repaint();
keyEventConsumed = true;
}
else if (evt.paramA == Portability.KEY_SOFT_RIGHT && softKeys[RIGHT] != null && softKeys[RIGHT].isVisible())
{
EventDispatcher.getInstance().fire(
Event.createEvent(Event.SB_EVENT, Portability.KEY_SOFT_RIGHT, softKeys[RIGHT].getRscId()));
softKeys[RIGHT].setKeyPressed(true);
softKeys[RIGHT].setTextColor(this.textColorSelected);
minime.core.Runtime.getInstance().repaint();
keyEventConsumed = true;
} else {
keyEventConsumed = false;
}
return keyEventConsumed;
}
public boolean onPointerReleased(int x, int y) {
boolean handled = pointerEventConsumed;
// reset consumed flag
pointerEventConsumed = false;
softKeys[LEFT].setTextColor(this.textColorDefault);
softKeys[MIDDLE].setTextColor(this.textColorDefault);
softKeys[RIGHT].setTextColor(this.textColorDefault);
minime.core.Runtime.getInstance().repaint();
return handled;
}
public boolean onKeyReleased(Event evt) {
boolean handled = keyEventConsumed;
// reset consumed flag
keyEventConsumed = false;
softKeys[LEFT].setTextColor(this.textColorDefault);
softKeys[MIDDLE].setTextColor(this.textColorDefault);
softKeys[RIGHT].setTextColor(this.textColorDefault);
minime.core.Runtime.getInstance().repaint();
return handled;
}
public int getPriority()
{
return SOFTBAR_PRIORITY;
}
public void renderImpl(Graphics gc)
{
synchronized (this) {
// Display soft key
for (int i = 0; i < NUM_SOFTBUTTON; i++)
{
if (softKeys[i] != null)
{
// coordinates translate already been done by view.composite
softKeys[i].render(gc);
}
}
}
}
public void setPosition(int left, int top) {
super.setPosition(left, top);
}
/**
* Set the bgImage and selected images of a softbar, the bgImages and selectImages
* should be length of 3, and we set the bgImages[0] as the leftKey bgImage, selectImages[0]
* as the bgImage when leftKey selected. and bgImages[1] and selectImages[1] is for the middle
* Key, the bgImages[2] and selectImages[2] is for the right key
*
* @param sbBgImgs
* @param sbSelectedImgs
*/
public void setEffectImages(Image[] sbBgImgs,Image[] sbSelectedImgs)
{
int[] softkeysXPos = new int[sbBgImgs.length];
// init softkeys coordinates
for (int i = 0; i < softkeysXPos.length; i++) {
if (i > 0)
softkeysXPos[i] = softkeysXPos[i - 1]
+ sbBgImgs[i - 1].getWidth();
else
softkeysXPos[0] = 0;
}
// set the coordinates
setSoftKeysXPos(softkeysXPos);
// removeAllSoftKey();
setSoftKeyEffect(SoftBar.LEFT, sbBgImgs[0], sbSelectedImgs[0]);
setSoftKeyEffect(SoftBar.MIDDLE, sbBgImgs[1], sbSelectedImgs[1]);
setSoftKeyEffect(SoftBar.RIGHT, sbBgImgs[2], sbSelectedImgs[2]);
setNeedLayout();
}
/**
* Set the
*
* @param softIndex
* @param bgImg
* @param sbSelectImg
*/
private void setSoftKeyEffect(int softIndex,Image bgImg,Image sbSelectImg)
{
if(softKeys[softIndex]==null)
{
throw new IllegalStateException("You should call SetSoftKey first");
}
if(softKeys[softIndex]!=null)
{
softKeys[softIndex].setKeyPressedBg(sbSelectImg);
softKeys[softIndex].setKeyUpBg(bgImg);
}
}
/**
* Clear the effect (bgImage and selectedImage)
*/
public void clearAllButtonEffect()
{
hasPointedXPos=false;
removeAllButtonEffect();
}
/**
* remove the button effect of each key
*/
private void removeAllButtonEffect()
{
synchronized (this) {
for (int i = 0; i < NUM_SOFTBUTTON; i++)
{
if(softKeys[i]==null)
continue;
//set the Height as zero to let the button to let the button
//to compute the height it self
softKeys[i].setHeight(0);
softKeys[i].clearButtonEffect();
}
}
}
/**
* @param lrpressed
* @param lrunpressed
* @param midpressed
* @param midunpressed
*/
public void setSoftBarImage(int lrpressed, int lrunpressed, int midpressed, int midunpressed)
{
LOG.debug("enter setSoftBarImage");
//set soft bar background image
Image[] sbKeyUpImg =
{
new Image(lrunpressed),
new Image(midunpressed),
new Image(lrunpressed)
};
Image[] sbKeyPressedImg =
{
new Image(lrpressed),
new Image(midpressed),
new Image(lrpressed)
};
setEffectImages(sbKeyUpImg, sbKeyPressedImg);
}
// huggly hack to let jaspme assign widget rsc to the softbar
public void setRscId(int pos, int txRscId)
{
softKeys[pos].setRscId(txRscId) ;
}
}
|