Search code examples
cmenuwindowncurses

Ncurses menu out of borders


I am trying to do simple menu, but I just can't get it to fit into box. Can you tell me what am I doing wrong?

 // main
ITEM** items = // items initialization
WINDOW* menuWindow = create_newwin(itemsCount + 2, 38, 3, 5, true);
keypad(menuWindow, TRUE);

MENU* menu = create_menu(itemsCount, menuWindow, items, 2, 2, 5);
refresh();
post_menu(menu);
wrefresh(menuWindow);

// create win 
WINDOW *create_newwin(const int height, const int width, const int starty, const int startx, const bool framed){

   WINDOW *local_win = newwin(height, width, starty, startx);
   if (framed) box(local_win, 0 , 0);
   wrefresh(local_win);     
   return local_win;
}

//create menu 
MENU* create_menu(const unsigned int count, WINDOW* window, ITEM** items, const unsigned int startx, const unsigned int starty, const unsigned int length){
    MENU* local = new_menu((ITEM **)items);
    menu_opts_off(local, O_ONEVALUE);
    set_menu_win(local, window);
    set_menu_sub(local, derwin(window, count + 2, length, startx, starty));
    set_menu_format(local, count, 1);
    set_menu_mark(local, " ");
    return local;
}

This is how my menu looks like: enter image description here


Solution

  • It would probably be helpful if you'd post the actual code that gives you the result in the screencap, because I can't reproduce it.

    I do see a couple problems here, though. First, this line:

    set_menu_sub(local, derwin(window, count + 2, length, startx, starty));
    

    Notice the count + 2 attempts to make a subwindow with height greater than its parent. According to the curs_window(3X) man page, derwin():

    returns an error if the parent window pointer is null, or if any of its ordinates or dimensions is negative, or if the resulting window does not fit inside the parent window.

    It's worth noting that on my machine, derwin() returns NULL on failure and doesn't set errno, so the documentation isn't necessarily all there.

    The other thing that looks strange is this:

    MENU* menu = create_menu(itemsCount, menuWindow, items, 2, 2, 5);
    

    Curses windows are 0-addressed from their origin, so with the rest of your code, that's going to attempt to put your menu at {2,2} of the menuWindow. That is, even if you fix the above, it's still going to write over the bottom border of your box with the last menu entry. What's more, your last parameter being 5 means your menu is only going to have five columns including the menu_mark string.

    For further reading, I would encourage you to look at the documentation for menu.h because they cover nearly this exact scenario.