轻量级的菜单系统,可移植性强

用c语言写的基于链表结构的多级菜单显示,菜单项目支持动态添加和删除,只要内存够用,理论上可以添加任意级菜单,类似于文件系统

menu.h

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include <curses.h>

#define DISPLAY_C
#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({          \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) ); })

#define CURR_PTR " =>>"

typedef enum
{
    key_left = 0,
    key_right,
    key_up,
    key_down,
    key_enter,
    key_back,
    key_sum,
    key_none,
} keys;
typedef struct displist_t
{
    int size;
    int cur_idx;
    endpot *cur;
    endpot *start;
    endpot *end;
} displist;
typedef enum{
    in_prev = 0,
    in_list,
    in_next,
    in_child,
    in_parent,
    in_error
}disp_ret;
struct stack_node
{
    unsigned long data;
    struct stack_node *next;
};
struct list_t
{
    struct list_t *prev, *next;
};

typedef enum
{
    pot = 0,
    dir,
} node_flag;

typedef struct menu
{
    int idx;
    char name[30];
    char *bmp;
    void *arg;
    void (*func)(void *);
    void (*disp)(void *);
} menu_item;

typedef struct node
{
    int lvl;
    node_flag flag;
    int subnum;
    menu_item item;
    struct node *current;
    struct node *first,*end;
    struct node *child, *parent;
    struct node *prev, *next;
} endpot;

typedef struct node *pendpot;

void init_list(endpot *ep);
//根目录
extern endpot root;
void endpot_add_next(endpot *ep, endpot *newone);
void endpot_del(endpot *del);
void endpot_add_child(endpot *ep, endpot *child);
void endpot_add_parent(endpot *ep, endpot *parent);
void endpot_init(endpot *ep, char *name, node_flag flag);

endpot *alloc_endpot(int num);
void free_endpot(endpot *p);

endpot *endpot_add(endpot *parent, char *name, node_flag flag, void (*fun)(void *), void *arg);

void endpot_delete(endpot *ep);
#define ADD_POT_MENU(parent, name, fun) \
    pendpot name = endpot_add(parent, #name, pot, fun)
#define ADD_DIR_MENU(parent, name) \
    pendpot name = endpot_add(parent, #name, dir, NULL)
#define ADD_POT(parent, name, fun) endpot_add(parent, name, pot, fun, NULL)
#define ADD_DIR(parent, name) endpot_add(parent, name, dir, NULL, NULL)
keys getkey(void);
endpot *get_cur_ep(endpot *ep, keys key);
int is_root(endpot *ep);
int update_itemlist_idx(endpot *ep);
void display_list(displist *disp);
void currentlistprint(endpot *ep);
void menu_run(endpot *ep);
typedef struct stack_node *PtrToNode;
typedef PtrToNode Stack;
Stack create_stack();
void push_stack(Stack s, unsigned long data);
void pop_stack(Stack s);
unsigned long top_stack(Stack s);
int stack_is_empty(Stack s);

最后添加一个小demo,demo.c

#include "myz_menu.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include <curses.h>

void quit_menu(void *arg)
{
    endwin();
    exit(1);
}

void printf_menu(void *arg)
{
    endwin();
    printf("hello world\n");
    sleep(1);
    exit(1);
}
void add_dir(void *arg)
{
    endpot *news = endpot_add(root.first, "new dir", dir, NULL, NULL);
}


void add_pot(void *arg)
{
    endpot *news = endpot_add(root.first, "new pot", pot, NULL, NULL);
    endpot_delete(root.first->next);
}

int main(int argc, char *argv[])
{
    pendpot file = ADD_DIR(&root, "file");
    pendpot edit = ADD_DIR(&root, "edit");
    pendpot select = ADD_DIR(&root, "select");
    pendpot view = ADD_DIR(&root, "view");
    pendpot gototo = ADD_DIR(&root, "goto");
    pendpot runs = ADD_DIR(&root, "runs");
    pendpot terml = ADD_DIR(&root, "terml");
    pendpot help = ADD_DIR(&root, "help");
    pendpot quit = ADD_POT(&root, "quit", quit_menu);
    pendpot new_file = ADD_DIR(file, "new file");
    pendpot open_file = ADD_DIR(file, "open file");
    pendpot closef = ADD_DIR(file, "closef");
    pendpot new_windows = ADD_DIR(file, "new_windows");
    pendpot open_windows = ADD_DIR(file, "open_windows");
    pendpot save_file = ADD_DIR(file, "save_file");
    pendpot save_all = ADD_DIR(file, "save_all");
    pendpot redo = ADD_DIR(edit, "redo");
    pendpot copy = ADD_DIR(edit, "copy");
    pendpot paste = ADD_DIR(edit, "paste");
    pendpot print = ADD_POT(edit, "print", printf_menu);
    pendpot add_p = ADD_POT(edit, "add a new pot", add_pot);
    pendpot add_d = ADD_POT(edit, "add a new dir", add_dir);
    pendpot s_all = ADD_DIR(select, "select all");
    pendpot us_all = ADD_DIR(select, "unselect all");
    pendpot repalce = ADD_DIR(select, "replace");
    pendpot aq = ADD_DIR(select, "problem");
    pendpot back = ADD_DIR(gototo, "back to");
    pendpot lunch = ADD_DIR(runs, "lunch");
    pendpot newterm = ADD_DIR(terml, "new term");
    pendpot closterm = ADD_DIR(terml, "close term");
    pendpot welcom = ADD_DIR(help, "welcome use");
    pendpot doc = ADD_DIR(help, "document");
#ifdef DISPLAY_C
    initscr();
    noecho();
    move(LINES / 2, COLS / 2);
    scroll(stdscr);
    box(stdscr, '*', '#');
    keypad(stdscr, TRUE);
    addstr("START MENU DEMO");
    move(LINES / 2 + 1, COLS / 2);
    int st = baudrate();
    mvprintw(LINES / 2 + 1, COLS / 2, "SPEED = %d BPS", st);
    refresh();
    sleep(1);
#endif
    menu_run(file);
#ifdef DISPLAY_C
    endwin();
#endif
}

linux上编译的时候需要提前安装curses
进入菜单
在这里插入图片描述
在这里插入图片描述
可以通过按动键盘上的 a,s,d,w,q,r控制菜单的跳转和执行
源码下载链接 :https://download.csdn.net/download/myz348/19475444

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值