Minigui开发之遥控控制逻辑算法
引言
在开发公司的minigui产品时,需要用遥控器来切换显示屏上的图标和控件,这就涉及到一个问题,如何获得下一个选中的图标或控件呢?
解决思路
利用每个控件自身的ID号,建立一张类似矩阵的表,用坐标来定位每个控件,通过编写的查找算法,输入当前选择的控件ID号和遥控动作(上下左右),输出下一个选中的控件ID号。
数据结构
typedef struct{
int id;
int row;
int col;
}NODE_T;
typedef struct{
int nRow;
int nCol;
NODE_T *arrayList[MAX_LOGIN_NUM][MAX_LOGIN_NUM];
}LIST_T;
其中LIST_T中的,nRow和nCol代表目前矩阵表的最大行数和列数,NODE_T为每个元素的结构体数据,arrayList为二维指针数组,最大可保存MAX_LOGIN_NUM*MAX_LOGIN_NUM个元素地址。
在NODE_T中,id即控件的ID号,row和col代表该元素在矩阵表中的坐标。
初始化
初始化过程非常简单,即将最大行数和列数设置为0,并初始化矩阵表,将指针设为NULL。
void initList(LIST_T *list)
{
list->nRow = ;
list->nCol = ; int i = ;
int j = ; for(i = ; i < MAX_LOGIN_NUM; i++)
{
for(j = ; j < MAX_LOGIN_NUM; j++)
{
list->arrayList[i][j] = NULL;
}
}
}
添加节点
添加节点的大体过程,即先判断需要存入的节点坐标,是否在已有矩阵表范围之外,如果在范围外,则需要扩充矩阵表的大小(即更改最大行数和列数),如果在范围内,则需要检查存入的坐标是否已经有节点存在了,在这里,如果该坐标已经有节点存在了,则执行添加节点失败,大家可以根据实际情况来处理。
int addNode(LIST_T *list, int id, int row, int col)
{
int isNeedCheck = ; //0:需要检查该坐标是否存在节点 1:无需检查 //数据合法校验
int numOfRow = getNumOfRow(list);
if(row > (numOfRow - ))
{
list->nRow = row + ;
isNeedCheck = ;
} int numOfCol = getNumOfCol(list);
if(col > (numOfCol - ))
{
list->nCol = col + ;
isNeedCheck = ;
} int ret = ; if( == isNeedCheck)
{
//插入位置是否存在节点,存在则不允许插入
ret = isNodeExist(list, row, col);
if(ret > )
{
printf("Node exist in (%d, %d)\n", row, col);
return (-);
}
} NODE_T *tmp = (NODE_T *)calloc(sizeof(NODE_T), );
tmp->row = row;
tmp->col = col;
tmp->id = id; //将节点插入到链表中
list->arrayList[row][col] = tmp; return ;
}
查找节点
下面就是本文的重点,也是遥控逻辑算法的核心:如何查找到下一个选中的节点。

如上图所示,当前有ABCD四个控件,即矩阵表中有四个元素,它们的坐标分别是 A(0, 0), B(0, 1), C(1, 2), D(2, 1)
此时,用户选中的是控件A,如果用户按下遥控上的“右键”,按照此图,程序应该找到A右边的节点,即B节点。当然这是非常理想的一种情况,实际情况要比这个更加复杂。
假如此时用户已经选择了B,再次按下“右键”时,程序应该有两种搜索方案:
1.同一行循环搜索。即一直在B所在的行来搜索下一个节点,首先搜索的是B的右边,即(0, 2)这个点,如果该点存在元素即返回该元素,如果搜索到了行的尽头仍然没有搜索到,即调回到这一行的开头继续从左至右的搜索,直到找到一个节点(这里将找到A节点)。
2.下跳一行搜索。过程和上述方法类似,都先找到行的尽头,不过这里将跳到下一行的开始,继续从左向右的搜索,直到找到一个节点(这里将找到C节点)。
以上是按下“右键”的处理方式,如果用户按下“左键”,搜索方式大体相同,只不过是将搜索方向由“从左至右”改为“从右至左”。
至于按下“上键”和“下键”的搜索方式,只是在以上两种情况上多加了一层处理,比如,用户当前选择了A节点,然后按下“下键”,首先搜寻的是A节点下方是否存在节点(即(1, 0)),若有则返回,如果没有搜寻到节点的话,则转为按下“右键”的搜寻方式,即在这里,算法将返回B节点。
同理,“上键”的处理方式在找不到上方节点的情况下,将转化为按下“左键”的处理方式。
还需补充一点的是,当搜索到行的尽头时,即第一行和最后一行,需要注意越界的问题,此时应跳转到具有有效数据的行(最后一行按下“下键”,跳到第一行搜索)
下面是“左键”和“右键”的搜索方式,“上键”和“下键”刚刚已经说过,只是多了一层处理而已。
int leftFind(LIST_T *list, int row, int col, int isCircle, int *outRow, int *outCol)
{
//从(row, col)开始向左寻找
getCoordinate(list, row, col, LEFT, isCircle, &row, &col); int i = col; for(; i >= ; i--)
{
if(list->arrayList[row][i] != NULL)
{
*outRow = list->arrayList[row][i]->row;
*outCol = list->arrayList[row][i]->col; return ;
}
} //尾递归调用
leftFind(list, row, col, isCircle, outRow, outCol); return ;
} int rightFind(LIST_T *list, int row, int col, int isCircle, int *outRow, int *outCol)
{
//从(row, col)开始向右寻找
getCoordinate(list, row, col, RIGHT, isCircle, &row, &col); int i = col; for(; i < getNumOfCol(list); i++)
{
if(list->arrayList[row][i] != NULL)
{
*outRow = list->arrayList[row][i]->row;
*outCol = list->arrayList[row][i]->col; return ;
}
} //尾递归调用
rightFind(list, row, col, isCircle, outRow, outCol); return ;
}
Minigui开发之遥控控制逻辑算法的更多相关文章
- 使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 6 - 业务逻辑
翻译:使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 6 - 业务逻辑 Part 3: 设计逻辑层:核心开发 如前所述,我们的解决方案 ...
- Python开发——利用正则表达式实现计算器算法
Python开发--利用正则表达式实现计算器算法 (1)不使用eval()等系统自带的计算方法 (2)实现四则混合运算.括号优先级解析 思路: 1.字符串预处理,将所有空格去除 2.判断是否存在括号运 ...
- cpu的控制单元与语言中的控制逻辑有没有关系?
cpu的控制单元与语言中的控制逻辑有没有关系?
- FIFO 的控制逻辑---verilog代码
FIFO 的控制逻辑---verilog代码 //fifo的例化 wire fifo_full; wire fifo_empty; : ] fifo_dout; :]rd_data_count; :] ...
- 自己动手开发手机APP控制西门子200smart 教程(原创干货)
自己动手开发手机APP控制西门子200smart 教程(原创干货) 自己动手开发手机APP控制西门子200smart 教程(原创干货) 2020-02-09 19:06:45 自己动手开发手机AP ...
- 鸿蒙开发板外设控制 之 实现按键“按下事件”和“释放事件”的通用框架(V0.0.1)
在帖子 <鸿蒙开发板外设控制>直播图文版(2020.10.28) 中我们提到过:"开发板上的按键也可以看作一种 GPIO 外设." 因此,要捕捉按键的状态(按下或释放) ...
- 03python开发之流程控制
03 python开发之流程控制 目录 03 python开发之流程控制 3 流程控制 3.1 流程判断之if判断 3.1.1 代码块 3.1.2 if判断基础语法 3.1.3 案例 3.1.4 if ...
- Form开发中组件控制的几个常用方法
转自:http://oracleseeker.com/2009/09/01/graphical_component_control_in_oracle_ebs_form/ 在Oracle EBS 的F ...
- project开发的程序设计与逻辑设计
非常多时候我们要做庞大project, 就像一棵大树, 方方面面都有自己的细枝末节,而作为开发员的我们,无法时时刻刻去保持对程序的全面认知,所以我们要把程序设计与逻辑设计区分开来. 那么什么是程序设计 ...
随机推荐
- C# Oracle insert 中文乱码
问题描述: 在PL SQL中insert 中文数据,显示不乱码,通过后台insert的中文数据,显示问号. 解决分三步: 1.Select userenv('language') from dual; ...
- hdu1536Nim
sg函数打表的基础应用,第一道ac的sg函数打表题纪念下,直接上代码: hdu1536题目连接 #include<iostream> #include<cstdio> #inc ...
- laravel sum 多个字段
laravel中怎么实现下面的SQL select sum('profit'),sum('order_count') from pro where......; 参考 self::where('id' ...
- Learning from the CakePHP source code - Part I
最近开始痛定思痛,研究cakephp的源码. 成长的路上从来没有捷径,没有小聪明. 只有傻傻的努力,你才能听到到成长的声音. 下面这篇文章虽然过时了,但是还是可以看到作者的精神,仿佛与作者隔着时空的交 ...
- C#变量修饰符
访问修饰符 关键字包括:internal,public,protected和private,用于设置变量的访问级别. public 变量可以做为它所属的类型的一个字段,可以在任何地方访问它. i ...
- JAVA多态问题总结(课堂总结)
面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点.多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发 ...
- 微信小程序跳转页面
小程序页面有2种跳转,可以在wxml页面或者js中: 1,在wxml页面中: <navigator url="../index/index">跳转到新页面</na ...
- openstack私有云布署实践【12.2 网络Neutron-controller节点配置(办公网环境)】
网络这一块推荐使用的是 Neutron--LinuxBirdge的Ha高可用,此高可用方案对Public作用不是很大,Public只用到DHCP,而Private则会用到L3 Agent,则此方案是有 ...
- 深入了解——CSS3新增属性
CSS3 选择器(Selector) 写过 CSS 的人应该对 CSS 选择器不陌生,我们所定义的 CSS 属性之所以能应用到相应的节点上,就是因为 CSS 选择器模式.参考下述代码: 清单 1. C ...
- eclipse怎么连接到MySQL中的表!!!!!
简介: 用eclipse编写的好的代码,我们怎么才能连接到数据库呢?对于初学者,特别是在连接数据库这块经常会发生一些莫名的错误,一般来说,归根是我们连接数据库这一过程发生错误.那么我们如何来解决呢?那 ...