PDcurses library menu.h extention I am currently learning how to use PDcurses in VC++ 2015 Community, and I noticed that menu.h is not implemented so I decided to extend the library for my own use (feel free to just copy the code if it's what you were looking for).

The only question I have is: was my use of namespaces (both named and unnamed) correct? And is this a good approach as I do not see a reason to make a singleton or something involving classes?

NOTE: I did research the web about dividing functions into namespaces like I did in the code, but I can't find if it's the correct approach for this specific task.

menu.h

#ifndef MENU_H
#define MENU_H

#include "curses.h"

namespace menu
{
    int renderMenu(WINDOW* menu_win, const char* title, const char* items[], int n_items);
    WINDOW* menuWin(const char* title, const char* items[], int n_items, int y, int x);
    void initMenu();
}

#endif  


menu.cpp

#include "menu.h"
#include &lt;string&gt;

namespace
{
    void renderItems(WINDOW* win, int selected, const char* items[], int n_items)
    {
        for (int index{}; index &lt; n_items; ++index) {
            if (index == selected) {
                wattron(win, A_BOLD);
                mvwprintw(win, 3 + index, 2, items[index]);
                wattroff(win, A_BOLD);
            }
            else 
                mvwprintw(win, 3 + index, 2, items[index]);
        }

        wrefresh(win);
    }

    int navigateMenu(WINDOW* win, const char* items[], int n_items)
    {
        int selected{};
        renderItems(win, selected, items, n_items);

        keypad(win, TRUE);
        while (true) {
            switch (wgetch(win)) {
              case KEY_DOWN:
                    if (selected &lt; n_items - 1)
                        ++selected;
                    else
                        selected = 0;
                  break;
              case KEY_UP:
                    if (selected &gt; 0)
                        --selected;
                    else
                        selected = n_items - 1;
                  break;
                case 10: /*enter key*/
                    return selected;
                    break;
            }

            renderItems(win, selected, items, n_items);
        }
    }
}

int menu::renderMenu(WINDOW* menu_win, const char* title, const char* items[], int n_items)
{
    std::string separator{ '+' + std::string(getmaxx(menu_win) - 2, '-') + '+' };
    mvwprintw(menu_win, 1, (getmaxx(menu_win) - strlen(title)) / 2, title); 
    wborder(menu_win, '|', '|', '-', '-', '+', '+', '+', '+');
    mvwprintw(menu_win, 2, 0, separator.c_str());
    wrefresh(menu_win);

    return navigateMenu(menu_win, items, n_items);
}

WINDOW * menu::menuWin(const char* title, const char* items[], int n_items, int y, int x)
{
    int width{};
    for (int index{}; index &lt; n_items; ++index) 
        if (width &lt; static_cast&lt;int&gt;(strlen(items[index])))
            width = strlen(items[index]);
    if (width &lt; static_cast&lt;int&gt;(strlen(title)))
        width = strlen(title);
    width += 4;

    int height{ 4 + n_items };

    return newwin(height, width, y, x);
}

void menu::initMenu()
{
    curs_set(FALSE);
    noecho();
    cbreak();
    refresh();
}


source.cpp &lt;--example of use 

#include "menu.h"
#include &lt;string&gt;

int main()
{
    const char* items[]{
        {"option a"},
        {"option b"},
        {"option c"}
    };

    const char* title{ "Main Menu" };

    initscr();
    menu::initMenu();

    WINDOW* menu = menu::menuWin(title, items, 3, 2, 2);
    int choice = menu::renderMenu(menu, title, items, 3);
    /*use choice to preform an action*/

    mvprintw(0, 0, "%s was chosen.", items[choice]);
    refresh();

    getch();
    endwin();
    return 0;
}
An if inside the loop is usually counterproductive. Consider highlighting the choice afterwards:

    for (int index{}; index &lt; n_items; ++index) {
        mvwprintw(win, 3 + index, 2, items[index]);
    }
    wattron(win, A_BOLD);
    mvwprintw(win, 3 + selected, 2, items[selected]);
    wattroff(win, A_BOLD);




It is very unclear what the 3 and 2 offsets stand for. Apparently they have something to do with the visual layout. Consider giving them some meaningful names.



Since you are writing in c++, you'd be in much better shape operating on vector&lt;char *&gt; rather than a raw array.