多级菜单框架(C实现)
2017-05-22 20:25
323 查看
以前见过的多级菜单都是用索引号实现,但是这种菜单修改不易,正好这段时间我要在OLED上显示菜单,所以就编了一个框架出来,代码如下
C文件
头文件
#ifndef _PARALLEL_MENU_H
#define _PARALLEL_MENU_H
#include "common.h"
#define MAX_NUM_OF_PAGE 24
typedef enum//键值枚举变量
{
keyup,
keydown,
keyleft,
keyright,
keyenter
}KeyValue;
typedef enum //屏幕位置枚举变量
{
fristline,
secondline,
thirdline,
fourthline
}OptPosition;
typedef enum
{
strings,//0
number,//1
smallnum,//2
adjustblestr,//3
adjustablenum,//4
adjustblesmall//5
}Type;
struct _SmallNum
{
int integer;
unsigned char leave;
};
union optcontent
{
unsigned char* str;
int* num;
struct _SmallNum smallnum;
};
struct _Page
{
char optnum;//选项数目
struct _Option* option;//本页选项结构体数组指针
char selection;//当前选中的选项标号,从0开始计数
};
struct _Option
{
Type flag;//用作标识普通选项与可调整选项的标志位 0普通 1可调整
unsigned char* name;
union optcontent content;
};
typedef struct _Page Page;
typedef struct _Option Option;
typedef struct _SmallNum SmallNum;
void SetPageNum(int num);
void SetPage(int num,int optnum,unsigned char* str);
void SetOptContent(char flag,unsigned char* name,void* content);
void EndPageSet();
void _SetPosition();
void process_KeyAction(KeyValue keyvalue);
void process_optchange(char flag);
void process_valuechange(char flag);
void process_Enter();
void _adjustblestr(char flag);
void _adjustablenum(char flag);
void _adjustblesmall(char flag);
因为为了展现框架,即与平台无关,一些显示函数如DrawOpt没有给出,另外优化部分也去除掉了
这个框架支持float,int型变量调整,我感觉写的时候应该用到了一丢丢C++,也不枉费我之前的学习了,233
不过确实,用C来写面向对象会感觉不自在。。。
应用例子:
SetPageNum(4);
SetPage(1,3,"S3010-PID");
SetOptContent(5,"S-P",&SP);
SetOptContent(5,"S-I",&SI);
SetOptContent(5,"S-D",&SD);
SetPage(2,3,"Motor-PID");
SetOptContent(5,"M-P",&MP);
SetOptContent(5,"M-I",&MI);
SetOptContent(5,"M-D",&MD);
SetPage(3,1,"Trg-Speed");
SetOptContent(4,"Trg-V",&spee
4000
d);
SetPage(4,1,"YuZhi");
SetOptContent(4,"yuzhi",&yuzhi);
EndPageSet();
我感觉这样设置就方便多了。。。
效果图:
C文件
#include "parallelmenu.h" #include "include.h" #include <string.h> #define check 1 Page* current_page; Option* current_opt; Page* start_of_pagelist; char pagenum; void SetPageNum(int num) { #if check if(num>MAX_NUM_OF_PAGE) return; #endif // check pagenum=num; start_of_pagelist=(Page*)malloc(num*sizeof(Page)); } void SetPage(int num,int optnum,unsigned char* str) { #if check if(num>pagenum||num<1) return; #endif // check optnum++;//加页面名字 current_page=start_of_pagelist+num-1; current_page->optnum=optnum; current_page->option=(Option*)malloc(optnum*sizeof(Option)); current_opt=current_page->option; current_opt->flag=(Type)0; current_opt->content.str=str; current_opt->name=0; } SmallNum GetSmallNum(float num) { SmallNum smallnum; smallnum.integer=(int)num; smallnum.leave=(int)((num-(int)num)*100); return smallnum; } void SetOptContent(char flag,unsigned char* name,void* content) { #if check if(current_opt>=current_page->option+current_page->optnum-1) return; #endif // check current_opt++; current_opt->flag=(Type)flag; switch(flag) { case 0: case 3: current_opt->content.str=(unsigned char*)content;break; case 1: case 4: current_opt->content.num=(int*)content;break; case 2: case 5: current_opt->content.smallnum=GetSmallNum(*(float*)content); default: break; } current_opt->name=name; } void EndPageSet() { current_page=start_of_pagelist; current_page->selection=0; current_opt=current_page->option; _SetPosition(); } void _SetPosition() { OLED_Clear(); char leave=current_page->optnum-current_page->selection; if(leave>4) leave=4; char i=0; for(;i<leave;i++) DrawOpt((OptPosition)i); OLED_Refresh_Gram(); } void process_KeyAction(KeyValue keyvalue) { switch(keyvalue) { case keyup: process_optchange(1);break; case keydown: process_optchange(0);break; case keyleft: process_valuechange(1);break; case keyright: process_valuechange(0);break; case keyenter: process_Enter();break; default: break; } } void process_optchange(char flag) { if(flag)//上键 { if(current_page->selection==0); else current_page->selection--; } else//下键 { if(current_page->selection==current_page->optnum-1); else current_page->selection++; } current_opt=current_page->option+current_page->selection;//更新 _SetPosition();//绘制 }//只把current_opt变为选择选项 void process_valuechange(char flag) { if(current_page->selection==0) { if(flag)//回退 { if(current_page-start_of_pagelist) { current_page--; current_opt=current_page->option; current_page->selection=0; } else { current_page=start_of_pagelist+pagenum-1; current_opt=current_page->option; current_page->selection=0; } } else//确认 { if(current_page-start_of_pagelist<pagenum-1) { current_page++; current_opt=current_page->option; current_page->selection=0; } else { current_page=start_of_pagelist; current_opt=current_page->option; current_page->selection=0; } } _SetPosition();//绘制 } else { switch(current_opt->flag) { //case adjustblestr: _adjustblestr(flag);break; //待扩展 case adjustablenum: _adjustablenum(flag);break; case adjustblesmall: _adjustblesmall(flag);break; default: break; } _SetPosition();//绘制 } void process_Enter() { } void _adjustblestr(char flag) { } void _adjustablenum(char flag) { if(flag)//左 { if(*current_opt->content.num) (*current_opt->content.num)--; } else//右 { if((*current_opt->content.num)<255) (*current_opt->content.num)++; } } void _adjustblesmall(char flag) { static SmallNum _smallnum; _smallnum=current_opt->content.smallnum; if(flag) { if(_smallnum.integer||_smallnum.leave) { if(!_smallnum.leave) { _smallnum.integer--; _smallnum.leave=99; } else _smallnum.leave--; } } else { if((~_smallnum.integer)||(~_smallnum.leave)) { if(_smallnum.leave==99) { _smallnum.integer++; _smallnum.leave=0; } else _smallnum.leave++; } } current_opt->content.smallnum=_smallnum; }
头文件
#ifndef _PARALLEL_MENU_H
#define _PARALLEL_MENU_H
#include "common.h"
#define MAX_NUM_OF_PAGE 24
typedef enum//键值枚举变量
{
keyup,
keydown,
keyleft,
keyright,
keyenter
}KeyValue;
typedef enum //屏幕位置枚举变量
{
fristline,
secondline,
thirdline,
fourthline
}OptPosition;
typedef enum
{
strings,//0
number,//1
smallnum,//2
adjustblestr,//3
adjustablenum,//4
adjustblesmall//5
}Type;
struct _SmallNum
{
int integer;
unsigned char leave;
};
union optcontent
{
unsigned char* str;
int* num;
struct _SmallNum smallnum;
};
struct _Page
{
char optnum;//选项数目
struct _Option* option;//本页选项结构体数组指针
char selection;//当前选中的选项标号,从0开始计数
};
struct _Option
{
Type flag;//用作标识普通选项与可调整选项的标志位 0普通 1可调整
unsigned char* name;
union optcontent content;
};
typedef struct _Page Page;
typedef struct _Option Option;
typedef struct _SmallNum SmallNum;
void SetPageNum(int num);
void SetPage(int num,int optnum,unsigned char* str);
void SetOptContent(char flag,unsigned char* name,void* content);
void EndPageSet();
void _SetPosition();
void process_KeyAction(KeyValue keyvalue);
void process_optchange(char flag);
void process_valuechange(char flag);
void process_Enter();
void _adjustblestr(char flag);
void _adjustablenum(char flag);
void _adjustblesmall(char flag);
因为为了展现框架,即与平台无关,一些显示函数如DrawOpt没有给出,另外优化部分也去除掉了
这个框架支持float,int型变量调整,我感觉写的时候应该用到了一丢丢C++,也不枉费我之前的学习了,233
不过确实,用C来写面向对象会感觉不自在。。。
应用例子:
SetPageNum(4);
SetPage(1,3,"S3010-PID");
SetOptContent(5,"S-P",&SP);
SetOptContent(5,"S-I",&SI);
SetOptContent(5,"S-D",&SD);
SetPage(2,3,"Motor-PID");
SetOptContent(5,"M-P",&MP);
SetOptContent(5,"M-I",&MI);
SetOptContent(5,"M-D",&MD);
SetPage(3,1,"Trg-Speed");
SetOptContent(4,"Trg-V",&spee
4000
d);
SetPage(4,1,"YuZhi");
SetOptContent(4,"yuzhi",&yuzhi);
EndPageSet();
我感觉这样设置就方便多了。。。
效果图:
相关文章推荐
- 用XSL与XML实现多级菜单
- 用popup实现右键多级菜单
- php ajax实现的二级(多级)联动菜单(2008-10-21,11:36:08)
- 用JavaScript实现横向滑出的多级竖向菜单_网页代码站(www.webdm.cn)
- 单片机c语言下lcd多级菜单的一种实现方法
- 用DWR框架技术轻松实现动态级联菜单
- 用XSL与XML实现多级树形菜单
- Android提高十七篇之多级树形菜单的实现
- php ajax实现的二级(多级)联动菜单(2008-10-21,11:36:08)
- Android提高十七篇之多级树形菜单的实现
- 用PHP实现多级树型菜单
- 用DWR框架技术轻松实现动态级联菜单
- JS实多级联动下拉菜单类,简单实现省市区联动菜单!
- php ajax实现的二级(多级)联动菜单(2008-10-21,11:36:08)
- 三个函数实现框架菜单自绘
- 用PHP实现多级树型菜单
- 用prototype实现的简单小巧的多级联动菜单
- Javascript实现网页上的多级菜单
- ExtJs多级联动菜单的一种实现
- Android提高十七篇之多级树形菜单的实现