我想創建一個最大10行窗口的菜單,並在窗口中顯示xml文件中的所有項目(包含超過10個項目),通過在窗口中向上/向下滾動查看文件的全部內容。滾動菜單(c代碼)
問題:如何實現這一點在我的API(如在ncurses的滾動菜單):
「如果一個窗口給出的子窗口是不是足夠大,以顯示所有的項目,然後將菜單將滾動。當你在當前列表中的最後一項時,如果你發送REQ_DOWN_ITEM,它將被轉換爲REQ_SCR_DLINE,並且菜單會滾動一個項目,你可以手動給REQ_SCR_操作做滾動,讓我們看看它是如何完成的。我的這個特徵代碼
部分:
static void menu(commands_t *cmd)
{
/* this display only first 10 line */
int i;
char string[ 128 ];
for(i = 0; i < 10; i++) {
snprintf(string, sizeof (string), "%s", list_get_name(cmd->listmgr, i));
menu_list_set_text(cmd->menu, i, string);
}
}
目前,該功能只能顯示從列表中的第10個項目。
A
B
C
D
E
-----------------
Line 01 | F |
Line 02 | G |
Line 03 | H |
Line 04 | I |
Line 05 | J |
Line 06 | K |
Line 07 | L |
Line 08 | M |
Line 09 | N |
Line 10 | O |
-----------------
P
Q
R
S
T
.......
Z
爲此,我試圖創建一個能夠設置在從列表菜單行文本API,在菜單向上/向下移動光標,但我現在該怎麼做出向上或向下移動線沒有。
typedef struct list_info_s list_info_t;
struct list_info_s
{
int position;
char name[ 50 ];
list_info_t *next;
list_info_t *prev;
};
const list_info_t *list_get_list(list_mgr_t *mgr, int pos)
{
const list_info_t *tmp = mgr->first;
int i;
for (i = 0; tmp && i < pos; i++)
tmp = tmp->next;
return tmp;
}
const char *list_get_name(list_mgr_t *mgr, int position)
{
const list_info_t *list = list_get_list(mgr, position);
if((list) && (*list->name)) {
return list->name;
} else {
return 0;
}
}
TO MOVE UP/DOWN:
void commands_handle(commands_t *cmd, int prog_cmd)
{
switch(prog_cmd) {
case MENU_UP:
cmd->menu_position = (cmd->menu_position + cmd->menu_size - 1) % (cmd->menu_size);
menu(cmd);
break;
case MENU_DOWN:
cmd->menu_position = (cmd->menu_position + 1) % (cmd->menu_size);
menu(cmd);
break;
return;
}
}
MENU:
static void menu(commands_t *cmd)
{
/* this display only first 10 line */
int i;
char string[ 128 ];
for(i = 0; i < 10; i++) {
snprintf(string, sizeof (string), "%s", list_get_name(cmd->listmgr, i));
menu_list_set_text(cmd->menu, i, string);
}
}
由於xml可能包含大量項目,因此菜單的窗口最多可用於10個項目行。 什麼編程選項必須通過向上/向下按鈕來顯示文件中的所有行以在菜單上可見?
這是菜單實際API:
#define MENU_MAX 10
struct menu_s
{
char *name;
char text[ MENU_MAX ][ 128 ];
char arguments[ MENU_MAX ][ 128 ];
int commands[ MENU_MAX ];
char back_argument[ 128 ];
int back_command;
int numlines;
int cursor;
int defaultcursor;
};
menu_t *menu_new(const char *name)
{
menu_t *menu = malloc(sizeof(menu_t));
if(!menu) {
return 0;
}
menu->numlines = 0;
menu->cursor = 0;
menu->defaultcursor = 0;
menu->name = strdup(name);
if(!menu->name) {
free(menu);
return 0;
}
return menu;
}
void menu_delete(menu_t *menu)
{
free(menu->name);
free(menu);
}
void menu_reset_num_lines(menu_t *menu)
{
menu->numlines = 0;
}
void menu_set_text(menu_t *menu, int line, const char *text)
{
snprintf(menu->text[ line ], sizeof(menu->text[ 0 ]), "%s", text);
if(line >= menu->numlines) menu->numlines = line + 1;
}
void menu_set_enter_command(menu_t *menu, int line, int command,
const char *argument)
{
menu->commands[ line ] = command;
snprintf(menu->argum#define MENU_MAX 10
struct menu_s
{
char *name;
char text[ MENU_MAX ][ 128 ];
char arguments[ MENU_MAX ][ 128 ];
int commands[ MENU_MAX ];
char back_argument[ 128 ];
int back_command;
int numlines;
int cursor;
int defaultcursor;
};
menu_t *menu_new(const char *name)
{
menu_t *menu = malloc(sizeof(menu_t));
if(!menu) {
return 0;
}
menu->numlines = 0;
menu->cursor = 0;
menu->defaultcursor = 0;
menu->name = strdup(name);
if(!menu->name) {
free(menu);
return 0;
}
return menu;
}
void menu_delete(menu_t *menu)
{
free(menu->name);
free(menu);
}
void menu_reset_num_lines(menu_t *menu)
{
menu->numlines = 0;
}
void menu_set_text(menu_t *menu, int line, const char *text)
{
snprintf(menu->text[ line ], sizeof(menu->text[ 0 ]), "%s", text);
if(line >= menu->numlines) menu->numlines = line + 1;
}
void menu_set_enter_command(menu_t *menu, int line, int command,
const char *argument)
{
menu->commands[ line ] = command;
snprintf(menu->arguments[ line ], sizeof(menu->arguments[ 0 ]),
"%s", argument);
}
void menu_set_back_command(menu_t *menu, int command,
const char *argument)
{
menu->back_command = command;
snprintf(menu->back_argument, sizeof(menu->back_argument),
"%s", argument);
}
void menu_set_cursor(menu_t *menu, int cursor)
{
menu->cursor = cursor;
}
const char *menu_get_name(menu_t *menu)
{
return menu->name;
}
int menu_get_num_lines(menu_t *menu)
{
return menu->numlines;
}
const char *menu_get_text(menu_t *menu, int line)
{
return menu->text[ line ];
}
int menu_get_enter_command(menu_t *menu, int line)
{
return menu->commands[ line ];
}
const char *menu_get_enter_argument(menu_t *menu, int line)
{
return menu->arguments[ line ];
}
int menu_get_back_command(menu_t *menu)
{
return menu->back_command;
}
const char *menu_get_back_argument(menu_t *menu)
{
return menu->back_argument;
}
int menu_get_cursor(menu_t *menu)
{
return menu->cursor;
}
int menu_get_default_cursor(menu_t *menu)
{
return menu->defaultcursor;
}
我嘗試了醜陋的解決方案:
static void menu(commands_t *cmd)
{
int i;
for(i = 0; i < 10; i++) {
char string[ 128 ];
snprintf(string, sizeof (string), "%s", list_get_name(cmd->listmgr, i)
menu_list_set_text(cmd->menu, i, string);
int scroll;
for(scroll = 0; scroll < list_size; scroll++) {
if(cmd->curmenupos == 10 + scroll) {
snprintf(string, sizeof (string), "%s", list_get_name(cmd->listmgr, i + scroll + 1)
menu_list_set_text(cmd->menu, i, string);
}
}
}
}
其中 「CMD-> curmenupos」 是命令來獲取菜單線位置和 「list_size」是來自xml的項目數量
你的問題是什麼? – OldProgrammer
難道你不能只使用[ncurses](http://en.wikipedia.org/wiki/Ncurses)?請參閱[滾動菜單示例](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/menus.html#SCROLLMENUS)。 – jweyrich
這是OSD菜單 – user1840007