CCMenuItem Positioning with alignItemsInColumns:

Forums Programming cocos2d support (graphics engine) CCMenuItem Positioning with alignItemsInColumns:

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

Viewing 9 posts - 1 through 9 (of 9 total)
Author Posts
Author Posts
July 29, 2010 at 7:47 pm #223600

codeman9
Participant
@codeman9

I’m not getting the desired effect of what I thought this method was supposed to do. Right now I have 4 menu items (2 images and 2 labels). I would like 2 rows with 2 columns each where cell 1,1 holds the image, cell 1,2 holds the label, cell 2,1 holds the image, and cell 2,2 holds the label. I create my image and label menuItems and then add them to the menu like so:

CCMenu *mainMenu = [CCMenu menuWithItems:startGameLeafItemImage, startGameLabel,
settingsItemImage, settingsLabel, nil];

and then I call:

[mainMenu alignItemsInColumns:[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2], nil];

but the items are nowhere near centered on the screen correctly. I believe this has to do with the fact that I am scaling my images down and it looks like CCMenu alignItemsInColumns: is using the contentSize of the node rather than the boundingBox of the node. So, I changed item.contentSize to [item boundingBox].size, but the items are still not centered correctly (though much closer to the desired effect). It looks to me like each item needs to be moved to the left by half the width of the image and the labels need to be moved down by half the height of the label.

Any advice?

August 26, 2010 at 12:55 pm #292474

Mechatronix
@mechatronix

It needs padding somehow. Does anyone know how to add padding?

August 26, 2010 at 1:41 pm #292475

Jack Here
@jack-here

Dont know if this is what your looking for:

[mainMenu alignItemsVerticallyWithPadding:15.0f];

August 29, 2010 at 8:39 am #292476

Mechatronix
@mechatronix

I need that combined with grids. “alignItemsVerticallyWithPadding” is useful but it only does it on one direction. I want to have a grid of say 4×4 menu options, all spaced evenly both horizontally and vertically. So “alignItemsVerticallyWithPadding” won’t work for me unfortunately. Unless I can somehow combine it?

August 29, 2010 at 9:20 am #292477

abitofcode
Moderator
@abitofcode

Have a look at MenuGrid from steffens source collection;

http://www.learn-cocos2d.com/knowledge-base/free-source-code/

January 21, 2012 at 9:41 am #292478

jeet.mg
@jeetmg

posted 1 year ago!! and still unsolved ?

April 1, 2012 at 10:16 pm #292479

ayt
Participant
@ayt

insert this in line 393 of CCMenu.m:

winSize.width*=1.2;

This will stretch the horizontally menu alignment by 1.2.

It’s just a quick & dirty solution but it’s enough for my purpose.

September 1, 2012 at 7:22 am #292480

travis.jo
@travisjo

Here’s the changes I made to Cocos2d 2.0 to get padding for column based menus.

Replace line 91 of CCMenu.h.

Old Line:

-(void) alignItemsInColumns: (NSNumber *) columns vaList: (va_list) args;

Replacement Lines:

-(void) alignItemsInColumns: (float)padding columns:(NSNumber *) columns, ... NS_REQUIRES_NIL_TERMINATION;
-(void) alignItemsInColumns: (float)padding columns:(NSNumber *) columns vaList: (va_list) args;

Replace function alignItemsInColumns starting at line 378 of CCMenu.m.

Old Function:

-(void) alignItemsInColumns: (NSNumber *) columns, ...
{
va_list args;
va_start(args, columns);

[self alignItemsInColumns:columns vaList:args];

va_end(args);
}

New Function:

-(void) alignItemsInColumns:(NSNumber *) columns, ...
{
[self alignItemsInColumns:0.0f columns:columns];
}

Add new function ‘-(void) alignItemsInColumns:(float)padding columns:(NSNumber *) columns, …’ to CCMenu.m below that function.

New Function Code:

-(void) alignItemsInColumns:(float)padding columns:(NSNumber *) columns, ...
{
va_list args;
va_start(args, columns);

[self alignItemsInColumns:padding columns:columns vaList:args];

va_end(args);
}

Replace function -(void) alignItemsInColumns: (NSNumber *) columns vaList: (va_list) args with new function -(void) alignItemsInColumns: (float)padding columns:(NSNumber *) columns vaList: (va_list) args at line 388

Old Function:

-(void) alignItemsInColumns: (NSNumber *) columns vaList: (va_list) args
{
NSMutableArray *rows = [[NSMutableArray alloc] initWithObjects:columns, nil];
columns = va_arg(args, NSNumber*);
while(columns) {
[rows addObject:columns];
columns = va_arg(args, NSNumber*);
}

int height = -5;
NSUInteger row = 0, rowHeight = 0, columnsOccupied = 0, rowColumns;
CCMenuItem *item;
CCARRAY_FOREACH(children_, item){
NSAssert( row < [rows count], @"Too many menu items for the amount of rows/columns.");

rowColumns = [(NSNumber *) [rows objectAtIndex:row] unsignedIntegerValue];
NSAssert( rowColumns, @"Can't have zero columns on a row");

rowHeight = fmaxf(rowHeight, item.contentSize.height);
++columnsOccupied;

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

columnsOccupied = 0;
rowHeight = 0;
++row;
}
}
NSAssert( !columnsOccupied, @"Too many rows/columns for available menu items." );

CGSize winSize = [[CCDirector sharedDirector] winSize];

row = 0; rowHeight = 0; rowColumns = 0;
float w, x, y = height / 2;
CCARRAY_FOREACH(children_, item) {
if(rowColumns == 0) {
rowColumns = [(NSNumber *) [rows objectAtIndex:row] unsignedIntegerValue];
w = winSize.width / (1 + rowColumns);
x = w;
}

CGSize itemSize = item.contentSize;
rowHeight = fmaxf(rowHeight, itemSize.height);
[item setPosition:ccp(x - winSize.width / 2,
y - itemSize.height / 2)];

x += w;
++columnsOccupied;

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

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

[rows release];
}

New Function:

-(void) alignItemsInColumns: (float)padding columns:(NSNumber *) columns vaList: (va_list) args
{
NSMutableArray *rows = [[NSMutableArray alloc] initWithObjects:columns, nil];
columns = va_arg(args, NSNumber*);
while(columns) {
[rows addObject:columns];
columns = va_arg(args, NSNumber*);
}

int height = -5;
NSUInteger row = 0, rowHeight = 0, columnsOccupied = 0, rowColumns;
CCMenuItem *item;
CCARRAY_FOREACH(children_, item){
NSAssert( row < [rows count], @"Too many menu items for the amount of rows/columns.");

rowColumns = [(NSNumber *) [rows objectAtIndex:row] unsignedIntegerValue];
NSAssert( rowColumns, @"Can't have zero columns on a row");

rowHeight = fmaxf(rowHeight, item.contentSize.height);
++columnsOccupied;

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

columnsOccupied = 0;
rowHeight = 0;
++row;
}
}
NSAssert( !columnsOccupied, @"Too many rows/columns for available menu items." );

CGSize winSize = [[CCDirector sharedDirector] winSize];

row = 0; rowHeight = 0; rowColumns = 0;
float w, x, y = height / 2;
int itemNumber = 0;
CCARRAY_FOREACH(children_, item) {
if(rowColumns == 0) {
rowColumns = [(NSNumber *) [rows objectAtIndex:row] unsignedIntegerValue];
w = winSize.width / (1 + rowColumns);
x = w;
}

CGSize itemSize = item.contentSize;
rowHeight = fmaxf(rowHeight, itemSize.height);
if(itemNumber%2) {
[item setPosition:ccp((x - winSize.width / 2)+padding,
y - itemSize.height / 2)];
} else {
[item setPosition:ccp((x - winSize.width / 2)-padding,
y - itemSize.height / 2)];
}

x += w;
++columnsOccupied;

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

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

[rows release];
}

October 19, 2012 at 6:42 pm #292481

simonthumper
@simonthumper

travis.jo your method is good, however only works with menu’s with 2 columns… I’m currently trying to make it work with 4 columns, and then I will have a think about how to make it work with n columns… :) If you have any ideas please let me know!

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

You must be logged in to reply to this topic.