-1

I would like to wrap a short text in a Text Box in Ncurses, but somehow my text keeps going off screen. How can I wrap the text so it (automatically) goes to a new line when reaching the end of the screen on the right?

I tried playing with '\n' and setting limits but witout results. Any tips what I am doing wrong? See below code for what is going on.

Thanks from a beginner programmer.

#include <ncurses.h>
#include <string.h>

void text(WINDOW* textborder, int wymax, int wxmax, char text5[], int size)
{
        
    for (int i=0;i<size;i++)
    {
        mvwaddch(textborder,2,i+i, text5[i]);
        if (i==wxmax)
        {
            mvwaddch(textborder,2,i+i, '\n');
        }
    }
        
}


int main()
{
    
    char text5[]={"Somebody is watching over us... controlling us. It's true, I tell you. It's true! We are merely sprites that dance at the beck and call of our button-pressing overlord. This is a video game. Don't you see? We are characters in a video game."};
    int size;
    size=strlen(text5);
    
    int wymax; int wxmax;
    
    initscr();
    
    WINDOW* textborder=newwin(LINES/4, COLS, LINES-LINES/4, 0);
    box(textborder,-1,-1);
    getmaxyx(textborder, wymax,wxmax);
    wxmax=wxmax-4;
    
    text(textborder, wymax, wxmax, text5, size);
    
    wgetch(textborder);
    endwin();
    return 0;
}

  • When using the `mvwaddch` function, you give X and Y coordinates of the characters. You increase the X coordinate, but always print with the Y coordinate equal to `2`. Perhaps you should increase that Y coordinate on a newline (and reset the X coordinate to begin at the start of the next line)? – Some programmer dude Aug 02 '22 at 10:39

2 Answers2

1

In theory the text should wrap itself. I think your issue may be coming from using mvwaddch, ch generally causes the text not to wrap. This may help Ncurses no-wrap mode when adding strings to window. Sorry I can't be more helpful :)

  • Interesting indeed. I tried using mvwaddstr(textborder,2,1, text5); which works as a standalone syntax without any for loop needed. Only downside is now that even though the text is wrapped, but does not seem to respect the right limit and still goes trough the border of the textbox for a couple of characters, before starting a new line. Will have to figure this out – Vigor The Destructible Aug 02 '22 at 13:35
  • Are those extra characters the end of words? I'm not too sure about the specifics of this to be honest but I remember having this problem a while back. – Guy Lawrence-Downs Aug 02 '22 at 14:32
  • No, any word is just cut off at a letter if it reaches the end, and the words continues on the next line. The letters just seem to overwrite the border of the `box(textborder,-1,-1);` – Vigor The Destructible Aug 02 '22 at 15:08
  • The text all contains of one complete string and they are meant to be cut off at the end off the line. However they still overwrite the graphical border of `box() `. The idea is that that a new line is started right before this border. – Vigor The Destructible Aug 02 '22 at 18:53
0

Applications that draw a box with a border in curses do this using two windows, one within the other. The outer box gets the border; the inner box gets the text. Text printed within the inner box does not affect the outer box.

For example, some of the demo/example programs in ncurses do this, e.g., test_addstr creates look (for the box) and show (for the text):

limit = LINES - 5;
if (level > 0) {
    look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1);
    work = newwin(limit - 2, COLS - (2 * level), 1, level);
    show = newwin(4, COLS, limit + 1, 0);
    box(look, 0, 0);
    wnoutrefresh(look);
    limit -= 2;
} else {
    work = stdscr;
    show = derwin(stdscr, 4, COLS, limit + 1, 0);
}
keypad(work, TRUE);
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105