Menu with items aligned in a grid (rows & columns), possible?

Forums Programming cocos2d support (graphics engine) Menu with items aligned in a grid (rows & columns), possible?

This topic contains 8 replies, has 4 voices, and was last updated by  chrene 1 year, 6 months ago.

Viewing 9 posts - 1 through 9 (of 9 total)
Author Posts
Author Posts
November 28, 2009 at 10:12 pm #218619

gaminghorror
Participant
@gaminghorror

Before i dig deeper and try to understand the CCMenu class i wanted to ask first if it’s possible with CCMenu to align items BOTH horizontally and vertically, like in a grid or table?

Since you have to initialize alignWithColumns/Rows with items i suppose it means it’s either vertical OR horizontal alignment. So at the moment i’m just using several CCMenu, one for each row. But i was looking to optimize this if possible and use just a single CCMenu.

November 28, 2009 at 10:40 pm #267351

gaminghorror
Participant
@gaminghorror

I just noticed i *have* to put them into the same CCMenu. Otherwise while touching and dragging only the items of one row are highlighted, if i move the finger to another row those items don’t get the touch highlight unless i start the touch in that particular row.

In addition i have one uneven row. All rows are 8 items but the last only has 3 items. The way it is setup by default makes that 3-item row centered instead of starting from the left.

November 28, 2009 at 11:40 pm #267352

gaminghorror
Participant
@gaminghorror

Argh! I give up (for today). I think it really does not support grid layout. I may have to add this myself.

November 28, 2009 at 11:53 pm #267353

gaminghorror
Participant
@gaminghorror

Ok, if someone could do me a favor and show me how i would go about adding MenuItems as va_list that would be nice. At the moment all i know is that if i want to alloc a CCMenu i have to pass some empty list to it just so that it compiles:

int dummyList[2] = {0, 0};
CCMenu* menu = [[CCMenu alloc] initWithItems:(MenuItem*)buttonBackground vaList:(va_list)dummyList];

What if i want to pass menu items instead? I tried and array with MenuItems but i always get “passing argument .. from incompatible pointer type”.

November 29, 2009 at 3:14 pm #267354

Codemattic
Moderator
@codemattic

fyi – after you create a menu – you can still add new items with addChild:

November 29, 2009 at 10:10 pm #267355

gaminghorror
Participant
@gaminghorror

Yes, i know. I think from all the cocos code, CCMenu is the first i would consider refactoring before v1.0.

I wrote my own MenuGrid class which simply aligns MenuItems in columns and rows and fills either columns up to x items before starting a new row and vice versa the same with rows and columns. This is just a few lines of code really.

CCMenu is just too awkward to work with. If i take some time and try to understand why all that extra code that seems so unnecessary is used in its alignment methods i would actually just refactor the whole thing myself. I guess it does so much extra to cope with … what? Different view settings? Camera angles? I don’t know and i really don’t want to know at this point.

November 29, 2009 at 10:12 pm #267356

gaminghorror
Participant
@gaminghorror

Oh sup … i’ll just post this here:

-(void) layoutWithStyle:(EMenuGridFillStyle)fillStyle itemLimit:(int)itemLimit;
{
int col = 0, row = 0, itemCount = 0;
for (CCMenuItem* item in self.children)
{
CGPoint newPosition = CGPointMake(self.position.x + col * padding.x, self.position.y - row * padding.y);
item.position = newPosition;
++itemCount;

if (fillStyle == kMenuGridFillColumnsFirst)
{
++col;
if (itemCount == itemLimit)
{
itemCount = 0;
col = 0;
++row;
}
}
else
{
++row;
if (itemCount == itemLimit)
{
itemCount = 0;
row = 0;
++col;
}
}
}
}

It’s called layoutWithStyle for a reason! ;)

October 1, 2011 at 9:06 pm #267357

pacoloco
@pacoloco

It’s called layoutWithStyle for a reason! ;)

You’re right!! :]]

I get it. Tnx for share!

October 23, 2012 at 12:04 am #267358

chrene
Participant
@chrene

The only problem with your code is that it would make the grid as followed by index

7 8 9

4 5 6

1 2 3

If you don’t write any index number on your levels or whatever you are making the grid for, your code is good enough, but I needed it to be like so:

1 2 3

4 5 6

7 8 9

So I “fix’d” it.

Other than that, I also made an opportunity to center the menugrid, for obvious reasons :)

Your code was fantastic startpoint, and I couldn’t appreciate it more, and without it I wouldn’t even have comed so far. So thx a ton.

Here is my newer version. It’s a mess, because I am a noob with cocos2d, but it should work.

Feel free to rewrite it :)

-(void) layoutWithStyle:(EGridStyle)gridStyle itemLimit:(int)itemLimit padding:(CGPoint)padding centerInParent:(BOOL) center{
int col = 0, row = 0, itemCount = 0;

for (CCMenuItem* item in self.children)
{
item.anchorPoint = ccp(0, 1);
CGPoint newPosition = CGPointMake(col * padding.x, row * padding.y);
newPosition = [[CCDirector sharedDirector] convertToUI:newPosition];
item.position = newPosition;
++itemCount;

if (gridStyle == kCollumsFirst)
{
++col;
if (itemCount == itemLimit)
{
itemCount = 0;
col = 0;
++row;
}
}
else
{
++row;
if (itemCount == itemLimit)
{
itemCount = 0;
row = 0;
++col;
}
}
}
if (center) {
self.position = ccp(0 , 0);
float locationForLowestItem = self.contentSize.height;

for (CCMenuItem* child in self.children) {
[child setAnchorPoint:ccp(0, 0)];
if (child.position.y < locationForLowestItem) {
locationForLowestItem = child.position.y;
}
}

for (CCMenuItem* child in self.children) {
[child setAnchorPoint:ccp(0, 0)];
child.position = ccp(child.position.x, child.position.y - locationForLowestItem);
}

float contentWidth = 0;
float contentHeight = 0;
for (CCNode* child in self.children) {
if (child.position.x + child.boundingBox.size.width > contentWidth) {
contentWidth = child.position.x + child.boundingBox.size.width;
}

if (child.position.y + child.boundingBox.size.height > contentHeight) {
contentHeight = child.position.y + child.boundingBox.size.height;
}

}

self.contentSize = CGSizeMake(contentWidth, contentHeight);
CGSize winSize = [[CCDirector sharedDirector] winSize];

self.position = ccp((winSize.width/2) - (self.contentSize.width/2) , (winSize.height/2)-(self.contentSize.height/2));

}
}

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.