/* * windows.c * * Created on: Aug 6, 2021 * Author: wuwenfeng */ #include "windows.h" #include "touch.h" //接口 //设置屏幕像素坐标 void Inteface_SetCursor(uint16_t Xpos, uint16_t Ypos) { LCD_SetCursor(Xpos,Ypos); //设置光标位置 LCD_REG_ADDRESS=lcddev.wramcmd; //开始写入GRAM } //往像素坐标写入一个颜色 void Inteface_SetColor(uint16_t color) { LCD_DATA_ADDRESS=color; } //新建一个UI对象 //当时都想法是类似windows的多桌面,每个桌面都能有n个窗口 UI *UI_Init(COLOR_16 background) { UI *ui; ui = (UI*)malloc(sizeof(UI)); if(ui!=NULL) { ui->x=0; ui->y=0; ui->high=240; ui->width=320; ui->background=background; ui->windows=NULL; ui->last_windows=NULL; ui->refresh_ui_flag=1; /* ui->touch=(touch_device*)malloc(sizeof(touch_device)); if(ui->touch!=NULL) { ui->touch->louck=0; ui->touch->tick=0; ui->touch->time=0; ui->touch->times=0; ui->touch->x=0; ui->touch->y=0; ui->touch->old_x=0; ui->touch->old_y=0; ui->touch->acc_x=0; ui->touch->acc_y=0; } */ return ui; } return NULL; } //新建一个窗口 //返回窗口的指针 //将窗口挂载到某个ui window *New_Window(UI *ui,uint16_t x,uint16_t y,uint16_t width,uint16_t high,COLOR_16 background,const char *title) { window *temp_window; temp_window = (window*)malloc(sizeof(window)); if(temp_window!=NULL) { temp_window->background=background; temp_window->high=high; temp_window->width=width; temp_window->x=x; temp_window->y=y; for(int a=0;a<16;a++) { temp_window->title[a]=title[a]; } }else{return NULL;} windows_stack *temp_windows_stack; temp_windows_stack=ui->last_windows; if(temp_windows_stack==NULL) { temp_windows_stack=(windows_stack*)malloc(sizeof(windows_stack)); temp_windows_stack->up=NULL; ui->windows=temp_windows_stack; }else { /* while(temp_windows_stack->next!=NULL) { temp_windows_stack=temp_windows_stack->next; } */ windows_stack *up=temp_windows_stack;//备份当前对象指针 temp_windows_stack->next=(windows_stack*)malloc(sizeof(windows_stack)); temp_windows_stack=temp_windows_stack->next; temp_windows_stack->up=up; } temp_windows_stack->next=NULL; temp_windows_stack->window=temp_window; ui->last_windows=temp_windows_stack; return temp_window; } //关闭某个窗口 //挺麻烦的,除了要释放窗口内存,还要去ui抹掉窗口的指针 void Close_Windows_Stack(UI *ui,windows_stack *temp_windows_stack) { if(temp_windows_stack==ui->windows) { if(temp_windows_stack->next!=NULL) { ui->windows=temp_windows_stack->next; ui->windows->up=NULL; }else { ui->windows=NULL; ui->last_windows=NULL; } }else if(temp_windows_stack==ui->last_windows) { if(temp_windows_stack->up!=NULL) { ui->last_windows=temp_windows_stack->up; ui->last_windows->next=NULL; }else { ui->windows=NULL; ui->last_windows=NULL; } }else { temp_windows_stack->up->next=temp_windows_stack->next; //取出这个节点 把节点的上下补上链接 temp_windows_stack->next->up=temp_windows_stack->up; } free(temp_windows_stack->window); free(temp_windows_stack); } //设置窗口标题 void Set_Windows_Title(window *this_window,const char *title) { for(int a=0;a<16;a++) { this_window->title[a]=title[a]; } } //测试用 void Set_Windows_XY_BY_ACC(window *temp_window,int acc_x,int acc_y) { temp_window->x=temp_window->x+acc_x; temp_window->y=temp_window->y+acc_y; } //显示一个窗口 void Refresh_Window(window *temp_window) { //开始绘制窗口//填充窗口背景 for(uint16_t temp_y=0;temp_yhigh;temp_y++) { Inteface_SetCursor(temp_window->x,temp_window->y+temp_y); for(uint16_t temp_i=0;temp_iwidth;temp_i++) { if(temp_i==0||temp_y==0||temp_i==temp_window->width-1||temp_y==temp_window->high-1) { Inteface_SetColor(BLUE); }else { Inteface_SetColor(temp_window->background); } } } //绘制bar for(uint16_t temp_y=0;temp_y<16;temp_y++) { Inteface_SetCursor(temp_window->x,temp_window->y+temp_y); for(uint16_t temp_i=0;temp_iwidth;temp_i++) { if(temp_i>temp_window->width-16) { Inteface_SetColor(RED); }else { Inteface_SetColor(BLUE); } } } //显示title LCD_ShowString(temp_window->x,temp_window->y,&temp_window->title,16,WHITE,WHITE); } /* * 很可惜 辛辛苦苦写的代码要被放弃 * 用算法实现遮挡关系计算真挺蠢 * * */ void Refresh_UI(UI *ui) { int flag=0; uint16_t dot_y=0,dot_x=0; //画背景 for(dot_y=ui->y;dot_yhigh;dot_y++) { Inteface_SetCursor(dot_x,dot_y); for(dot_x=ui->x;dot_xwidth;dot_x++) { Inteface_SetColor(ui->background); } } windows_stack *temp_windows_stack,*temp_windows_stack2; temp_windows_stack=ui->windows; do { if(temp_windows_stack!=NULL) { flag=1; Refresh_Window(temp_windows_stack->window); //绘制下一个窗口 temp_windows_stack=temp_windows_stack->next; }else { flag=0; } }while(flag); //画背景 /* for(dot_y=0;dot_y<240;dot_y++) { Inteface_SetCursor(dot_x,dot_y); for(dot_x=0;dot_x<320;dot_x++) { flag2=1; temp_windows_stack2 =ui->windows; for(uint16_t temp_a=0;temp_awindow,dot_x,dot_y)) { flag2=0; flag3=1; break; } temp_windows_stack2=temp_windows_stack2->next; } if(flag2==1) { if(flag3==1) { Inteface_SetCursor(dot_x,dot_y); flag3=0; } Inteface_SetColor(ui->background); } } } */ } /* * 检查坐标是否命中窗口 * * */ #define BODY 1 #define BAR 2 #define CLOSE 3 uint8_t Chack(window *this_window,int x,int y) { int a=0; if(((x>=this_window->x)&&(x<(this_window->x+this_window->width)))&&((y>=this_window->y+16)&&(y<(this_window->y+this_window->high)))) { a=1; } if(((x>=this_window->x)&&(x<(this_window->x+this_window->width-16)))&&((y>=this_window->y)&&(y<(this_window->y+16)))) { a=2; } if((x>=(this_window->x+this_window->width-16))&&(x<(this_window->x+this_window->width))&&((y>=this_window->y)&&(y<(this_window->y+16)))) { a=3; } return a; } void UI_Server(UI *ui) { windows_stack *temp_windows_stack=NULL; window *temp_window; //touch_device *temp_touch=NULL; int flag=0; uint8_t hit_flag=0; int t_x,t_y; //touch //temp_touch=ui->touch; if(TP_XY(&t_x, &t_y))//Touch_Server(temp_touch)) { temp_window=NULL; temp_windows_stack=ui->last_windows; //获取ui中最前端的窗口 从前往后扫描 do { if(temp_windows_stack!=NULL) //如果有窗口就开始扫描 { flag=1; //检查到有窗口 需要循环一次以检查是否有下一个窗口 // temp_window=temp_windows_stack->window; //取出这个窗口 hit_flag=Chack(temp_window,t_x,t_y); //检查触摸是否命中 直接返回命中窗口的位置 if(hit_flag) // 命中继续 { if(temp_windows_stack!=ui->last_windows) //检查是否最前端的窗口 如果不是就放最前面 { if(temp_windows_stack!=ui->windows) //检查是否最后端的窗口 因为显示是从最后端往前显示的 所以ui有最后端窗口的入口 { temp_windows_stack->up->next=temp_windows_stack->next; //取出这个节点 把节点的上下补上链接 temp_windows_stack->next->up=temp_windows_stack->up; }else { ui->windows=temp_windows_stack->next; //如果是最后端的窗口 则取出这个节点后入口就变下一个节点了 ui->windows->up=NULL; //倒数第二变最后端 在走就没了 所以要清空指针 } temp_windows_stack->next=NULL; //取出的节点要放在最前端 所以 无法再往前 清空往前的指针 temp_windows_stack->up=ui->last_windows; //上一个指针就是原来的最后一个 ui->last_windows->next=temp_windows_stack; //原来的最后一个指向现在的最后一个 ui->last_windows=temp_windows_stack; //更新ui中的最后一个的入口 ui->refresh_ui_flag=1; //发生了变化 刷新ui的显示 } //检查标中窗口的什么位置 switch(hit_flag) { case CLOSE: Close_Windows_Stack(ui,temp_windows_stack); ui->refresh_ui_flag=1; //发生了变化 刷新ui的显示 break; case BAR: if(ui->window_move_lock==0) { ui->window_move_x=t_x; ui->window_move_y=t_y; } Set_Windows_XY_BY_ACC(temp_windows_stack->window,t_x-ui->window_move_x,t_y-ui->window_move_y); ui->window_move_x=t_x; ui->window_move_y=t_y; ui->refresh_ui_flag=1; //发生了变化 刷新ui的显示 break; case BODY: //ui->background=temp_windows_stack->window->background; //ui->refresh_ui_flag=1; break; } flag=0; //结束扫描 防止穿透当前窗口 } temp_windows_stack=temp_windows_stack->up; //往前扫描 }else { flag=0; //一个窗口都没有 直接结束循环 } }while(flag); ui->window_move_lock=1; }else { ui->window_move_lock=0; } //display if(ui->refresh_ui_flag==1) { ui->refresh_ui_flag=0; Refresh_UI(ui); } }