302 lines
7.5 KiB
C
302 lines
7.5 KiB
C
/**
|
||
* @file menu_param.c
|
||
* @brief 菜单参数管理模块(可裁剪功能)
|
||
*/
|
||
#include "menu_core.h"
|
||
#include "menu_data.h"
|
||
|
||
#if MENU_CONFIG_ENABLE_PARAM
|
||
|
||
/************************** 全局变量定义 **************************/
|
||
MenuParam s_menu_params[MENU_CONFIG_MAX_PARAMS];
|
||
|
||
/**
|
||
* @brief 查找参数(通过参数ID)
|
||
* @param param_id 参数ID
|
||
* @return 参数指针(NULL表示未找到)
|
||
*/
|
||
static MenuParam* menu_param_find(uint16_t param_id)
|
||
{
|
||
for (uint16_t i = 0; i < MENU_CONFIG_MAX_PARAMS; i++)
|
||
{
|
||
if (s_menu_params[i].is_registered && s_menu_params[i].id == param_id)
|
||
{
|
||
return &s_menu_params[i];
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* @brief 将浮点值转换为参数内部值(根据类型)
|
||
* @param param 参数指针
|
||
* @param value 浮点值
|
||
* @return 转换后的内部值(通过指针返回)
|
||
*/
|
||
static void menu_param_float_to_internal(MenuParam* param, float value)
|
||
{
|
||
MENU_ASSERT(param != NULL);
|
||
|
||
// 确保值在范围内
|
||
if (value < param->min_val)
|
||
{
|
||
value = param->min_val;
|
||
}
|
||
else if (value > param->max_val)
|
||
{
|
||
value = param->max_val;
|
||
}
|
||
|
||
// 应用缩放因子
|
||
value /= param->scale;
|
||
|
||
// 根据参数类型转换
|
||
switch (param->type)
|
||
{
|
||
case MENU_PARAM_TYPE_INT8:
|
||
param->value.i8 = (int8_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT8:
|
||
param->value.u8 = (uint8_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_INT16:
|
||
param->value.i16 = (int16_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT16:
|
||
param->value.u16 = (uint16_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_INT32:
|
||
param->value.i32 = (int32_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT32:
|
||
param->value.u32 = (uint32_t)value;
|
||
break;
|
||
case MENU_PARAM_TYPE_FLOAT:
|
||
param->value.f = value;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 将参数内部值转换为浮点值(根据类型)
|
||
* @param param 参数指针
|
||
* @return 浮点值
|
||
*/
|
||
static float menu_param_internal_to_float(const MenuParam* param)
|
||
{
|
||
MENU_ASSERT(param != NULL);
|
||
|
||
float value = 0.0f;
|
||
|
||
// 根据参数类型转换
|
||
switch (param->type)
|
||
{
|
||
case MENU_PARAM_TYPE_INT8:
|
||
value = (float)param->value.i8;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT8:
|
||
value = (float)param->value.u8;
|
||
break;
|
||
case MENU_PARAM_TYPE_INT16:
|
||
value = (float)param->value.i16;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT16:
|
||
value = (float)param->value.u16;
|
||
break;
|
||
case MENU_PARAM_TYPE_INT32:
|
||
value = (float)param->value.i32;
|
||
break;
|
||
case MENU_PARAM_TYPE_UINT32:
|
||
value = (float)param->value.u32;
|
||
break;
|
||
case MENU_PARAM_TYPE_FLOAT:
|
||
value = param->value.f;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// 应用缩放因子
|
||
return value * param->scale;
|
||
}
|
||
|
||
/**
|
||
* @brief 注册参数到菜单节点(参数管理功能)
|
||
* @param node_id 菜单节点ID(参数与菜单绑定)
|
||
* @param param_id 参数ID(唯一)
|
||
* @param type 参数类型
|
||
* @param min_val 最小值(浮点型,内部自动转换)
|
||
* @param max_val 最大值(浮点型,内部自动转换)
|
||
* @param default_val 默认值(浮点型,内部自动转换)
|
||
* @param scale 缩放因子(如0.1表示保留1位小数)
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_register(MenuNodeId node_id, uint16_t param_id, MenuParamType type, float min_val, float max_val, float default_val, float scale)
|
||
{
|
||
if (scale <= 0.0f)
|
||
{
|
||
return MENU_ERR_INVALID_PARAM;
|
||
}
|
||
|
||
// 查找菜单节点
|
||
MenuNode* node = menu_core_find_node(node_id);
|
||
if (node == NULL)
|
||
{
|
||
return MENU_ERR_NODE_NOT_FOUND;
|
||
}
|
||
|
||
// 检查参数ID是否已存在
|
||
if (menu_param_find(param_id) != NULL)
|
||
{
|
||
return MENU_ERR_INVALID_PARAM;
|
||
}
|
||
|
||
// 查找空闲参数位置
|
||
MenuParam* param = NULL;
|
||
for (uint16_t i = 0; i < MENU_CONFIG_MAX_PARAMS; i++)
|
||
{
|
||
if (!s_menu_params[i].is_registered)
|
||
{
|
||
param = &s_menu_params[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (param == NULL)
|
||
{
|
||
return MENU_ERR_OUT_OF_MEMORY;
|
||
}
|
||
|
||
// 初始化参数
|
||
MENU_MEM_SET_ZERO(param, sizeof(MenuParam));
|
||
param->id = param_id;
|
||
param->type = type;
|
||
param->min_val = min_val;
|
||
param->max_val = max_val;
|
||
param->scale = scale;
|
||
param->is_registered = true;
|
||
|
||
// 设置默认值
|
||
menu_param_float_to_internal(param, default_val);
|
||
// 保存默认值
|
||
menu_param_float_to_internal((MenuParam*)¶m->default_val, default_val);
|
||
|
||
// 将参数与菜单节点绑定
|
||
node->param_id = param_id;
|
||
|
||
MENU_DEBUG("Param registered: ID=%d, Type=%d, Range=[%0.2f, %0.2f], Default=%0.2f, Scale=%0.2f",
|
||
param_id, type, min_val, max_val, default_val, scale);
|
||
|
||
return MENU_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置参数值
|
||
* @param param_id 参数ID
|
||
* @param value 新值(浮点型,内部自动转换)
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_set_value(uint16_t param_id, float value)
|
||
{
|
||
// 查找参数
|
||
MenuParam* param = menu_param_find(param_id);
|
||
if (param == NULL)
|
||
{
|
||
return MENU_ERR_NODE_NOT_FOUND;
|
||
}
|
||
|
||
// 设置新值
|
||
menu_param_float_to_internal(param, value);
|
||
|
||
MENU_DEBUG("Param set: ID=%d, Value=%0.2f (Internal: %0.2f)",
|
||
param_id, value, menu_param_internal_to_float(param));
|
||
|
||
return MENU_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取参数值
|
||
* @param param_id 参数ID
|
||
* @param value 输出参数,当前值(浮点型)
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_get_value(uint16_t param_id, float* value)
|
||
{
|
||
if (value == NULL)
|
||
{
|
||
return MENU_ERR_INVALID_PARAM;
|
||
}
|
||
|
||
// 查找参数
|
||
MenuParam* param = menu_param_find(param_id);
|
||
if (param == NULL)
|
||
{
|
||
return MENU_ERR_NODE_NOT_FOUND;
|
||
}
|
||
|
||
// 获取当前值
|
||
*value = menu_param_internal_to_float(param);
|
||
|
||
MENU_DEBUG("Param get: ID=%d, Value=%0.2f", param_id, *value);
|
||
|
||
return MENU_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief 将参数恢复为默认值
|
||
* @param param_id 参数ID
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_restore_default(uint16_t param_id)
|
||
{
|
||
// 查找参数
|
||
MenuParam* param = menu_param_find(param_id);
|
||
if (param == NULL)
|
||
{
|
||
return MENU_ERR_NODE_NOT_FOUND;
|
||
}
|
||
|
||
// 恢复默认值
|
||
float default_val = menu_param_internal_to_float((const MenuParam*)¶m->default_val);
|
||
return menu_param_set_value(param_id, default_val);
|
||
}
|
||
|
||
/**
|
||
* @brief 增加参数值(用于菜单上下键调整)
|
||
* @param param_id 参数ID
|
||
* @param step 步长(浮点型)
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_increase(uint16_t param_id, float step)
|
||
{
|
||
float current_val = 0.0f;
|
||
MenuErrCode err = menu_param_get_value(param_id, ¤t_val);
|
||
if (err != MENU_OK)
|
||
{
|
||
return err;
|
||
}
|
||
|
||
return menu_param_set_value(param_id, current_val + step);
|
||
}
|
||
|
||
/**
|
||
* @brief 减少参数值(用于菜单上下键调整)
|
||
* @param param_id 参数ID
|
||
* @param step 步长(浮点型)
|
||
* @return 错误码
|
||
*/
|
||
MenuErrCode menu_param_decrease(uint16_t param_id, float step)
|
||
{
|
||
float current_val = 0.0f;
|
||
MenuErrCode err = menu_param_get_value(param_id, ¤t_val);
|
||
if (err != MENU_OK)
|
||
{
|
||
return err;
|
||
}
|
||
|
||
return menu_param_set_value(param_id, current_val - step);
|
||
}
|
||
|
||
#endif // MENU_CONFIG_ENABLE_PARAM
|