FileDocCategorySizeDatePackage
ChoiceGroupPopupLFImpl.javaAPI DocphoneME MR2 API (J2ME)36606Wed May 02 18:00:20 BST 2007javax.microedition.lcdui

ChoiceGroupPopupLFImpl

public class ChoiceGroupPopupLFImpl extends ChoiceGroupLFImpl
This is the Look &s; Feel implementation for ChoiceGroupPopup.

Fields Summary
private boolean
itemSelectedWhenPressed
pressed on a valid item in popup layer
CGPopupLayer
popupLayer
The PopupLayer that represents open state of this ChoiceGroup POPUP.
int[]
viewable
Content of the popupLayer is drawn in ChoiceGroupPopupLFImpl. That content can be taller then the layer itself. viewable holds information of the current scroll position and the size of the content (X, Y, WIDTH, HEIGHT)
Constructors Summary
ChoiceGroupPopupLFImpl(ChoiceGroup choiceGroup)
Creates ChoiceGroupPopupLF for the passed in choiceGroup of Choice.POPUP type.

param
choiceGroup the ChoiceGroup object associated with this view

        super(choiceGroup);
        
        ChoiceGroupResources.load();
        
        viewable = new int[4];
        popupLayer = new CGPopupLayer(this);
    
Methods Summary
intgetIndexByPointer(int x, int y)
Find the choice index inside of the list containing the pointer

param
x x coordinate of pointer
param
y y coordinate of pointer
return
choice index, -1 - if index is not found

        int popupLayer_bounds[]= popupLayer.getBounds();
        int id = -1;
        if (cg.numOfEls > 0) {
            ScreenLFImpl sLF = (ScreenLFImpl)cg.owner.getLF();
            x = x +(bounds[X] - sLF.viewable[X]) - popupLayer_bounds[X];
            y = y +(bounds[Y] - sLF.viewable[Y]) - popupLayer_bounds[Y];
            
            if (x >= 0 && x <= popupLayer_bounds[WIDTH] &&
                y >= 0 && y <= popupLayer_bounds[HEIGHT]) {
                int visY =  0;
                int i = 0;
                
                // calculate the scroll position and update the y coordinate accordingly.
                y += viewable[Y];
                
                for (i = 0; i < cg.numOfEls; i++) {
                    int h = elHeights[i];
                    if (y > visY && y < visY + h) {
                        break;
                    }
                    visY += h;
                }
                if (i < cg.numOfEls) {
                    id = i;
                }
            }
        }
        return id;
    
booleanitemContainsPointer(int x, int y)
Check if the pointer is clicked to the item

param
x x coordinate of pointer
param
y y coordinate of pointer
return
true if the item contains the pointer, otherwise - false

        if (!popupLayer.isPopupOpen()) {
            return super.itemContainsPointer(x, y);
        } else {
            // We grab the whole screen, so consider all clicks contained
            // by this item.
            return true;
        }
    
booleanlCallTraverse(int dir, int viewportWidth, int viewportHeight, int[] visRect)
Handle traversal within this ChoiceGroup

param
dir the direction of traversal
param
viewportWidth the width of the viewport
param
viewportHeight the height of the viewport
param
visRect the in/out rectangle for the internal traversal location
return
true if traversal occurred within this ChoiceGroup


        boolean ret = false;
        // If we have no elements, or if the user pressed left/right,
        // don't bother with the visRect and just return false
        if (cg.numOfEls > 0) {

            // If we are a closed popup, don't bother with the visRect
            // and return true on the initial traverse, false on subsequent
            // traverses
            if (popupLayer.isPopupOpen()) {
                ret = super.lCallTraverse(dir, viewportWidth, viewportHeight, visRect);
            } else {
                 visRect[X] = 0;
                 visRect[Y] = 0;
                 visRect[HEIGHT] = bounds[HEIGHT];
                 visRect[WIDTH] = bounds[WIDTH];
            }
        }
        
        return ret;
    
public voidlGetContentSize(int[] size, int width)
Sets the content size in the passed in array. Content is calculated based on the availableWidth. size[WIDTH] and size[HEIGHT] should be set by this method.

param
size The array that holds Item content size and location in Item internal bounds coordinate system.
param
width The width available for this Item


        // no label and empty popup => nothing is drawn
        // no elements => only label is drawn
        if (cg.numOfEls == 0) {
            size[WIDTH] = size[HEIGHT] = 0;
            return;
        }

        int w = getAvailableContentWidth(Choice.POPUP, width);
        int maxContentWidth = getMaxElementWidth(w);

        viewable[HEIGHT] = calculateHeight(w);

        int s = (selectedIndex < 0) ? 0 : selectedIndex;
        size[HEIGHT] = cg.cgElements[s].getFont().getHeight() + 
            (2 * ChoiceGroupSkin.PAD_V);

        if (maxContentWidth < w) {
            size[WIDTH] = width - w + maxContentWidth;
        } else {
            size[WIDTH] = width;
        }
        viewable[WIDTH] = size[WIDTH];
    
voidlPaintContent(Graphics g, int width, int height)
Paints the content area of the ChoiceGroup POPUP. Graphics is translated to contents origin.

param
g The graphics where Item content should be painted
param
width The width available for the Item's content
param
height The height available for the Item's content

        // paint closed state of the popup

        // if there are no elements, we are done
        if (cg.numOfEls == 0) {
            return;
        }

        // draw background
        if (ChoiceGroupSkin.IMAGE_BG != null) {
            CGraphicsUtil.draw9pcsBackground(g, 0, 0, width, height,
                ChoiceGroupSkin.IMAGE_BG);
        } else {
            // draw widget instead of using images
            CGraphicsUtil.drawDropShadowBox(g, 0, 0, width, height,
                ChoiceGroupSkin.COLOR_BORDER,
                ChoiceGroupSkin.COLOR_BORDER_SHD,
                ChoiceGroupSkin.COLOR_BG);
        }

        // draw icon
        if (ChoiceGroupSkin.IMAGE_BUTTON_ICON != null) {
            int w = ChoiceGroupSkin.IMAGE_BUTTON_ICON.getWidth();
            int yOffset = height -
                ChoiceGroupSkin.IMAGE_BUTTON_ICON.getHeight();
            if (yOffset > 0) {
                yOffset = yOffset / 2;
            } else {
                yOffset = 0;
            }
            width -= (w + 1);
            if (ChoiceGroupSkin.IMAGE_BUTTON_BG != null) {
                CGraphicsUtil.draw9pcsBackground(
                    g, width, 1, w, height - 2,
                    ChoiceGroupSkin.IMAGE_BUTTON_BG);
            }
            g.drawImage(ChoiceGroupSkin.IMAGE_BUTTON_ICON,
                        width, yOffset + 1,
                        Graphics.LEFT | Graphics.TOP);
            width -= ChoiceGroupSkin.PAD_H;
        }

        g.translate(ChoiceGroupSkin.PAD_H, ChoiceGroupSkin.PAD_V);

        int s = selectedIndex < 0 ? 0 : selectedIndex;

        // paint value

        int textOffset = 0;

        if (cg.cgElements[s].imageEl != null) {
            int iX = g.getClipX();
            int iY = g.getClipY();
            int iW = g.getClipWidth();
            int iH = g.getClipHeight();

            g.clipRect(0, 0,
                       ChoiceGroupSkin.WIDTH_IMAGE,
                       ChoiceGroupSkin.HEIGHT_IMAGE);
            g.drawImage(cg.cgElements[s].imageEl,
                        0, 0,
                        Graphics.LEFT | Graphics.TOP);
            g.setClip(iX, iY, iW, iH);
            textOffset = ChoiceGroupSkin.WIDTH_IMAGE +
                ChoiceGroupSkin.PAD_H;
        }

        g.translate(textOffset, 0);
        Text.drawTruncString(g,
                        cg.cgElements[s].stringEl,
                        cg.cgElements[s].getFont(),
                        (hasFocus) ? ScreenSkin.COLOR_FG_HL :
                            ChoiceGroupSkin.COLOR_FG,
                        width);
        g.translate(-textOffset, 0);
        
        g.translate(-ChoiceGroupSkin.PAD_H, -ChoiceGroupSkin.PAD_V);

        if (popupLayer.isSizeChanged() && cachedWidth != INVALID_SIZE) {
            popupLayer.refresh();
            popupLayer.setSizeChanged(false);
        }
    
booleantraverseInPopup(int dir, int viewportWidth, int viewportHeight)
Handle traversal in the open popup

param
dir - the direction of traversal (Canvas.UP, Canvas.DOWN)
param
viewportWidth - the width of the viewport
param
viewportHeight - the height of the viewport
return
true if traverse event was handled, false - otherwise

        boolean ret = false;
        if (popupLayer.isPopupOpen()) {
            if (cg.numOfEls > 1) {
                int prevIndex = hilightedIndex;
                int hilightY = 0;
                switch (dir) {
                case Canvas.UP:
                    if (hilightedIndex > 0) {
                        hilightedIndex--;
                    } else {
                        hilightedIndex = cg.numOfEls - 1;
                    }
                    break;
                case Canvas.DOWN:
                    if (hilightedIndex < (cg.numOfEls - 1)) {
                        hilightedIndex++;
                    } else {
                        hilightedIndex = 0;
                    }
                    break;
                default:
                    break;
                }
                
                if (ret = prevIndex != hilightedIndex) {
                    for (int i = 0; i < hilightedIndex; i++) {
                        hilightY += elHeights[i];
                    }
                    int y2= hilightY + elHeights[hilightedIndex];
                    
                    if (hilightY < viewable[Y]) {
                        viewable[Y] = hilightY;
                    } else if (y2 > viewable[Y] + viewportHeight) {
                        viewable[Y] = y2 - viewportHeight;
                    }
                    lRequestPaint();
                }
            } 
        } // popus is opened
        return ret;
    
voiduCallKeyPressed(int keyCode)
Handle a key press event

param
keyCode the key which was pressed


        Form form = null;

        synchronized (Display.LCDUILock) {

            if (cg.numOfEls == 0) {
                return;
            }
            
            if (!popupLayer.isPopupOpen()) {
                if (keyCode != Constants.KEYCODE_SELECT) {
                    return;
                }
                // show popup

                ScreenLFImpl sLF = (ScreenLFImpl)cg.owner.getLF();
                int x = getInnerBounds(X) - sLF.viewable[X] + contentBounds[X];
                int y = getInnerBounds(Y) - sLF.viewable[Y] + contentBounds[Y];
                hilightedIndex = selectedIndex > 0 ? selectedIndex : 0;

                popupLayer.show(x, y,
                                contentBounds[WIDTH], contentBounds[HEIGHT],
                                viewable[WIDTH], viewable[HEIGHT],
                                y, 
                                sLF.viewport[HEIGHT] - 
                                y - contentBounds[HEIGHT]);
            } else {

                // popup is closed when SELECT, LEFT or RIGHT is pressed;
                // popup selection is changed only when SELECT is pressed
                if (keyCode != Constants.KEYCODE_SELECT &&
                    keyCode != Constants.KEYCODE_LEFT && 
                    keyCode != Constants.KEYCODE_RIGHT) {
                    return;
                }

                // IMPL_NOTE Check if we need notification if selected element 
                // did not change
                if (keyCode == Constants.KEYCODE_SELECT) {
                    if (selectedIndex >= 0) {
                        lSetSelectedIndex(hilightedIndex, true);
                        form = (Form)cg.owner; // To be called outside the lock
                    }
                }
                hilightedIndex = 0;
                popupLayer.hide();
            }
            lRequestPaint();
        } // synchronized
        
        // Notify itemStateListener if necessary
        if (form != null) {
            form.uCallItemStateChanged(cg);
        }
    
voiduCallPointerPressed(int x, int y)
Called by the system to signal a pointer press

param
x the x coordinate of the pointer down
param
y the y coordinate of the pointer down

        itemWasPressed = true;
        itemSelectedWhenPressed = false;
        if (popupLayer.isPopupOpen()) {
            // popupLayer.
            int i = getIndexByPointer(x, y);
            if (i >= 0) {
                itemSelectedWhenPressed = true;
                if (hilightedIndex != i) {
                    hilightedIndex = i;
                    uRequestPaint();//request paint as the highlighted changed
                    popupLayer.requestRepaint();//of course, we should repaint the popupLayer
                    getCurrentDisplay().serviceRepaints(cg.owner.getLF());
                }
            } else {
                hilightedIndex = 0;
                popupLayer.hide();
                uRequestPaint();
            }
        }
    
voiduCallPointerReleased(int x, int y)
Called by the system to signal a pointer release

param
x the x coordinate of the pointer up
param
y the x coordinate of the pointer up

        if (!itemWasPressed)
            return;
        
        if (popupLayer.isPopupOpen()) {
            // do not dismiss the popup until a new selection is made.
            int i = getIndexByPointer(x, y);
            if ( (i >= 0 && hilightedIndex == i && itemSelectedWhenPressed) ||
                 (!itemSelectedWhenPressed)) {
                uCallKeyPressed(itemSelectedWhenPressed ?
                                // close the popup with highlighted item selected
                                Constants.KEYCODE_SELECT :
                                // close the popup as cancel
                                Constants.KEYCODE_RIGHT);
            }
        } else if (super.itemContainsPointer(x + bounds[X], y + bounds[Y])) {
            uCallKeyPressed(Constants.KEYCODE_SELECT);
        }
        itemSelectedWhenPressed = false;
        itemWasPressed = false;

    
voiduCallSizeChanged(int w, int h)
Called by the system to indicate the size available to this Item has changed

param
w the new width of the item's content area
param
h the new height of the item's content area

        super.uCallSizeChanged(w,h);
        synchronized (Display.LCDUILock) {
            popupLayer.setSizeChanged(true);
        }
    
voiduCallTraverseOut()
Called by the system to indicate traversal has left this Item This function simply calls lCallTraverseOut() after obtaining LCDUILock.

        super.uCallTraverseOut();
        
        synchronized (Display.LCDUILock) {
            if (popupLayer.isPopupOpen()) {
                hilightedIndex = 0;
                popupLayer.hide();
            }
        }