5

I am using the ncurses library to write a console application. I have a function that is suppose to write to a window buffer and then refresh the window. In my test function I then call the window function and something happens, since the program moves to the next line (getch() which just waits for a character from me), but nothing is displayed.

Here is my function:

void UI::drawAudience(int audience1, int audience2)
{

    string bar1 = "", bar2 = "";

    for (int i; i < BAR_SIZE; i++)
    {

        bar1 += (i <= audience1) ? ' ' : '+';

        if (i <= audience2)
            bar2 += '+';
    }

    string audienceName = "Audience Name";

    //mvwprintw(audience, 0, 11 - audienceName.size() / 2, "%s", audienceName.c_str());
    //mvwprintw(audience, 1, 0, "%s|%s", bar1.c_str(), bar2.c_str());
    wprintw(audience, "Test");

    wrefresh(audience);
}

Here is my test code:

#include "Tests.h"
#include <string>

using namespace std;

void test()
{
    int y = 1;

    UI testUI;

    initscr();
    cbreak();

    WINDOW* windowTest = newwin(1, 23, 3, 0);

    wprintw(windowTest, "This is a new window");
    wrefresh(windowTest);

    getch();

    clear();

    delwin(windowTest);

    testUI.drawAudience(4,5);

    getch();

    endwin();

}
Ironlenny
  • 634
  • 7
  • 10

2 Answers2

17

EDIT: The cause of you problem is the getch() line. By calling getch() your program sticks the stdscr back on top. A solution is to use wgetch() as described in (https://stackoverflow.com/a/3808913/2372604).

Another solution I found is the following, unfortunately this may not work depending on your implementation of the UI class. Try the following code with both refresh() lines commented out and then try running again with either (or both) lines uncommented. If you don't refresh the screen before refreshing the window, you never get to see your window.

#include <ncurses.h>

int main(int argc, char** argv)
{
    initscr();
    cbreak();
    refresh();      // Important to refresh screen before refresh window

    WINDOW* windowTest = newwin(1, 23, 3, 0);
    wprintw(windowTest, "Hello World");

    //refresh();      // Refresh here works as well
    wrefresh(windowTest);

    getch();

    delwin(windowTest);
    endwin();

    return 0;
}
Community
  • 1
  • 1
ilent2
  • 5,171
  • 3
  • 21
  • 30
0

As @ilent2 mentioned after creating each window stdscr needs to be updated to include your new window. but the same effect can be achived with wnoutrefresh(stdscr) which copies the named window into virtual screen and doesn't call doupdate() which do the actual outputing and you can call doupdate() yourself once you're done with your windows; with the benefit of less cpu time

but even a better solution: Use panels

#include <curses.h>
#include <panel.h>

int main()
{
    initscr();

    // use default width and height
    WINDOW* p = newwin(0, 0, LINES/2, COLS/2);
    // create a panel of a newly created window 
    // managing windows is easy now
    PANEL* p_panel = new_panel(p);
    waddstr(p, "that's what i'm talking about!");

    update_panels(); // update windows once and for all

    doupdate(); // the actual updating (calculate changes with the curscr)

    endwin();
}

As you can see panels can help a lot. managing each window separately is tedious and error-prone. So obviously you can do several window:

WINDOW* win = newwin(height, width, beginy, beginx); // variables defined somewhere
WINDOW* win2 = newwin(height, width, beginy+5, beginx+10);

PANEL* p1 = new_panel(win);
PANEL* P2 = new_panel(win2);

// changing my windows without worrying about updating in the correct order (because they're overlapping)

update_panels();

doupdate();
etzl
  • 105
  • 1
  • 8