#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();

} 

Tag | ,

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다