DNESS / cocos2d-iphone

Automatically exported from code.google.com/p/cocos2d-iphone
1 stars 0 forks source link

radio button for Menus #381

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Keith Peters wrote:

The other one is an extension of Menu. Basically I needed a menu where you
could choose among the different options and rather than triggering an
action immediately, the chosen item would just stay selected. You could
then query the menu for the selected item. Basically like a set of radio
buttons. Here's what I came up with.

#import <Foundation/Foundation.h>
#import "Menu.h"

@interface RadioMenu : Menu {
}

@property int selectedItem;

-(MenuItem *) itemForTouch: (UITouch *) touch idx: (int*) idx;

@end

#import "RadioMenu.h"
#import "cocos2d.h"

@implementation RadioMenu

@synthesize selectedItem;

- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
       UITouch *touch = [touches anyObject];  
       int idx;
       MenuItem *item = [self itemForTouch:touch idx:&idx];

       if( item ) {
               for(int i = 0; i < [children count]; i++)
               {
                       [[children objectAtIndex:i] unselected];
               }
               [item selected];
               selectedItem = idx;
               return kEventHandled;
       }

       return kEventIgnored;
}

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
       UITouch *touch = [touches anyObject];  
       int idx;
       MenuItem *item = [self itemForTouch:touch idx:&idx];

       if( item ) {
               for(int i = 0; i < [children count]; i++)
               {
                       [[children objectAtIndex:i] unselected];
               }
               [item selected];
               [item activate];
               selectedItem = idx;
               return kEventHandled;
       }
       return kEventIgnored;
}

- (BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
       UITouch *touch = [touches anyObject];  
       int idx;
       MenuItem *item = [self itemForTouch:touch idx:&idx];

       // "mouse" draged inside a button
       if( item ) {
               for(int i = 0; i < [children count]; i++)
               {
                       [[children objectAtIndex:i] unselected];
               }
               [item selected];
               selectedItem = idx;
               return kEventHandled;
               // "mouse" draged outside the selected button
       }
       return kEventIgnored;
}

-(MenuItem *) itemForTouch: (UITouch *) touch idx: (int*) idx;
{
       CGPoint touchLocation = [touch locationInView: [touch view]];
       touchLocation = [[Director sharedDirector] convertCoordinate:
touchLocation];

       int i=0;
       for( MenuItem* item in children ) {
               CGPoint local = [item convertToNodeSpace:touchLocation];

               CGRect r = [item rect];
               r.origin = CGPointZero;

               if( CGRectContainsPoint( r, local ) ) {
                       *idx = i;
                       return item;
               }

               i++;
       }
       return nil;
}

- (void)setSelectedItem:(int)item
{
       selectedItem = item;
       [[children objectAtIndex:selectedItem] selected];      
}

@end

I'm using it for a game where you select one map out of 3 choices and then
a difficulty level, also 3 choices, and then start the game.
This allows each choice to be visible before you start. Then I can query
each menu to see what choices were made. I can also set the selected item
programatically.
Working pretty well. I think others could benefit from it.

Original issue reported on code.google.com by ricardoq...@gmail.com on 28 May 2009 at 9:59

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 13 Jul 2009 at 6:29

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 27 Aug 2009 at 1:15

GoogleCodeExporter commented 9 years ago
rescheduled for v0.9

Original comment by ricardoq...@gmail.com on 31 Oct 2009 at 3:47

GoogleCodeExporter commented 9 years ago
I made also a CCRadioMenu which works with 0.9 alpha :

cheers!

------------------------------
//  CCRadioMenu.h

@interface CCRadioMenu : CCMenu {
    int selectedItemIndex;
    int fallBackItemIndex;
}

@property int selectedItemIndex;

-(CCMenuItem *) itemForTouch: (UITouch *) touch;

@end

------------------------------
//  CCRadioMenu.m

#import "CCRadioMenu.h"

@implementation CCRadioMenu

@synthesize selectedItemIndex;

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    if( state != kMenuStateWaiting ) return NO;

    selectedItem = [self itemForTouch:touch];

    if( selectedItem ) 
    {
        [selectedItem selected];
        state = kMenuStateTrackingTouch;
        return YES;
    }
    return NO;
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    NSAssert(state == kMenuStateTrackingTouch, @"[Menu ccTouchEnded] -- invalid state");

    for( CCMenuItem* item in children ) 
    {
        [item unselected];  
    }

    if (selectedItem)
    {
        [selectedItem selected];
        [selectedItem activate];
        fallBackItemIndex = selectedItemIndex;
    }
    else
    {
        self.selectedItemIndex = fallBackItemIndex;
    }   

    state = kMenuStateWaiting;
}

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
    NSAssert(state == kMenuStateTrackingTouch, @"[Menu ccTouchCancelled] -- invalid state");

    for( CCMenuItem* item in children ) 
    {
        [item unselected];  
    }

    self.selectedItemIndex = fallBackItemIndex;

    state = kMenuStateWaiting;
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    NSAssert(state == kMenuStateTrackingTouch, @"[Menu ccTouchMoved] -- invalid state");

    CCMenuItem *currentItem = [self itemForTouch:touch];

    if (currentItem != selectedItem) 
    {               
        [selectedItem unselected];
        selectedItem = currentItem;

        if (selectedItem)
        {       
            [selectedItem selected];
        }
        else
        {
            [[children objectAtIndex:fallBackItemIndex]selected];
        }

    }
}

-(CCMenuItem *) itemForTouch: (UITouch *) touch
{
    CGPoint touchLocation = [touch locationInView: [touch view]];
    touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
    int idx = -1;

    for( CCMenuItem* item in children ) 
    {
        idx++;
        CGPoint local = [item convertToNodeSpace:touchLocation];

        CGRect r = [item rect];
        r.origin = CGPointZero;

        if( CGRectContainsPoint( r, local ) )
        {
            selectedItemIndex = idx;
            return item;
        }
    }

    return nil;
}

-(int) selectedItemIndex
{
    return selectedItemIndex;
}

- (void)setSelectedItemIndex:(int) value 
{
    for( CCMenuItem* item in children ) 
    {
        [item unselected];  
    }

    selectedItemIndex = value;  
    selectedItem = [children objectAtIndex:selectedItemIndex];

    fallBackItemIndex = selectedItemIndex;

    [selectedItem selected];      
}

@end

Original comment by hamm.h...@googlemail.com on 25 Nov 2009 at 1:13

GoogleCodeExporter commented 9 years ago
Attached is an example of how to use my code.

Original comment by hamm.h...@googlemail.com on 27 Nov 2009 at 6:38

Attachments:

GoogleCodeExporter commented 9 years ago
I added a patch to add (my) CCRadioButtonMenu - dont know if this issue is yet 
solved.

but I dont know how to submit a testscene (see above).

Original comment by hamm.h...@googlemail.com on 10 Dec 2009 at 11:08

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 8 Feb 2010 at 4:21

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 8 Feb 2010 at 4:24

GoogleCodeExporter commented 9 years ago
Since I dont know if there is a CCRadioMenu yet or not and if its based on my 
code or
on ricardoquesada I just post a small fix for my code here :
-----------
I fixed a small bug in my code :
when you slide over the items and again over the currentlySelected (fallback) 
item,
the selection will get lost. To fix this you just have to change one line of 
code in
CCRadioMenu.m (in ccTouchMoved method):

if (currentItem != selectedItem) 
to
if (currentItem != selectedItem && currentItem != fallBackItem) 

or you could also completly replace ccTouchMoved function with this one if you 
dont
want to seek:

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    NSAssert(state == kMenuStateTrackingTouch, @"[Menu ccTouchMoved] -- invalid state");

    MenuItem * currentItem = [self itemForTouch:touch];
    MenuItem * fallBackItem = (MenuItem *) [children objectAtIndex:fallBackItemIndex];
    if (currentItem != selectedItem && currentItem != fallBackItem) // CHANGED
    {               
        [selectedItem unselected];
        selectedItem = currentItem;

        if (selectedItem)
        {       
            [selectedItem selected];
        }
        else
        {
            [[children objectAtIndex:fallBackItemIndex]selected];
        }

    }
}

Original comment by hamm.h...@googlemail.com on 19 Feb 2010 at 12:36

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 19 Mar 2010 at 10:48

GoogleCodeExporter commented 9 years ago
Is this issue yet solved or should some one take care about it? I could submit a
patch for my own solution, but I don't know if its a good solution since I 
haven't
got much feed back.

Original comment by hamm.h...@googlemail.com on 22 Mar 2010 at 9:20

GoogleCodeExporter commented 9 years ago
This issue is not fixed yet, but it is planned to be included in the v0.99.x 
series

Original comment by ricardoq...@gmail.com on 22 Mar 2010 at 1:14

GoogleCodeExporter commented 9 years ago
Is there a working code other than mine - otherwise I could clean up my code a 
bit -
its working fine in my own projects. 
- What could I do to help come forward with this issue? 
- Should I paste my code into CCMenu.m or should it be placed in an own file 
like
CCRadioMenu.m ? 
- Should I submit a project template?
- Should I submit a patch for the current build ?

Original comment by hamm.h...@googlemail.com on 22 Mar 2010 at 1:30

GoogleCodeExporter commented 9 years ago
Yes, a patch against trunk (current SVN version) would be great.
A new file would be nice too: CCRadioMenu.m
And also, it would be great if you could patch tests/MenuTest.m so that it also 
includes 
a RadioMenu test.
Thanks!

Original comment by ricardoq...@gmail.com on 22 Mar 2010 at 2:03

GoogleCodeExporter commented 9 years ago
So here comes the diff and also the needed resource files for the menu test.
I hope I made everything correct. 
The patch is a diff from revision 1877.

Original comment by hamm.h...@googlemail.com on 22 Mar 2010 at 7:26

Attachments:

GoogleCodeExporter commented 9 years ago
If needed, here are the single source files I changed / added :

Original comment by hamm.h...@googlemail.com on 22 Mar 2010 at 7:30

Attachments:

GoogleCodeExporter commented 9 years ago
Hi, 
is it helpful what I posted? Or should I change something?
cheers,
Hans

Original comment by hamm.h...@googlemail.com on 25 Mar 2010 at 4:42

GoogleCodeExporter commented 9 years ago
I have not looked at it yet. 

Original comment by ricardoq...@gmail.com on 25 Mar 2010 at 4:49

GoogleCodeExporter commented 9 years ago
Dont hurry - was just wondering if its helpful :-)

Original comment by hamm.h...@googlemail.com on 25 Mar 2010 at 5:25

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 24 Apr 2010 at 2:12

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 26 May 2010 at 6:20

GoogleCodeExporter commented 9 years ago
Some time has gone - had you checked the code? Was it useful? Will it be in the 
next release?

Original comment by hamm.h...@googlemail.com on 2 Jul 2010 at 2:37

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 14 Jul 2010 at 9:48

GoogleCodeExporter commented 9 years ago
ping

Original comment by hamm.h...@googlemail.com on 10 Nov 2010 at 9:07

GoogleCodeExporter commented 9 years ago
thanks for the patch hamm. I couldn't look at it yet.

Original comment by ricardoq...@gmail.com on 10 Nov 2010 at 3:47

GoogleCodeExporter commented 9 years ago

Original comment by ricardoq...@gmail.com on 17 Mar 2011 at 7:02

GoogleCodeExporter commented 9 years ago
rescheduled for v1.1

Original comment by ricardoq...@gmail.com on 13 Jul 2011 at 9:44

GoogleCodeExporter commented 9 years ago
I started using cocos2d v1.0.1 and I needed to modified the last .m to use it 
in my project. Here's the modifications done.

Original comment by maca...@gmail.com on 6 Sep 2011 at 1:27

Attachments: