#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <conio.h>
using namespace std;
using namespace std::tr1;
#define interface struct
#define clrscr() system("cls")
//***************************************
// IMenuHandler
//***************************************
interface IMenuHandler
{
virtual ~IMenuHandler() {}
virtual void OnCommand( unsigned int id ) = 0;
};
//***************************************
// AbstractMenu
//***************************************
class AbstractMenu
{
string title;
public:
AbstractMenu( string s) : title(s) {}
virtual ~AbstractMenu() {}
virtual string GetTitle() const { return title;}
virtual void Command() = 0;
};
//***************************************
// MenuItem
//***************************************
class MenuItem : public AbstractMenu
{
unsigned int id;
IMenuHandler* pMenuHandler;
public:
MenuItem( string s, unsigned int i, IMenuHandler* pHandler)
: AbstractMenu(s), id(i), pMenuHandler(pHandler) {}
virtual void Command() { pMenuHandler->OnCommand( id ); }
};
//***************************************
// PopupMenu
//***************************************
class PopupMenu : public AbstractMenu
{
typedef shared_ptr<AbstractMenu> PAbstractMenu;
vector<PAbstractMenu> menu_list;
bool isroot;
typedef list<Tape*> TapeList; // 테입 리스트를 명확하게 표현 해준다.
public:
static string str_exit;
static string str_goback;
int xpos, ypos; // 현재 팝업 메뉴가 나타 날 위치로 메뉴를 뜨게 해준다.!!
public:
PopupMenu(string s, bool b = false) : AbstractMenu( s ), isroot(b) {}
void Append(AbstractMenu* m) { menu_list.push_back( (PAbstractMenu)m);}
virtual void Command()
{
while( 1 )
{
clrscr();
size_t cnt = menu_list.size();
for ( size_t i = 0; i < cnt; ++i )
cout << i + 1 << ". " <<
menu_list[i]->GetTitle() << endl;
cout << cnt + 1 << ". " <<
( isroot ? str_exit:str_goback) << endl;
unsigned int cmd;
cout << "메뉴를선택하세요>> ";
cin >> cmd;
// 문자를 입력 한 경우
if ( cin.fail() )
{
cin.clear();
cin.ignore(256, '\n');
continue;
}
if ( cmd < 1 || cmd > cnt + 1 ) continue;
if ( cmd == cnt + 1 ) return ;
menu_list[cmd-1]->Command();
}
}
};
string PopupMenu::str_exit = "종료";
string PopupMenu::str_goback = "이전메뉴로";
//---------------------------------------------
// Menu Class 활용 예제..
class VideoShop : public IMenuHandler
{
shared_ptr<PopupMenu> pMenuBar; // video shop의 메인 메뉴
public:
VideoShop() : pMenuBar( new PopupMenu("ROOT", true))
{ }
virtual void OnCommand( unsigned int id )
{
cout << id << " 메뉴가선택됨" << endl;
getch();
}
void InitMenu()
{
// initialize menu
PopupMenu* p1 = new PopupMenu( "고객관리" );
p1->Append( new MenuItem( "고객등록", 1, this ));
p1->Append( new MenuItem( "고객삭제", 2, this ));
p1->Append( new MenuItem( "기타", 3, this ));
PopupMenu* p2 = new PopupMenu( "Tape 관리" );
p2->Append( new MenuItem( "Tape 등록", 11, this ));
p2->Append( new MenuItem( "Tape 삭제", 12, this ));
p2->Append( new MenuItem( "기타", 13, this ));
PopupMenu* p3 = new PopupMenu( "대여관리" );
p3->Append( new MenuItem( "대여등록", 21, this ));
p3->Append( new MenuItem( "반납", 22, this ));
p3->Append( new MenuItem( "기타", 23, this ));
pMenuBar->Append( p1 );
pMenuBar->Append( p2 );
pMenuBar->Append( p3 );
PopupMenu::str_exit = "Exit";
PopupMenu::str_goback = "Go Back";
}
void Start()
{
InitMenu();
pMenuBar->Command();
}
};
int main()
{
VideoShop vs;
vs.Start();
}