我目前正在学习如何在PDcurses 2015社区中使用VC++,并且我注意到menu.h还没有实现,所以我决定扩展这个库供我自己使用(如果您想要的话,尽管复制代码就行了)。
我唯一的问题是:我对名称空间(命名空间和未命名空间)的使用是否正确?这是不是一个很好的方法,因为我看不出有什么理由让一个单独的人或什么东西涉及到类?
注意:我确实像在代码中一样,研究了将函数划分为名称空间的web,但是我找不到它是否适合这个特定的任务。
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 <string>
namespace
{
void renderItems(WINDOW* win, int selected, const char* items[], int n_items)
{
for (int index{}; index < 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 < n_items - 1)
++selected;
else
selected = 0;
break;
case KEY_UP:
if (selected > 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 < n_items; ++index)
if (width < static_cast<int>(strlen(items[index])))
width = strlen(items[index]);
if (width < static_cast<int>(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 <--使用示例
#include "menu.h"
#include <string>
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;
}发布于 2017-10-09 01:57:09
循环中的if通常适得其反。考虑在此之后突出显示选择:
for (int index{}; index < 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);目前还不清楚3和2的抵消意味着什么。很明显他们和视觉布局有关。考虑给他们一些有意义的名字。
因为您是用c++编写的,所以在vector<char *>上操作比在原始数组上操作要好得多。
https://codereview.stackexchange.com/questions/177489
复制相似问题