/*---------------------------------------------------------------------------* Project: Horizon File: Menu.h Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev:$ *---------------------------------------------------------------------------*/ #ifndef NN_SAMPLE_DEMOS_PHTSEL_MENU_H_ #define NN_SAMPLE_DEMOS_PHTSEL_MENU_H_ #include #include "demo.h" #include "PadEx.h" class ItemBase; //////////////////////////////////////////////////////////////////////////////////////////////// /// Menu /// //////////////////////////////////////////////////////////////////////////////////////////////// class Menu { public: Menu() : m_nItemNum(0) , m_nCurItem(0) { // Nop } /// Add item void Append( ItemBase* pItem ) { NN_ASSERT( m_nItemNum < ITEM_MAX ); const ItemInfo info = { pItem }; m_itemInfoList[m_nItemNum] = info; ++m_nItemNum; } //============================== /// Get number of items int GetItemNum() const { return m_nItemNum; } /// Get selected item int GetSelectItemIndex() const { return m_nCurItem; } /// Switch selected item void AddSelectItemIndex( int inc ) { m_nCurItem += inc; if( m_nCurItem >= m_nItemNum ) m_nCurItem = 0; if( m_nCurItem < 0 ) m_nCurItem = m_nItemNum-1; } /// Get item const ItemBase* GetItemPtr( int nItemIdx ) const { return m_itemInfoList[nItemIdx].pItem; } ItemBase* GetItemPtr( int nItemIdx ) { return m_itemInfoList[nItemIdx].pItem; } /// Get selected item const ItemBase* GetSelectItemPtr() const { return GetItemPtr( GetSelectItemIndex() ); } ItemBase* GetSelectItemPtr() { return GetItemPtr( GetSelectItemIndex() ); } private: struct ItemInfo { ItemBase* pItem; }; // Dynamic memory allocation failed, so let's try a fixed-length array static const int ITEM_MAX = 32; typedef ItemInfo ItemInfoContainer[ITEM_MAX]; private: s32 m_nItemNum; s32 m_nCurItem; ItemInfoContainer m_itemInfoList; }; //////////////////////////////////////////////////////////////////////////////////////////////// /// Item base class /// //////////////////////////////////////////////////////////////////////////////////////////////// class ItemBase { public: explicit ItemBase( const char* pName, s32 nValueNum, bool bEnableDetailEditMode=false ) : m_pName(pName) , m_nValueNum(nValueNum) , m_bEnableDetailEditMode(bEnableDetailEditMode) , m_nSelectIdx(0) , m_bDetailEdit(false) {}; virtual ~ItemBase() {}; /// Number of values s32 GetValueNum() const { return m_nValueNum; } /// Item name const char* GetItemName() const { return m_pName; } /// Is there an advanced edit mode? bool IsEnableDetailEditMode() const { return m_bEnableDetailEditMode; } /// Advanced edit mode void SetDetailEditMode( bool bDetailEdit ) { m_bDetailEdit = bDetailEdit; } bool IsDetailEditMode() const { return m_bDetailEdit; } /// Selection void SetSelectIndex( int idx ) { NN_ASSERT( idx>=0 && idx 0 ) { m_nSelectIdx += add; if( m_nSelectIdx >= GetValueNum() ) m_nSelectIdx = 0; if( m_nSelectIdx < 0 ) m_nSelectIdx = GetValueNum()-1; } } /// Get selection s32 GetSelectIndex() const { return m_nSelectIdx; } //============================== /// Manipulate individual items virtual void Proc( const PadEx& padEx ) { if ( (padEx.GetRepeat() & (nn::hid::BUTTON_LEFT)) ) { AddSelectIndex( -1 ); } else if ( (padEx.GetRepeat() & (nn::hid::BUTTON_RIGHT)) ) { AddSelectIndex( 1 ); } } /// Render virtual void Draw( demo::RenderSystemDrawing& df, s32 x, s32 y, bool bSelectItem ) const = 0; protected: /// Common rendering of item name void DrawItemNameCommon( demo::RenderSystemDrawing& df, s32 x, s32 y, bool bSelectItem ) const { const bool bColor = bSelectItem && !IsDetailEditMode(); if( bColor ) df.SetColor(1.0f, 0.5f, 0.1f); else df.SetColor(1.0f, 1.0f, 1.0f); df.DrawText( x, y, "%s", GetItemName() ); if( IsEnableDetailEditMode() ) { df.SetColor(1.0f, 1.0f, 0.0f); df.DrawText( x+160-8*2, y, IsDetailEditMode() ? "B<" : "A>" ); if( bColor ) df.SetColor(1.0f, 0.5f, 0.1f); else df.SetColor(1.0f, 1.0f, 1.0f); } } private: const char* const m_pName; const s32 m_nValueNum; const bool m_bEnableDetailEditMode; NN_PADDING3; s32 m_nSelectIdx; bool m_bDetailEdit; NN_PADDING3; }; //////////////////////////////////////////////////////////////////////////////////////////////// /// Array definition item /// //////////////////////////////////////////////////////////////////////////////////////////////// template class ArrayItem : public ItemBase { public: typedef ValueType value_type; public: template ArrayItem( const char* pName, const value_type (&pValueArray)[ArraySize], const char* const (&pNameArray)[ArraySize] ) : ItemBase(pName, ArraySize) , m_pValueArray(pValueArray) , m_pNameArray(pNameArray) , m_nArraySize(ArraySize) { // Nop } /// Render virtual void Draw( demo::RenderSystemDrawing& df, s32 x, s32 y, bool bSelectItem ) const { DrawItemNameCommon( df, x, y, bSelectItem ); NN_ASSERT( GetSelectValueName() ); //df.DrawText( x+160, y, "%d/%d:%s", GetSelectIndex()+1, GetValueNum(), GetSelectValueName() ); df.DrawText( x+160, y, "%s", GetSelectValueName() ); } //============================== /// Get value value_type GetValue( s32 idx ) const { NN_ASSERT( idx>=0 && idx class RangeItem : public ItemBase { NN_STATIC_ASSERT( MinValue <= MaxValue ); public: typedef s32 value_type; public: RangeItem( const char* pName ) : ItemBase(pName, MaxValue - MinValue + 1) {} /// Render virtual void Draw( demo::RenderSystemDrawing& df, s32 x, s32 y, bool bSelectItem ) const { DrawItemNameCommon( df, x, y, bSelectItem ); //df.DrawText( x+160, y, "%d/%d:%d", GetSelectIndex()+1, GetValueNum(), GetSelectValue() ); df.DrawText( x+160, y, "%d", GetSelectValue() ); } //============================== /// Get value value_type GetValue( s32 idx ) const { NN_ASSERT( idx>=0 && idx