数值加减框控件的设计
这是一个典型的动态操作控件,我们需要按照下面的分析方法来构建
第一步,建立需求基线
实际上就是整理需求条目:
- 数值支持设置上限、下限、步长、数值等参数,数值加减不超过上下限;
- 数值显示允许设置倍数、小数位数来转成浮点字符串来显示,参见itos 语句
- 支持短按和长按两种状态,短按步长每按一次加减一次步长;长按快速加减步长;
- 提供数值设置好的onchange事件
第二步,分析
构建用例
用户-->按下+按钮[1]-->抬起+按钮[2]
用户-->按下+按钮[1]-->长按+按钮[3]-->定时器累加[4]-->抬起+按钮[5]
用户-->按下-按钮[11]-->抬起-按钮[12]
用户-->按下-按钮[11]-->长按-按钮[13]-->定时器累加[14]-->抬起-按钮[15]
(注:中括号内部是步骤号)
构建属性
这里我们主要关注状态,因此先构建核心属性:
属性 | 类型 | 描述 | 备注 |
---|---|---|---|
val | int | 值 | 开始传入的是默认值 |
minval | int | 下限 | |
maxval | int | 上限 | |
step | int | 步长 | |
bs | int | 倍数 | |
fw | int | 小数位数 | |
m | int | 状态 | 内部使用 0-代表无操作 |
time | int | 定时长度 | 使用settime函数赋值 |
构建各个步骤的识别状态表
过滤掉永久不变的属性,t/rn是onmouse参数
步骤 | val前 | time前 | m前 | t | rn | onmouse事件 | ontimer事件 | val后 | time后 | m后 | 备注 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | val | 0 | 0 | 0 | 1 | m=1,+框变色 | 无 | val | 0 | 1 | |
2 | val | 0 | 1 | 2 | 1 | m=0;val+;+框恢复 | 无 | val+ | 0 | 0 | |
3 | val | 0 | 1 | 3 | 1 | m=2;time=10; | 无 | val | 10 | 2 | |
4 | val | 10 | 2 | - | - | 无 | val+ | val+ | 10 | 2 | |
5 | val | 10 | 2 | 2 | 1 | m=0;time=0;+框恢复 | 无 | val | 0 | 0 | |
11 | val | 0 | 0 | 0 | 2 | m=11,-框变色 | 无 | val | 0 | 11 | |
12 | val | 0 | 11 | 2 | 2 | m=0;val-;-框恢复 | 无 | val- | 0 | 0 | |
13 | val | 0 | 11 | 3 | 2 | m=12;time=10; | 无 | val | 10 | 12 | |
14 | val | 10 | 12 | - | - | 无 | val- | val- | 10 | 12 | |
15 | val | 10 | 12 | 2 | 2 | m=0;time=0;-框恢复 | 无 | val | 0 | 0 |
精简一下:
步骤 | m前 | t | rn | onmouse事件 | ontimer事件 | m后 |
---|---|---|---|---|---|---|
1 | 0 | 0 | 1 | m=1,+框变色 | 无 | 1 |
2 | 1 | 2 | 1 | m=0;val+;+框恢复 | 无 | 0 |
3 | 1 | 3 | 1 | m=2;time=10; | 无 | 2 |
4 | 2 | - | - | 无 | val+ | 2 |
5 | 2 | 2 | 1 | m=0;time=0;+框恢复 | 无 | 0 |
11 | 0 | 0 | 2 | m=11,-框变色 | 无 | 11 |
12 | 11 | 2 | 2 | m=0;val-;-框恢复 | 无 | 0 |
13 | 11 | 3 | 2 | m=12;time=10; | 无 | 12 |
14 | 12 | - | - | 无 | val- | 12 |
15 | 12 | 2 | 2 | m=0;time=0;-框恢复 | 无 | 0 |
第三步:书写代码
//以下代码仅有状态变化的代码,关于绘制控件的draw、show方法请直接参见 数字加减框 控件的源码:
void valadd(){
val=val+step;
if (val>maxval) val=maxval;
}
void valdec(){
val=val-step;
if (val<minval) val=minval;
}
void onchange(){}; //用户继承
//----onmouse方法,用户点击触摸屏上的热区,会调用此方法,其中:
//t:触摸模式: t=0 按下鼠标按钮,相当于触摸屏点击 ;t=1 鼠标移动 ;t=2鼠标抬起;t=3鼠标长按
//rn:热区编号,允许一个控件对应多个热区,多个热区靠rn变量识别,对于按钮等整个控件一个热区,可以忽视rn
void onmouse(int t,int rn)
{ //在此书写有关热区处理方法的代码
if (t==0){
if (rn==1){ //+按钮
m=1;
//+框变色
}
if (rn==2){
m=11;
//-框变色
}
}
if (t==2){
if (rn==1){
if (m==1){
valadd();
}
if (m==2){
settimer(0);
}
m=0;
//+框恢复
}
if (rn==2){
if (m==11){
valdec();
}
if (m==12){
settimer(0);
}
m=0;
//-框恢复
}
onchange();//调用事件告诉用户,数值调整了
}
if (t==3){
if (rn==1){
m=2;
settimer(10);
}
if (rn==2){
m=12;
settimer(10);
}
}
}
//----ontimer方法:status中设置的定时器会调用此方法
//当本控件有属性数值发生变化后,系统会自动调用show方法显示,定时器代码中无需操作界面
void ontimer()
{ //在此书写有关定期器对数据的修改代码
if (m==2){
valadd();
}
if (mm=12){
valdec();
}
}