Используя нативные оболочки C ++ для ncurses, Как я могу создать систему меню / подменю? - PullRequest
0 голосов
/ 19 декабря 2018

Я провел последний год, изучая C ++ (используя C ++ Primer в качестве рекомендованного материала от https://stackoverflow.com/a/388282/1440199).. Я хотел научиться использовать ncurses для создания моей первой летающей сольной программы. Несмотря на то, что NCurses основан на C, онболее или менее малоизвестно, что встроенных оболочек ncurses C ++ существует . Однако документации для них практически не существует, есть файл demo.cc, который я использовал в качестве основы, и несколько местпо всему Интернету . В любом случае, я сделал свой итоговый экзамен, так сказать, чтобы понять и использовать эти оболочки.

Проблема, с которой я сталкиваюсь, относится к типу "лучших практик программирования": из-заОтсутствие документированных примеров, я не уверен, что лучший способ создать подменю из системы начального меню демо .

Лучшая идея, которую я могу придумать, - это использовать пример способа в присоединение NCursesUserItem ncurses ++ к пункту меню . Будет ли указатель пользователя указателем на предыдущий класс меню? В NCurses,Вы можете публиковать и отменять публикацию меню, поэтому я также предполагаю, что я хочу «отменить публикацию» предыдущего меню, когда новое «отправляет», поэтому при отображении нового я хотел указатель на предыдущее меню.

Типичный безопасный способ присоединения пользовательских данных (для set_item_userptr) к пункту меню:

template<class T> class SubMenu : public NCursesUserItem<T>
{
  public:
    SubMenu (const char* p_name,
             const T* p_UserData)
            : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData){}

    virtual ~SubMenu() {}

    bool action() {
        // I believe I want to unpost the previous menu here
        //  before posting the new submenu?
        NCursesUserItem<T>::UserData()->prev_menu()->unpost();
        //This doesn't work, but its kind of what I want to do.
        NCursesUserItem<T>::UserData()->post();
        return FALSE;
    }
};

Объект главного меню.Я создал здесь объект Submenu и передал ему «this» (указатель главного меню) в качестве аргумента.

class MainMenu : public NCursesMenu
{
  private:
    NCursesMenuItem** I;
    Choice0Menu* u;
#define n_items 3
  public:
    MainMenu ()
    : NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), u(0)
    {
        u = new Choice0Menu(this);
        I = new NCursesMenuItem*[1+n_items];
        I[0] = new SubMenu<Choice0Menu> ("Choice 0", u);
        I[1] = new PadAction("Choice 1");
        I[2] = new QuitItem();
        I[3] = new NCursesMenuItem();

        InitMenu(I, TRUE, TRUE);
    }
};

Класс Choice0Menu, который должен содержать кнопку возврата для возврата в главное меню (I [2])

class Choice0Menu : public NCursesMenu
{
  private:
    NCursesMenuItem** I;
    MainMenu* w;
#define n_items 3

  public:
    Choice0Menu (MainMenu* prev)
    : NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), w(prev)
{
    I = new NCursesMenuItem*[1+n_items];
    I[0] = new ScanAction("Submenu Choice 0");
    I[1] = new PadAction("Submenu Choice 1");
    I[2] = new MainMenuAction("Go Back");
    I[3] = new NCursesMenuItem();

    InitMenu(I, TRUE, TRUE);

    // returns the pointer to the prev object
    MainMenu* prev_menu() const{
        return w;
    }
};

У меня просто много сомнений относительно этого способа, например, может быть, мне не нужно передавать весь указатель this в главное меню при создании подменю,просто пост и отстойники.И классы MainMenu и Choice0Menu очень похожи по функциям, так что, может быть, даже превратить их в один шаблонный класс?Так как Choice0Menu принимает MainMenu в качестве аргумента, может быть, для выбора любого типа меню нужно использовать T *.

Мой метод не кажется «чистым» способом программирования проблемы.

Спасибо за помощь.Я изучаю эту проблему почти 2 недели ...

...