Popup with alpha channel background

2009-02-09 18:42
Submit by WebSeed

Apologies, this is a bit of a hack - I hope this is okay to post. Whilst the new "grayed-color" style property introduced in the 1.0.2 version of Kuix is useful for graying out parts of the background for popups, what I really required was a semi-transparent background (without the dotted/gauze effect). The easiest way to achieve this involved editing the Kuix Desktop.java file (!):

...

// ----------------------
// Transparency variables
// ----------------------
private Image cachedGrayBgImage = null;
private final static int TILE_SIZE = 50; // 50x50x4 = 10 KB memory
private final static int TRANSPARENCY_LEVEL = 128; // 0-255

/* (non-Javadoc)
 * @see org.kalmeo.kuix.widget.Widget#paintImpl(javax.microedition.lcdui.Graphics)
 */
public void paintImpl(Graphics g) {
    if (getBackgroundColor() == null) {
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
    super.paintImpl(g);

    // Grayed layer if defined on the las popup child
    if (popupContainer.getLastChild() != null) {

        // Retrieve the last child gray color
        Color grayedColor = popupContainer.getLastChild().getGrayedColor();
        if (grayedColor != null) {

            // ----------------
            // COMMENT OUT THIS
            // ----------------

            /*
            // Draw the grayed layer
            int maxSize = Math.max(getWidth(), getHeight());
            int minSize = Math.min(getWidth(), getHeight());
            g.setColor(grayedColor.getRGB());
            int i, j;
            for (i = 0; i < maxSize; i = i + 2) {
            g.drawLine(i, 0, 0, i);
            }
            for (j = 0; j < minSize; j = j + 2) {
            g.drawLine(i, j, j, i);
            }
             */

            // --------
            // ADD THIS
            // --------

            // Create semi-transparent tile
            if (cachedGrayBgImage == null) {
                int len = TILE_SIZE * TILE_SIZE;
                int[] rgb = new int[len];
                int c = (TRANSPARENCY_LEVEL << 24) | grayedColor.getRGB();
                for (int i = 0; i < len; i++) {
                    rgb[i] = c;
                }
                cachedGrayBgImage = Image.createRGBImage(rgb, TILE_SIZE, TILE_SIZE, true);
                rgb = null;
            }

            // Paint
            int x = 0;
            int y = 0;
            int numTiles = (getWidth() / TILE_SIZE + 1) * (getHeight() / TILE_SIZE + 1);
            for (int i = 0; i < numTiles; i++) {
                g.drawImage(cachedGrayBgImage, x, y, 0);
                x += TILE_SIZE;
                if (x > getWidth()) {
                    x = 0;
                    y += TILE_SIZE;
                }
            }
        }
    }

    popupContainer.paintImpl(g);
}

...

 

This works by lazily creating a relatively small semi-transparent tile image. Instead of drawing lines to obscure the background, this routine paints these semi-transparent tiles so that they fill the screen (note that it will still use the grayed-color property). A tile is used instead of one large image covering the desktop to ensure we don't consume too much memory (a 50x50 transparent tile will take up 10 KB, whereas a 240x320 image would take up >300KB) and to ensure it will easily adapt to a change in screen orientation. I'm fairly certain there's a better way to do this, but it works for now :) You could obviously create the transparent tile ahead of time to prevent a potential small delay for the first popup.


Tags: popup transparent background hack Popularity: 784

Comments

aeurielesn 2009-02-09 18:42

Thanks, I used it to implement a MenuPopup with alpha channel background, using the bg-color attribute.