Jacob Anderson Menu Group management class
Posts 178
Location Totally Evil Entertainment - San Diego
Added by Jacob Anderson 12 months ago

This is a class that will manage a set of CCMenuItemToggle instances. This is useful when you want a radio group. maybe this already exists in cocos2d? I couldn't find it.

using System;
using System.Collections.Generic;
// using System.Linq; @@@ removed to make this compile in MonoDevelop
using System.Text;
using cocos2d;

namespace MyExtensions.Cocos2d
{
    public delegate void MenuGroupCallback(CCMenuItemToggle sender);

    /// <summary>
    /// Menu group management. This will manage a group of toggle buttons such that only one will ever be
    /// selected. Assumes that index=0 is the ON toggle indicator, and index=1 is the OFF indicator.
    /// This is NOT a displayable object. It is just a management object to handle the single-state of
    /// the group.
    /// </summary>
    public class TEMenuGroup : SelectorProtocol
    {
        /// <summary>
        /// The index of the selected item that indicates ON for the toggle menu items
        /// </summary>
        public static int ON_INDEX = 0;
        /// <summary>
        /// The index of the selected item that indicates OFF for the toggle menu items.
        /// </summary>
        public static int OFF_INDEX = 1;

        private CCMenuItemToggle[] _MenuItems;
        private MenuGroupCallback _ItemChangeCallback;
        private int _SelectedIndex = -1;

        public void init(CCMenuItemToggle[] items)
        {
            _MenuItems = items;
        }

        public MenuGroupCallback SelectionChangedCallback
        {
            get
            {
                return (_ItemChangeCallback);
            }
            set
            {
                _ItemChangeCallback = value;
            }
        }

        /// <summary>
        /// Get/set the ZERO based selection index that indicates
        /// which menu item is currently selected.
        /// </summary>
        public int SelectedIndex
        {
            get
            {
                return (_SelectedIndex);
            }
            set
            {
                _SelectedIndex = value;
                if (value < 0)
                {
                    _SelectedIndex = 0;
                }
                if (value >= _MenuItems.Length)
                {
                    _SelectedIndex = _MenuItems.Length - 1;
                }
                ToggleIndicators();
            }
        }

        private void ToggleIndicators()
        {
            for (int i = 0; i < _MenuItems.Length; i++)
            {
                if (_SelectedIndex == i)
                {
                    _MenuItems[i].SelectedIndex = ON_INDEX;
                }
                else
                {
                    _MenuItems[i].SelectedIndex = OFF_INDEX;
                }
            }
        }

        public void ccMenuCallback(CCObject sender)
        {
            int idx = -1, i=0;
            CCMenuItemToggle menu = (CCMenuItemToggle)sender;
            foreach (CCMenuItemToggle m in _MenuItems)
            {
                if (sender == m)
                {
                    idx = i;
                    break;
                }
                i++;
            }
            // System.Diagnostics.Debug.WriteLine("ccMenuCallback:idx={0}, selected={1}", idx, _SelectedIndex);
            if (idx == _SelectedIndex && idx != -1)
            {
                // No change, so don't change the state of the toggle but make sure it is selected
                if (menu.SelectedIndex == OFF_INDEX)
                {
                    menu.SelectedIndex = ON_INDEX;
                }
                return;
            }
            // Cocos2d will manage the index toggle for me. 
            _SelectedIndex = idx;
            ToggleIndicators();
            if (SelectionChangedCallback != null)
            {
                SelectionChangedCallback.Invoke(_MenuItems[idx]);
            }
        }

        /// <summary>
        /// Convenience method to create an instance initialized with the given toggle button items.
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public static TEMenuGroup initWithItems(params CCMenuItemToggle[] items)
        {
            TEMenuGroup grp = new TEMenuGroup();
            foreach(CCMenuItemToggle m in items) 
            {
                m.setTarget(grp, new SEL_MenuHandler(grp.ccMenuCallback));
            }
            grp.init(items);
            return (grp);
        }

        public static TEMenuGroup initWithItems(MenuGroupCallback cb, params CCMenuItemToggle[] items)
        {
            TEMenuGroup grp = initWithItems(items);
            grp.SelectionChangedCallback = cb;
            return (grp);
        }

#region SelectorProtocol Members

        public void update(float dt)
        {
            // Ignored
        }

#endregion
    }
}