0

I have two version of my program. One that uses ncurses and another that doesn't. The one which doe not use ncurses works well enough, nothing is wrong with it. I want to upgrade my program so I decided that I will use ncurses for that. The problem is I don't understand how the window system works. There is no decent documentations and the tutorials aren't very helpful. What I am asking is for general help regarding windows in ncurses as well as an example of such the feature working using my code.

What I tried:

//g++ main.cpp -lncurses -W -Wall -Wpedandtic -std=c++23; ./a.out
#include <string>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include "ncurses.h"

void start() {
  initscr();
  noecho();
  std::cout << "Hello, word!" << '\n';
  getch();
}

int main() {
  initscr();
  noecho();
  cbreak();

  int yMax;
  int xMax;
  getmaxyx(stdscr, yMax, xMax);

  std::string line;
  std::ifstream file("resources/graphics/logo.txt");
  if(file.is_open()) {
    while(getline(file, line)) {
      std::cout << line << '\n';
    }
  } else {
    std::cout << "logo.txt could not be found!" << '\n';
  }
  
  WINDOW * menuwin = newwin(6, xMax / 2, 10, xMax / 4);
  keypad(menuwin, true);
  box(menuwin, 0, 0);
  refresh();
  wrefresh(menuwin);

  std::string choices[4] = {"Start", "Continue", "Settings", "Controls"};
  int choice;
  int highlight = 0;
  while(1) {
    for(int i = 0; i < 4; ++i) {
      if(i == highlight) {
    wattron(menuwin, A_REVERSE);
      }
      mvwprintw(menuwin, i + 1, 1, choices[i].c_str());
      wattroff(menuwin, A_REVERSE);
    }
    choice = wgetch(menuwin);
    switch(choice) {
    case KEY_UP:
      highlight--;
      if(highlight == -1) {
    highlight = 0;
      }
      break;
    case KEY_DOWN:
      highlight++;
      if(highlight == 4) {
    highlight = 3 ;
      }
      break;
    default:
      break;
    }
    //keycode 10 = enter;
    if(choice == 10) {
      break;
    }
  }
  if(choices[highlight].c_str() == 0 | 1 | 2 | 3) {
    start();
  }
  //printw("%s", choices[highlight].c_str());
  getch();
  endwin();
}

What I expected(graphical representation):



        ####
       #     #   ####   #####   #    #  #   ####   #    #  #  #####   ######
       #        #    #  #    #  ##   #  #  #       #    #  #  #    #  #
       #  ####  #    #  #    #  # #  #  #   ####   ######  #  #    #  #####
       #     #  #    #  #####   #  # #  #       #  #    #  #  #####   #
       #     #  #    #  #   #   #   ##  #  #    #  #    #  #  #   #   #
        #####    ####   #    #  #    #  #   ####   #    #  #  #    #  ######
                                                               #    
       #          ##    #####   #   #  #####   #  #    #    #    #    #
       #         #  #   #    #  #  #   #    #  #  ##   #    #    #    #
       #        #    #  #####    ##    #    #  #  # #  #    #    ######
       #        ######  #    #   #     #####   #  #  # #    #    #    #
       #        #    #  #    #  #      #   #   #  #   ##    #    #    #
       #######  #    #  #####  #       #    #  #  #    #  #####  #    #
                  #             #              #             #
                                                #
                                  Start
                                  Continue
                                  Settings
                                  Controls

What I got(graphical representation):

Start
Continue
Settings
Controls[]Hello, world!

The [] represents a graphical glitch, btw.

I have a main2.cpp where I tried adding multiple windows but what happens is they load independently of each others. So, windows1 loads, waits for input, and closes. Then window2 opens. I want both of them to be open or preferable for both of the functions to be in the same windows.

1 Answers1

0

In ncurses, each window is a separate entity and they don't know about each other. When you refresh a window, it gets drawn on the virtual screen. The actual screen doesn't get updated until you call refresh() or doupdate().

In your code, you're using std::cout to print the logo and the "Hello, world!" message. However, std::cout doesn't work well with ncurses because ncurses uses its own buffering system. Instead, you should use ncurses functions like printw(), mvprintw(), wprintw(), or mvwprintw() to print to the screen or a window.

For your issue with multiple windows, you need to create and refresh all your windows first, then call doupdate() to update the actual screen. This way, all your windows will appear at the same time.

#include <ncurses.h>

int main() {
    initscr();
    noecho();
    cbreak();

    int yMax, xMax;
    getmaxyx(stdscr, yMax, xMax);

    WINDOW *win1 = newwin(yMax / 2, xMax / 2, 0, 0);
    box(win1, 0, 0);
    mvwprintw(win1, 1, 1, "This is window 1");
    wrefresh(win1);

    WINDOW *win2 = newwin(yMax / 2, xMax / 2, yMax / 2, xMax / 2);
    box(win2, 0, 0);
    mvwprintw(win2, 1, 1, "This is window 2");
    wrefresh(win2);

    doupdate();

    getch();
    endwin();

    return 0;
}
Kozydot
  • 515
  • 1
  • 6