views:

881

answers:

1

Scenario
In a screen I have 2 managers: 1) menu manager at the top and 2) body manager that has info/button elements. The menu manager does custom drawing so that its menu elements (LabelFields) are properly spaced.

Core Issue - Manager and subfield drawing order
The screen draws fine except when the user preforms an action (clicks a button) that results in an element withing the body manager being added/removed. Once field elements are added/removed from the body, the order in which the menu is drawn gets mixed up.

When the body manager adds or removes a field, instead of the menu manager drawing itself and then its sub elements (label fields), the menu manager begins to draw its sub elements and then itself; thus painting on top of the label fields and making them look like they've disappeared.

Comments
Already tried invalidate and other options -- I've tried to call invalidate, invalidateall, updateDisplay... after adding/removing field elements from body. All without success.

Removing custom sublayout works -- The only way that I can resolve this issue is to remove the menu managers custom sublayout logic. Unfortunately the menu system then draws in a traditional manner and does not provide enough spacing.

Below is the sublayout code for the menu manager, am I missing something here?

public void sublayout(int iWidth, int iHeight)
{
    final int iNumFields = getFieldCount();
    int maxHeight = 0;


    final int segmentWidth = iWidth / iNumFields;
    final int segmentWidthHalf = segmentWidth / 2;

    for (int i = 0; i < iNumFields; i++)
    {
        final Item currentField = (Item)this.getField(i);

        // 1. Use index to compute bounds of the field
        final int xSegmentTrueCenter = segmentWidth * i + segmentWidthHalf;

        // 2. center field inbetween bounds using field width (find fill width of text)
        final int xFieldStart = xSegmentTrueCenter - currentField.getFont().getAdvance(currentField.getText())/2;

        // set up position
        setPositionChild(currentField, xFieldStart, getContentTop() + MenuAbstract.PADDING_VERTICAL);

        // allow child to draw itself
        layoutChild(currentField, iWidth, currentField.getHeight());


        // compute max height of the field
        //int fieldheight = currentField.getHeight();
        maxHeight = currentField.getHeight() > maxHeight
            ? currentField.getHeight() + 2 * MenuAbstract.PADDING_VERTICAL
      : maxHeight;
    }
    this.setExtent(iWidth, maxHeight);
}

Final Questions
Ultimately I want to keep the custom layout of the menu manager while being allowed to redraw field elements. Here are my final questions:

  1. Have you experienced this before?

  2. Why would the menu manager begin drawing in the wrong order when a field element is added/remove to the screen?

  3. Does the native Manager.sublayout() do something that I'm not to maintain drawing order?

+1  A: 

I haven't seen the behavior you describe, but the following line is a little troubling:

// allow child to draw itself
layoutChild(currentField, iWidth, currentField.getHeight());

getHeight() shouldn't return a sensible value until the field has had setExtent called through the layoutChild method. Though I'd expect that it would cause problems in all cases - not sure why this would work the first time around. In your logic I think you can safely just use iHeight instead of currentField.getHeight() in that line. The field will only make itself as big as it needs to be - it won't use all of iHeight unless it's something like a VerticalFieldManager

Anthony Rizk
thanks for the comment, I'll try that out!
AtariPete