cocos2d / cocos2d-x-for-xna

port cocos2d-x into c# based on XNA
124 stars 49 forks source link

CCMenu.alignItemsInColumns does not compute correctly #20

Closed totallyevil closed 12 years ago

totallyevil commented 12 years ago

CCMenu.alignItemsInColumns

  1. Does not use the content size "scale" when doing its column layout calculations (a more systemic problem in CCMenu)
  2. Incorrectly creates third-size columns when 2 columns are designed on the window.
  3. Has a hard coded padding of '5' instead of using the kDefaultPadding value (which defaults to 5).

My suggested code change:

    /** align items in rows of columns */
    public void alignItemsInColumns(params int[] columns)
    {
        int[] rows = columns;

        int height = -5;
        int row = 0;
        int rowHeight = 0;
        int columnsOccupied = 0;
        int rowColumns;

        if (m_pChildren != null  && m_pChildren.Count > 0)
        {
            foreach (CCNode pChild in m_pChildren)
            {
                if (null != pChild)
                {
                    Debug.Assert(row < rows.Length);

                    rowColumns = rows[row];
                    // can not have zero columns on a row
                    Debug.Assert(rowColumns > 0);

                    float tmp = pChild.contentSize.height;
                    rowHeight = (int)((rowHeight >= tmp) ? rowHeight : tmp);

                    ++columnsOccupied;
                    if (columnsOccupied >= rowColumns)
                    {
                        height += rowHeight + (int)kDefaultPadding;

                        columnsOccupied = 0;
                        rowHeight = 0;
                        ++row;
                    }
                }
            }
        }   

        // check if too many rows/columns for available menu items
        //assert(! columnsOccupied);

        CCSize winSize = CCDirector.sharedDirector().getWinSize();

        row = 0;
        rowHeight = 0;
        rowColumns = 0;
        float w = 0.0f;
        float x = 0.0f;
        float y = (float)(height / 2);

        if (m_pChildren != null && m_pChildren.Count > 0)
        {
            foreach (CCNode pChild in m_pChildren)
            {
                if (pChild != null)
                {
                    if (rowColumns == 0)
                    {
                        rowColumns = rows[row];
                        if (rowColumns == 0)
                        {
                            throw (new ArgumentException("Can not have a zero column size for a row."));
                        }
                        w = (winSize.width - 2 * kDefaultPadding) / rowColumns; // 1 + rowColumns
                        x = w/2f; // center of column
                    }

                    float tmp = pChild.contentSize.height*pChild.scaleY;
                    rowHeight = (int)((rowHeight >= tmp) ? rowHeight : tmp);

                    pChild.position = new CCPoint(kDefaultPadding + x - (winSize.width - 2*kDefaultPadding) / 2,
                                           y - pChild.contentSize.height*pChild.scaleY / 2);

                    x += w;
                    ++columnsOccupied;

                    if (columnsOccupied >= rowColumns)
                    {
                        y -= rowHeight + 5;

                        columnsOccupied = 0;
                        rowColumns = 0;
                        rowHeight = 0;
                        ++row;
                    }
                }
            }
        }   
    }